Todas las operaciones responden JSON en el mismo envoltorio (envelope), tengan éxito o fallen, así que un mismo código puede leer cualquier respuesta. La única excepción son las respuestas en texto para agentes de IA, que tú pides.
El envoltorio
| Campo | Si tiene éxito | Si falla |
|---|---|---|
success |
true |
false |
data |
El resultado: un registro, una página o lo que declare la operación. | null |
error |
null |
El objeto de error. |
metadata |
{ "requestId": "…" } |
{ "requestId": "…" } |
Un éxito, aquí de account.apiKeys.delete:
{
"success": true,
"data": { "id": "exampleClientId0001", "deleted": true },
"error": null,
"metadata": { "requestId": "00000000-0000-4000-8000-000000000001" }
}El código de estado también distingue el éxito del fallo: los éxitos responden 200, los fallos 4xx o 5xx. El SDK de TypeScript resuelve con el envoltorio completo y lanza ApiError con cualquier otro estado; el SDK de Rust devuelve data.
El objeto de error
Un fallo, aquí una solicitud sin una credencial válida:
{
"success": false,
"data": null,
"error": {
"code": "UNAUTHORIZED",
"message": "A valid access token is required.",
"retryable": false,
"data": {}
},
"metadata": { "requestId": "00000000-0000-4000-8000-000000000002" }
}| Campo | Significado |
|---|---|
code |
El código del fallo, estable entre versiones. Decide según él. |
message |
Qué salió mal, para personas. Nunca contiene valores de la entrada. No lo analices. |
retryable |
Si repetir la misma solicitud puede tener éxito. Consulta Reintentos. |
data |
Diagnósticos que declara el código. Vacío en la mayoría de los códigos. |
Para INVALID_INPUT, data.issues lista hasta 10 problemas, cada uno con un path, que es un JSON Pointer RFC 6901 al campo rechazado (vacío para la entrada completa), y un message.
Códigos comunes
Estos códigos pueden venir de cualquier servicio. La página de cada operación en la referencia de la API lista los códigos que responde, por estado.
| Estado | code |
retryable |
Significado |
|---|---|---|---|
400 |
INVALID_INPUT |
false |
La solicitud no coincide con el esquema publicado. |
401 |
UNAUTHORIZED |
false |
Se requiere un token de acceso válido. Consulta 401 o 403. |
403 |
FORBIDDEN |
false |
El token no autoriza esta operación. |
404 |
NOT_FOUND |
false |
Nada coincide con la ruta. |
405 |
HTTP_METHOD_NOT_ALLOWED |
false |
El método HTTP no se admite para este recurso. |
413 |
REQUEST_TOO_LARGE |
false |
La solicitud supera el tamaño permitido. Consulta Límites de tamaño. |
415 |
UNSUPPORTED_MEDIA_TYPE |
false |
El tipo de contenido de la solicitud no se admite. Envía los cuerpos JSON como application/json. |
429 |
RATE_LIMITED |
true |
Se superó el límite de solicitudes. Espera los segundos de Retry-After. |
500 |
INTERNAL_ERROR |
false |
El servicio no pudo completar la operación. |
502 |
OUTCOME_UNKNOWN |
false |
Puede que la operación se haya aplicado. Revisa su resultado antes de repetirla. |
503 |
UPSTREAM_UNAVAILABLE |
true |
El servicio de origen (upstream) no pudo completar la solicitud. |
504 |
UPSTREAM_TIMEOUT |
true |
El servicio de origen no respondió antes de su plazo. |
Los servicios agregan sus propios códigos para sus propias reglas, como API_KEY_NOT_FOUND (404) en Cuenta o VERSION_CONFLICT (409) en Raíz.
Ids de solicitud
Cada respuesta lleva un encabezado X-Request-Id, y el envoltorio lo repite como metadata.requestId. Regístralo con cada fallo e inclúyelo cuando reportes un problema.
Las respuestas a 429, y a algunos otros fallos según lo indique su referencia, también llevan Retry-After: los segundos que hay que esperar antes de otro intento.
Límites de tamaño
Cada operación acepta una solicitud y devuelve una respuesta de un tamaño máximo, que su página en la referencia de la API indica en Limits. Un cuerpo más grande se rechaza con 413 REQUEST_TOO_LARGE; en MCP, el límite aplica a la entrada de la herramienta.
La mayoría de las operaciones aceptan un cuerpo de hasta 32 KiB. Las operaciones que llevan archivos aceptan más, como raiz.knowledge.create (12 MiB) y raiz.contacts.import (16 MiB). Las respuestas van desde 256 KiB, como en account.organization.get, hasta 16 MiB en account.invoiceDocuments.get. El SDK de Rust trata como inválida una respuesta más grande que el límite de su operación.
En el documento OpenAPI de la API (https://api.getarbol.com/v1/<service>/openapi.json), cada operación lleva sus límites en bytes, en x-max-body-bytes y x-max-output-bytes.
Respuestas en texto para agentes de IA
Algunas operaciones de integraciones, como las de SURA, Nueva EPS y ADRES, reciben un agentMode opcional. Con agentMode: true responden un texto breve en español, pensado para un agente de IA, con la misma autorización. Según la operación, el texto llega como text/plain en lugar de JSON, o dentro del envoltorio, en data.text; la página de cada operación en la referencia dice cuál. Omítelo para recibir el resultado estructurado.