Centro de Ayuda de Dardo

Errores y códigos de respuesta

Qué forma tiene una respuesta de la API, qué significa cada código HTTP y qué hacer con cada uno

Cómo interpretar lo que devuelve la API: la forma de una respuesta exitosa, la tabla de códigos, y las trampas que conviene conocer antes de escribir el manejo de errores.

El envelope de respuesta

Ningún endpoint devuelve el recurso "pelado". Todo viene envuelto en la misma estructura, y el recurso vive adentro de data.

Respuesta simple

CampoTipoQué es
responseIdstring (uuid)Identificador único de esta respuesta
createdAtstring (date-time)Momento en que se generó
codeintegerEl status HTTP repetido dentro del body
dataobjectEl recurso solicitado
{
  "responseId": "0d4d1c1e-3f5a-4f0e-9b2a-2f5a7c9e1b44",
  "createdAt": "2026-09-07T16:37:46+00:00",
  "code": 200,
  "data": {
    "id": 1234,
    "companyId": 77
  }
}

Respuesta de listado

Los endpoints que devuelven colecciones agregan un bloque meta y data pasa a ser un array.

CampoTipoQué es
responseIdstring (uuid)Identificador único de esta respuesta
createdAtstring (date-time)Momento en que se generó
codeintegerEl status HTTP repetido dentro del body
meta.totalItemsintegerTotal de registros que matchean la consulta, no los de esta página
meta.itemsPerPageintegerTamaño de página efectivo
meta.currentPageintegerPágina devuelta
dataarrayLos recursos de esta página
{
  "responseId": "0d4d1c1e-3f5a-4f0e-9b2a-2f5a7c9e1b44",
  "createdAt": "2026-09-07T16:37:46+00:00",
  "code": 200,
  "meta": {
    "totalItems": 250,
    "itemsPerPage": 30,
    "currentPage": 1
  },
  "data": []
}

Cómo recorrer un listado completo está en Límites y paginación.

El code del body no es fuente de verdad. Duplica el status HTTP, pero hay errores que reusan este mismo envelope. Basá tu lógica de control de flujo en el status HTTP real de la respuesta, no en el code del JSON.

Headers de toda respuesta

HeaderPara qué sirve
X-Request-IDIdentificador de la request del lado del servidor. Presente en 200, 401, 404 y 429
Content-Typeapplication/json en las respuestas de la aplicación. Algunos errores devuelven text/html

Logueá el X-Request-ID de cada respuesta, incluidas las que salieron bien. Cuando escribas a soporte@dardo.ai, ese identificador es lo que nos permite encontrar tu request exacta en vez de pedirte que reproduzcas el problema. Un ticket con X-Request-ID se resuelve mucho más rápido que uno sin él.

Tabla de códigos

CódigoSignificadoCausa típicaQué hacer
200OKLectura o acción ejecutadaLeer data
201CreatedRecurso creadoLeer data y guardar el id devuelto
400 / 422Payload inválidoBody mal formado, campo requerido faltante o fuera de rango, lista de eventos inválida en webhooksCorregir el payload. No reintentar sin cambiarlo
401No autenticadoHeader X-API-Key ausente, mal escrito, o clave inválidaRevisar el header y el valor de la clave. No reintentar
403Sin permisoEl plan de la cuenta no habilita la API, o el recurso está fuera del alcance de la claveVerificar el plan y el nivel de la clave. No reintentar
404No existeID inexistente, recurso borrado, o path mal escritoVerificar el ID y la URL. No reintentar
429Demasiados pedidosSe superó el límite de tasaReintentar con backoff exponencial, leyendo antes la advertencia de idempotencia
5xxError del servidorFalla temporal de nuestro ladoReintentar con backoff. Si persiste, ticket con el X-Request-ID

Si recién arrancás y todo te da 403, lo primero a revisar no es tu código: es el plan de la cuenta. La API está disponible únicamente en el plan Business. Una cuenta en Start o Grow tiene el dashboard funcionando perfecto y aun así no accede a la API. Es el error más probable de un integrador nuevo, y se pierden horas buscándolo en el lugar equivocado.

El segundo sospechoso es el nivel de la clave: una clave de sub-cuenta pegándole a endpoints de administración de cuentas es un rechazo esperable. Ver alcance de la clave.

