Endpoint reference

Endpoints estables de la v1. Body JSON, respuestas JSON. Para el contrato machine-readable ver /v1/openapi.json.

Recursos cubiertos

  • Contacts (CRUD)
  • Conversations (read)
  • Messages (send + read)
  • Agent runs (read)
POST/v1/contactsScope: contacts:write

Crea un contacto en el workspace. Idempotente con header Idempotency-Key.

curl -X POST https://sentinel.hivium.app/v1/contacts \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f4c..." \
  -d '{
    "first_name": "Carla",
    "last_name": "M.",
    "email": "carla@example.com",
    "phone": "+15551234567",
    "consent": { "email": true, "whatsapp": false }
  }'

201{ "id": "cnt_…", "created_at": "…", … }.

GET/v1/contacts/:idScope: contacts:read

Devuelve el contacto. 404 si no existe en el workspace.

GET/v1/contactsScope: contacts:read

Lista contactos. Query: limit, cursor, q (búsqueda en nombre/email/phone), tag, updated_since.

GET/v1/conversationsScope: conversations:read

Lista conversaciones. Query: status (active | archived), contact_id, channel (email | whatsapp | ghl).

POST/v1/messagesScope: messages:write

Encola un mensaje outbound. Body requiere contacto, channel, body. Idempotency-Key recomendado.

{
  "contact_id": "cnt_abc",
  "channel": "whatsapp",
  "text": "Hola Carla, retomamos lo del plan enterprise…",
  "metadata": { "campaign": "stale-revival-may" }
}

202{ "id": "msg_…", "status": "queued" }.

GET/v1/agents/runsScope: agents:read

Lista corridas de sub-agents. Query: agent_slug (daily-brief, lead-triage, etc.), status (queued | running | succeeded | failed | awaiting_approval), since (ISO timestamp).

La respuesta incluye cost_usd, tokens, error (si aplica) y el output JSON del agent.

Rate limits

60 req/min por API key (sliding window). Headers en cada respuesta:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset (Unix timestamp)
  • En 429: Retry-After (segundos).

Errores

{
  "error": {
    "code": "consent_missing",
    "message": "Contact cnt_abc has no whatsapp consent on file.",
    "request_id": "req_…"
  }
}
HTTPcodeSignificado
400validation_errorBody inválido — leer message.
401invalid_api_keyKey faltante o revocada.
403insufficient_scopeFalta scope en la key.
403consent_missingOutbound bloqueado por falta de consent.
404not_foundRecurso fuera del workspace.
409idempotency_conflictMisma key con body distinto.
429rate_limitedEsperar Retry-After.
5xxinternal_errorRetry con backoff exponencial.

Retry strategy

  • Idempotent (con Idempotency-Key): retry hasta 3 veces con backoff exponencial 1s/2s/4s.
  • 5xx: retry permitido.
  • 4xx (excepto 429): no retry — son bugs del cliente.
  • 429: respetar Retry-After.

SDKs / clients

  • Node/TS SDK: @sentinel/sdk (próximamente como paquete público; hoy vendored en src/lib/sdk/sentinel-client.ts).
  • OpenAPI: /v1/openapi.json — generá clientes con openapi-generator.
  • Postman: collection placeholder — TODO publicar link.