VitrinaAPI

Flows de WhatsApp

Formularios estructurados de varias pantallas que se abren dentro de una conversación de WhatsApp, construidos y publicados desde Vitrina.

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.

Usar plantillas y Flows de WhatsApp explica este recurso en prosa, con ejemplos ejecutables.

MétodoRutaQué hace
GET/whatsapp-flowsLive list of a channel's WhatsApp Flows (composer picker)
GET/whatsapp-flows/managedList flows built in the Vitrina flow builder
POST/whatsapp-flows/managedCreate a flow in the builder
DELETE/whatsapp-flows/managed/{id}Delete a draft flow
GET/whatsapp-flows/managed/{id}Fetch one managed flow
PATCH/whatsapp-flows/managed/{id}Update a draft flow
POST/whatsapp-flows/managed/{id}/deprecateDeprecate a published flow
POST/whatsapp-flows/managed/{id}/duplicateDuplicate a flow as a new draft
GET/whatsapp-flows/managed/{id}/previewGet (or refresh) a flow preview link
POST/whatsapp-flows/managed/{id}/publishPublish a flow
POST/whatsapp-flows/syncReconcile a channel's managed flows against Meta

GET /whatsapp-flows

Live list of a channel's WhatsApp Flows (composer picker)

A live proxy read from Meta via the bridge — includes a flow authored outside Vitrina, which the /managed/* builder never sees. messaging_account_id is required; there is no tenant-wide list.

ParámetroEnTipoObligatorioRestricciones
messaging_account_idqueryuuid
curl https://api.vitrinadev.com/api/v1/whatsapp-flows \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": [
    {
      "id": "e3e3e3e3-0000-4000-8000-000000000001",
      "name": "Agenda tu visita",
      "status": "PUBLISHED",
      "categories": [
        "APPOINTMENT_BOOKING"
      ]
    }
  ],
  "meta": {
    "total": 1
  }
}

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

GET /whatsapp-flows/managed

List flows built in the Vitrina flow builder

messaging_account_id is required.

ParámetroEnTipoObligatorioRestricciones
messaging_account_idqueryuuid
curl https://api.vitrinadev.com/api/v1/whatsapp-flows/managed \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": [
    {
      "id": "e3e3e3e3-0000-4000-8000-000000000001",
      "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
      "meta_flow_id": "1200300400500600",
      "name": "Agenda tu visita",
      "categories": [
        "APPOINTMENT_BOOKING"
      ],
      "status": "PUBLISHED",
      "builder_state": {
        "screens": [
          {
            "title": "¿Cuándo te acomoda?",
            "footer_label": "Continuar",
            "components": [
              {
                "kind": "heading",
                "text": "Agenda tu visita"
              },
              {
                "kind": "date_picker",
                "name": "fecha",
                "label": "Fecha preferida",
                "required": true
              }
            ]
          }
        ]
      },
      "validation_errors": null,
      "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
      "preview_expires_at": "2026-09-15T19:20:00.000Z",
      "created_at": "2026-01-10T13:00:00.000Z",
      "updated_at": "2026-09-15T18:20:00.000Z"
    }
  ],
  "meta": {
    "total": 1
  }
}

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

POST /whatsapp-flows/managed

Create a flow in the builder

builder_state is the ordered screen list; the Flow JSON is generated and uploaded to Meta as part of this call, and validation_errors reports what Meta rejected, if anything. Always created DRAFT.

Cuerpo

CampoTipoObligatorioRestricciones
messaging_account_iduuid
namestringmín. 1, máx. 200
categoriesSIGN_UP \SIGN_IN \APPOINTMENT_BOOKING \
builder_stateobject
curl -X POST https://api.vitrinadev.com/api/v1/whatsapp-flows/managed \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "name": "Agenda tu visita",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    }
  }'

Ejemplo de respuesta (201)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "meta_flow_id": "1200300400500600",
    "name": "Agenda tu visita",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "status": "DRAFT",
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    },
    "validation_errors": null,
    "preview_url": null,
    "preview_expires_at": null,
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-15T18:20:00.000Z"
  }
}

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

DELETE /whatsapp-flows/managed/{id}

Delete a draft flow

A published flow is immutable on Meta’s side — this is a 409 once status is PUBLISHED. POST /whatsapp-flows/managed/\{id\}/duplicate is the way to keep iterating: it always creates a fresh DRAFT copy.

ParámetroEnTipoObligatorioRestricciones
idpathuuid
curl -X DELETE https://api.vitrinadev.com/api/v1/whatsapp-flows/managed/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

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

GET /whatsapp-flows/managed/{id}

Fetch one managed flow

The flow row, including its builder_state (the screen/component tree) and its status on Meta.

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

Ejemplo de respuesta (200)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "meta_flow_id": "1200300400500600",
    "name": "Agenda tu visita",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "status": "PUBLISHED",
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    },
    "validation_errors": null,
    "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
    "preview_expires_at": "2026-09-15T19:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-15T18:20:00.000Z"
  }
}

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

PATCH /whatsapp-flows/managed/{id}

Update a draft flow

A published flow is immutable on Meta’s side — this is a 409 once status is PUBLISHED. POST /whatsapp-flows/managed/\{id\}/duplicate is the way to keep iterating: it always creates a fresh DRAFT copy.

ParámetroEnTipoObligatorioRestricciones
idpathuuid

Cuerpo

CampoTipoObligatorioRestricciones
namestringmín. 1, máx. 200
categoriesSIGN_UP \SIGN_IN \APPOINTMENT_BOOKING \
builder_stateobject
curl -X PATCH https://api.vitrinadev.com/api/v1/whatsapp-flows/managed/<id> \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Agenda tu visita al showroom"
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "meta_flow_id": "1200300400500600",
    "name": "Agenda tu visita al showroom",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "status": "PUBLISHED",
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    },
    "validation_errors": null,
    "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
    "preview_expires_at": "2026-09-15T19:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-15T18:20:00.000Z"
  }
}

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

POST /whatsapp-flows/managed/{id}/deprecate

Deprecate a published flow

Stops it being offered as new; conversations already inside it are unaffected.

ParámetroEnTipoObligatorioRestricciones
idpathuuid
curl -X POST https://api.vitrinadev.com/api/v1/whatsapp-flows/managed/<id>/deprecate \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "meta_flow_id": "1200300400500600",
    "name": "Agenda tu visita",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "status": "DEPRECATED",
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    },
    "validation_errors": null,
    "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
    "preview_expires_at": "2026-09-15T19:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-15T18:20:00.000Z"
  }
}

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

POST /whatsapp-flows/managed/{id}/duplicate

Duplicate a flow as a new draft

The escape hatch for an immutable PUBLISHED flow: copies its builder_state into a brand-new DRAFT flow (a new meta_flow_id), leaving the original untouched. name defaults to the original’s name with a suffix.

ParámetroEnTipoObligatorioRestricciones
idpathuuid

Cuerpo

CampoTipoObligatorioRestricciones
namestringmín. 1, máx. 200
curl -X POST https://api.vitrinadev.com/api/v1/whatsapp-flows/managed/<id>/duplicate \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Agenda tu visita (copia)"
  }'

Ejemplo de respuesta (201)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "meta_flow_id": "1200300400500600",
    "name": "Agenda tu visita (copia)",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "status": "DRAFT",
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    },
    "validation_errors": null,
    "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
    "preview_expires_at": "2026-09-15T19:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-15T18:20:00.000Z"
  }
}

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

GET /whatsapp-flows/managed/{id}/preview

Get (or refresh) a flow preview link

Read-only and side-effect free by default — answers the cached preview URL. ?refresh=true forces a fresh one through the bridge when the cached one has expired.

ParámetroEnTipoObligatorioRestricciones
idpathuuid
refreshqueryboolean | nullno
curl https://api.vitrinadev.com/api/v1/whatsapp-flows/managed/<id>/preview \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
    "preview_expires_at": "2026-09-15T19:20:00.000Z",
    "status": "PUBLISHED",
    "validation_errors": null
  }
}

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

POST /whatsapp-flows/managed/{id}/publish

Publish a flow

Refused while validation_errors is non-empty. Publishing is one-way — see duplicate for the way to keep editing afterwards.

ParámetroEnTipoObligatorioRestricciones
idpathuuid
curl -X POST https://api.vitrinadev.com/api/v1/whatsapp-flows/managed/<id>/publish \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "id": "e3e3e3e3-0000-4000-8000-000000000001",
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
    "meta_flow_id": "1200300400500600",
    "name": "Agenda tu visita",
    "categories": [
      "APPOINTMENT_BOOKING"
    ],
    "status": "PUBLISHED",
    "builder_state": {
      "screens": [
        {
          "title": "¿Cuándo te acomoda?",
          "footer_label": "Continuar",
          "components": [
            {
              "kind": "heading",
              "text": "Agenda tu visita"
            },
            {
              "kind": "date_picker",
              "name": "fecha",
              "label": "Fecha preferida",
              "required": true
            }
          ]
        }
      ]
    },
    "validation_errors": null,
    "preview_url": "https://business.facebook.com/wa/manage/flows/1200300400500600/preview/",
    "preview_expires_at": "2026-09-15T19:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-15T18:20:00.000Z"
  }
}

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

POST /whatsapp-flows/sync

Reconcile a channel's managed flows against Meta

The most destructive call on this router: local rows Meta no longer reports are deleted. Reports \{ checked, updated, removed \}.

Cuerpo

CampoTipoObligatorioRestricciones
messaging_account_iduuid
curl -X POST https://api.vitrinadev.com/api/v1/whatsapp-flows/sync \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001"
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "checked": 3,
    "updated": 1,
    "removed": 0
  }
}

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

En esta página