Ir al contenido

Errores

Todo error responde con un código HTTP distinto de 2xx y este cuerpo:

{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "Esta API key no tiene el permiso \"sales:read\". Crea una key con ese permiso en cuenta.posdata.so → Desarrolladores.",
"required_scope": "sales:read",
"request_id": "req_6vJx0Qm2cPp1bK9a"
}
}
Campo Qué es
code El código estable para tu lógica. Ramifica por code, nunca por message. Los códigos no cambian de nombre ni se reutilizan.
message Explicación en español para una persona, con el siguiente paso. Puede cambiar de redacción.
param El campo que causó el error, cuando aplica (por ejemplo sku, warehouse_id o Idempotency-Key). En errores de validación puede ser una ruta con puntos.
request_id El identificador de la petición. También llega en el header Request-Id de todas las respuestas.

Algunos errores traen campos adicionales: required_scope (en INSUFFICIENT_SCOPE), feature (en PLAN_REQUIRED), retry_after (en RATE_LIMITED) y devices (en DEVICES_OUTDATED). Tu código debe tolerar campos nuevos.

Guarda el request_id en tus logs. Si escribes a soporte, inclúyelo: con él encontramos la petición exacta. Los errores nunca exponen detalles internos (trazas, SQL ni mensajes de otros servicios).

Código HTTP Cuándo pasa Qué hacer
UNAUTHENTICATED 401 Falta el header Authorization o no tiene la forma Bearer <key>. Envía Authorization: Bearer pdk_….
INVALID_API_KEY 401 La key no empieza por pdk_live_/pdk_test_ o no existe. Revisa que la copiaste completa. Si la perdiste, crea otra.
API_KEY_REVOKED 401 La key fue revocada. Crea una nueva en cuenta.posdata.so → Desarrolladores.
API_KEY_EXPIRED 401 La key llegó a su fecha de vencimiento. Crea una nueva y actualiza tu integración.
API_KEY_WRONG_ENVIRONMENT 401 Usas una key de pruebas en producción o al revés. pdk_live_ va con api.posdata.so; pdk_test_ con apidev.posdata.so.
ACCOUNT_INACTIVE 401 La cuenta dueña de la key está inactiva. Escribe a soporte.
Código HTTP Cuándo pasa Qué hacer
PLAN_REQUIRED 403 La cuenta no tiene el plan Pro activo. Trae feature: "public_api". Las keys siguen guardadas y vuelven a funcionar cuando la cuenta tenga Pro. No reintentes en bucle.
INSUFFICIENT_SCOPE 403 La key no tiene el permiso del endpoint. Trae required_scope. Crea una key con ese permiso.
BROWSER_REQUESTS_NOT_ALLOWED 403 La petición trae el header Origin (viene de un navegador). Llama a la API desde tu servidor. Nunca pongas la key en un front-end.
Código HTTP Cuándo pasa Qué hacer
VALIDATION_ERROR 400 Un campo o parámetro no es válido, falta uno obligatorio, o enviaste uno que no existe (los filtros y campos desconocidos se rechazan, no se ignoran). También con 415 si el cuerpo no es JSON en UTF-8. Lee message y param, corrige y reintenta.
INVALID_JSON 400 El cuerpo no es JSON válido. Revisa la serialización y envía Content-Type: application/json.
PAYLOAD_TOO_LARGE 413 El cuerpo supera 256 KB. Envía menos datos por petición.
INVALID_CURSOR 400 starting_after no es un cursor válido. Usa el next_cursor de la respuesta anterior tal cual, sin modificarlo.
NOT_FOUND 404 El recurso no existe en esta cuenta (o el id no tiene formato de uuid). Verifica el id. Un id de otra cuenta responde igual que uno inventado.
ROUTE_NOT_FOUND 404 La ruta o el método no existen. Revisa la referencia.
Código HTTP Cuándo pasa Qué hacer
IDEMPOTENCY_KEY_REQUIRED 400 Un POST sin header Idempotency-Key. Envía un valor único por operación (un UUID).
IDEMPOTENCY_KEY_REUSED 422 Usaste el mismo Idempotency-Key con una petición distinta. Usa un valor nuevo para cada operación distinta.
IDEMPOTENCY_IN_PROGRESS 409 La primera petición con ese Idempotency-Key todavía se está procesando, o se interrumpió antes de terminar. Espera unos segundos y reintenta con el mismo valor. Si sigue igual, verifica con un GET si el recurso se creó antes de usar un valor nuevo.

Detalle en Idempotencia.

Código HTTP Cuándo pasa Qué hacer
CONFLICT 409 Ya existe un registro con esos datos únicos. Busca el registro existente en vez de crearlo otra vez.
SKU_ALREADY_EXISTS 409 Al editar una variante (PATCH /products/{id}/variants/{variantId}), otra variante de la cuenta ya usa ese sku. Trae param: "sku". Usa un SKU distinto o busca la variante que ya lo tiene.
NO_WAREHOUSE 409 Un movimiento de stock (o un producto con initial_stock) sin warehouse_id, y la cuenta no tiene una bodega predeterminada: o todavía no hay bodegas sincronizadas desde las cajas, o hay varias y ninguna es la predeterminada. Indica warehouse_id (consúltalas con GET /warehouses) o abre Posdata en una caja con conexión para que sincronice sus bodegas.
DEVICES_OUTDATED 409 Al editar un producto o una variante (PATCH /products/{id} o PATCH /products/{id}/variants/{variantId}), algún dispositivo del negocio todavía no tiene la versión de Posdata que acepta ediciones sin stock. No se modificó nada. Trae devices: la lista de esos dispositivos, cada uno con name, kind, platform, app_version y last_seen_at. Abre esos dispositivos con internet para que se actualicen solos (tardan un minuto en reportarse) y reintenta, o revoca los que ya no uses en cuenta.posdata.so → Dispositivos. Crear productos y mover stock sí funciona mientras tanto. Mira por qué.
VARIANT_STOCK_UNSUPPORTED 422 Intentaste mover stock de un producto con variantes. Por ahora ajústalo desde Posdata. Mira por qué.
COMPOSITE_STOCK_UNSUPPORTED 422 Intentaste mover stock de un producto que se arma con receta. Mueve el stock de sus insumos.
Código HTTP Cuándo pasa Qué hacer
RATE_LIMITED 429 Superaste un límite de uso. Trae retry_after (segundos) y el header Retry-After. Espera lo que indica Retry-After y reintenta.
INTERNAL_ERROR 500 Falló algo de nuestro lado. Reintenta con espera exponencial. Si persiste, escríbenos con el request_id.
  • Sí: 429 (después de Retry-After), 409 IDEMPOTENCY_IN_PROGRESS, 500 y errores de red o tiempos de espera. Si es un POST, reintenta con el mismo Idempotency-Key.
  • No, sin cambiar algo antes: el resto de 4xx. Repetir la misma petición dará el mismo error.