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: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
Reintentarate_limit_error y api_error. No reintentes errores 4xx sin
cambios; van a fallar igual.
Códigos de error
Todos loserror.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. Devuelvelinks.next sin cambios, con los mismos filtros y el mismo orden.
unknown_expand
Una relación enexpand no existe en este recurso.
expand_limit_exceeded
Demasiadas relaciones enexpand; el límite es 4.
unknown_field
Un nombre enfields 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 eseexternal_id; el mensaje dice cuál.
external_id_conflict
Elexternal_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 eseexternal_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
EseIdempotency-Key ya se usó con otro cuerpo. Usa una clave nueva para una solicitud nueva.
idempotency_key_in_flight
Una solicitud con eseIdempotency-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. Usaassign para cambiar de persona.
conversation_with_ai
El agente de IA tiene esta conversación. Usahandoff 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
Elassignee_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 unvalue y no se envió ninguno, o lo prohíbe y se envió uno.
HTTP 429
rate_limit_exceeded
Demasiadas solicitudes en este token. EsperaRetry-After segundos antes de reintentar.
HTTP 500
internal_error
Algo salió mal de nuestro lado. Reintenta con backoff y comparteerror.request_id con soporte si persiste.
Códigos por campo
Un errorvalidation_failed lista cada campo con problemas en detail, con uno de estos códigos o un tipo de validación estándar como missing.