Saltar al contenido principal
Las secuencias son campañas de cold-outreach. Defines una audiencia con criterios de leads, un throttle que controla el ritmo y el horario hábil, y luego lanzas la secuencia para enrolar los leads que coincidan en una cola de despacho por contacto. Cada endpoint en esta página opera dentro del tenant de la organización que llama — no puedes leer ni escribir secuencias de otra organización con la misma key.
Hoy solo el canal call es despachable. SequenceChannel también define whatsapp y email, pero esos canales están diferidos. POST /sequences solo acepta channel: "call".

Ciclo de vida

Una secuencia atraviesa un conjunto fijo de estados SequenceStatus:
draft  →  running  ⇄  paused  →  completed
  • draft — recién creada. Editable y eliminable. Aún no se encola nada.
  • running — lanzada. El worker de despacho está procesando la cola de contactos.
  • paused — detenida temporalmente. Reanuda para continuar donde quedó.
  • completed — se establece automáticamente cuando la cola se vacía (cada contacto alcanzó un estado terminal). Terminal.
Reglas de transición — las transiciones ilegales devuelven 400 BAD_REQUEST:
AcciónPermitida desdeNotas
PATCH (editar)solo draftUna vez lanzada, la configuración queda congelada.
DELETEsolo draftLas secuencias lanzadas conservan su historial de contactos y no se pueden eliminar.
launchsolo draftRequiere una audiencia no vacía de máximo 5000 leads elegibles.
pausesolo running
resumesolo paused

Listar secuencias

GET /sequences
Scope: sequences:read. Devuelve todas las secuencias de la organización, las más recientes primero. Este endpoint no está paginado — devuelve un array plano data.

Query parameters

ParámetroTipoNotas
statusenumOpcional. Filtrar por SequenceStatus: draft, running, paused o completed. Un valor inválido devuelve 400 VALIDATION_ERROR.

Response 200

Cada secuencia incluye un objeto progress derivado de su cola de contactos.
{
  "data": [
    {
      "id": "seq_...",
      "organizationId": "org_...",
      "name": "Rellamadas en frío Q3",
      "channel": "call",
      "status": "running",
      "criteria": {
        "statuses": ["new", "contacted"],
        "stageIds": ["b1f2...-uuid"],
        "sources": ["meta", "website"],
        "minScore": 40
      },
      "channelConfig": {},
      "throttle": {
        "maxPerMinute": 5,
        "businessHoursStart": "09:00",
        "businessHoursEnd": "18:00",
        "timezone": "America/Santo_Domingo",
        "weekdays": [1, 2, 3, 4, 5]
      },
      "createdBy": null,
      "createdAt": "2026-06-20T14:00:00.000Z",
      "updatedAt": "2026-06-21T09:30:00.000Z",
      "startedAt": "2026-06-21T09:30:00.000Z",
      "completedAt": null,
      "progress": {
        "total": 320,
        "pending": 210,
        "inProgress": 4,
        "sent": 100,
        "failed": 5,
        "skipped": 1
      }
    }
  ]
}

El objeto progress

Conteos de contactos por SequenceContactStatus. total es la suma del resto.
CampoDescripción
totalTotal de contactos enrolados en la secuencia.
pendingEn cola, aún sin intentar.
inProgressEn despacho actualmente (in_progress).
sentDespachados correctamente.
failedEl despacho falló tras los reintentos.
skippedOmitidos (p. ej. el lead se dio de baja o dejó de ser elegible).

Crear una secuencia

POST /sequences
Scope: sequences:write. Crea una secuencia en estado draft. No se encola nada hasta que la lanzas.

Request body

{
  "name": "Rellamadas en frío Q3",
  "channel": "call",
  "criteria": {
    "statuses": ["new", "contacted"],
    "stageIds": ["b1f2...-uuid"],
    "sources": ["meta", "website"],
    "minScore": 40
  },
  "throttle": {
    "maxPerMinute": 5,
    "businessHoursStart": "09:00",
    "businessHoursEnd": "18:00",
    "timezone": "America/Santo_Domingo",
    "weekdays": [1, 2, 3, 4, 5]
  }
}
CampoRequeridoNotas
name1..120 caracteres (con trim).
channelnoPor defecto call. Solo se acepta call (SequenceChannel).
criteriaFiltro de audiencia. Ver abajo.
throttleReglas de ritmo. Ver abajo.

criteria — filtro de audiencia

Todos los campos son opcionales y se combinan con AND. Un objeto vacío {} matchea todos los leads de la organización.
CampoTipoNotas
statusesstring[]Matchea leads cuyo status sea uno de estos valores de LeadStatus.
stageIdsstring[] (uuid)Matchea leads en cualquiera de estas etapas del pipeline. Descubre los IDs de etapa con GET /pipeline/stages.
sourcesstring[]Matchea leads cuyo source sea uno de estos valores de LeadSource.
minScoreinteger (0–100)Matchea leads con score >= minScore.

throttle — ritmo y horario hábil

