API REST

Documentación oficial.

Conectá Chatia con tus sistemas. Creá agentes desde tu backend, leé y exportá conversaciones, recibí eventos firmados con HMAC y dejale a tu asistente IA la spec paste-ready para que orqueste todo solo.

Base URL · https://www.chatia.proAuth · Bearer tokenVersión · v1

Autenticación

Toda llamada a la API se autentica con una API key como Bearer token. Generá la tuya en /dashboard/developers. La key se muestra una sola vez al crearla; guardala.

bashAuthorization: Bearer chatia_58_abcd_efgh_ijkl_mnop_qrst_uvwx_yza
Nunca pongas una key en código cliente. Se almacena hasheada en nuestra DB; si la perdés, revocala en el dashboard y generá otra.

Quickstart

Tres pasos para tener un agente público respondiendo en webchat.

bash# 1) Crear cuenta + API key (1 vez por user)
#    - Registrate en https://www.chatia.pro/register (gratis, $3 USD welcome credit).
#    - Andá a https://www.chatia.pro/dashboard/developers → "Crear API key".
#    - Copiá la key (empieza con chatia_…) — solo se muestra una vez.
export CHATIA_API_KEY="chatia_..."

# 2) Crear agente + publicarlo + recibir TODOS los links en 1 llamada
curl -X POST https://www.chatia.pro/api/developers/agents \
  -H "Authorization: Bearer $CHATIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Soporte Cliente",
    "description": "Atiende FAQs, captura leads, escala a humano.",
    "system_prompt": "Sos un agente de soporte. Tono cálido, profesional. Si no podés resolver, capturá el lead y derivá.",
    "first_message": "¡Hola! ¿En qué puedo ayudarte?",
    "tools": ["capture_lead", "send_whatsapp_handoff", "send_nps_survey"],
    "publish": true
  }'

# Response (todo absoluto, copy-paste directo):
# {
#   "id": 42,
#   "chat_url":             "https://www.chatia.pro/chat/soporte-cliente-42",
#   "dashboard_url":        "https://www.chatia.pro/dashboard/agents/42",
#   "widget_snippet":       "<script src=\"https://www.chatia.pro/widget.js?slug=soporte-cliente-42\" defer></script>",
#   "wordpress_plugin_url": "https://www.chatia.pro/wordpress",
#   "tools": ["capture_lead", "send_whatsapp_handoff", "send_nps_survey"]
# }

# 3) Probalo en vivo
open https://www.chatia.pro/chat/soporte-cliente-42

# 4) Embeberlo en tu sitio — pegá widget_snippet antes de </body>.
# Para WordPress: descargá el plugin (~7 KB) en https://www.chatia.pro/wordpress y
# pegá solo el slug en Ajustes → Chatia.

Chatia Pro Agent API

Chat Completions API · compatible con OpenAI.

chatia-lite es el slug del modelo gestionado por Chatia (gpt-5.4 detrás, 1.05M context). Hablás contra /api/v1/chat/completions con la misma forma que OpenAI, así que cualquier SDK oficial funciona apenas cambiás el base_url. Te facturamos por tokens reales con markup 2.5x sobre upstream — typical $0.02–$0.10 por response. Dashboard de consumo en /api/v1/usage.

Input

$0.00045 / 1k tokens

≈ $0.45 / 1M

Output

$0.0018 / 1k tokens

≈ $1.80 / 1M

Latencia p95

< 500 ms

Edge inference

cURL

bash# Chat Completions · OpenAI-compatible
curl -X POST https://www.chatia.pro/api/v1/chat/completions \
  -H "Authorization: Bearer $CHATIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "chatia-lite",
    "messages": [
      { "role": "system", "content": "Sos un asistente comercial breve." },
      { "role": "user",   "content": "Hola, ¿cuánto tarda un envío a Posadas?" }
    ],
    "temperature": 0.5,
    "stream": false
  }'

Python · openai

python# Funciona con el SDK oficial de OpenAI sin cambios — solo apuntá la
# base_url a Chatia y usá tu API key de Chatia.
from openai import OpenAI

client = OpenAI(
    api_key="<CHATIA_API_KEY>",
    base_url="https://www.chatia.pro/api/v1",
)

resp = client.chat.completions.create(
    model="chatia-lite",
    messages=[
        {"role": "system", "content": "Respondé breve, en español."},
        {"role": "user",   "content": "Resumime qué es WhatsApp Cloud API."},
    ],
    stream=True,
)
for chunk in resp:
    print(chunk.choices[0].delta.content or "", end="", flush=True)

