VitrinaAPI

Espacio de prueba

Un workspace sintético aparte de tus datos reales, con claves `sk_test_`: aprovisionar, reiniciar y ver lo que quedó capturado en vez de salir.

Beta
Puede cambiar en cualquier momento, con una entrada en el changelog y aviso a quienes la llamaron recientemente — ver versionado.

Descarga la proyección completa de la API pública: openapi.json.

Probar tu integración sin tocar datos reales explica este recurso en prosa, con ejemplos ejecutables.

MétodoRutaQué hace
GET/sandboxThis workspace's sandbox state
POST/sandbox/automotiveProvision a synthetic automotora (the sandbox for sk_test_ keys)
POST/sandbox/clinicProvision a synthetic demonstration clinic
GET/sandbox/outboundOutbound sends that were captured instead of delivered
GET/sandbox/outbound/{id}One outbound send that was captured instead of delivered
POST/sandbox/resetReset a sandbox to the data its seed generates

GET /sandbox

This workspace's sandbox state

Whether the calling workspace IS a sandbox (and from which seed), and whether it has provisioned one. Both halves are about the caller; there is no cross-tenant read here.

curl https://api.vitrinadev.com/api/v1/sandbox \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "is_sandbox": false,
    "seed": null,
    "sandbox_of": null,
    "vertical": null,
    "provisioned_sandbox": {
      "tenant_id": "34d213e0-5cac-4c86-a57c-4db28d59b9ec",
      "name": "Autos Alameda (demostración)",
      "slug": "autos-alameda-demo-3",
      "seed": "docs-2697-demo",
      "vertical": "automotive",
      "created_at": "2026-09-23T05:10:02.000Z"
    }
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /sandbox/automotive

Provision a synthetic automotora (the sandbox for sk_test_ keys)

Creates this workspace's SANDBOX: a separate workspace bound to it, holding a generated dealership — ~40 units with real makes, models and CLP prices, 30 buyers each with a conversation and a lead, 10 cotizaciones and 5 reservas — and mints one sk_test_ key for it, returned once. Test keys minted later with POST /api-keys \{livemode:false\} bind to the same sandbox. A test key authenticates ONLY there: it can never read or write this workspace. Zero real data (phones in an unassigned mobile block, e-mail on RFC 2606 domains, RUTs in a never-issued block, no plates or VINs). Every outbound send is captured instead of delivered, and no real channel may be connected. Deterministic from seed. Idempotent: one sandbox per workspace, of either vertical — a second call returns it with created: false, its vertical and no key.

Cuerpo

CampoTipoObligatorioRestricciones
seedstringmín. 3, máx. 64
namestringmín. 2, máx. 120
vehicle_countinteger≥ 10, ≤ 200
contact_countinteger≥ 15, ≤ 300
curl -X POST https://api.vitrinadev.com/api/v1/sandbox/automotive \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "seed": "docs-2697-demo"
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "created": false,
    "tenant": {
      "id": "34d213e0-5cac-4c86-a57c-4db28d59b9ec",
      "name": "Autos Alameda (demostración)",
      "slug": "autos-alameda-demo-3"
    },
    "vertical": "automotive",
    "seed": "docs-2697-demo",
    "stats": {},
    "test_key": null
  }
}

Responde: 200 · 201 · 400 · 401 · 403 · 404 · 409 · 429

POST /sandbox/clinic

Provision a synthetic demonstration clinic

Creates a workspace holding a generated dental clinic — professionals, catálogo, a year of agenda, presupuestos with their lineages, payments in instalments, expenses, boletas, packs and commissions — and mints an MCP key for it. The clinic is a pure function of seed, so the same seed reproduces the same clinic. Zero real data: RUTs come from a reserved, never-issued block, phones from an unassigned mobile block and e-mail addresses from RFC 2606 domains. Every outbound send the workspace makes is captured instead of delivered, and no real channel may be connected to it. Idempotent per asking workspace: a second call returns the first call's sandbox with created: false and no key.

Cuerpo

CampoTipoObligatorioRestricciones
seedstringmín. 3, máx. 64
namestringmín. 2, máx. 120
monthsinteger≥ 1, ≤ 24
patient_countinteger≥ 20, ≤ 2000
professional_countinteger≥ 4, ≤ 6
curl -X POST https://api.vitrinadev.com/api/v1/sandbox/clinic \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "seed": "docs-2697-clinic"
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "created": false,
    "tenant": {
      "id": "cdc3ebc7-ca87-4dec-aadc-583c6af4fdc2",
      "name": "Clínica Dental Aurora (demo)",
      "slug": "clinica-demo-2"
    },
    "seed": "docs-2697-clinic",
    "stats": {},
    "mcp": null
  }
}