Todos los campos son requeridos.
CampoTipoNotas
maxPerMinuteinteger (1–60)Máximo de contactos despachados por minuto.
businessHoursStartstring "HH:MM"Inicio de la ventana diaria de despacho, en hora local de timezone.
businessHoursEndstring "HH:MM"Fin de la ventana diaria de despacho.
timezonestringTimezone IANA (p. ej. America/Santo_Domingo), 1..64 caracteres.
weekdaysinteger[]Días de la semana ISO en que la secuencia puede despachar (Lun=1 … Dom=7). Mínimo uno, máximo siete.

Response 201

{ "id": "seq_..." }

Errores comunes

  • 400 VALIDATION_ERROR — body inválido (p. ej. name vacío, channel distinto de call, throttle malformado).

Obtener una secuencia

GET /sequences/{sequenceId}
Scope: sequences:read. Devuelve la misma forma que un ítem del listado, incluyendo el objeto progress. 404 NOT_FOUND si la secuencia no existe o pertenece a otra org.

Actualizar una secuencia

PATCH /sequences/{sequenceId}
Scope: sequences:write. Solo drafts — editar una secuencia lanzada devuelve 400 BAD_REQUEST.

Request body

Todos los campos opcionales; envía solo lo que quieras cambiar. channel no se puede cambiar.
{
  "name": "Rellamadas en frío Q3 (afinada)",
  "criteria": { "statuses": ["new"], "minScore": 60 },
  "throttle": {
    "maxPerMinute": 8,
    "businessHoursStart": "10:00",
    "businessHoursEnd": "17:00",
    "timezone": "America/Santo_Domingo",
    "weekdays": [1, 2, 3, 4, 5]
  }
}
criteria y throttle se reemplazan por completo cuando se envían — manda el objeto completo, no un patch parcial.

Response 200

{ "id": "seq_..." }

Errores comunes

  • 400 BAD_REQUEST"Only draft sequences can be edited".
  • 400 VALIDATION_ERROR — body inválido.
  • 404 NOT_FOUND — secuencia desconocida.

Eliminar una secuencia

DELETE /sequences/{sequenceId}
Scope: sequences:write. Solo drafts. Las secuencias lanzadas son dueñas de su cola e historial de contactos (a quién se llamó, resultados, referencias de proveedor), por lo que se conservan como registro y no se pueden eliminar.

Response 200

{ "deleted": true, "id": "seq_..." }

Errores comunes

  • 400 BAD_REQUEST"Only draft sequences can be deleted; launched sequences keep their contact history".
  • 404 NOT_FOUND — secuencia desconocida.

Previsualizar la audiencia

POST /sequences/preview-audience
Scope: sequences:read. Cuenta cuántos leads coinciden actualmente con un conjunto de criterios — sin crear ni lanzar nada. Úsalo para dimensionar una audiencia antes de comprometerte, y para confirmar que está por debajo del tope de 5000 leads del lanzamiento.

Request body

{
  "criteria": {
    "statuses": ["new", "contacted"],
    "sources": ["meta"],
    "minScore": 40
  }
}
El objeto criteria sigue el mismo schema que en la creación.

Response 200

{ "count": 1840 }

Lanzar una secuencia

POST /sequences/{sequenceId}/launch
Scope: sequences:write. Solo drafts. Resuelve la audiencia a partir de los criterios de la secuencia, enrola cada lead que coincide en la cola de contactos y pasa la secuencia a running.
Lanzar consume tu cuota mensual de API de forma proporcional al tamaño de la audiencia. A diferencia de todos los demás endpoints — que cuestan una unidad — un lanzamiento consume una unidad por cada contacto encolado. Un lanzamiento que enrola 1.200 leads cuesta 1.200 unidades de tu cuota mensual. Previsualiza la audiencia primero, y consulta Rate limits para saber cómo se contabiliza el costo mensual ponderado.

Response 200

{ "id": "seq_...", "enqueued": 1200 }
enqueued es la cantidad de contactos enrolados (la cantidad de unidades cobradas).

Errores comunes

  • 400 BAD_REQUEST"Only draft sequences can be launched" (ya está running, paused o completed).
  • 400 BAD_REQUEST"No eligible leads match this sequence's criteria" (audiencia vacía).
  • 400 BAD_REQUEST"Audience too large (over 5000 eligible leads). Narrow the criteria before launching."
  • 404 NOT_FOUND — secuencia desconocida.

Pausar una secuencia

POST /sequences/{sequenceId}/pause
Scope: sequences:write. Solo running. Detiene el despacho; los contactos en vuelo terminan, pero no se toman nuevos contactos.

Response 200

{ "id": "seq_..." }

Errores comunes

  • 400 BAD_REQUEST"Only running sequences can be paused".

Reanudar una secuencia

POST /sequences/{sequenceId}/resume
Scope: sequences:write. Solo paused. Devuelve la secuencia a running y el worker continúa con los contactos pending restantes.

Response 200

{ "id": "seq_..." }

Errores comunes

  • 400 BAD_REQUEST"Only paused sequences can be resumed".