Secuencias
Cada camino de seguimiento (Al llegar, Si no responde, Avisos) con sus pasos, esperas, canales y resultados.
Descarga la proyección completa de la API pública: openapi.json.
| Método | Ruta | Qué hace |
|---|---|---|
GET | /sequences | List the workspace’s sequences |
POST | /sequences | Create a custom sequence |
DELETE | /sequences/{id} | Delete a custom sequence |
GET | /sequences/{id} | Read one sequence |
PATCH | /sequences/{id} | Edit a custom sequence’s name, entry, goal or agent |
GET | /sequences/{id}/definition | Read a sequence’s whole definition |
DELETE | /sequences/{id}/draft | Discard a sequence’s draft |
GET | /sequences/{id}/draft | Read a sequence’s draft |
PUT | /sequences/{id}/draft | Save a sequence’s draft |
GET | /sequences/{id}/draft/diff | What publishing the draft would change |
GET | /sequences/{id}/draft/validation | What blocks publishing the draft |
GET | /sequences/{id}/enrollments | List the people in a sequence with their consent |
POST | /sequences/{id}/enrollments/{enrollment_id}/promised-date | Record the date a customer promised |
GET | /sequences/{id}/enrollments/batches | List the enrollment batches of a sequence |
GET | /sequences/{id}/enrollments/batches/{batch_id} | Read an enrollment batch |
POST | /sequences/{id}/enrollments/batches/{batch_id}/activate | Activate an enrollment batch |
POST | /sequences/{id}/enrollments/batches/{batch_id}/cancel | Cancel a pending enrollment batch |
POST | /sequences/{id}/enrollments/from-list | Preview and record the consent to enroll a list |
GET | /sequences/{id}/legal-review | Where the legal review of a collection sequence stands |
POST | /sequences/{id}/legal-review | Record the legal review of a collection sequence |
POST | /sequences/{id}/publish | Publish a sequence’s draft |
POST | /sequences/{id}/simulate | Simulate what one customer will receive |
GET | /sequences/{id}/versions | List a sequence’s versions |
POST | /sequences/{id}/versions/{version}/revert | Go back to a version |
GET | /sequences/collection-rules | Collection rules of the workspace |
PUT | /sequences/collection-rules | Replace the collection rules |
PUT | /sequences/order | Set the priority order of the sequences |
GET | /sequences/templates | List the templates for a new sequence |
GET /sequences
List the workspace’s sequences
Every sequence of the workspace, lowest priority first (an agreed reminder wins over the others), each with its whole graph and the numbers of the last 30 days. Each sequence carries situations (its lanes: «Conversó y dejó de responder», «Nunca respondió», «Ya está perdido» for builtin:si-no-responde; one per lead source for builtin:al-llegar; one per recipe for builtin:avisos), steps (channel, the configured wait, the drawn wait_after_previous and at_hours, mode as configured and mode_effective, the config block it comes from in config_ref, and stats: waiting_now, sent_30d, reply_rate_30d, daily_14d), connections between step keys and the entry / exit / end:<situation> nodes (reply_exit is «si responde»), window_markers (where WhatsApp’s 24 h window closes; from there only approved templates) and ends (mark lost, finish, or continue in another sequence). Order, gaps and markers of «Si no responde» come from the same simulation GET /followups/recontacto/plan renders.
A workspace with nothing configured still lists the three built-ins, status: paused. lang picks the labels; omitted = the workspace’s language. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"id": "42bcd0a4-e0bd-5418-8a00-71495a4d3e46",
"key": "builtin:avisos",
"kind": "builtin",
"name": "Avisos",
"description": "Lo que el cliente pidió que le recordáramos.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_asked_reminder",
"filters": [
{
"field": "trigger",
"op": "in",
"values": [
"after_delay"
]
}
]
},
"goal": {
"type": "promise_kept",
"label": "Cumplir lo que le prometimos"
},
"agent_id": null,
"priority": 1,
"situations": [
{
"key": "33333333-3333-4333-8333-333333333333",
"name": "Recordatorio acordado",
"enabled": true,
"first_step": "followup-33333333-3333-4333-8333-333333333333",
"waiting_now": 10,
"notes": []
}
],
"steps": [
{
"id": "15c4a32c-b151-589d-ad47-25181454816b",
"key": "followup-33333333-3333-4333-8333-333333333333",
"situation": "33333333-3333-4333-8333-333333333333",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "agreed_time"
},
"wait_after_previous": null,
"at_hours": null,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "promise",
"followup_id": "33333333-3333-4333-8333-333333333333",
"trigger_key": "after_delay"
},
"config_ref": {
"type": "followup",
"followup_id": "33333333-3333-4333-8333-333333333333",
"trigger_key": "after_delay"
},
"warnings": [],
"stats": {
"waiting_now": 10,
"sent_30d": 14,
"reply_rate_30d": 0.429,
"daily_14d": [
0,
1,
1,
0,
2,
1,
0,
1,
1,
2,
1,
0,
1,
3
]
}
}
],
"connections": [
{
"from": "entry",
"to": "followup-33333333-3333-4333-8333-333333333333",
"kind": "next",
"situation": "33333333-3333-4333-8333-333333333333"
},
{
"from": "followup-33333333-3333-4333-8333-333333333333",
"to": "exit",
"kind": "reply_exit",
"situation": "33333333-3333-4333-8333-333333333333"
},
{
"from": "followup-33333333-3333-4333-8333-333333333333",
"to": "end:33333333-3333-4333-8333-333333333333",
"kind": "end",
"situation": "33333333-3333-4333-8333-333333333333"
}
],
"window_markers": [],
"ends": [
{
"key": "end:33333333-3333-4333-8333-333333333333",
"situation": "33333333-3333-4333-8333-333333333333",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Avisado",
"detail": null,
"continues_in": null
}
],
"stats": {
"waiting_now": 10,
"sent_30d": 14,
"reply_rate_30d": 0.429,
"daily_14d": [
0,
1,
1,
0,
2,
1,
0,
1,
1,
2,
1,
0,
1,
3
]
}
},
{
"id": "01f68f1c-696b-5fc5-8191-d26ac3a3a8ee",
"key": "builtin:al-llegar",
"kind": "builtin",
"name": "Al llegar",
"description": "Un lead que no abrió el chat recibe el primer mensaje.",
"status": "active",
"entry": {
"type": "event",
"event": "lead_arrived",
"filters": [
{
"field": "source",
"op": "in",
"values": [
"website"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente responda"
},
"agent_id": null,
"priority": 2,
"situations": [
{
"key": "website",
"name": "Lead del sitio web",
"enabled": true,
"first_step": "first_touch-website",
"waiting_now": null,
"notes": []
}
],
"steps": [
{
"id": "168d38eb-62b8-5ecc-b0cb-663736f9be97",
"key": "first_touch-website",
"situation": "website",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "minutes",
"from": "start",
"from_step": null,
"hours": 0.08333333333333333
},
"wait_after_previous": {
"value": 5,
"unit": "minutes"
},
"at_hours": 0.08333333333333333,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "template_ladder",
"templates": [
{
"name": "cotizacion_web",
"language": "es"
}
]
},
"config_ref": {
"type": "first_touch",
"source": "website",
"config_origin": "configured"
},
"warnings": [],
"stats": {
"waiting_now": null,
"sent_30d": 322,
"reply_rate_30d": 0.304,
"daily_14d": [
10,
12,
11,
13,
12,
11,
12,
13,
10,
11,
12,
13,
11,
12
]
}
}
],
"connections": [
{
"from": "entry",
"to": "first_touch-website",
"kind": "next",
"situation": "website"
},
{
"from": "first_touch-website",
"to": "exit",
"kind": "reply_exit",
"situation": "website"
},
{
"from": "first_touch-website",
"to": "end:website",
"kind": "end",
"situation": "website"
}
],
"window_markers": [],
"ends": [
{
"key": "end:website",
"situation": "website",
"type": "continue",
"after": null,
"at_hours": null,
"label": "Si no responde, sigue en «Nunca respondió»",
"detail": null,
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "never_replied"
}
}
],
"stats": {
"waiting_now": null,
"sent_30d": 322,
"reply_rate_30d": 0.304,
"daily_14d": [
10,
12,
11,
13,
12,
11,
12,
13,
10,
11,
12,
13,
11,
12
]
}
},
{
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"kind": "builtin",
"name": "Si no responde",
"description": "Le escribimos a quien dejó de responder, nunca respondió o ya está perdido.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente vuelva a responder"
},
"agent_id": null,
"priority": 3,
"situations": [
{
"key": "conversed",
"name": "Conversó y dejó de responder",
"enabled": true,
"first_step": "unanswered_message-1",
"waiting_now": 45,
"notes": []
},
{
"key": "never_replied",
"name": "Nunca respondió",
"enabled": true,
"first_step": "never_replied-1",
"waiting_now": 1,
"notes": []
},
{
"key": "lost",
"name": "Ya está perdido",
"enabled": true,
"first_step": "lost-1",
"waiting_now": 9,
"notes": [
"A quien compró en otro lado o dijo que no quiere, no le escribimos."
]
}
],
"steps": [
{
"id": "8a385269-303e-5d82-8ce3-d2c82d1c2af7",
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"wait_after_previous": {
"value": 4,
"unit": "hours"
},
"at_hours": 4,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 18,
"sent_30d": 212,
"reply_rate_30d": 0.231,
"daily_14d": [
6,
8,
7,
9,
8,
7,
8,
9,
6,
7,
8,
9,
7,
8
]
}
},
{
"id": "4a6f17b4-0255-5c56-bdc5-93d14b544d5d",
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"wait_after_previous": {
"value": 30,
"unit": "hours"
},
"at_hours": 34,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [
"Instagram no permite escribir pasadas 24 h: este mensaje no saldrá a quien no tenga teléfono."
],
"stats": {
"waiting_now": 11,
"sent_30d": 164,
"reply_rate_30d": 0.14,
"daily_14d": [
5,
6,
5,
6,
5,
6,
5,
6,
5,
6,
5,
6,
5,
6
]
}
},
{
"id": "7876340a-bc26-5e3c-8ef7-778cd18f1eda",
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"wait_after_previous": {
"value": 14,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 9,
"sent_30d": 120,
"reply_rate_30d": 0.092,
"daily_14d": [
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4
]
}
},
{
"id": "3f04a26b-1479-5a3b-9f58-95c52e16c0a5",
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 7,
"sent_30d": 46,
"reply_rate_30d": 0.065,
"daily_14d": [
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2
]
}
},
{
"id": "ec87b5be-92d7-51a5-9936-c5131838d9ab",
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"wait_after_previous": {
"value": 3,
"unit": "hours"
},
"at_hours": 3,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [
"Muy pronto: un seguimiento a menos de 12 horas de nuestro primer mensaje casi nunca tiene respuesta."
],
"stats": {
"waiting_now": 1,
"sent_30d": 92,
"reply_rate_30d": 0.076,
"daily_14d": [
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3
]
}
},
{
"id": "9211cfce-9740-5f79-b76c-962cb908f160",
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"wait_after_previous": {
"value": 5,
"unit": "hours"
},
"at_hours": 8,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "2e4ea654-9d30-50e7-b586-6aae005a35f3",
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"wait_after_previous": {
"value": 40,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "5a157200-6687-519a-b3a1-7c7da36b88d8",
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "09d4bf1d-8cbb-553c-8b68-ff0373a4cb37",
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"wait_after_previous": {
"value": 30,
"unit": "days"
},
"at_hours": 720,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 9,
"sent_30d": 27,
"reply_rate_30d": 0.185,
"daily_14d": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
]
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"window_markers": [
{
"situation": "conversed",
"after_step": "unanswered_message-1",
"label": "se cierra la ventana de WhatsApp (se cuenta desde el último mensaje del cliente): desde aquí, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Fin de este camino.",
"detail": "Si vuelve a escribir y después se queda en silencio, empieza otro.",
"continues_in": null
}
],
"stats": {
"waiting_now": 55,
"sent_30d": 661,
"reply_rate_30d": 0.148,
"daily_14d": [
20,
24,
21,
25,
22,
23,
22,
25,
20,
23,
22,
25,
21,
24
]
}
}
]
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences
Create a custom sequence
A custom sequence is the workspace’s own: who enters (entry: an event — lead_arrived, customer_went_quiet, stage_changed, quoted_not_booked, appointment_booked; signed_up_not_bought and installment_overdue are accepted but cannot be published yet; or a list, enrolled with consent through POST /sequences/\{id\}/enrollments/from-list — with filters on interest, source, stage or tag), the goal that makes a person leave when met (reply, books_visit, books_demo; pays cannot be published yet) and the steps, edited as a draft and run once published (POST /sequences/\{id\}/publish). A person is in ONE sequence at a time among «Si no responde» and the custom ones, and enters the highest-priority one they qualify for; «Al llegar» and «Avisos» stay outside that rule. The engine sends through the same guards as «Si no responde»: contact hours, per-person limits, opt-out, the 24 h WhatsApp window, pauses and «Con tu OK».
Creates the sequence from template (a key from GET /sequences/templates; its suggested steps become the first draft) or from scratch (blank), as a DRAFT: status: draft, nothing runs until it is published. name, entry and goal override the template’s. It goes to the bottom of the priority list. Every suggested step starts as «Con tu OK» (approval). Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
lang | query | es \ | en | no |
curl -X POST https://api.vitrinadev.com/api/v1/sequences \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "quote_followup",
"name": "Seguimiento de cotización"
}'Ejemplo de respuesta (201)
{
"data": {
"sequence": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"kind": "custom",
"name": "Seguimiento de cotización",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"status": "draft",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit",
"label": "Agenda visita"
},
"agent_id": null,
"collection": false,
"priority": 4,
"situations": [],
"steps": [
{
"id": "affce008-6fdb-52eb-8273-329b6da03c90",
"key": "step-1",
"situation": null,
"position": 1,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 72,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "fed60c11-4a4e-50dd-adbd-bdc25a39fc35",
"key": "step-2",
"situation": null,
"position": 2,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 96,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "81573e28-456d-5a69-9c16-b7e2082b589a",
"key": "step-3",
"situation": null,
"position": 3,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 120,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
}
}
],
"connections": [
{
"from": "entry",
"to": "step-1",
"kind": "next",
"situation": null
},
{
"from": "step-1",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-1",
"to": "step-2",
"kind": "next",
"situation": null
},
{
"from": "step-2",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-2",
"to": "step-3",
"kind": "next",
"situation": null
},
{
"from": "step-3",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-3",
"to": "end",
"kind": "end",
"situation": null
}
],
"window_markers": [
{
"situation": null,
"after_step": null,
"label": "Pasadas las 24 h, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end",
"situation": null,
"type": "finish",
"after": null,
"at_hours": null,
"label": "Termina",
"detail": null,
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": null,
"draft": {
"version_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"change_count": 6,
"updated_at": "2026-11-02T15:00:00.000Z"
}
},
"draft": {
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"sequence_key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"version_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"based_on_version": null,
"change_count": 6,
"created_at": "2026-11-02T15:00:00.000Z",
"updated_at": "2026-11-02T15:00:00.000Z",
"created_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"updated_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222"
},
"definition": {
"schema_version": 1,
"name": "Seguimiento de cotización",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit"
},
"agent_id": null,
"priority": 0,
"situations": [],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null
},
{
"key": "step-3",
"situation": null,
"kind": "message",
"position": 3,
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null
}
],
"connections": [
{
"from": "entry",
"to": "step-1",
"kind": "next",
"situation": null
},
{
"from": "step-1",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-1",
"to": "step-2",
"kind": "next",
"situation": null
},
{
"from": "step-2",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-2",
"to": "step-3",
"kind": "next",
"situation": null
},
{
"from": "step-3",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-3",
"to": "end",
"kind": "end",
"situation": null
}
],
"ends": [
{
"key": "end",
"situation": null,
"type": "finish",
"after": null,
"continues_in": null
}
],
"settings": {
"type": "none"
}
},
"sequence": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"kind": "custom",
"name": "Seguimiento de cotización",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"status": "draft",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit",
"label": "Agenda visita"
},
"agent_id": null,
"collection": false,
"priority": 4,
"situations": [],
"steps": [
{
"id": "affce008-6fdb-52eb-8273-329b6da03c90",
"key": "step-1",
"situation": null,
"position": 1,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 72,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "fed60c11-4a4e-50dd-adbd-bdc25a39fc35",
"key": "step-2",
"situation": null,
"position": 2,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 96,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "81573e28-456d-5a69-9c16-b7e2082b589a",
"key": "step-3",
"situation": null,
"position": 3,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 120,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
}
}
],
"connections": [
{
"from": "entry",
"to": "step-1",
"kind": "next",
"situation": null
},
{
"from": "step-1",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-1",
"to": "step-2",
"kind": "next",
"situation": null
},
{
"from": "step-2",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-2",
"to": "step-3",
"kind": "next",
"situation": null
},
{
"from": "step-3",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-3",
"to": "end",
"kind": "end",
"situation": null
}
],
"window_markers": [
{
"situation": null,
"after_step": null,
"label": "Pasadas las 24 h, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end",
"situation": null,
"type": "finish",
"after": null,
"at_hours": null,
"label": "Termina",
"detail": null,
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": null,
"draft": {
"version_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"change_count": 6,
"updated_at": "2026-11-02T15:00:00.000Z"
}
}
}
}
}Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429
DELETE /sequences/{id}
Delete a custom sequence
Deletes a custom sequence. People still in it leave with reason sequence_deleted (exited says how many) and its queued messages are cancelled, never sent; its history stays. Built-ins cannot be deleted (404). Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl -X DELETE https://api.vitrinadev.com/api/v1/sequences/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"deleted": true,
"exited": 3
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}
Read one sequence
One sequence by its uuid or by its key (builtin:al-llegar, builtin:si-no-responde, builtin:avisos). Each sequence carries situations (its lanes: «Conversó y dejó de responder», «Nunca respondió», «Ya está perdido» for builtin:si-no-responde; one per lead source for builtin:al-llegar; one per recipe for builtin:avisos), steps (channel, the configured wait, the drawn wait_after_previous and at_hours, mode as configured and mode_effective, the config block it comes from in config_ref, and stats: waiting_now, sent_30d, reply_rate_30d, daily_14d), connections between step keys and the entry / exit / end:<situation> nodes (reply_exit is «si responde»), window_markers (where WhatsApp’s 24 h window closes; from there only approved templates) and ends (mark lost, finish, or continue in another sequence). Order, gaps and markers of «Si no responde» come from the same simulation GET /followups/recontacto/plan renders.
A built-in’s uuid is stable for the workspace. 404 for any other id. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"kind": "builtin",
"name": "Si no responde",
"description": "Le escribimos a quien dejó de responder, nunca respondió o ya está perdido.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente vuelva a responder"
},
"agent_id": null,
"priority": 3,
"situations": [
{
"key": "conversed",
"name": "Conversó y dejó de responder",
"enabled": true,
"first_step": "unanswered_message-1",
"waiting_now": 45,
"notes": []
},
{
"key": "never_replied",
"name": "Nunca respondió",
"enabled": true,
"first_step": "never_replied-1",
"waiting_now": 1,
"notes": []
},
{
"key": "lost",
"name": "Ya está perdido",
"enabled": true,
"first_step": "lost-1",
"waiting_now": 9,
"notes": [
"A quien compró en otro lado o dijo que no quiere, no le escribimos."
]
}
],
"steps": [
{
"id": "8a385269-303e-5d82-8ce3-d2c82d1c2af7",
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"wait_after_previous": {
"value": 4,
"unit": "hours"
},
"at_hours": 4,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 18,
"sent_30d": 212,
"reply_rate_30d": 0.231,
"daily_14d": [
6,
8,
7,
9,
8,
7,
8,
9,
6,
7,
8,
9,
7,
8
]
}
},
{
"id": "4a6f17b4-0255-5c56-bdc5-93d14b544d5d",
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"wait_after_previous": {
"value": 30,
"unit": "hours"
},
"at_hours": 34,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [
"Instagram no permite escribir pasadas 24 h: este mensaje no saldrá a quien no tenga teléfono."
],
"stats": {
"waiting_now": 11,
"sent_30d": 164,
"reply_rate_30d": 0.14,
"daily_14d": [
5,
6,
5,
6,
5,
6,
5,
6,
5,
6,
5,
6,
5,
6
]
}
},
{
"id": "7876340a-bc26-5e3c-8ef7-778cd18f1eda",
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"wait_after_previous": {
"value": 14,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 9,
"sent_30d": 120,
"reply_rate_30d": 0.092,
"daily_14d": [
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4
]
}
},
{
"id": "3f04a26b-1479-5a3b-9f58-95c52e16c0a5",
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 7,
"sent_30d": 46,
"reply_rate_30d": 0.065,
"daily_14d": [
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2,
1,
2
]
}
},
{
"id": "ec87b5be-92d7-51a5-9936-c5131838d9ab",
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"wait_after_previous": {
"value": 3,
"unit": "hours"
},
"at_hours": 3,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [
"Muy pronto: un seguimiento a menos de 12 horas de nuestro primer mensaje casi nunca tiene respuesta."
],
"stats": {
"waiting_now": 1,
"sent_30d": 92,
"reply_rate_30d": 0.076,
"daily_14d": [
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3
]
}
},
{
"id": "9211cfce-9740-5f79-b76c-962cb908f160",
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"wait_after_previous": {
"value": 5,
"unit": "hours"
},
"at_hours": 8,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "2e4ea654-9d30-50e7-b586-6aae005a35f3",
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"wait_after_previous": {
"value": 40,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "5a157200-6687-519a-b3a1-7c7da36b88d8",
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "09d4bf1d-8cbb-553c-8b68-ff0373a4cb37",
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"wait_after_previous": {
"value": 30,
"unit": "days"
},
"at_hours": 720,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 9,
"sent_30d": 27,
"reply_rate_30d": 0.185,
"daily_14d": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
]
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"window_markers": [
{
"situation": "conversed",
"after_step": "unanswered_message-1",
"label": "se cierra la ventana de WhatsApp (se cuenta desde el último mensaje del cliente): desde aquí, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Fin de este camino.",
"detail": "Si vuelve a escribir y después se queda en silencio, empieza otro.",
"continues_in": null
}
],
"stats": {
"waiting_now": 55,
"sent_30d": 661,
"reply_rate_30d": 0.148,
"daily_14d": [
20,
24,
21,
25,
22,
23,
22,
25,
20,
23,
22,
25,
21,
24
]
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
PATCH /sequences/{id}
Edit a custom sequence’s name, entry, goal or agent
A custom sequence is the workspace’s own: who enters (entry: an event — lead_arrived, customer_went_quiet, stage_changed, quoted_not_booked, appointment_booked; signed_up_not_bought and installment_overdue are accepted but cannot be published yet; or a list, enrolled with consent through POST /sequences/\{id\}/enrollments/from-list — with filters on interest, source, stage or tag), the goal that makes a person leave when met (reply, books_visit, books_demo; pays cannot be published yet) and the steps, edited as a draft and run once published (POST /sequences/\{id\}/publish). A person is in ONE sequence at a time among «Si no responde» and the custom ones, and enters the highest-priority one they qualify for; «Al llegar» and «Avisos» stay outside that rule. The engine sends through the same guards as «Si no responde»: contact hours, per-person limits, opt-out, the 24 h WhatsApp window, pauses and «Con tu OK».
Writes name, description, entry and goal and agent_id (the AI agent that runs it; 400 unless it is an active agent of the workspace, null = the workspace’s current agent) into the draft (opening one from the published version when there is none), so who enters a running sequence changes only when it is published. Before the first publish the list shows the new name at once. Built-ins: 404 (edit them through their draft). Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
curl -X PATCH https://api.vitrinadev.com/api/v1/sequences/<id> \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Cotizó y no vino a la tienda"
}'Ejemplo de respuesta (200)
{
"data": {
"sequence": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"kind": "custom",
"name": "Cotizó y no vino a la tienda",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"status": "draft",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit",
"label": "Agenda visita"
},
"agent_id": null,
"collection": false,
"priority": 4,
"situations": [],
"steps": [
{
"id": "affce008-6fdb-52eb-8273-329b6da03c90",
"key": "step-1",
"situation": null,
"position": 1,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 72,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "fed60c11-4a4e-50dd-adbd-bdc25a39fc35",
"key": "step-2",
"situation": null,
"position": 2,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 96,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "81573e28-456d-5a69-9c16-b7e2082b589a",
"key": "step-3",
"situation": null,
"position": 3,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 120,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
}
}
],
"connections": [
{
"from": "entry",
"to": "step-1",
"kind": "next",
"situation": null
},
{
"from": "step-1",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-1",
"to": "step-2",
"kind": "next",
"situation": null
},
{
"from": "step-2",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-2",
"to": "step-3",
"kind": "next",
"situation": null
},
{
"from": "step-3",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-3",
"to": "end",
"kind": "end",
"situation": null
}
],
"window_markers": [
{
"situation": null,
"after_step": null,
"label": "Pasadas las 24 h, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end",
"situation": null,
"type": "finish",
"after": null,
"at_hours": null,
"label": "Termina",
"detail": null,
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": null,
"draft": {
"version_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"change_count": 6,
"updated_at": "2026-11-02T15:00:00.000Z"
}
},
"draft": {
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"sequence_key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"version_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"based_on_version": null,
"change_count": 6,
"created_at": "2026-11-02T15:00:00.000Z",
"updated_at": "2026-11-02T15:00:00.000Z",
"created_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"updated_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222"
},
"definition": {
"schema_version": 1,
"name": "Seguimiento de cotización",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit"
},
"agent_id": null,
"priority": 0,
"situations": [],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null
},
{
"key": "step-3",
"situation": null,
"kind": "message",
"position": 3,
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null
}
],
"connections": [
{
"from": "entry",
"to": "step-1",
"kind": "next",
"situation": null
},
{
"from": "step-1",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-1",
"to": "step-2",
"kind": "next",
"situation": null
},
{
"from": "step-2",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-2",
"to": "step-3",
"kind": "next",
"situation": null
},
{
"from": "step-3",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-3",
"to": "end",
"kind": "end",
"situation": null
}
],
"ends": [
{
"key": "end",
"situation": null,
"type": "finish",
"after": null,
"continues_in": null
}
],
"settings": {
"type": "none"
}
},
"sequence": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"kind": "custom",
"name": "Seguimiento de cotización",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"status": "draft",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit",
"label": "Agenda visita"
},
"agent_id": null,
"collection": false,
"priority": 4,
"situations": [],
"steps": [
{
"id": "affce008-6fdb-52eb-8273-329b6da03c90",
"key": "step-1",
"situation": null,
"position": 1,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 72,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "fed60c11-4a4e-50dd-adbd-bdc25a39fc35",
"key": "step-2",
"situation": null,
"position": 2,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 96,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
}
},
{
"id": "81573e28-456d-5a69-9c16-b7e2082b589a",
"key": "step-3",
"situation": null,
"position": 3,
"config_ref": {
"type": "custom",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"kind": "message",
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"wait_after_previous": {
"value": 1,
"unit": "days"
},
"at_hours": 120,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
}
}
],
"connections": [
{
"from": "entry",
"to": "step-1",
"kind": "next",
"situation": null
},
{
"from": "step-1",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-1",
"to": "step-2",
"kind": "next",
"situation": null
},
{
"from": "step-2",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-2",
"to": "step-3",
"kind": "next",
"situation": null
},
{
"from": "step-3",
"to": "exit",
"kind": "reply_exit",
"situation": null
},
{
"from": "step-3",
"to": "end",
"kind": "end",
"situation": null
}
],
"window_markers": [
{
"situation": null,
"after_step": null,
"label": "Pasadas las 24 h, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end",
"situation": null,
"type": "finish",
"after": null,
"at_hours": null,
"label": "Termina",
"detail": null,
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": null,
"draft": {
"version_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e10",
"change_count": 6,
"updated_at": "2026-11-02T15:00:00.000Z"
}
}
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/definition
Read a sequence’s whole definition
The complete SequenceDefinition of one version: the thing to start a draft from (PUT /sequences/\{id\}/draft takes the whole definition back). version is published (default; for a built-in, what its engine reads today, rungs and settings included), draft, or a version number. version and version_id are null for a built-in that was never versioned and for a draft. 404 sequence_draft when asking for a draft that does not exist, sequence_version for an unknown number. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
version | query | any | no | |
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/definition \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"sequence_key": "builtin:si-no-responde",
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"version": 2,
"status": "published",
"definition": {
"schema_version": 1,
"name": null,
"description": null,
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply"
},
"agent_id": null,
"priority": 3,
"steps": [
{
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"continues_in": null
}
],
"situations": [
{
"key": "conversed",
"name": null,
"enabled": true
},
{
"key": "never_replied",
"name": null,
"enabled": true
},
{
"key": "lost",
"name": null,
"enabled": true
}
],
"settings": {
"type": "recontacto",
"config": {
"enabled": true,
"daily_cap": 200,
"daily_review_budget": 500,
"lost_lookback_days": 90,
"max_evaluations_per_step": 3,
"re_evaluation_after_days": 1,
"excluded_template_ids": [],
"voice_examples": [],
"pacing": {
"min_gap_hours": null,
"max_per_day": null,
"pause_after_unanswered_days": null,
"approval_after_silence_days": null,
"approval_fallback_hours": null,
"entry_max_silence_days": 45,
"hot_leads_faster": false,
"max_paths_per_lead": 3,
"max_messages_per_person_90d": 6
},
"after_handoff": {
"followups": "draft_for_owner",
"auto_send_after_hours": 1,
"while_silent": "draft_auto_send",
"ai_answers_waiting": "after_minutes",
"ai_answers_waiting_after_minutes": 60,
"ai_answers_waiting_after_hours": 1,
"ai_answers_waiting_keep_owner": true
},
"situations": {
"never_replied": {
"enabled": true,
"lose_after_days": 7
},
"stalled": {
"enabled": true,
"lose_after_days": 7
},
"lost": {
"enabled": true,
"lose_after_days": null
}
},
"unanswered_message": {
"enabled": true,
"conversation_lifetime_cap": 4,
"template_after_window": true
}
}
}
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
DELETE /sequences/{id}/draft
Discard a sequence’s draft
Deletes the open draft («Descartar cambios»); the published version is untouched. Idempotent: discarded: false when there was none. Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl -X DELETE https://api.vitrinadev.com/api/v1/sequences/<id>/draft \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"discarded": true
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/draft
Read a sequence’s draft
Editing a sequence writes a DRAFT beside the published version; nothing reaches a customer until it is published. A draft holds the whole SequenceDefinition: the steps (channel, wait, mode), the situations (enabled), and for a built-in its settings (what is not a step: Recontacto’s «Ritmo», the first-touch source blocks). Publishing a built-in writes it through to the storage its engine reads (/followups/recontacto, the «Al llegar» source blocks, the /followups recipes) in the same transaction, so «Al llegar» is configurable here by API key and connector too. A published change to a wait applies to people already in the sequence from their next message.
The open draft with its definition and the sequence rendered from it (same shape as GET /sequences/\{id\}; the counts are today’s). 404 when there is no draft. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/draft \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"sequence_key": "builtin:si-no-responde",
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"based_on_version": 1,
"change_count": 1,
"created_at": "2026-11-02T15:00:00.000Z",
"updated_at": "2026-11-02T15:04:00.000Z",
"created_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"updated_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222"
},
"definition": {
"schema_version": 1,
"name": null,
"description": null,
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply"
},
"agent_id": null,
"priority": 3,
"steps": [
{
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"continues_in": null
}
],
"situations": [
{
"key": "conversed",
"name": null,
"enabled": true
},
{
"key": "never_replied",
"name": null,
"enabled": true
},
{
"key": "lost",
"name": null,
"enabled": true
}
],
"settings": {
"type": "recontacto",
"config": {
"enabled": true,
"daily_cap": 200,
"daily_review_budget": 500,
"lost_lookback_days": 90,
"max_evaluations_per_step": 3,
"re_evaluation_after_days": 1,
"excluded_template_ids": [],
"voice_examples": [],
"pacing": {
"min_gap_hours": null,
"max_per_day": null,
"pause_after_unanswered_days": null,
"approval_after_silence_days": null,
"approval_fallback_hours": null,
"entry_max_silence_days": 45,
"hot_leads_faster": false,
"max_paths_per_lead": 3,
"max_messages_per_person_90d": 6
},
"after_handoff": {
"followups": "draft_for_owner",
"auto_send_after_hours": 1,
"while_silent": "draft_auto_send",
"ai_answers_waiting": "after_minutes",
"ai_answers_waiting_after_minutes": 60,
"ai_answers_waiting_after_hours": 1,
"ai_answers_waiting_keep_owner": true
},
"situations": {
"never_replied": {
"enabled": true,
"lose_after_days": 7
},
"stalled": {
"enabled": true,
"lose_after_days": 7
},
"lost": {
"enabled": true,
"lose_after_days": null
}
},
"unanswered_message": {
"enabled": true,
"conversation_lifetime_cap": 4,
"template_after_window": true
}
}
}
},
"sequence": {
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"kind": "builtin",
"name": "Si no responde",
"description": "Le escribimos a quien dejó de responder, nunca respondió o ya está perdido.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente vuelva a responder"
},
"agent_id": null,
"priority": 3,
"situations": [
{
"key": "conversed",
"name": "Conversó y dejó de responder",
"enabled": true,
"first_step": "unanswered_message-1",
"waiting_now": 0,
"notes": []
},
{
"key": "never_replied",
"name": "Nunca respondió",
"enabled": true,
"first_step": "never_replied-1",
"waiting_now": 0,
"notes": []
},
{
"key": "lost",
"name": "Ya está perdido",
"enabled": true,
"first_step": "lost-1",
"waiting_now": 0,
"notes": [
"A quien compró en otro lado o dijo que no quiere, no le escribimos."
]
}
],
"steps": [
{
"id": "8a385269-303e-5d82-8ce3-d2c82d1c2af7",
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"wait_after_previous": {
"value": 4,
"unit": "hours"
},
"at_hours": 4,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "4a6f17b4-0255-5c56-bdc5-93d14b544d5d",
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"wait_after_previous": {
"value": 30,
"unit": "hours"
},
"at_hours": 34,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [
"Instagram no permite escribir pasadas 24 h: este mensaje no saldrá a quien no tenga teléfono."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "7876340a-bc26-5e3c-8ef7-778cd18f1eda",
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"wait_after_previous": {
"value": 14,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "3f04a26b-1479-5a3b-9f58-95c52e16c0a5",
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"wait_after_previous": {
"value": 2,
"unit": "days"
},
"at_hours": 96,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "ec87b5be-92d7-51a5-9936-c5131838d9ab",
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"wait_after_previous": {
"value": 3,
"unit": "hours"
},
"at_hours": 3,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [
"Muy pronto: un seguimiento a menos de 12 horas de nuestro primer mensaje casi nunca tiene respuesta."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "9211cfce-9740-5f79-b76c-962cb908f160",
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"wait_after_previous": {
"value": 5,
"unit": "hours"
},
"at_hours": 8,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "2e4ea654-9d30-50e7-b586-6aae005a35f3",
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"wait_after_previous": {
"value": 40,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "5a157200-6687-519a-b3a1-7c7da36b88d8",
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "09d4bf1d-8cbb-553c-8b68-ff0373a4cb37",
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"wait_after_previous": {
"value": 30,
"unit": "days"
},
"at_hours": 720,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"window_markers": [
{
"situation": "conversed",
"after_step": "unanswered_message-1",
"label": "se cierra la ventana de WhatsApp (se cuenta desde el último mensaje del cliente): desde aquí, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 264,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Fin de este camino.",
"detail": "Si vuelve a escribir y después se queda en silencio, empieza otro.",
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": 1,
"draft": {
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"change_count": 1,
"updated_at": "2026-11-02T15:04:00.000Z"
}
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
PUT /sequences/{id}/draft
Save a sequence’s draft
Editing a sequence writes a DRAFT beside the published version; nothing reaches a customer until it is published. A draft holds the whole SequenceDefinition: the steps (channel, wait, mode), the situations (enabled), and for a built-in its settings (what is not a step: Recontacto’s «Ritmo», the first-touch source blocks). Publishing a built-in writes it through to the storage its engine reads (/followups/recontacto, the «Al llegar» source blocks, the /followups recipes) in the same transaction, so «Al llegar» is configurable here by API key and connector too. A published change to a wait applies to people already in the sequence from their next message.
Creates the draft or replaces it with definition (start from GET /sequences/\{id\}/definition). The stored draft is what the definition compiles to, read back: a built-in cannot express everything (a «Si no responde» step cannot be skipped, the first message of «Al llegar» always waits 5 minutes), and what it cannot express is a 400 naming the step. A built-in’s first draft also records today’s config as version 1. Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
Cuerpo
| Campo | Tipo | Obligatorio | Restricciones |
|---|---|---|---|
definition | SequenceDefinition | sí |
curl -X PUT https://api.vitrinadev.com/api/v1/sequences/<id>/draft \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"definition": {
"schema_version": 1,
"name": null,
"description": null,
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply"
},
"agent_id": null,
"priority": 3,
"steps": [
{
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"continues_in": null
}
],
"situations": [
{
"key": "conversed",
"name": null,
"enabled": true
},
{
"key": "never_replied",
"name": null,
"enabled": true
},
{
"key": "lost",
"name": null,
"enabled": true
}
],
"settings": {
"type": "recontacto",
"config": {
"enabled": true,
"daily_cap": 200,
"daily_review_budget": 500,
"lost_lookback_days": 90,
"max_evaluations_per_step": 3,
"re_evaluation_after_days": 1,
"excluded_template_ids": [],
"voice_examples": [],
"pacing": {
"min_gap_hours": null,
"max_per_day": null,
"pause_after_unanswered_days": null,
"approval_after_silence_days": null,
"approval_fallback_hours": null,
"entry_max_silence_days": 45,
"hot_leads_faster": false,
"max_paths_per_lead": 3,
"max_messages_per_person_90d": 6
},
"after_handoff": {
"followups": "draft_for_owner",
"auto_send_after_hours": 1,
"while_silent": "draft_auto_send",
"ai_answers_waiting": "after_minutes",
"ai_answers_waiting_after_minutes": 60,
"ai_answers_waiting_after_hours": 1,
"ai_answers_waiting_keep_owner": true
},
"situations": {
"never_replied": {
"enabled": true,
"lose_after_days": 7
},
"stalled": {
"enabled": true,
"lose_after_days": 7
},
"lost": {
"enabled": true,
"lose_after_days": null
}
},
"unanswered_message": {
"enabled": true,
"conversation_lifetime_cap": 4,
"template_after_window": true
}
}
}
}
}'Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"sequence_key": "builtin:si-no-responde",
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"based_on_version": 1,
"change_count": 1,
"created_at": "2026-11-02T15:00:00.000Z",
"updated_at": "2026-11-02T15:04:00.000Z",
"created_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"updated_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222"
},
"definition": {
"schema_version": 1,
"name": null,
"description": null,
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply"
},
"agent_id": null,
"priority": 3,
"steps": [
{
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
}
},
{
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"mode": "auto",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
}
},
{
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"continues_in": null
}
],
"situations": [
{
"key": "conversed",
"name": null,
"enabled": true
},
{
"key": "never_replied",
"name": null,
"enabled": true
},
{
"key": "lost",
"name": null,
"enabled": true
}
],
"settings": {
"type": "recontacto",
"config": {
"enabled": true,
"daily_cap": 200,
"daily_review_budget": 500,
"lost_lookback_days": 90,
"max_evaluations_per_step": 3,
"re_evaluation_after_days": 1,
"excluded_template_ids": [],
"voice_examples": [],
"pacing": {
"min_gap_hours": null,
"max_per_day": null,
"pause_after_unanswered_days": null,
"approval_after_silence_days": null,
"approval_fallback_hours": null,
"entry_max_silence_days": 45,
"hot_leads_faster": false,
"max_paths_per_lead": 3,
"max_messages_per_person_90d": 6
},
"after_handoff": {
"followups": "draft_for_owner",
"auto_send_after_hours": 1,
"while_silent": "draft_auto_send",
"ai_answers_waiting": "after_minutes",
"ai_answers_waiting_after_minutes": 60,
"ai_answers_waiting_after_hours": 1,
"ai_answers_waiting_keep_owner": true
},
"situations": {
"never_replied": {
"enabled": true,
"lose_after_days": 7
},
"stalled": {
"enabled": true,
"lose_after_days": 7
},
"lost": {
"enabled": true,
"lose_after_days": null
}
},
"unanswered_message": {
"enabled": true,
"conversation_lifetime_cap": 4,
"template_after_window": true
}
}
}
},
"sequence": {
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"kind": "builtin",
"name": "Si no responde",
"description": "Le escribimos a quien dejó de responder, nunca respondió o ya está perdido.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente vuelva a responder"
},
"agent_id": null,
"priority": 3,
"situations": [
{
"key": "conversed",
"name": "Conversó y dejó de responder",
"enabled": true,
"first_step": "unanswered_message-1",
"waiting_now": 0,
"notes": []
},
{
"key": "never_replied",
"name": "Nunca respondió",
"enabled": true,
"first_step": "never_replied-1",
"waiting_now": 0,
"notes": []
},
{
"key": "lost",
"name": "Ya está perdido",
"enabled": true,
"first_step": "lost-1",
"waiting_now": 0,
"notes": [
"A quien compró en otro lado o dijo que no quiere, no le escribimos."
]
}
],
"steps": [
{
"id": "8a385269-303e-5d82-8ce3-d2c82d1c2af7",
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"wait_after_previous": {
"value": 4,
"unit": "hours"
},
"at_hours": 4,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "4a6f17b4-0255-5c56-bdc5-93d14b544d5d",
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"wait_after_previous": {
"value": 30,
"unit": "hours"
},
"at_hours": 34,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [
"Instagram no permite escribir pasadas 24 h: este mensaje no saldrá a quien no tenga teléfono."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "7876340a-bc26-5e3c-8ef7-778cd18f1eda",
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"wait_after_previous": {
"value": 14,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "3f04a26b-1479-5a3b-9f58-95c52e16c0a5",
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"wait_after_previous": {
"value": 2,
"unit": "days"
},
"at_hours": 96,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "ec87b5be-92d7-51a5-9936-c5131838d9ab",
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"wait_after_previous": {
"value": 3,
"unit": "hours"
},
"at_hours": 3,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [
"Muy pronto: un seguimiento a menos de 12 horas de nuestro primer mensaje casi nunca tiene respuesta."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "9211cfce-9740-5f79-b76c-962cb908f160",
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"wait_after_previous": {
"value": 5,
"unit": "hours"
},
"at_hours": 8,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "2e4ea654-9d30-50e7-b586-6aae005a35f3",
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"wait_after_previous": {
"value": 40,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "5a157200-6687-519a-b3a1-7c7da36b88d8",
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "09d4bf1d-8cbb-553c-8b68-ff0373a4cb37",
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"wait_after_previous": {
"value": 30,
"unit": "days"
},
"at_hours": 720,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"window_markers": [
{
"situation": "conversed",
"after_step": "unanswered_message-1",
"label": "se cierra la ventana de WhatsApp (se cuenta desde el último mensaje del cliente): desde aquí, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 264,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Fin de este camino.",
"detail": "Si vuelve a escribir y después se queda en silencio, empieza otro.",
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": 1,
"draft": {
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"change_count": 1,
"updated_at": "2026-11-02T15:04:00.000Z"
}
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/draft/diff
What publishing the draft would change
Every change of the draft against the published version: field (steps.stalled-2.wait, situations.lost.enabled, settings.pacing.max_per_day), before, after, and people_affected_now: the people at that step (or in that situation, or in the sequence) right now. For a built-in the published version is what its engine reads today. 404 when there is no draft. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/draft/diff \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"base_version": 1,
"change_count": 1,
"changes": [
{
"kind": "changed",
"field": "steps.stalled-2.wait",
"step_key": "stalled-2",
"situation": "conversed",
"before": {
"value": 3,
"unit": "days"
},
"after": {
"value": 2,
"unit": "days"
},
"people_affected_now": 12
}
]
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/draft/validation
What blocks publishing the draft
Checks the open draft the way publishing does. blockers stop POST /sequences/\{id\}/publish; warnings do not. Each problem has a machine-readable code, the step_id it is about (null for the whole draft), a Spanish message and a fix: kind is draft_template (have the AI write the missing WhatsApp template: POST /followups/recontacto/template-draft), connect_channel, request_review, remove_step, change_channel, pick_agent or contact_support, with a target (the same vocabulary as notifications) when there is a screen for it. Blocker codes: no_fitting_approved_template (a WhatsApp step past the 24 h window with no approved template Vitrina can fill), channel_not_connected (WhatsApp, email, Instagram), step_type_unavailable (a channel the workspace cannot use yet, e.g. SMS), agent_unavailable (the chosen AI agent is no longer active), agent_not_supported (an agent set on «Al llegar» or «Avisos»), review_required. Warning codes: instagram_past_24h, whatsapp_past_24h_without_template. Steps that never send (mode skip, a situation switched off) are not checked. Never calls a model. 404 when there is no draft. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/draft/validation \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"blockers": [
{
"code": "no_fitting_approved_template",
"step_id": "stalled-2",
"message": "Este paso escribe pasadas las 24 horas y para eso necesita una plantilla de WhatsApp aprobada. Todavía no hay ninguna que sirva.",
"fix": {
"kind": "draft_template",
"target": {
"kind": "page",
"page": "settings.templates"
}
}
}
],
"warnings": [
{
"code": "instagram_past_24h",
"step_id": "stalled-3",
"message": "Instagram solo deja escribir dentro de las 24 horas desde el último mensaje del cliente. Este paso no se enviará pasado ese plazo.",
"fix": {
"kind": "change_channel"
}
}
]
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/enrollments
List the people in a sequence with their consent
Enrollments of the sequence, newest first, each with the consent it entered on (consent.basis, note, time; null for people who entered by an event). Filter by contact_id (a person’s record) or batch_id. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
contact_id | query | uuid | no | |
batch_id | query | uuid | no | |
limit | query | integer | no | ≥ 1, ≤ 500 |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e50",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"contact_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e40",
"status": "active",
"exit_reason": null,
"entered_at": "2026-11-02T15:10:00.000Z",
"exited_at": null,
"batch_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"consent": {
"basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse",
"at": "2026-11-02T15:00:00.000Z"
}
}
]
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/enrollments/{enrollment_id}/promised-date
Record the date a customer promised
Sets (or clears, with date: null) the day a person in a custom sequence promised, e.g. to pay. A step wait_until \{kind:"date_field", field:"promised_date"\} («Esperar hasta la fecha prometida») waits until 00:00 of that day in the workspace’s time zone instead of its timeout, and consumes the date when it ends (a loop back waits for a NEW promise). A person already waiting at such a step is re-timed at once (waiting_for_date: true). The enrollment_id travels on every message the sequence queues (decision_payload.enrollment_id on GET /outbound/approvals). 404 sequence_enrollment when the person is no longer in that sequence. Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
enrollment_id | path | uuid | sí |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments/<id>/promised-date \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"date": "2026-11-15"
}'Ejemplo de respuesta (200)
{
"data": {
"enrollment_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e11",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"contact_id": "33333333-3333-4333-8333-333333333333",
"promised_date": "2026-11-15",
"current_step": "step-2",
"next_due_at": "2026-11-02T15:00:00.000Z",
"waiting_for_date": true
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/enrollments/batches
List the enrollment batches of a sequence
Every batch made from a list for this sequence, newest first, with status, consent and funnel. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments/batches \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"list_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e30",
"list_name": "Registrados sin comprar",
"status": "pending_activation",
"channel": "whatsapp",
"consent": {
"basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse",
"by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"at": "2026-11-02T15:00:00.000Z"
},
"funnel": {
"total": 120,
"reachable": 96,
"will_enroll": 90,
"excluded": {
"blocked": 2,
"spam": 0,
"archived": 1,
"no_identifier": 15,
"invalid_identifier": 3,
"duplicate": 3,
"opted_out": 5,
"already_in_sequence": 0,
"in_higher_sequence": 6,
"in_lower_sequence": 0,
"in_recontacto": 0
},
"opted_out_by": {
"stop_keyword": 4,
"unsubscribe": 1
}
},
"warnings": [
{
"code": "whatsapp_marketing_cost",
"message": "El primer mensaje por WhatsApp a quien no te escribió en las últimas 24 horas sale como plantilla de marketing aprobada, y Meta cobra cada conversación de marketing. Revisa la tarifa vigente en tu cuenta de Meta antes de activar."
}
],
"result": null,
"activated_at": null,
"activated_by": null,
"created_at": "2026-11-02T15:00:00.000Z"
}
]
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/enrollments/batches/{batch_id}
Read an enrollment batch
The batch status (pending_activation, activated, cancelled), its consent, the preview funnel and, once activated, the result (enrolled and what was skipped and why). Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
batch_id | path | uuid | sí |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments/batches/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"list_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e30",
"list_name": "Registrados sin comprar",
"status": "pending_activation",
"channel": "whatsapp",
"consent": {
"basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse",
"by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"at": "2026-11-02T15:00:00.000Z"
},
"funnel": {
"total": 120,
"reachable": 96,
"will_enroll": 90,
"excluded": {
"blocked": 2,
"spam": 0,
"archived": 1,
"no_identifier": 15,
"invalid_identifier": 3,
"duplicate": 3,
"opted_out": 5,
"already_in_sequence": 0,
"in_higher_sequence": 6,
"in_lower_sequence": 0,
"in_recontacto": 0
},
"opted_out_by": {
"stop_keyword": 4,
"unsubscribe": 1
}
},
"warnings": [
{
"code": "whatsapp_marketing_cost",
"message": "El primer mensaje por WhatsApp a quien no te escribió en las últimas 24 horas sale como plantilla de marketing aprobada, y Meta cobra cada conversación de marketing. Revisa la tarifa vigente en tu cuenta de Meta antes de activar."
}
],
"result": null,
"activated_at": null,
"activated_by": null,
"created_at": "2026-11-02T15:00:00.000Z"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/enrollments/batches/{batch_id}/activate
Activate an enrollment batch
Step 2: the owner starts it. Everyone is checked again (opt-out, blocked, no channel, exclusivity): a person already in a higher sequence (or in «Si no responde» when it ranks above) is skipped and counted in result.excluded. The rest are enrolled with the batch and basis on their enrollment, and the sequence runs them like any other: its own agent writes, contact hours, pause and per-person limits apply. The sequence must be published (409 sequence_not_published); a batch activates once (409 batch_not_pending). Requires followups:write and campaigns:write (it starts outbound messages).
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
batch_id | path | uuid | sí |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments/batches/<id>/activate \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"list_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e30",
"list_name": "Registrados sin comprar",
"status": "activated",
"channel": "whatsapp",
"consent": {
"basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse",
"by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"at": "2026-11-02T15:00:00.000Z"
},
"funnel": {
"total": 120,
"reachable": 96,
"will_enroll": 90,
"excluded": {
"blocked": 2,
"spam": 0,
"archived": 1,
"no_identifier": 15,
"invalid_identifier": 3,
"duplicate": 3,
"opted_out": 5,
"already_in_sequence": 0,
"in_higher_sequence": 6,
"in_lower_sequence": 0,
"in_recontacto": 0
},
"opted_out_by": {
"stop_keyword": 4,
"unsubscribe": 1
}
},
"warnings": [
{
"code": "whatsapp_marketing_cost",
"message": "El primer mensaje por WhatsApp a quien no te escribió en las últimas 24 horas sale como plantilla de marketing aprobada, y Meta cobra cada conversación de marketing. Revisa la tarifa vigente en tu cuenta de Meta antes de activar."
}
],
"result": {
"total": 120,
"reachable": 96,
"will_enroll": 90,
"excluded": {
"blocked": 2,
"spam": 0,
"archived": 1,
"no_identifier": 15,
"invalid_identifier": 3,
"duplicate": 3,
"opted_out": 5,
"already_in_sequence": 0,
"in_higher_sequence": 6,
"in_lower_sequence": 0,
"in_recontacto": 0
},
"opted_out_by": {
"stop_keyword": 4,
"unsubscribe": 1
},
"enrolled": 90
},
"activated_at": "2026-11-02T15:10:00.000Z",
"activated_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222"
},
"created_at": "2026-11-02T15:00:00.000Z"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/enrollments/batches/{batch_id}/cancel
Cancel a pending enrollment batch
Drops a batch that was never activated; nothing was sent. 409 batch_not_pending otherwise. Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
batch_id | path | uuid | sí |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments/batches/<id>/cancel \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"list_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e30",
"list_name": "Registrados sin comprar",
"status": "cancelled",
"channel": "whatsapp",
"consent": {
"basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse",
"by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"at": "2026-11-02T15:00:00.000Z"
},
"funnel": {
"total": 120,
"reachable": 96,
"will_enroll": 90,
"excluded": {
"blocked": 2,
"spam": 0,
"archived": 1,
"no_identifier": 15,
"invalid_identifier": 3,
"duplicate": 3,
"opted_out": 5,
"already_in_sequence": 0,
"in_higher_sequence": 6,
"in_lower_sequence": 0,
"in_recontacto": 0
},
"opted_out_by": {
"stop_keyword": 4,
"unsubscribe": 1
}
},
"warnings": [
{
"code": "whatsapp_marketing_cost",
"message": "El primer mensaje por WhatsApp a quien no te escribió en las últimas 24 horas sale como plantilla de marketing aprobada, y Meta cobra cada conversación de marketing. Revisa la tarifa vigente en tu cuenta de Meta antes de activar."
}
],
"result": null,
"activated_at": null,
"activated_by": null,
"created_at": "2026-11-02T15:00:00.000Z"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/enrollments/from-list
Preview and record the consent to enroll a list
Step 1 of enrolling a list into a custom sequence. Records the consent basis (customer_relationship, explicit_opt_in, other_documented) with the evidence note, who chose it and when, and answers the funnel: total (the list) -> reachable (a usable phone or email for the first step, not opted out) -> will_enroll (free to enter), with a count per exclusion reason (blocked, spam, no_identifier, opted_out by reason, in_higher_sequence, ...). For WhatsApp the warnings carry the cost note: the first message is an approved marketing template and Meta charges per marketing conversation. Nothing is sent and nobody is enrolled: the batch is pending_activation until POST .../activate. A list is a saved audience; importing contacts never enrolls anyone. 201. Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/enrollments/from-list \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"list_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e30",
"consent_basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse"
}'Ejemplo de respuesta (201)
{
"data": {
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e20",
"sequence_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"list_id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e30",
"list_name": "Registrados sin comprar",
"status": "pending_activation",
"channel": "whatsapp",
"consent": {
"basis": "explicit_opt_in",
"note": "Aceptaron términos al registrarse",
"by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"at": "2026-11-02T15:00:00.000Z"
},
"funnel": {
"total": 120,
"reachable": 96,
"will_enroll": 90,
"excluded": {
"blocked": 2,
"spam": 0,
"archived": 1,
"no_identifier": 15,
"invalid_identifier": 3,
"duplicate": 3,
"opted_out": 5,
"already_in_sequence": 0,
"in_higher_sequence": 6,
"in_lower_sequence": 0,
"in_recontacto": 0
},
"opted_out_by": {
"stop_keyword": 4,
"unsubscribe": 1
}
},
"warnings": [
{
"code": "whatsapp_marketing_cost",
"message": "El primer mensaje por WhatsApp a quien no te escribió en las últimas 24 horas sale como plantilla de marketing aprobada, y Meta cobra cada conversación de marketing. Revisa la tarifa vigente en tu cuenta de Meta antes de activar."
}
],
"result": null,
"activated_at": null,
"activated_by": null,
"created_at": "2026-11-02T15:00:00.000Z"
}
}Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/legal-review
Where the legal review of a collection sequence stands
status: not_required (not a collection sequence), missing, valid (recorded against the current rules version) or outdated (the rules changed since). review is the newest recorded one. Publishing a collection sequence is refused with review_required unless the status is valid. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/legal-review \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "0192f0b2-0000-7000-8000-00000000c001",
"required": true,
"status": "valid",
"rules_version": 3,
"review": {
"id": "0192f0b2-0000-7000-8000-00000000d001",
"reviewer_member_id": "0192f0b2-0000-7000-8000-00000000a002",
"reviewed_on": "2027-03-02",
"note": "Revisado con la abogada del estudio",
"attachment_url": "https://docs.ejemplo.cl/opinion-legal.pdf",
"rules_version": 3,
"created_at": "2027-03-02T14:25:00.000Z",
"created_by": {
"kind": "user",
"id": "0192f0b2-0000-7000-8000-00000000a001"
}
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/legal-review
Record the legal review of a collection sequence
Records who reviewed the sequence and the rules (reviewer_member_id, reviewed_on, a note and/or an attachment_url) against the current rules version, which clears the review_required blocker. Append-only: the history is kept. 422 for a sequence that is not a collection sequence; 409 rules_version_stale when rules_version is no longer current. Requires followups:write.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/legal-review \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"reviewer_member_id": "0192f0b2-0000-7000-8000-00000000a002",
"reviewed_on": "2027-03-02",
"note": "Revisado con la abogada del estudio",
"attachment_url": "https://docs.ejemplo.cl/opinion-legal.pdf"
}'Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "0192f0b2-0000-7000-8000-00000000c001",
"required": true,
"status": "valid",
"rules_version": 3,
"review": {
"id": "0192f0b2-0000-7000-8000-00000000d001",
"reviewer_member_id": "0192f0b2-0000-7000-8000-00000000a002",
"reviewed_on": "2027-03-02",
"note": "Revisado con la abogada del estudio",
"attachment_url": "https://docs.ejemplo.cl/opinion-legal.pdf",
"rules_version": 3,
"created_at": "2027-03-02T14:25:00.000Z",
"created_by": {
"kind": "user",
"id": "0192f0b2-0000-7000-8000-00000000a001"
}
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/publish
Publish a sequence’s draft
The draft becomes the next numbered version, atomically: the previous version is archived and, for a built-in, its storage is rewritten in the same transaction. Recorded in the change history (who, when, the diff: GET /sequences/\{id\}/versions, and the audit log). 404 when there is no draft. 422 VALIDATION_ERROR while the draft has blockers: details.problems is the blocker list (same items as GET /sequences/\{id\}/draft/validation), details.warnings the rest. Requires followups:write. A publish that LOOSENS outbound (switching Recontacto or a first-touch source on, a step to auto or auto_unless_assigned, clearing or raising a limit) also needs campaigns:write, judged exactly as PUT /followups/recontacto judges the same edit; without it the answer is 403 and nothing changes.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
lang | query | es \ | en | no |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/publish \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"version": 2,
"published_at": "2026-11-02T15:06:00.000Z",
"origin": "edit",
"changes": [
{
"kind": "changed",
"field": "steps.stalled-2.wait",
"step_key": "stalled-2",
"situation": "conversed",
"before": {
"value": 3,
"unit": "days"
},
"after": {
"value": 2,
"unit": "days"
},
"people_affected_now": 12
}
],
"sequence": {
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"kind": "builtin",
"name": "Si no responde",
"description": "Le escribimos a quien dejó de responder, nunca respondió o ya está perdido.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente vuelva a responder"
},
"agent_id": null,
"priority": 3,
"situations": [
{
"key": "conversed",
"name": "Conversó y dejó de responder",
"enabled": true,
"first_step": "unanswered_message-1",
"waiting_now": 0,
"notes": []
},
{
"key": "never_replied",
"name": "Nunca respondió",
"enabled": true,
"first_step": "never_replied-1",
"waiting_now": 0,
"notes": []
},
{
"key": "lost",
"name": "Ya está perdido",
"enabled": true,
"first_step": "lost-1",
"waiting_now": 0,
"notes": [
"A quien compró en otro lado o dijo que no quiere, no le escribimos."
]
}
],
"steps": [
{
"id": "8a385269-303e-5d82-8ce3-d2c82d1c2af7",
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"wait_after_previous": {
"value": 4,
"unit": "hours"
},
"at_hours": 4,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "4a6f17b4-0255-5c56-bdc5-93d14b544d5d",
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"wait_after_previous": {
"value": 30,
"unit": "hours"
},
"at_hours": 34,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [
"Instagram no permite escribir pasadas 24 h: este mensaje no saldrá a quien no tenga teléfono."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "7876340a-bc26-5e3c-8ef7-778cd18f1eda",
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"wait_after_previous": {
"value": 14,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "3f04a26b-1479-5a3b-9f58-95c52e16c0a5",
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"wait_after_previous": {
"value": 2,
"unit": "days"
},
"at_hours": 96,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "ec87b5be-92d7-51a5-9936-c5131838d9ab",
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"wait_after_previous": {
"value": 3,
"unit": "hours"
},
"at_hours": 3,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [
"Muy pronto: un seguimiento a menos de 12 horas de nuestro primer mensaje casi nunca tiene respuesta."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "9211cfce-9740-5f79-b76c-962cb908f160",
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"wait_after_previous": {
"value": 5,
"unit": "hours"
},
"at_hours": 8,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "2e4ea654-9d30-50e7-b586-6aae005a35f3",
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"wait_after_previous": {
"value": 40,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "5a157200-6687-519a-b3a1-7c7da36b88d8",
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "09d4bf1d-8cbb-553c-8b68-ff0373a4cb37",
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"wait_after_previous": {
"value": 30,
"unit": "days"
},
"at_hours": 720,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"window_markers": [
{
"situation": "conversed",
"after_step": "unanswered_message-1",
"label": "se cierra la ventana de WhatsApp (se cuenta desde el último mensaje del cliente): desde aquí, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 264,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Fin de este camino.",
"detail": "Si vuelve a escribir y después se queda en silencio, empieza otro.",
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": 2,
"draft": null
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/simulate
Simulate what one customer will receive
Walks «Si no responde» for ONE person: a real contact_id or a test persona (has_whatsapp, has_email optional, opted_out), from the moment our last message went out (last_message_at), with what the customer does (behavior: never_replies, replies_after_step; pays and promises_date are collections behaviors and are no-ops for sequences without payment steps). AI call steps end as call_outcomes says (\{step_id: outcome\}, default no_answer; nothing is called and no model runs). Returns the timeline (each step with the moment the ladder draws it, planned_at, and the moment the engine really sends it after contact hours and pacing, shifted_at, with shift_reason, a preview when a stored draft or approved template exists, and a status) and the real end reason: replied, end_of_sequence, marked_lost, no_fitting_approved_message, no_channel_left, message_limit_reached or opted_out. It is the same simulation GET /followups/recontacto/plan renders, so it follows the engine’s rules (contact hours from 9:00, the 24 h WhatsApp window, per-person limits, opt-out). Deterministic: no model call, nothing is sent or stored. version is published (default), draft (the open draft, GET /sequences/\{id\}/draft) or a version id (GET /sequences/\{id\}/versions). builtin:si-no-responde and custom sequences are simulable (a custom sequence walks its own steps through the same engine rules; steps timed before an appointment are listed in notes). Custom sequences with conditions, waits until and loops follow the scenario: replies_after_step → the yes branch of «¿Respondió?» (a reply ends the sequence only when its goal is a reply), pays → «¿Pagó?», promises_date → «Esperar hasta la fecha prometida» ends that day; decisions (\{step key or id: branch key\}) picks any condition’s branch, and «La IA decide» is never called here (without a decision it takes its first branch). The response then carries path (every step passed, the branch taken, loop laps) and timeline entries met again in a loop carry iteration. Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/simulate \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"persona": {
"name": "Cliente de prueba",
"has_whatsapp": true,
"opted_out": false
},
"last_message_at": "2026-10-21T19:00:00Z",
"situation": "never_replied",
"behavior": {
"kind": "replies_after_step",
"step": 2
}
}'Ejemplo de respuesta (200)
{
"data": {
"timeline": [
{
"step_id": "c2f1a7b4-6d0e-5b8a-9a77-0b9f5d3e1c10",
"step_key": "never_replied-1",
"channel": "whatsapp",
"planned_at": "2026-10-21T22:00:00.000Z",
"shifted_at": "2026-10-21T22:00:00.000Z",
"status": "sends"
},
{
"step_id": "3a9d6e52-1f48-5c3b-8e0d-7a4c2b6f9d21",
"step_key": "never_replied-2",
"channel": "whatsapp",
"planned_at": "2026-10-22T03:00:00.000Z",
"shifted_at": "2026-10-22T12:00:00.000Z",
"shift_reason": "outside_contact_hours",
"status": "sends"
}
],
"end": {
"reason": "replied",
"at_step": "3a9d6e52-1f48-5c3b-8e0d-7a4c2b6f9d21",
"at": "2026-10-22T12:00:00.000Z"
},
"notes": []
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/{id}/versions
List a sequence’s versions
Every numbered version, newest first: status (published is the one running, archived the history), origin (edit a published draft, revert, materialized = version 1 read from the config a built-in had, external = that config was changed through its own route since), who created and published it, when, and the changes it published. Empty until the first draft. limit 1–200 (default 50). Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
limit | query | integer | no | ≥ 1, ≤ 200 |
curl https://api.vitrinadev.com/api/v1/sequences/<id>/versions \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"version": 2,
"status": "published",
"origin": "edit",
"based_on_version": 1,
"reverted_from": null,
"change_count": 1,
"changes": [
{
"kind": "changed",
"field": "steps.stalled-2.wait",
"step_key": "stalled-2",
"situation": "conversed",
"before": {
"value": 3,
"unit": "days"
},
"after": {
"value": 2,
"unit": "days"
},
"people_affected_now": 12
}
],
"created_at": "2026-11-02T15:00:00.000Z",
"created_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222",
"via": null
},
"published_at": "2026-11-02T15:06:00.000Z",
"published_by": {
"kind": "user",
"id": "22222222-2222-4222-8222-222222222222"
}
},
{
"id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0f",
"version": 1,
"status": "archived",
"origin": "materialized",
"based_on_version": null,
"reverted_from": null,
"change_count": 0,
"changes": [],
"created_at": "2026-11-02T15:00:00.000Z",
"created_by": {
"kind": "system",
"id": null,
"via": null
},
"published_at": "2026-11-02T15:00:00.000Z",
"published_by": {
"kind": "system",
"id": null
}
}
]
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /sequences/{id}/versions/{version}/revert
Go back to a version
Publishes a NEW version equal to version (history is never rewritten; «deshacer» after a publish is a revert to the version before it). An open draft stays as it is. 404 for an unknown version. Requires followups:write. A publish that LOOSENS outbound (switching Recontacto or a first-touch source on, a step to auto or auto_unless_assigned, clearing or raising a limit) also needs campaigns:write, judged exactly as PUT /followups/recontacto judges the same edit; without it the answer is 403 and nothing changes.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | string | sí | mín. 1, máx. 120 |
version | path | integer | sí | ≥ 1 |
lang | query | es \ | en | no |
curl -X POST https://api.vitrinadev.com/api/v1/sequences/<id>/versions/<id>/revert \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"sequence_id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"version_id": "0192f0a1-7c3e-7b2a-9d4e-5f6a7b8c9d0e",
"version": 3,
"published_at": "2026-11-02T15:06:00.000Z",
"origin": "revert",
"changes": [
{
"kind": "changed",
"field": "steps.stalled-2.wait",
"step_key": "stalled-2",
"situation": "conversed",
"before": {
"value": 2,
"unit": "days"
},
"after": {
"value": 3,
"unit": "days"
},
"people_affected_now": 12
}
],
"sequence": {
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"kind": "builtin",
"name": "Si no responde",
"description": "Le escribimos a quien dejó de responder, nunca respondió o ya está perdido.",
"status": "active",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": [
{
"field": "situation",
"op": "in",
"values": [
"conversed",
"never_replied",
"lost"
]
}
]
},
"goal": {
"type": "reply",
"label": "Que el cliente vuelva a responder"
},
"agent_id": null,
"priority": 3,
"situations": [
{
"key": "conversed",
"name": "Conversó y dejó de responder",
"enabled": true,
"first_step": "unanswered_message-1",
"waiting_now": 0,
"notes": []
},
{
"key": "never_replied",
"name": "Nunca respondió",
"enabled": true,
"first_step": "never_replied-1",
"waiting_now": 0,
"notes": []
},
{
"key": "lost",
"name": "Ya está perdido",
"enabled": true,
"first_step": "lost-1",
"waiting_now": 0,
"notes": [
"A quien compró en otro lado o dijo que no quiere, no le escribimos."
]
}
],
"steps": [
{
"id": "8a385269-303e-5d82-8ce3-d2c82d1c2af7",
"key": "unanswered_message-1",
"situation": "conversed",
"kind": "message",
"position": 1,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 4,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 4
},
"wait_after_previous": {
"value": 4,
"unit": "hours"
},
"at_hours": 4,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": false,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 1,
"after_hours": 4,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "4a6f17b4-0255-5c56-bdc5-93d14b544d5d",
"key": "unanswered_message-2",
"situation": "conversed",
"kind": "message",
"position": 2,
"channel": "same_chat",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "hours",
"from": "previous_step",
"from_step": "unanswered_message-1",
"hours": 30
},
"wait_after_previous": {
"value": 30,
"unit": "hours"
},
"at_hours": 34,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "unanswered_message",
"step": 2,
"after_hours": 30,
"unit": null,
"autonomy": "auto",
"channel": null,
"min_score": null
},
"warnings": [
"Instagram no permite escribir pasadas 24 h: este mensaje no saldrá a quien no tenga teléfono."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "7876340a-bc26-5e3c-8ef7-778cd18f1eda",
"key": "stalled-1",
"situation": "conversed",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 48
},
"wait_after_previous": {
"value": 14,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 1,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "3f04a26b-1479-5a3b-9f58-95c52e16c0a5",
"key": "stalled-2",
"situation": "conversed",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "stalled-1",
"hours": 48
},
"wait_after_previous": {
"value": 2,
"unit": "days"
},
"at_hours": 96,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "stalled",
"step": 2,
"after_hours": 48,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "ec87b5be-92d7-51a5-9936-c5131838d9ab",
"key": "never_replied-1",
"situation": "never_replied",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 3
},
"wait_after_previous": {
"value": 3,
"unit": "hours"
},
"at_hours": 3,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 1,
"after_hours": 3,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [
"Muy pronto: un seguimiento a menos de 12 horas de nuestro primer mensaje casi nunca tiene respuesta."
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "9211cfce-9740-5f79-b76c-962cb908f160",
"key": "never_replied-2",
"situation": "never_replied",
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-1",
"hours": 5
},
"wait_after_previous": {
"value": 5,
"unit": "hours"
},
"at_hours": 8,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 2,
"after_hours": 5,
"unit": "h",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "2e4ea654-9d30-50e7-b586-6aae005a35f3",
"key": "never_replied-3",
"situation": "never_replied",
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 40,
"unit": "hours",
"from": "previous_step",
"from_step": "never_replied-2",
"hours": 40
},
"wait_after_previous": {
"value": 40,
"unit": "hours"
},
"at_hours": 48,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 3,
"after_hours": 40,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "5a157200-6687-519a-b3a1-7c7da36b88d8",
"key": "never_replied-4",
"situation": "never_replied",
"kind": "message",
"position": 4,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "previous_step",
"from_step": "never_replied-3",
"hours": 72
},
"wait_after_previous": {
"value": 3,
"unit": "days"
},
"at_hours": 120,
"mode": "auto",
"mode_effective": "auto",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "never_replied",
"step": 4,
"after_hours": 72,
"unit": "d",
"autonomy": "auto",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
},
{
"id": "09d4bf1d-8cbb-553c-8b68-ff0373a4cb37",
"key": "lost-1",
"situation": "lost",
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 30,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 720
},
"wait_after_previous": {
"value": 30,
"unit": "days"
},
"at_hours": 720,
"mode": "approval",
"mode_effective": "approval",
"sends": true,
"not_sent_reason": null,
"needs_template": true,
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": {
"type": "recontacto",
"rail": "lost",
"step": 1,
"after_hours": 720,
"unit": "d",
"autonomy": "approval",
"channel": "whatsapp",
"min_score": null
},
"warnings": [],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
}
],
"connections": [
{
"from": "entry",
"to": "unanswered_message-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-1",
"to": "unanswered_message-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "unanswered_message-2",
"to": "stalled-1",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-1",
"to": "stalled-2",
"kind": "next",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "exit",
"kind": "reply_exit",
"situation": "conversed"
},
{
"from": "stalled-2",
"to": "end:conversed",
"kind": "end",
"situation": "conversed"
},
{
"from": "entry",
"to": "never_replied-1",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-1",
"to": "never_replied-2",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-2",
"to": "never_replied-3",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-3",
"to": "never_replied-4",
"kind": "next",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "exit",
"kind": "reply_exit",
"situation": "never_replied"
},
{
"from": "never_replied-4",
"to": "end:never_replied",
"kind": "end",
"situation": "never_replied"
},
{
"from": "entry",
"to": "lost-1",
"kind": "next",
"situation": "lost"
},
{
"from": "lost-1",
"to": "exit",
"kind": "reply_exit",
"situation": "lost"
},
{
"from": "lost-1",
"to": "end:lost",
"kind": "end",
"situation": "lost"
}
],
"window_markers": [
{
"situation": "conversed",
"after_step": "unanswered_message-1",
"label": "se cierra la ventana de WhatsApp (se cuenta desde el último mensaje del cliente): desde aquí, solo plantillas aprobadas"
}
],
"ends": [
{
"key": "end:conversed",
"situation": "conversed",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 264,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:never_replied",
"situation": "never_replied",
"type": "mark_lost",
"after": {
"value": 7,
"unit": "days"
},
"at_hours": 288,
"label": "Lo marcamos perdido",
"detail": "Si sigue sin responder 7 días después del último mensaje.",
"continues_in": {
"sequence_key": "builtin:si-no-responde",
"situation": "lost"
}
},
{
"key": "end:lost",
"situation": "lost",
"type": "finish",
"after": null,
"at_hours": null,
"label": "Fin de este camino.",
"detail": "Si vuelve a escribir y después se queda en silencio, empieza otro.",
"continues_in": null
}
],
"stats": {
"waiting_now": 0,
"sent_30d": 0,
"reply_rate_30d": null,
"daily_14d": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
"published_version": 3,
"draft": null
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/collection-rules
Collection rules of the workspace
The days, hours and caps collection sequences obey on top of the shared guards (contact hours, per-person limits): weekdays, the hours window, calls_per_day, calls_per_week, messages_per_week, min_spacing_hours and over_cap (skip or move). The defaults are the limits of Ley 19.496 art. 37 (Ley 21.320) and CPC art. 59: Monday to Saturday except holidays, 08:00 to 20:00, one call per week, two messages per week at least 48 h apart. ceilings are those legal limits: a workspace may be stricter, never looser. version is 0 until the rules are saved. Requires followups:read.
curl https://api.vitrinadev.com/api/v1/sequences/collection-rules \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"rules": {
"weekdays": [
1,
2,
3,
4,
5,
6
],
"hours": {
"start": "08:00",
"end": "20:00"
},
"skip_holidays": true,
"calls_per_day": 1,
"calls_per_week": 1,
"messages_per_week": 2,
"min_spacing_hours": 48,
"over_cap": "skip"
},
"version": 3,
"is_default": false,
"updated_at": "2027-03-02T14:20:00.000Z",
"updated_by": {
"kind": "user",
"id": "0192f0b2-0000-7000-8000-00000000a001"
},
"ceilings": {
"weekdays": [
1,
2,
3,
4,
5,
6
],
"hours": {
"start": "08:00",
"end": "20:00"
},
"calls_per_day": 1,
"calls_per_week": 1,
"messages_per_week": 2,
"min_spacing_hours": 48
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
PUT /sequences/collection-rules
Replace the collection rules
Replaces the rules (fields left out take the platform defaults). 422 VALIDATION_ERROR with details.problems when a value is looser than the law allows. A real change raises version, which makes every recorded legal review outdated: collection sequences need a new review before they publish again. Saving the rules already in force changes nothing. Requires followups:write.
curl -X PUT https://api.vitrinadev.com/api/v1/sequences/collection-rules \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages_per_week": 1,
"hours": {
"start": "09:00",
"end": "19:00"
}
}'Ejemplo de respuesta (200)
{
"data": {
"rules": {
"weekdays": [
1,
2,
3,
4,
5,
6
],
"hours": {
"start": "09:00",
"end": "19:00"
},
"skip_holidays": true,
"calls_per_day": 1,
"calls_per_week": 1,
"messages_per_week": 1,
"min_spacing_hours": 48,
"over_cap": "skip"
},
"version": 3,
"is_default": false,
"updated_at": "2027-03-02T14:20:00.000Z",
"updated_by": {
"kind": "user",
"id": "0192f0b2-0000-7000-8000-00000000a001"
},
"ceilings": {
"weekdays": [
1,
2,
3,
4,
5,
6
],
"hours": {
"start": "08:00",
"end": "20:00"
},
"calls_per_day": 1,
"calls_per_week": 1,
"messages_per_week": 2,
"min_spacing_hours": 48
}
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
PUT /sequences/order
Set the priority order of the sequences
The ONE priority list a person is placed by: builtin:si-no-responde and every custom sequence id, highest first, each exactly once (400 otherwise, naming what is missing or unknown). A person who qualifies for two enters only the higher one, and is in one at a time. «Avisos» (1) and «Al llegar» (2) keep their places outside the list. Answers the list with each sequence’s id, key and priority as GET /sequences shows it (a built-in’s uuid is accepted too). Requires followups:write.
curl -X PUT https://api.vitrinadev.com/api/v1/sequences/order \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"order": [
"0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"builtin:si-no-responde"
]
}'Ejemplo de respuesta (200)
{
"data": {
"order": [
{
"id": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"key": "0192f0b2-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"priority": 3
},
{
"id": "dd63825c-cb16-553d-90cc-6cb4fa694ce8",
"key": "builtin:si-no-responde",
"priority": 4
}
]
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /sequences/templates
List the templates for a new sequence
A custom sequence is the workspace’s own: who enters (entry: an event — lead_arrived, customer_went_quiet, stage_changed, quoted_not_booked, appointment_booked; signed_up_not_bought and installment_overdue are accepted but cannot be published yet; or a list, enrolled with consent through POST /sequences/\{id\}/enrollments/from-list — with filters on interest, source, stage or tag), the goal that makes a person leave when met (reply, books_visit, books_demo; pays cannot be published yet) and the steps, edited as a draft and run once published (POST /sequences/\{id\}/publish). A person is in ONE sequence at a time among «Si no responde» and the custom ones, and enters the highest-priority one they qualify for; «Al llegar» and «Avisos» stay outside that rule. The engine sends through the same guards as «Si no responde»: contact hours, per-person limits, opt-out, the 24 h WhatsApp window, pauses and «Con tu OK».
The «Nueva secuencia» catalogue: Seguimiento de cotización, Reactivar clientes, Se registró y no pagó, Cobranza de cuotas, Recordatorio de cita and Desde cero, each with its entry, goal and suggested steps (a step whose channel is not available yet is flagged by the draft validation, not hidden). Requires followups:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
lang | query | es \ | en | no |
curl https://api.vitrinadev.com/api/v1/sequences/templates \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"key": "quote_followup",
"name": "Seguimiento de cotización",
"description": "Cotizó y no agendó visita: recordatorio, luego un llamado.",
"entry": {
"type": "event",
"event": "quoted_not_booked",
"filters": []
},
"goal": {
"type": "books_visit",
"label": "Agenda visita"
},
"channels": [
"whatsapp",
"whatsapp",
"call"
],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 3,
"unit": "days",
"from": "start",
"from_step": null,
"hours": 72
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Recordatorio de la cotización"
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Quedan 24 h de cotización"
},
{
"key": "step-3",
"situation": null,
"kind": "message",
"position": 3,
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Llamada para agendar"
}
]
},
{
"key": "reactivate",
"name": "Reactivar clientes",
"description": "Clientes con una compra anterior: novedad y oferta.",
"entry": {
"type": "list",
"list_id": null
},
"goal": {
"type": "books_visit",
"label": "Agenda visita"
},
"channels": [
"whatsapp",
"email",
"whatsapp"
],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 0,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 0
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Novedad personalizada"
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "email",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 2,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 48
},
"mode": "approval",
"content": {
"type": "email",
"subject": null,
"custom_body": false
},
"config_ref": null,
"label": "Detalle de la oferta"
},
{
"key": "step-3",
"situation": null,
"kind": "message",
"position": 3,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 5,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 120
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Último recordatorio"
}
]
},
{
"key": "signup_not_paid",
"name": "Se registró y no pagó",
"description": "Usuarios que crearon cuenta pero no compraron: ofrece una demo.",
"entry": {
"type": "list",
"list_id": null
},
"goal": {
"type": "books_demo",
"label": "Agenda demo"
},
"channels": [
"email",
"whatsapp",
"call",
"email"
],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "email",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 0,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 0
},
"mode": "approval",
"content": {
"type": "email",
"subject": null,
"custom_body": false
},
"config_ref": null,
"label": "Bienvenida + link a demo"
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Te ayudo a configurarlo"
},
{
"key": "step-3",
"situation": null,
"kind": "message",
"position": 3,
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Llamada para agendar demo"
},
{
"key": "step-4",
"situation": null,
"kind": "message",
"position": 4,
"channel": "email",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 32,
"unit": "hours",
"from": "previous_step",
"from_step": "step-3",
"hours": 32
},
"mode": "approval",
"content": {
"type": "email",
"subject": null,
"custom_body": false
},
"config_ref": null,
"label": "Caso de éxito de su rubro"
}
]
},
{
"key": "installments",
"name": "Cobranza de cuotas",
"description": "Cuota vencida: correo, llamada, WhatsApp y aviso formal.",
"entry": {
"type": "event",
"event": "installment_overdue",
"filters": []
},
"goal": {
"type": "pays",
"label": "Paga"
},
"channels": [
"email",
"call",
"whatsapp",
"call",
"email"
],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "email",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 0,
"unit": "hours",
"from": "start",
"from_step": null,
"hours": 0
},
"mode": "approval",
"content": {
"type": "email",
"subject": null,
"custom_body": false
},
"config_ref": null,
"label": "Recordatorio con link de pago"
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-1",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Llamada de cobranza"
},
{
"situation": null,
"config_ref": null,
"key": "call-1-outcome",
"kind": "condition",
"position": 3,
"wait": {
"type": "duration",
"value": 0,
"unit": "hours",
"from": "previous_step",
"from_step": "step-2",
"hours": 0
},
"test": "call_outcome",
"ai_prompt": null,
"branches": [
{
"key": "promised_pay",
"label": "Prometió pagar",
"to": "promise-1-wait"
},
{
"key": "no_answer",
"label": "No contestó",
"to": "step-3"
}
],
"default_branch": "no_answer",
"label": "¿Cómo salió la llamada?"
},
{
"situation": null,
"config_ref": null,
"key": "promise-1-wait",
"kind": "wait_until",
"position": 4,
"until": {
"kind": "date_field",
"field": "promised_date"
},
"timeout": {
"value": 14,
"unit": "days"
},
"label": "Esperar hasta la fecha prometida"
},
{
"situation": null,
"config_ref": null,
"key": "paid-1",
"kind": "condition",
"position": 5,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "promise-1-wait",
"hours": 24
},
"test": "paid",
"ai_prompt": null,
"branches": [
{
"key": "yes",
"label": "Sí",
"to": "end"
},
{
"key": "no",
"label": "No",
"to": "step-3"
}
],
"default_branch": null,
"label": "¿Pagó?"
},
{
"key": "step-3",
"situation": null,
"kind": "message",
"position": 6,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-2",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Recordatorio + link"
},
{
"key": "step-4",
"situation": null,
"kind": "message",
"position": 7,
"channel": "call",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "step-3",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Segunda llamada"
},
{
"situation": null,
"config_ref": null,
"key": "call-2-outcome",
"kind": "condition",
"position": 8,
"wait": {
"type": "duration",
"value": 0,
"unit": "hours",
"from": "previous_step",
"from_step": "step-4",
"hours": 0
},
"test": "call_outcome",
"ai_prompt": null,
"branches": [
{
"key": "promised_pay",
"label": "Prometió pagar",
"to": "promise-2-wait"
},
{
"key": "no_answer",
"label": "No contestó",
"to": "step-5"
}
],
"default_branch": "no_answer",
"label": "¿Cómo salió la llamada?"
},
{
"situation": null,
"config_ref": null,
"key": "promise-2-wait",
"kind": "wait_until",
"position": 9,
"until": {
"kind": "date_field",
"field": "promised_date"
},
"timeout": {
"value": 14,
"unit": "days"
},
"label": "Esperar hasta la fecha prometida"
},
{
"situation": null,
"config_ref": null,
"key": "paid-2",
"kind": "condition",
"position": 10,
"wait": {
"type": "duration",
"value": 1,
"unit": "days",
"from": "previous_step",
"from_step": "promise-2-wait",
"hours": 24
},
"test": "paid",
"ai_prompt": null,
"branches": [
{
"key": "yes",
"label": "Sí",
"to": "end"
},
{
"key": "no",
"label": "No",
"to": "step-5"
}
],
"default_branch": null,
"label": "¿Pagó?"
},
{
"key": "step-5",
"situation": null,
"kind": "message",
"position": 11,
"channel": "email",
"fallback_channel": null,
"wait": {
"type": "duration",
"value": 32,
"unit": "hours",
"from": "previous_step",
"from_step": "step-4",
"hours": 32
},
"mode": "approval",
"content": {
"type": "email",
"subject": null,
"custom_body": false
},
"config_ref": null,
"label": "Aviso formal"
}
]
},
{
"key": "appointment_reminder",
"name": "Recordatorio de cita",
"description": "Antes de una visita o cita agendada, confirma asistencia.",
"entry": {
"type": "event",
"event": "appointment_booked",
"filters": []
},
"goal": {
"type": "reply",
"label": "Responde"
},
"channels": [
"whatsapp",
"whatsapp"
],
"steps": [
{
"key": "step-1",
"situation": null,
"kind": "message",
"position": 1,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "before_appointment",
"value": 24,
"unit": "hours",
"hours": 24
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Confirmar asistencia"
},
{
"key": "step-2",
"situation": null,
"kind": "message",
"position": 2,
"channel": "whatsapp",
"fallback_channel": null,
"wait": {
"type": "before_appointment",
"value": 2,
"unit": "hours",
"hours": 2
},
"mode": "approval",
"content": {
"type": "ai_message",
"template_after_window": true
},
"config_ref": null,
"label": "Te esperamos hoy"
}
]
},
{
"key": "blank",
"name": "Desde cero",
"description": "Elige quién entra, el objetivo y arma los pasos.",
"entry": {
"type": "event",
"event": "customer_went_quiet",
"filters": []
},
"goal": {
"type": "reply",
"label": "Responde"
},
"channels": [],
"steps": []
}
]
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429