Skip to main content
Cada respuesta que no es 2xx tiene el mismo body:
Bifurca por type para el control de flujo y por code para el manejo específico. Ambos son estables; message está escrito para humanos y puede reformularse. Siempre loguea request_id. Se ecoa en el header de respuesta X-Request-ID, y citarlo nos deja encontrar tu petición exacta.

Tipos

Un 404 no distingue “no existe” de “pertenece a otro workspace”. Es deliberado: distinguirlos le permitiría a cualquiera sondear ids de registros entre workspaces.

Scopes faltantes

Un 403 de un chequeo de scope nombra exactamente lo que falta, para que no tengas que adivinar:
Un 403 que no es insufficient_scope suele significar política de write del workspace — por ejemplo, una entidad espejada desde un CRM externo. Llama GET /v1/capabilities para ver qué entidades puedes escribir.

Reintentos

Reintenta rate_limit_error y api_error. No reintentes errores 4xx sin cambios; van a fallar igual.
Usa backoff exponencial con jitter. Reintentar de inmediato durante un rate limit lo extiende.

Códigos de error

Todos los error.code, agrupados por status HTTP. error.documentation_url lleva directo a la entrada del código que recibiste. Los códigos son permanentes: úsalos para decidir qué hacer.

HTTP 400

bad_request

No se pudo entender la solicitud.

invalid_cursor

El cursor está dañado o se emitió para otra consulta. Devuelve links.next sin cambios, con los mismos filtros y el mismo orden.

unknown_expand

Una relación en expand no existe en este recurso.

expand_limit_exceeded

Demasiadas relaciones en expand; el límite es 4.

unknown_field

Un nombre en fields no existe en este recurso.

unknown_sort_field

Este recurso no se puede ordenar por esa clave.

unknown_entity

Ningún recurso tiene ese nombre.

too_many_filter_values

Un parámetro de filtro se repitió más veces de lo permitido.

unsupported_sort

Esta colección no se puede ordenar así.

invalid_window

La ventana de tiempo está vacía o invertida.

HTTP 401

unauthorized

El token falta, es desconocido, fue revocado o expiró.

token_expired

El token de acceso OAuth expiró. Renuévalo y vuelve a intentar.

HTTP 403

insufficient_scope

Al token le falta un scope que este endpoint necesita; param nombra el primero que falta. GET /v1/me lista lo que tiene el token.

forbidden

La solicitud no está permitida para este token.

local_write_denied

El workspace desactivó este tipo de escritura, por lo general porque un CRM externo es la fuente de verdad. GET /v1/capabilities muestra la política.

user_grant_denied

La persona que autorizó esta conexión OAuth no puede hacer este cambio en Sailer.

note_author_only

Solo la persona del equipo que escribió la nota puede cambiarla o eliminarla.

conversation_access_denied

La persona que autorizó esta conexión OAuth no puede actuar sobre esta conversación en Sailer.

channel_access_denied

La persona que autorizó esta conexión OAuth no puede usar un canal por el que envía esta campaña.

campaign_dispatch_denied

La persona que autorizó esta conexión OAuth no tiene permiso para enviar campañas.

HTTP 404

not_found

No existe ese registro en este workspace.

contact_not_found

Un id de contacto en la solicitud no existe en este workspace.

pipeline_not_found

El id del pipeline no existe en este workspace.

stage_not_found

No hay etapa con ese id o nombre en el pipeline.

record_not_found

Un id de contacto, organización o negocio en el cuerpo no existe en este workspace o no es visible para este token; param nombra el campo, como record_id, contact_id u organization_id.

HTTP 405

api_error

El método no está soportado en esta ruta.

HTTP 409

conflict

La solicitud entra en conflicto con el estado actual.

already_exists

El registro ya existe.

external_id_taken

Otro registro del mismo recurso ya tiene ese external_id; el mensaje dice cuál.

external_id_conflict

El external_id y el phone de un upsert apuntan a contactos distintos, o el contacto encontrado ya tiene otro external id.

phone_mismatch

El contacto con ese external_id tiene otro teléfono. El upsert nunca cambia el teléfono de un contacto.

contact_already_exists

Ya existe un contacto con ese teléfono; el mensaje dice cuál. POST /v1/contacts/upsert crea o actualiza en una sola llamada.

campaign_not_accepting_participants

La campaña terminó y no acepta participantes nuevos.

idempotency_key_reused

Ese Idempotency-Key ya se usó con otro cuerpo. Usa una clave nueva para una solicitud nueva.

idempotency_key_in_flight

Una solicitud con ese Idempotency-Key todavía se está procesando. Vuelve a intentar cuando termine.

tag_already_exists

El catálogo de etiquetas del recurso ya tiene una etiqueta con ese nombre.

conversation_closed

La conversación está cerrada; no se puede transferir, asignar ni retomar.

conversation_not_with_ai

Una persona del equipo o la cola ya tiene esta conversación, así que no hay nada que transferir. Usa assign para cambiar de persona.

conversation_with_ai

El agente de IA tiene esta conversación. Usa handoff para pasarla antes a una persona.

conversation_already_with_ai

El agente de IA ya tiene esta conversación.

conversation_has_no_contact

La conversación no tiene contacto, o su contacto ya no existe, así que no se puede cerrar aquí.

no_agent_available

La cola de la conversación no tiene un agente de IA activo con parte del trabajo para devolvérsela.

conversation_queue_unavailable

La cola en la que está la conversación ya no existe, así que no se puede transferir. Muévela a otra cola en Sailer.

campaign_not_running

Solo una campaña en ejecución se puede pausar.

campaign_not_paused

Solo una campaña pausada se puede retomar.

campaign_not_ready

A la campaña le falta configuración que necesita para enviar; el mensaje dice cuál.

campaign_has_no_message

La campaña no tiene un mensaje activo para enviar.

campaign_template_variables_unresolved

Una variable de plantilla en el mensaje de la campaña no se puede completar.

campaign_template_not_approved

Una plantilla que envía la campaña todavía no fue aprobada por WhatsApp.

campaign_channel_unavailable

Un canal por el que envía la campaña falta o no está activo.

already_reversed

Este evento ya se revirtió; un evento solo se puede revertir una vez.

not_a_record

Una reversión no se puede revertir.

HTTP 422

validation_failed

Algunos campos son inválidos; detail lista cada uno. Los problemas de query, ruta o header responden 400 con el mismo código.

invalid_request

La solicitud está bien formada, pero no se puede aplicar tal como se envió.

stage_not_in_pipeline

La etapa pertenece a un pipeline distinto al del negocio.

agent_activity_read_only

Esta actividad es el plan del agente de IA para volver a escribirle al contacto; solo se puede completar o cancelar.

assignee_not_found

El assignee_id no es de una persona del equipo que pueda tomar esta conversación.

won_reason_without_won

won_reason solo se acepta con outcome: won.

unknown_event_code

El workspace no tiene un tipo de evento de éxito con ese código. GET /v1/success-event-types los lista.

value_basis_mismatch

El tipo de evento exige un value y no se envió ninguno, o lo prohíbe y se envió uno.

HTTP 429

rate_limit_exceeded

Demasiadas solicitudes en este token. Espera Retry-After segundos antes de reintentar.

HTTP 500

internal_error

Algo salió mal de nuestro lado. Reintenta con backoff y comparte error.request_id con soporte si persiste.

Códigos por campo

Un error validation_failed lista cada campo con problemas en detail, con uno de estos códigos o un tipo de validación estándar como missing.