Responde: 200 · 201 · 400 · 401 · 403 · 404 · 409 · 429

GET /sandbox/outbound

Outbound sends that were captured instead of delivered

The demonstration surface: every WhatsApp, e-mail, voice call, webhook and document a sandbox workspace tried to send, with the rendered body and the destination the rail had computed. Always empty on a workspace that is not a sandbox — the rail exists everywhere and only ever fires inside one.

ParámetroEnTipoObligatorioRestricciones
railquerywhatsapp \email \instagram \
limitqueryintegerno≥ 1, ≤ 200
offsetqueryinteger | nullno≥ 0
curl https://api.vitrinadev.com/api/v1/sandbox/outbound \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": [
    {
      "id": "0aab045e-1441-41f3-9258-8a780c501b1a",
      "tenant_id": "34d213e0-5cac-4c86-a57c-4db28d59b9ec",
      "rail": "whatsapp",
      "provider": "whatsapp_cloud",
      "destination": "56908450000",
      "subject": null,
      "body": "Hola, te confirmo tu cita para el jueves a las 10.",
      "conversation_id": "f6506b7f-a342-48d6-8590-011f263f6b13",
      "origin": "provider.sendTextMessage",
      "idempotency_key": "74ec9181-edf1-48dc-aab3-4883c7eb2e2e",
      "captured_at": "2026-09-23T05:28:53.464Z"
    }
  ],
  "meta": {
    "summary": [
      {
        "rail": "whatsapp",
        "count": 1
      }
    ],
    "rails": [
      "whatsapp",
      "email",
      "instagram",
      "messenger",
      "webchat",
      "voice",
      "tax_document",
      "portal",
      "other"
    ]
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

GET /sandbox/outbound/{id}

One outbound send that was captured instead of delivered

A single row of the capture ledger — the rendered body, the destination the rail computed, the raw payload the intercepted call was given, the call site (origin) and, when the send carried one, its idempotency_key (a retried send with the same key returns this same row). Portal publishing (Chileautos, Mercado Libre, Facebook Marketplace listings) captures on rail portal. Scoped to the calling workspace: another workspace's id answers 404, never 403.

ParámetroEnTipoObligatorioRestricciones
idpathuuid
curl https://api.vitrinadev.com/api/v1/sandbox/outbound/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "id": "0aab045e-1441-41f3-9258-8a780c501b1a",
    "tenant_id": "34d213e0-5cac-4c86-a57c-4db28d59b9ec",
    "rail": "whatsapp",
    "provider": "whatsapp_cloud",
    "destination": "56908450000",
    "subject": null,
    "body": "Hola, te confirmo tu cita para el jueves a las 10.",
    "payload": {
      "to": "56908450000",
      "type": "text",
      "text": {
        "body": "Hola, te confirmo tu cita para el jueves a las 10."
      }
    },
    "conversation_id": "f6506b7f-a342-48d6-8590-011f263f6b13",
    "origin": "provider.sendTextMessage",
    "idempotency_key": "74ec9181-edf1-48dc-aab3-4883c7eb2e2e",
    "captured_at": "2026-09-23T05:28:53.464Z"
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /sandbox/reset

Reset a sandbox to the data its seed generates

Deletes the sandbox's synthetic data — and everything created on top of it since (leads, notes, cotizaciones, citas, …) — plus every captured send, then regenerates the dataset from the sandbox's seed with the generator for its vertical (automotive or healthcare). Kept: the workspace, its members, its API keys (test keys keep working), its webhook subscriptions and its free subscription. Same seed, same data: the same units, prices, buyers or patients, with dates re-anchored to the day of the reset and display ids starting over. Called from a live workspace it resets THAT workspace's sandbox (409 SANDBOX_NOT_PROVISIONED when it has none); called from inside a sandbox (an sk_test_ key) it resets that sandbox. It can never reach a live workspace.

Cuerpo

CampoTipoObligatorioRestricciones
curl -X POST https://api.vitrinadev.com/api/v1/sandbox/reset \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Ejemplo de respuesta (200)

{
  "data": {
    "tenant_id": "34d213e0-5cac-4c86-a57c-4db28d59b9ec",
    "vertical": "automotive",
    "seed": "docs-2697-demo",
    "counts": {
      "vehicle": 40,
      "contact": 30,
      "lead": 30
    },
    "deleted": {
      "vehicle": 40,
      "contact": 30,
      "sandbox_outbound_capture": 1
    }
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

En esta página