Node · openai

tsimport OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.CHATIA_API_KEY!,
  baseURL: "https://www.chatia.pro/api/v1",
});

const stream = await client.chat.completions.create({
  model: "chatia-lite",
  messages: [
    { role: "system", content: "Respondé breve, en español." },
    { role: "user",   content: "Hola, ¿cuánto cuesta tu plan?" },
  ],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Te devolvemos siempre model: "chatia-lite" aunque actualicemos el modelo upstream. Eso significa: sin breaking changes para tu integración cuando mejoramos el modelo o agregamos un tierchatia-pro.
Cada call queda registrada en /dashboard/billing con tokens y costo. Si te freneamos por error rate o spike, vamos a usar 429 con Retry-After; reintentá con back-off exponencial.

Endpoints

Todos los endpoints autenticados con API key forman la API pública. Los que requieren sesión son sólo para el dashboard.

GET/api/v1/modelsAPI key

Catálogo de modelos públicos con su pricing.

Response 200

json{
  "object": "list",
  "data": [
    {
      "id": "chatia-lite",
      "object": "model",
      "owned_by": "chatia",
      "context_window": 8192,
      "pricing": { "input_per_1k_usd": 0.00045, "output_per_1k_usd": 0.0018 }
    }
  ]
}
POST/api/v1/chat/completionsAPI key

Chat Completions OpenAI-compatible. Soporta streaming SSE.

  • Forma idéntica a OpenAI — cualquier SDK (openai-python, openai-node, etc.) funciona apuntando base_url a /api/v1.
  • Si stream=true, la respuesta es SSE. El último frame incluye usage: {prompt_tokens, completion_tokens}.

Request

json{
  "model": "chatia-lite",
  "messages": [
    { "role": "system", "content": "Sos un asistente comercial breve." },
    { "role": "user",   "content": "¿Cuánto tarda un envío a Posadas?" }
  ],
  "temperature": 0.5,
  "stream": true
}

Response 200

json{
  "id": "chatcmpl_...",
  "object": "chat.completion",
  "model": "chatia-lite",
  "choices": [{
    "index": 0,
    "finish_reason": "stop",
    "message": { "role": "assistant", "content": "24-48hs..." }
  }],
  "usage": { "prompt_tokens": 38, "completion_tokens": 22, "total_tokens": 60 }
}
GET/api/v1/usageSesión

Tu consumo de tokens y costo en USD por día y por modelo.

Response 200

json{
  "days": 30,
  "totals": { "calls": 482, "prompt_tokens": 38211, "completion_tokens": 19002,
              "total_tokens": 57213, "cost_usd": 0.0228, "avg_ms": 312 },
  "by_day":   [{ "day": "...", "calls": 12, "tokens": 1820, "cost_usd": 0.0007 }],
  "by_model": [{ "model": "chatia-lite", "calls": 482, "tokens": 57213, "cost_usd": 0.0228 }]
}
GET/api/developers/agentsAPI key

Lista todos los agentes del owner de la API key.

Response 200

json[
  {
    "id": 14,
    "name": "Soporte cliente",
    "status": "published",
    "is_published": true,
    "public_slug": "soporte-cliente-14",
    "provider": "openai",
    "model": "gpt-5.4-mini"
  }
]
POST/api/developers/agentsAPI key

Crea un agente, le adjunta tools del catálogo y opcionalmente lo publica como webchat.

  • Las tools deben pertenecer al catálogo expuesto en GET /api/developers/skills.
  • publish=true publica directamente. Si querés revisar antes, mandá publish=false y llamá a /publish después.
  • Rate limit: 30/min por API key. Excederlo devuelve 429 con Retry-After.
  • Response enriquecida: chat_url + widget_snippet vienen listos para devolver al user — no hace falta componer strings.

Request

json{
  "name": "Agente soporte",
  "description": "Atiende consultas del e-commerce.",
  "system_prompt": "Sos el agente de soporte. Respondé breve, capturá leads cuando falte info.",
  "first_message": "¡Hola! Soy el asistente. ¿En qué te ayudo?",
  "language": "es",
  "provider": "openai",
  "model": "gpt-5.4-mini",
  "tools": ["capture_lead", "schedule_appointment", "http_request"],
  "publish": true
}

Response 200

json{
  "id": 14,
  "name": "Agente soporte",
  "status": "published",
  "is_published": true,
  "public_slug": "agente-soporte-14",
  "chat_url": "https://www.chatia.pro/chat/agente-soporte-14",
  "dashboard_url": "https://www.chatia.pro/dashboard/agents/14",
  "widget_snippet": "<script src=\"https://www.chatia.pro/widget.js?slug=agente-soporte-14\" defer></script>",
  "wordpress_plugin_url": "https://www.chatia.pro/wordpress",
  "tools": ["capture_lead", "schedule_appointment", "http_request"]
}
POST/api/developers/agents/:id/publishAPI key

Publica un agente como webchat público.

  • Rate limit: 30/min por API key.

Response 200

json{
  "agent_id": 14,
  "slug": "agente-soporte-14",
  "chat_url": "https://www.chatia.pro/chat/agente-soporte-14",
  "dashboard_url": "https://www.chatia.pro/dashboard/agents/14",
  "widget_snippet": "<script src=\"https://www.chatia.pro/widget.js?slug=agente-soporte-14\" defer></script>",
  "wordpress_plugin_url": "https://www.chatia.pro/wordpress"
}
GET/api/developers/agents/:id/conversationsAPI key

Lista conversaciones del agente paginadas, ordenadas por actividad reciente.

  • Query params: limit (1-200), offset, channel (webchat|whatsapp|api).

Response 200

json{
  "total": 132,
  "limit": 50,
  "offset": 0,
  "conversations": [
    {
      "id": 9341,
      "agent_id": 14,
      "visitor_id": "v_ab123",
      "channel": "whatsapp",
      "title": "Consulta envíos",
      "message_count": 12,
      "ai_paused": false,
      "last_message_at": "2026-04-26T20:11:42Z",
      "created_at": "2026-04-26T18:55:02Z"
    }
  ]
}
GET/api/developers/conversations/:idAPI key

Devuelve la conversación completa con todos los mensajes.

Response 200

json{
  "conversation": {
    "id": 9341,
    "agent_id": 14,
    "channel": "whatsapp",
    "title": "Consulta envíos",
    "ai_paused": false,
    "message_count": 12,
    "last_message_at": "2026-04-26T20:11:42Z"
  },
  "messages": [
    { "id": 5001, "role": "user", "content": "Hola, ¿cuánto tarda un envío a Posadas?", "created_at": "2026-04-26T18:55:02Z" },
    { "id": 5002, "role": "assistant", "content": "Hola! 24-48hs hábiles a Posadas. ¿Querés cotizarlo?", "created_at": "2026-04-26T18:55:04Z" }
  ]
}
GET/api/developers/conversations/:id/exportAPI key

Descarga la conversación en JSON (default), CSV o TXT.

  • Query: ?format=json|csv|txt. Default: json.
  • Útil para fine-tuning, BI o auditoría.

Response 200

json# CSV
id,role,content,created_at
5001,user,"Hola, ¿cuánto tarda un envío a Posadas?",2026-04-26T18:55:02Z
5002,assistant,"24-48hs hábiles a Posadas. ¿Querés cotizarlo?",2026-04-26T18:55:04Z
GET/api/v1/agentsAPI key

Lista agentes del owner (versión REST v1, OpenAPI-first).

  • Filtro opcional ?is_published=true|false.
  • Mismo dato que /api/developers/agents pero con branding completo embebido + demo_url.

Response 200

json{
  "agents": [
    {
      "id": 14,
      "name": "Soporte cliente",
      "description": "...",
      "is_published": true,
      "public_slug": "soporte-cliente-14",
      "demo_url": "/chat/soporte-cliente-14",
      "branding": {
        "logo_url": "/api/branding/logo/agent/14.png",
        "avatar_url": "/api/branding/logo/agent_avatar/14.png",
        "primary_color": "#10b981",
        "theme": "dark",
        "powered_by_text": "Powered by Mi Empresa",
        "powered_by_url": "https://mi-empresa.com",
        "show_powered_by": true
      }
    }
  ]
}
GET/api/v1/agents/:idAPI key

Detalle del agente con branding + demo_url.

Response 200

json{
  "id": 14,
  "name": "Soporte cliente",
  "description": "...",
  "system_prompt": "Sos un asistente comercial breve...",
  "first_message": "Hola, ¿en qué te ayudo?",
  "language": "es",
  "provider": "openai",
  "model": "gpt-5.4-mini",
  "status": "published",
  "is_published": true,
  "public_slug": "soporte-cliente-14",
  "demo_url": "/chat/soporte-cliente-14",
  "branding": { "primary_color": "#10b981", "theme": "dark", "...": "..." }
}
GET/api/v1/agents/:id/brandingAPI key

Branding actual del webchat del agente.

  • logo_url y avatar_url son cadenas vacías si el dueño no subió todavía.
  • theme posibles: 'dark' | 'light' | 'auto'.

Response 200

json{
  "branding": {
    "logo_url": "/api/branding/logo/agent/14.png",
    "avatar_url": "/api/branding/logo/agent_avatar/14.png",
    "primary_color": "#10b981",
    "theme": "dark",
    "powered_by_text": "Powered by Mi Empresa",
    "powered_by_url": "https://mi-empresa.com",
    "show_powered_by": true,
    "can_hide_powered_by": true
  }
}
PATCH/api/v1/agents/:id/brandingAPI key

Actualiza color, tema y/o powered_by del webchat.

  • Todos los campos son opcionales — los que no mandás no se tocan.
  • primary_color debe ser hex (#RRGGBB o #RGB).
  • show_powered_by sólo se respeta en planes pagos; en Free queda forzado a true.
  • Para subir el logo o el avatar usá los endpoints /api/branding/agents/:id/logo y /api/branding/agents/:id/avatar (multipart, requieren sesión web del owner — todavía no expuestos en v1).

Request

json{
  "primary_color": "#8b5cf6",
  "theme": "light",
  "powered_by_text": "Powered by Mi Empresa",
  "powered_by_url": "https://mi-empresa.com",
  "show_powered_by": true
}

Response 200

json{ "branding": { "primary_color": "#8b5cf6", "theme": "light", "...": "..." } }
GET/api/v1/agents/:id/knowledgeAPI key

Lista chunks del KB con filtros + stats globales.

  • Query: ?q=palabras (AND-search en title+content) y ?tags=faq,ventas (filtro).
  • Pinned aparecen primero, después por created_at desc.
  • Default limit=50, max=200.

Response 200

json{
  "chunks": [
    {
      "id": 503,
      "title": "Política de devolución",
      "content": "Tenemos 30 días corridos desde la entrega...",
      "source": "manual",
      "source_ref": "",
      "tags": ["faq", "ventas"],
      "char_count": 1184,
      "pinned": true,
      "created_at": "2026-04-27T20:11:00Z"
    }
  ],
  "stats": {
    "total_chunks": 17,
    "total_chars": 38211,
    "tags": ["faq", "ventas", "soporte"]
  }
}
POST/api/v1/agents/:id/knowledgeAPI key

Crea un chunk manual.

  • content: 10–50.000 chars.
  • tags: hasta 6, coma-separados, normalizamos a lowercase.
  • Para textos grandes (>50k) usá el endpoint upload-file que auto-chunkea.

Request

json{
  "title": "Política de devolución",
  "content": "Tenemos 30 días corridos desde la entrega para cambios. Sin uso, etiqueta puesta...",
  "tags": "faq, ventas",
  "pinned": true
}

Response 200

json{ "id": 503, "title": "Política de devolución", "char_count": 1184, "...": "..." }
PATCH/api/v1/agents/:id/knowledge/:chunk_idAPI key

Edita title/content/tags/pinned in-place.

Request

json{ "pinned": false, "tags": "faq" }

Response 200

json{ "id": 503, "pinned": false, "tags": ["faq"], "...": "..." }
DELETE/api/v1/agents/:id/knowledge/:chunk_idAPI key

Borra un chunk.

Response 200

json{ "deleted": 503 }
POST/api/v1/agents/:id/knowledge/upload-fileAPI key

Sube PDF/TXT/MD/CSV. Auto-chunkea archivos grandes.

  • PDF se procesa con pypdf; TXT/MD/CSV pasan tal cual.
  • Auto-chunking en pedazos de ~5k chars con 200 chars de solapamiento, cortando en bordes de párrafo/oración.
  • Cap: 8 MB por archivo.

Request

json# multipart/form-data
file=@manual_de_ventas.pdf
title=Manual de ventas (opcional)
tags=ventas,onboarding (opcional)

Response 200

json{
  "ingested": [
    { "id": 510, "title": "Manual de ventas · 1/4", "char_count": 4980 },
    { "id": 511, "title": "Manual de ventas · 2/4", "char_count": 4920 },
    { "id": 512, "title": "Manual de ventas · 3/4", "char_count": 4860 },
    { "id": 513, "title": "Manual de ventas · 4/4", "char_count": 1240 }
  ],
  "summary": { "filename": "manual_de_ventas.pdf", "chars": 16000, "chunks_created": 4 }
}
POST/api/v1/agents/:id/knowledge/import-urlAPI key

Fetchea una URL pública y la guarda como chunks.

  • Soporta páginas HTML (extraemos texto visible) y PDFs públicos.
  • URLs privadas (localhost, 127.*, 10.*, 192.168.*, 169.254.*, 172.16-31.*) están bloqueadas — SSRF guard.
  • Mismo auto-chunking que upload-file.

Request

json{ "url": "https://mi-empresa.com/preguntas-frecuentes", "tags": "faq" }

Response 200

json{
  "ingested": [
    { "id": 520, "title": "Preguntas frecuentes — Mi Empresa", "char_count": 4900 },
    { "id": 521, "title": "Preguntas frecuentes — Mi Empresa · 2/2", "char_count": 1100 }
  ],
  "summary": { "url": "https://mi-empresa.com/preguntas-frecuentes", "chars": 6000, "chunks_created": 2 }
}
GET/api/v1/accountAPI key

Plan + uso del owner. Útil antes de mandar mensajes.

Response 200

json{
  "plan": "pro",
  "plan_name": "Pro",
  "plan_price_usd": 12.0,
  "messages_included": 2500,
  "messages_used": 1284,
  "messages_remaining": 1216,
  "agents_used": 4,
  "agents_limit": 6,
  "has_payment_method": true
}
POST/api/developers/eventsAPI key

Emite un evento custom hacia tus webhook endpoints.

Request

json{
  "type": "agent.message.created",
  "agent_id": 14,
  "data": { "external_ref": "ticket-1234", "source": "crm" }
}

Response 200

json{ "status": "ok", "event_id": "evt_5af30098ae98486d861585683a887752" }
GET/api/developers/skillsSesión

Devuelve el catálogo de tools disponibles para los agentes.

Response 200

json{
  "tools": [
    {
      "name": "capture_lead",
      "display_name": "Capturar lead",
      "description": "Guarda nombre, teléfono, email e interés del visitante.",
      "schema": { "type": "object", "properties": { "name": { "type": "string" }, "phone": { "type": "string" } }, "required": ["name", "interest"] }
    }
  ]
}
GET/api/developers/usageSesión

Estadísticas de uso de tus API keys (totales, por día y por endpoint).

Response 200

json{
  "days": 14,
  "totals": { "calls": 1283, "errors": 12, "error_rate": 0.0094 },
  "by_day": [{ "day": "2026-04-13", "count": 84 }],
  "by_endpoint": [{ "method": "POST", "path": "/api/developers/agents", "count": 312 }],
  "recent": [{ "id": 99, "method": "GET", "path": "/api/developers/agents", "status_code": 200, "duration_ms": 32, "at": "..." }]
}
DELETE/api/developers/api-keys/:idSesión

Revoca una API key. Operación irreversible.

Response 200

json{ "status": "ok" }
GET/api/developers/clientsAPI key

Lista todos tus clientes (sub-users con role=client).

  • Los clientes acceden al portal /client con su email+contraseña.
  • team_size cuenta a sus integrantes; team_cap es el máximo (5).

Response 200

json{
  "clients": [
    {
      "id": 17,
      "email": "[email protected]",
      "name": "Ana López",
      "is_active": true,
      "team_size": 2,
      "team_cap": 5,
      "has_brand_override": true,
      "agents": [{ "agent_id": 42, "scopes": "messages,leads" }]
    }
  ]
}
POST/api/developers/clientsAPI key

Crea un cliente y opcionalmente le da acceso a agentes.

  • El cliente recibe un email de bienvenida con link al portal.
  • Vos recibís un email con tips para gestionarlo.
  • Dispara webhook event client.created.

Request

json{
  "email": "[email protected]",
  "name": "Ana López",
  "password": "temporal-1234",
  "agent_ids": [42, 47]
}

Response 200

json{
  "id": 17,
  "email": "[email protected]",
  "name": "Ana López",
  "is_active": true,
  "agents": [{ "agent_id": 42, "scopes": "messages,leads" }],
  "team_size": 0, "team_cap": 5
}
POST/api/developers/clients/:id (PATCH)API key

Actualiza nombre o estado activo del cliente.

  • Dispara webhook event client.updated cuando hay cambios reales.

Request

json{ "name": "Ana M. López", "is_active": true }

Response 200

json{ "id": 17, "name": "Ana M. López", "is_active": true, "...": "..." }
DELETE/api/developers/clients/:idAPI key

Elimina un cliente y revoca sus grants. Irreversible.

  • Dispara webhook event client.removed.

Response 200

json{ "deleted": 17 }
POST/api/developers/clients/:id/reset-passwordAPI key

Genera una contraseña nueva para el cliente. Se devuelve UNA SOLA VEZ.

  • Compartila vos por canal seguro (no la guardes en logs).
  • Dispara webhook event client.password_reset (sin la password en el payload).

Response 200

json{
  "new_password": "abc123-XyZ-...",
  "note": "Se muestra una sola vez. Compartila por canal seguro."
}
POST/api/developers/clients/:id/branding (PATCH)API key

Setea branding override del portal del cliente.

  • El logo del cliente se sube por separado: ver /api/branding/agents/:id/logo en el panel.
  • El cliente y sus team-members ven este branding en /client.
  • show_powered_by sólo se respeta en planes pagos.
  • Dispara webhook event client.branding.updated.

Request

json{
  "brand_name": "Estudio Ana",
  "primary_color": "#8b5cf6",
  "powered_by_text": "Powered by Estudio Ana",
  "powered_by_url": "https://estudio-ana.com",
  "show_powered_by": true
}

Response 200

json{ "branding": { "brand_name": "Estudio Ana", "primary_color": "#8b5cf6", "..." : "..." } }
GET/api/developers/clients/:id/team-membersAPI key

Lista los integrantes (team_members) del cliente.

  • Los 5 seats son para que el equipo del cliente gestione interacciones (mensajes, leads, takeover).
  • team_members no pueden invitar a más gente ni ver el dashboard de métricas.

Response 200

json{
  "members": [
    { "id": 33, "email": "[email protected]", "name": "Pedro", "is_active": true, "created_at": "..." }
  ],
  "cap": 5,
  "current": 1,
  "can_invite": true
}
POST/api/developers/clients/:id/team-membersAPI key

Crea un integrante del equipo del cliente.

  • Cap = 5 por cliente; sólo disponible en plan pago del owner.
  • Hereda los grants de agentes del cliente padre.
  • Dispara webhook event client.team_member.added.

Request

json{ "email": "[email protected]", "name": "Lucía", "password": "temp-pass" }

Response 200

json{ "id": 34, "email": "[email protected]", "name": "Lucía", "is_active": true, "created_at": "..." }
DELETE/api/developers/clients/:id/team-members/:member_idAPI key

Elimina un integrante del equipo del cliente.

  • Dispara webhook event client.team_member.removed.

Response 200

json{ "deleted": 34 }
POST/api/developers/clients/:id/features (PATCH)API key

Toggles que el owner habilita por cliente. Hoy: dashboard de interacciones.

  • Cuando dashboard_enabled=true el cliente ve /client/dashboard con métricas (mensajes/día, leads, breakdown por agente).
  • team_members no ven el dashboard: es exclusivo del cliente titular.

Request

json{ "dashboard_enabled": true }

Response 200

json{ "features": { "dashboard_enabled": true } }

Webhooks firmados

Cada evento te llega como POST JSON. Verificá la firma para no aceptar payloads de un atacante.

ts// Cada POST a tu endpoint trae headers:
//   x-chatia-signature: sha256=<hex>
//   x-chatia-timestamp: 1714152000
//   x-chatia-event:     agent.lead.captured
//   x-chatia-event-id:  evt_5af30098...

import { createHmac, timingSafeEqual } from "crypto";

function verify(rawBody: string, headers: Record<string,string>, secret: string) {
  const ts = headers["x-chatia-timestamp"];
  const sig = headers["x-chatia-signature"]; // "sha256=..."
  if (!ts || !sig) return false;
  // 5-minute replay window
  if (Math.abs(Date.now()/1000 - Number(ts)) > 300) return false;
  const expected = "sha256=" + createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");
  return timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
agent.createdagent.publishedagent.branding.updatedagent.message.createdagent.reply.createdagent.lead.capturedagent.tool.calledagent.handoff.requestedagent.message.deliveredagent.message.readagent.message.failedagent.outbound.skipped_24h_windowagent.phone_number.quality_changedagent.phone_number.bannedclient.createdclient.updatedclient.removedclient.password_resetclient.branding.updatedclient.agent_grant.addedclient.agent_grant.removedclient.team_member.addedclient.team_member.removedportal.branding.updatedagent.sale.startedagent.sale.updatedagent.sale.confirmed
Reintentamos hasta 6 veces con back-off exponencial cuando tu endpoint responde 5xx o timeout. Verás cada intento en el dashboard, en “Últimas entregas”.

Códigos de error

CódigoSignificadoCuándo
200OKLa operación se completó.
400Bad requestJSON mal formado o campo requerido faltante.
401UnauthorizedFalta el header Authorization o la key fue revocada.
404Not foundEl agente o la conversación no existen o no son tuyos.
429Rate limitedExcediste el límite. Volvé a intentar después del Retry-After.
5xxServer errorIssue en nuestro lado. Reintentá con back-off exponencial.

Spec paste-ready para tu asistente IA

Pegá este bloque en Claude Code, Cursor, Codex o tu agente de código favorito. Es todo lo que necesita para construir contra Chatia: endpoints, auth, tools, rate limits, errores y checklist de creación autónoma de agentes.

AGENTS.md · v0.2

Recomendado para pegar. Instrucciones operativas concisas (~200 LOC), formato system-prompt ready. Reglas duras, mapping vertical → tools, checklist autónomo, errores comunes.

Ver AGENTS.md

SKILL.md · v0.2

Spec completa (~700 LOC) — todos los endpoints, modelos de datos, recetas Python/Node, tools nativas detalladas, verificación de firma. Para devs que quieren la referencia full.

Ver SKILL.md
md# Chatia · spec paste-ready para Claude Code / Codex / Cursor

Base URL: https://www.chatia.pro
Auth: Authorization: Bearer <CHATIA_API_KEY>

## Endpoints — Agentes
- GET  /api/developers/agents
- POST /api/developers/agents          { name, system_prompt, tools[], publish }
- POST /api/developers/agents/:id/publish
- GET  /api/developers/agents/:id/conversations?limit=50&offset=0
- GET  /api/developers/conversations/:id
- GET  /api/developers/conversations/:id/export?format=json|csv|txt
- POST /api/developers/events           { type, agent_id?, data }

## Endpoints — Clientes (sub-users)
- GET    /api/developers/clients
- POST   /api/developers/clients               { email, name, password, agent_ids[] }
- PATCH  /api/developers/clients/:id           { name?, is_active? }
- DELETE /api/developers/clients/:id
- POST   /api/developers/clients/:id/reset-password
- PATCH  /api/developers/clients/:id/branding  { brand_name?, primary_color?, powered_by_text?, powered_by_url?, show_powered_by? }

## Endpoints — Equipo del cliente (max 5 seats para gestionar interacciones)
- GET    /api/developers/clients/:id/team-members
- POST   /api/developers/clients/:id/team-members  { email, name, password }
- DELETE /api/developers/clients/:id/team-members/:member_id

## REST v1 — Agents detail + Branding + Knowledge (auth API key)
- GET   /api/v1/agents
- GET   /api/v1/agents/:id
- GET   /api/v1/agents/:id/branding
- PATCH /api/v1/agents/:id/branding   { primary_color?, theme?, powered_by_text?, powered_by_url?, show_powered_by? }
        # theme: "dark" | "light" | "auto"
- GET   /api/v1/agents/:id/knowledge?q=...&tags=ventas,faq
- POST  /api/v1/agents/:id/knowledge  { title, content, tags?, pinned? }
- PATCH /api/v1/agents/:id/knowledge/:chunk_id   { title?, content?, tags?, pinned? }
- DELETE /api/v1/agents/:id/knowledge/:chunk_id
- POST  /api/v1/agents/:id/knowledge/upload-file   # multipart, PDF/TXT/MD/CSV, auto-chunking
- POST  /api/v1/agents/:id/knowledge/import-url    { url, tags? }
- GET   /api/v1/account                              # plan + uso

## Rate limits (por API key, no por IP)
- POST /api/developers/agents             — 30/min
- POST /api/developers/agents/:id/publish — 30/min
- POST /api/developers/events             — 120/min
- POST /api/developers/webhooks/:id/test  — 20/min
  Excederlos devuelve 429 con header Retry-After (segundos).

## Tools (skills) nativas que el agente puede usar (catálogo vivo: GET /api/developers/skills)
Captura/CRM:
- capture_lead, update_lead_status, add_lead_note
Calendario:
- create_calendar_event, list_availability, cancel_appointment, reschedule_appointment
Comunicación:
- send_email, send_whatsapp_handoff, send_whatsapp_text,
  whatsapp_send_template, send_whatsapp_image
Knowledge:
- query_knowledge
Encuestas:
- send_nps_survey
Recruitment / RRHH:
- register_candidate, score_candidate, flag_for_review
HTTP genérico (custom integrations):
- http_request

## Mapping vertical → tool-set default
- Ventas / E-commerce  → capture_lead + send_whatsapp_handoff + update_lead_status + add_lead_note
- Soporte / FAQ        → query_knowledge + send_whatsapp_handoff + send_nps_survey
- Turnos / Agenda      → create_calendar_event + list_availability + cancel/reschedule + capture_lead
- Recruitment / RRHH   → register_candidate + score_candidate + flag_for_review + send_email
- Mixto                → combinar según caso

## Webhooks — eventos disponibles (27 totales)
- agent.created, agent.published, agent.branding.updated
- agent.message.created, agent.reply.created
- agent.lead.captured, agent.tool.called, agent.handoff.requested
- agent.message.delivered/read/failed, agent.outbound.skipped_24h_window
- agent.phone_number.quality_changed/banned
- agent.sale.started, agent.sale.updated, agent.sale.confirmed
- client.created/updated/removed/password_reset
- client.branding.updated, client.agent_grant.added/removed
- client.team_member.added/removed
- portal.branding.updated

## Errores comunes
- 401 Missing/Invalid API key → user genera key en /dashboard/developers
- 402 insufficient_balance    → user agrega tarjeta en /billing
- 403 agents_limit_reached    → borrar agente o subir de plan
- 422 Validation error        → tools no en catálogo (ver /developers/skills)
- 429 Too many requests       → leer Retry-After + backoff exponencial
- 5xx                         → reintentar con backoff (1, 2, 4, 8, 16s)

## Workflow típico para "AI agent autonomous create flow"
1. (One-time) User crea cuenta en /register + API key en /dashboard/developers
2. POST /api/developers/agents con system_prompt + tools + publish=true
   → Response trae chat_url, dashboard_url, widget_snippet, wordpress_plugin_url
3. Devolver al user los 4 links — copy-paste directo, sin componer strings
4. (Opcional) PATCH /api/v1/agents/:id/branding con color + theme
5. (Opcional) POST /api/v1/agents/:id/knowledge/import-url para cargar FAQ
6. (Opcional) POST /api/developers/webhooks para recibir eventos en CRM
7. (Opcional) Si user tiene WordPress → /wordpress (plugin .zip ~7 KB)
   Si user tiene Shopify → snippet en theme.liquid antes de </body>
   Si user tiene HTML / Wix / Webflow → widget_snippet directo

## Checklist como agente IA externo (Claude / Codex / Cursor)
[  ] Confirmar CHATIA_API_KEY o redirigir a /dashboard/developers
[  ] Inferir vertical (ventas / soporte / turnos / RRHH / mixto)
[  ] Elegir tools del mapping vertical
[  ] Redactar system_prompt 2-4 oraciones (rol + tono + cuándo capturar lead)
[  ] Redactar first_message saludo natural
[  ] POST /api/developers/agents con publish=true
[  ] Devolver chat_url + dashboard_url + widget_snippet
[  ] Si user mencionó canales (WA, IG) → explicar OAuth en /dashboard/agents/:id#integrations
[  ] Si user tiene sitio WP/Shopify/Wix → mostrar snippet adecuado
[  ] Si user quiere CRM/notif → guiarlo en setup de webhooks

Skill completo + recetas Python/Node + verificación de firma:
https://www.chatia.pro/SKILL.md

WhatsApp · Kapso

Integrá WhatsApp Cloud en 60 segundos.

Conectamos los agentes de Chatia a WhatsApp via Kapso. El usuario pega su API key, asigna un número y el webhook queda configurado. La documentación de Kapso cubre alta del WABA, números, plantillas y rate limits.

Abrir docs.kapso.ai

Próximo paso

Generá tu primera API key

Desde el dashboard creás keys, configurás webhooks, mirás estadísticas de uso y revocás claves comprometidas en un click.