Resumen de la API
Todos los endpoints REST de RolChat siguen un mismo contrato: la misma URL base, el mismo sobre de respuesta, la misma paginación, la misma forma de error. Apréndelo una vez y todas las familias de endpoints de la referencia de endpoints se leerán igual.
URL base y versionado
Sección titulada «URL base y versionado»https://api.rolchat.com/api/v1/La versión está en la ruta. Añadir campos opcionales, endpoints nuevos o parámetros de consulta nuevos con valores predeterminados no es un cambio incompatible y no incrementa la versión. Los cambios incompatibles se publican como v2, y los endpoints de v1 declarados obsoletos siguen funcionando al menos seis meses después de su anuncio (consulta Obsolescencia).
Autenticación
Sección titulada «Autenticación»| Método | Cabecera | Se usa para |
|---|---|---|
| JWT bearer | Authorization: Bearer <access_token> |
Sesiones interactivas (la aplicación web, las apps móviles) |
| Clave de API | Authorization: Bearer rcp_<secret> |
Llamadas entre máquinas, claves de API de plugins |
| Firma HMAC | X-RolChat-Signature: sha256=… |
Webhooks entrantes desde tus sistemas, consulta Webhooks |
| Ninguno | - | Endpoints públicos del widget (/widget/…, /forms/…), limitados por sitio y origen |
Para las integraciones usa una clave de API (un token de acceso personal). Las claves se crean en Configuración → Plugins → Claves de API de RolChat, se muestran una sola vez y se almacenan solo como hash. Una clave nunca puede hacer más que el miembro que la creó: en cada llamada sus ámbitos se comprueban frente a los permisos actuales de ese miembro. Consulta Autenticación para la duración de los JWT, la cabecera X-Account-Id y las sesiones con varias empresas.
Sobre de respuesta
Sección titulada «Sobre de respuesta»Un recurso individual:
{ "data": { "id": "cnt_01HK…", "email": "ada@example.com" }, "meta": { "request_id": "req_01HK…" }}Una lista:
{ "data": [ { … }, { … } ], "meta": { "request_id": "req_01HK…", "count": 50, "next_cursor": "cur_01HK…", "prev_cursor": "cur_01HK…", "has_more": true }}Las respuestas sin cuerpo (204 No Content tras una eliminación) siguen incluyendo la cabecera X-Request-Id.
Un error:
{ "errors": [ { "code": "validation_failed", "message": "Email must be valid.", "field": "email", "details": { "received": "not-an-email" } } ], "meta": { "request_id": "req_01HK…" }}code es legible por máquina, en snake_case, y es el valor sobre el que conviene ramificar; message está en inglés y está pensado para los registros. field y details aparecen cuando ayudan y nunca contienen datos personales. La API nunca responde 200 con un array errors: si hay errores, el estado es 400 o superior. La lista completa de códigos está en la página Errores.
Paginación
Sección titulada «Paginación»Los endpoints de lista que pueden crecer usan paginación por cursor. Pide la primera página sin cursor y después devuelve tal cual el next_cursor que recibiste:
GET /api/v1/contacts?limit=50GET /api/v1/contacts?limit=50&cursor=eyJrIjoi…limitvale 50 por defecto y tiene un máximo de 200; los valores mayores se rechazan con400 validation_failed.- Los cursores son opacos y caducan a las 24 horas (
400 validation_failedconcode: cursor_expired). - Los resultados son coherentes con la instantánea tomada en la primera página: los registros eliminados entre páginas desaparecen y los nuevos solo aparecen cuando empiezas de nuevo sin cursor.
- También se envía una cabecera
Linkconrel="next"yrel="prev"para los clientes que la prefieran.
Idempotencia
Sección titulada «Idempotencia»Envía una cabecera Idempotency-Key (un UUID o ULID de hasta 255 caracteres) con cualquier POST, PATCH o DELETE:
- La primera petición con una clave se ejecuta y su estado y cuerpo se guardan durante 24 horas.
- Una repetición con la misma clave y el mismo cuerpo devuelve la respuesta guardada sin volver a ejecutar efectos secundarios.
- Una repetición con la misma clave pero un cuerpo distinto se rechaza con
409 idempotency_key_conflict.
Úsala en cada llamada que cree algo con efectos secundarios: enviar un mensaje, un email o un SMS, realizar una llamada, cualquier cosa que se facture. Las peticiones GET son siempre idempotentes e ignoran la cabecera.
Límites de uso
Sección titulada «Límites de uso»Los límites se cuentan por minuto y se asocian a la cuenta, la clave de API o el usuario (a la dirección IP en las rutas que no requieren iniciar sesión). Los máximos por defecto:
| Cubo | Límite por defecto | Por minuto |
|---|---|---|
| Peticiones sin iniciar sesión (por IP) | 60 | por IP |
| Usuario con sesión iniciada (panel) | 1 000 | por usuario |
| Clave de API | 1 000 | por clave |
| Endpoints públicos del widget | 60 por visitante y 600 por dirección de red | por minuto |
Inicio de sesión (/auth/login) |
5 | por IP |
| Webhooks entrantes | 300 | por minuto |
| Servidor MCP | 600 | por minuto |
| Endpoints de OAuth | 600 | por minuto |
Los máximos son los valores por defecto de la plataforma y el operador puede cambiarlos; tu plan no los multiplica, y los límites de Enterprise se acuerdan en tu contrato. Los endpoints con límite de uso devuelven:
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 543Cuando superas un límite, la respuesta es 429 con code: rate_limited en el array errors y una cabecera Retry-After en segundos. Espera ese tiempo antes de la siguiente llamada. Diez inicios de sesión fallidos bloquean la cuenta durante 30 minutos.
Tamaños y tiempos de espera
Sección titulada «Tamaños y tiempos de espera»| Categoría | Cuerpo máximo de la petición | Tiempo de espera del servidor |
|---|---|---|
| Predeterminado | 1 MB | 30 s |
| Mensaje con adjuntos | 25 MB | 30 s |
| Importación CSV | 50 MB | devuelve 202 y se ejecuta en segundo plano |
| Imágenes de la base de conocimiento | 10 MB | 30 s |
| API masiva | 10 MB | 30 s |
| Búsqueda | 1 MB | 10 s |
| Peticiones de IA | 1 MB | 60 s |
| Endpoints del widget | 100 KB | 30 s |
Los cuerpos demasiado grandes reciben 413 payload_too_large. Un servicio de origen que agota el tiempo responde 504 con code: upstream_timeout y una indicación retry_after cuando reintentar puede ayudar.
Tipos de contenido, fechas e identificadores
Sección titulada «Tipos de contenido, fechas e identificadores»- Las peticiones y respuestas son
application/json; charset=utf-8. Las subidas de archivos usanmultipart/form-data; las exportaciones CSV devuelventext/csv. El UTF-8 no válido se rechaza con400 validation_failed. - Las marcas de tiempo son ISO-8601 en UTC con precisión de milisegundos:
2026-04-20T14:23:45.123Z. En la entrada se acepta cualquier desfase ISO-8601, que se normaliza a UTC. - Los identificadores son ULID o UUID opacos. No hay identificadores numéricos, y las direcciones de email o los números de teléfono nunca aparecen en una URL.
Aislamiento de inquilinos y permisos
Sección titulada «Aislamiento de inquilinos y permisos»Cada petición autenticada se ejecuta dentro de una cuenta. Un recurso que pertenece a otra cuenta, o a un sitio que el rol de quien llama no cubre, responde 404 not_found en lugar de 403, para que nunca se filtre la existencia de registros. Un token válido sin el permiso necesario (por ejemplo contacts.delete) responde 403 forbidden. Algunos permisos llevan un sufijo de ámbito (conversations.read:own, :team, :all) que restringe lo que devuelve una lista.
PATCH solo acepta campos modificables. id, account_id, created_at, updated_at y los campos de estado como resolved_at son de solo lectura; enviar uno devuelve 400 validation_failed con details.forbidden_fields. Los cambios de estado pasan por acciones específicas como POST /tickets/:id/resolve.
Cada escritura queda registrada en el registro de auditoría de la cuenta.
Cabeceras de observabilidad
Sección titulada «Cabeceras de observabilidad»Cada respuesta incluye:
X-Request-Id: req_01HK…Registra X-Request-Id. Es lo primero que pide el equipo de soporte.
El origen del panel en el navegador es https://app.rolchat.com. Los endpoints públicos del widget admiten cualquier origen, o solo los orígenes que verifiques para un sitio. Las llamadas de servidor a servidor con una clave de API no están sujetas a CORS.
Obsolescencia
Sección titulada «Obsolescencia»- El cambio se anuncia en el registro de cambios y el endpoint afectado empieza a enviar
Deprecation: truey una cabeceraSunsetcon la fecha de retirada. - Los endpoints públicos siguen funcionando al menos seis meses después del anuncio.
- La retirada solo ocurre en una nueva versión mayor. Dentro de
v1los cambios son aditivos.
Estado de salud
Sección titulada «Estado de salud»Cada servicio expone /healthz (actividad) y /readyz (disponibilidad).