Errores de autenticación: la forma real

Comportamiento verificado contra https://api.dardo.ai/api/v2/profile.

Sin header X-API-Key:

{ "message": "Full authentication is required to access this resource." }

Con una clave inválida o revocada:

{ "message": "API key is invalid" }

Los dos llegan con status 401, Content-Type: application/json y su X-Request-ID.

La diferencia entre los dos mensajes es útil para diagnosticar: si recibís "Full authentication is required", la API no encontró ninguna credencial —el header no llegó, o llegó con otro nombre—. Si recibís "API key is invalid", el header llegó bien y lo que falla es el valor de la clave.

X-API-Key es el único header de autenticación que la API lee para estos endpoints. Mandar la clave como Authorization: Bearer <clave> devuelve "Full authentication is required", porque ese header directamente se ignora. El nombre no distingue mayúsculas de minúsculas: x-api-key funciona igual.

Punto de venta: 403, no 401

Las tres operaciones de Punto de venta usan X-App-Token en lugar de X-API-Key, y responden con 403:

{ "errors": ["Missed header X-App-Token"] }   // el header no llegó
{ "errors": ["Authentication failed"] }       // el header llegó, el token no sirve

En este grupo, el cuerpo se valida antes que la credencial. Un pedido con el Check mal armado devuelve 400 por el cuerpo aunque el X-App-Token también esté mal — el 403 aparece recién cuando el cuerpo es válido.

Al depurar, arreglá primero lo que dice el 400: hasta que el cuerpo no pase, no vas a ver si tu token funciona.

Conviven varios formatos de error

Esto es lo más importante de esta página a la hora de escribir el cliente HTTP.

Hoy no hay una única forma canónica de error en la API. Conviven al menos tres:

FormaDónde apareceEjemplo
{"message": "..."}Errores de autenticación{"message":"API key is invalid"}
{"errors": [...]}Las tres operaciones de Punto de venta{"errors":["Authentication failed"]}
El envelope ResponseLos 400 de Webhooks{"responseId":"...","code":400,"data":{}}
HTML404 y 429 (ver abajo)

No podés parsear los errores de forma uniforme todavía. Escribí el manejo de errores defensivo: ramificá por status HTTP, chequeá el Content-Type antes de parsear —o envolvé el JSON.parse en un try/catch— y tratá el mensaje del body como texto para loguear, no como un contrato estable.

Es información accionable, no una excusa: si asumís JSON con una forma fija, tu integración se va a caer el día que toque un endpoint del otro grupo.

Errores que no vienen de la aplicación

Dos casos donde la respuesta no es JSON:

404 en un path inexistente devuelve una página HTML de error, con Content-Type: text/html.

429 por límite de tasa lo emite nginx antes de llegar a la aplicación, también en HTML:

<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>nginx</center>
</body>
</html>

Ese 429 no trae Retry-After ni headers X-RateLimit-*. No hay forma de saber cuánto esperar: el backoff es a ciegas. Detalles en Límites y paginación.

Qué declara la especificación

Un dato honesto para calibrar expectativas: la enorme mayoría de las operaciones de la API documenta únicamente respuestas 2xx. Solo tres grupos declaran respuestas de error en la especificación:

GrupoErrores declarados
Punto de venta400 y 403, con la forma {"errors": [...]}
Webhooks400, reusando el envelope Response
Servicios externosUna respuesta default sin contenido declarado

Los grupos que va a usar una integración típica —Tarjetas, Clientes, Operacionesno declaran ninguna respuesta de error en la referencia. Eso no significa que no las devuelvan: significa que la referencia no las lista, y por eso esta página existe.

La tabla de códigos de arriba es la guía práctica. No esperes encontrar una tabla de errores endpoint por endpoint en la referencia, porque hoy no está.

Estrategia de reintentos

Código¿Reintentar?Cómo
400 / 422NoEl payload está mal, reintentar da lo mismo
401NoCredencial inválida, arreglar la configuración
403NoPlan o permiso insuficiente, escalar
404NoEl recurso no existe
429Backoff exponencial con jitter
5xxBackoff exponencial, 3 a 5 intentos como máximo
Timeout de redCon cuidadoVer la advertencia de idempotencia antes de reintentar una escritura

Ver también

On this page