Saltar al contenido
Referencia API

Referencia de Errores

Catálogo completo de errores de la API v1 y MCP Gateway de Trusteed. Úsalo para escribir retry logic preciso y gestionar fallos de forma elegante.

Formato de Respuesta de Error

REST y MCP fallan de forma distinta, y la diferencia importa al escribir la lógica de reintentos. REST devuelve un código HTTP con un sobre JSON; una herramienta MCP devuelve HTTP 200 con isError dentro del resultado.

// REST — GET/POST /api/v1/...
{
  "success": false,
  "error": "Mensaje legible por humanos",
  "code": "MACHINE_CODE",   // presente en algunos endpoints, no en todos
  "details": { ... }        // opcional
}

// Resultado de herramienta MCP — el estado del transporte es 200
{
  "isError": true,
  "content": [{ "type": "text", "text": "Mensaje legible por humanos" }],
  "structuredContent": {
    "error": {
      "code": "CART_NOT_MUTABLE",
      "remedy": "refresh_state",
      "retryable": false,
      "scope": "call",
      "details": { ... },
      "reference": "https://trusteed.xyz/es/developers/errors#CART_NOT_MUTABLE"
    }
  }
}

En REST, error lleva el mensaje y code todavía no es uniforme en todos los endpoints — decide por el código HTTP. En MCP, structuredContent.error.code es el discriminador estable, y la tabla de abajo se genera desde la misma fuente que emite el servidor.

Errores de Autenticación

Se devuelven cuando falta la API key, es inválida o carece de los permisos necesarios para realizar la acción solicitada.

Código HTTPErrorSignificadoAcción Recomendada
401unauthorizedAPI key ausente o inválidaVerifica que el header X-Agent-Api-Key esté presente y con formato correcto (agnt_xxx)
401token_expiredEl token OAuth ha expiradoRefresca el token con POST /api/v1/oauth/token
403forbiddenLa clave carece del scope necesario para esta acciónRevisa los scopes de la clave en el Dashboard bajo Agent Keys
403store_suspendedEl comercio no está disponible por el momentoElige un merchant diferente del directorio

Errores de Rate Limit

Los rate limits se aplican por clave y por herramienta. Lee el header X-RateLimit-Reset para saber cuándo se renueva la ventana.

Código HTTPErrorSignificadoAcción Recomendada
429rate_limit_exceededLímite de peticiones por clave alcanzadoPausa y reintenta tras el timestamp Unix en X-RateLimit-Reset

Headers de respuesta de rate limit

  • X-RateLimit-LimitMáximo de peticiones permitidas en la ventana actual
  • X-RateLimit-RemainingPeticiones restantes antes de alcanzar el límite
  • X-RateLimit-ResetTimestamp Unix (segundos) en que se renueva la ventana

Errores de Lógica de Negocio

Se devuelven cuando una petición es estructuralmente válida pero falla por el estado de la aplicación (p.ej. carrito expirado, tienda no encontrada).

Código HTTPErrorSignificadoAcción RecomendadaReintentable
404store_not_foundLa tienda no existe o está inactivaVerifica el slug en el directorio de merchantsNo
500internal_errorError de servidor inesperadoReintenta con backoff exponencial (ver Guía de Reintentos abajo)
503service_unavailableSobrecarga temporal o mantenimientoReintenta después de 30 segundos

Errores de Herramientas MCP

Cuando una herramienta MCP falla, el transporte sigue devolviendo 200 — el fallo va en el resultado. Decide por structuredContent.error.remedy: es un conjunto cerrado, así que puedes cubrirlo por completo. Los códigos marcados como fondos capturados significan que puede existir ya un cargo; reintentar uno de ésos puede cobrar dos veces al comprador.

CódigoQué significaRemedio¿Reintentar?Vale para
HUMAN_CONFIRMATION_DECLINEDA human was asked and declined. Nothing was changed. Re-asking without new information is not acceptable behaviour.Para — no reintentesNoSólo esta llamada
IDEMPOTENCY_KEY_CONFLICTThis session is already bound to a different idempotency_key. Reusing the session under a new key is refused because it cannot be distinguished from a double-submit.Para — no reintentesNoSólo esta llamada
ORDER_OWNERSHIP_FAILEDThe order is not associated with the authenticated customer. Retrying under the same identity is refused, and repeated attempts are recorded.Para — no reintentesNoSólo esta llamada
PAYMENT_AMOUNT_MISMATCHPuede haber fondos ya capturadosThe captured amount does not match the amount the session authorised. Funds have moved. Do not retry; this needs reconciliation.Para — no reintentesNoSólo esta llamada
PAYMENT_CAPTURED_FINALIZATION_FAILEDPuede haber fondos ya capturadosThe capture SUCCEEDED and order finalization then failed. The buyer has been charged. Do not retry — a retry risks a second charge. Escalate with `details.capture_reference`.Para — no reintentesNoSólo esta llamada
HUMAN_CONFIRMATION_REQUIREDThe action needs a human to approve it and this path cannot ask one — the client does not support elicitation, or the approver is the merchant rather than the buyer. `details.approver` says who. Nothing was changed.Debe decidirlo una personaNoSólo esta llamada
NATIVE_CHECKOUT_REQUIREDThis merchant requires the purchase to complete on the platform's own hosted checkout. `details.checkout_url` carries where to send the buyer.Debe decidirlo una personaNoEste comercio (cacheable)
ORDER_NOT_CANCELLABLEThe order has advanced past the point where an agent may cancel it. `details.status` carries the current status.Debe decidirlo una personaNoSólo esta llamada
RETURN_WINDOW_EXPIREDThe merchant's return window has closed for this order. Only a human on the merchant side can override it.Debe decidirlo una personaNoSólo esta llamada
AGENT_TOKEN_INVALIDThe supplied agent token failed verification. `details.reason` carries the verifier's reason. Re-mint the token; do not retry the same one.Corrige los argumentosNoSólo esta llamada
CURRENCY_MISMATCHThe requested items do not share a single currency. Split them into one cart per currency.Corrige los argumentosNoSólo esta llamada
IDENTITY_TOKEN_REJECTEDThe supplied identity token failed verification. `details.reason` carries the reason.Corrige los argumentosNoSólo esta llamada
IDENTITY_TOKEN_STORE_MISMATCHThe identity token is valid but was issued for a different store. Tokens are not portable across merchants.Corrige los argumentosNoSólo esta llamada
INSUFFICIENT_INPUTThe call is well-formed but does not carry enough material to act on — e.g. a comparison with fewer than two resolvable products.Corrige los argumentosNoSólo esta llamada
INVALID_ARGUMENTAn argument is malformed — a non-UUID id, an unparseable product id, or a value outside the accepted range. `details.field` names it when known.Corrige los argumentosNoSólo esta llamada
MANDATE_LIMIT_EXCEEDEDThe order exceeds a boundary of the payment mandate the caller itself presented — amount, currency, audience or expiry. `details` carries the mandate's own limit and the cart total, because both are already known to the caller. Correct the cart (or present a mandate that covers it) and call again; the identical call cannot succeed.Corrige los argumentosNoSólo esta llamada
MISSING_REQUIRED_ARGUMENTA required argument was omitted, or a conditionally-required one was omitted for the chosen mode. `details.field` names it.Corrige los argumentosNoSólo esta llamada
ORDER_NOT_FOUNDNo order matches the given id for this store.Corrige los argumentosNoSólo esta llamada
PRODUCT_NOT_FOUNDNo product matches the given id in this store. Re-run discovery rather than retrying the id.Corrige los argumentosNoSólo esta llamada
TOOL_NOT_FOUNDNo tool is registered under that name for this store. The set of tools a store exposes is fixed for the session — re-run discovery rather than guessing another name.Corrige los argumentosNoEste comercio (cacheable)
CART_NOT_FOUNDNo cart session exists for that id, or it has expired. Create a new cart; do not retry with the same id.Relee el estado y vuelve a llamarNoSólo esta llamada
CART_NOT_MUTABLEThe cart was modified, completed or expired since it was read. Re-read the cart state and reapply the change against the current version.Relee el estado y vuelve a llamarNoSólo esta llamada
CHECKOUT_SESSION_NOT_FOUNDNo checkout session exists for that id, or it has expired. Start from cart creation.Relee el estado y vuelve a llamarNoSólo esta llamada
CHECKOUT_STATUS_INVALIDThe operation is not legal from the session's current status. `details.status` carries that status; advance the session through the documented transition first.Relee el estado y vuelve a llamarNoSólo esta llamada
PRECONDITION_NOT_META prerequisite step has not been completed — no shipping method selected, no shipping options loaded yet. `details.required_step` names the tool to call first; retrying this one without it repeats the same refusal.Relee el estado y vuelve a llamarNoSólo esta llamada
SESSION_INACTIVEThe session is no longer active and accepts no further changes.Relee el estado y vuelve a llamarNoSólo esta llamada
STATE_RECONFIRMATION_REQUIREDThe merchant's own state moved between the approved preview and this execution, by more than the tolerance but not past the blocking cut. `details.reconfirm_state_hash` is the hash of the state now in force; call again passing it as `reconfirmed_state_hash` to execute against THAT state. A retry without it, or with a stale hash, is refused again.Relee el estado y vuelve a llamarNoSólo esta llamada
VERIFICATION_NOT_FOUNDNo attribute verification exists for that reference, or it has expired before being polled. Start a new verification.Relee el estado y vuelve a llamarNoSólo esta llamada
CHECKOUT_BLOCKED_BY_POLICYA merchant enforcement rule blocked this checkout. `details.rule_code` names the rule. The block follows from THIS order — a different amount, item set or destination may pass — so retrying the identical checkout will not.Prueba otra víaNoSólo esta llamada
FEATURE_NOT_ENABLEDThe merchant has not enabled this capability. It is a configuration state, not a fault — retrying never flips it.Prueba otra víaNoEste comercio (cacheable)
NOT_ELIGIBLEThe request is valid and the capability is enabled, but this subject does not qualify under the merchant's rules.Prueba otra víaNoSólo esta llamada
PAYMENT_DECLINEDThe payment instrument was declined by the processor. Nothing was captured. Retrying the same instrument reproduces the decline.Prueba otra víaNoSólo esta llamada
PAYMENT_METHOD_NOT_CONFIGUREDThe requested payment rail is not configured for this store. Call get_payment_methods and pick one that is.Prueba otra víaNoEste comercio (cacheable)
PLAN_UPGRADE_REQUIREDThe merchant's plan does not include this path. Only the merchant can change that; pick another payment method or tool.Prueba otra víaNoEste comercio (cacheable)
STATE_EXECUTION_BLOCKEDThe merchant's own state diverged from the approved preview past the point where reconfirming is acceptable — insufficient stock, a price move too large, or a policy version change under a prior approval. `details.reasons` says which. No reconfirmation is offered: a different item set or quantity may pass.Prueba otra víaNoSólo esta llamada
STORE_NOT_CONFIGUREDThis store has not completed the configuration this tool depends on. Retrying will not change that; another store or another tool may work.Prueba otra víaNoEste comercio (cacheable)
UPSTREAM_RESPONSE_INVALIDA dependency answered, but its response failed schema validation. Retrying reproduces it — the upstream contract is broken, not the connection.Prueba otra víaNoSólo esta llamada
CHECKOUT_ALREADY_IN_PROGRESSA checkout for this session is already running or has completed. Retrying with the SAME idempotency_key is safe and returns the existing order.Reintenta la misma llamadaSólo esta llamada
PAYMENT_FAILED_ROLLED_BACKThe payment attempt failed and the session was rolled back to READY_FOR_PAYMENT. Nothing was captured; retrying with a fresh payment token is safe.Reintenta la misma llamadaSólo esta llamada
PAYMENT_NOT_APPROVEDThe payer did not approve the payment. Nothing was captured and the session was rolled back to READY_FOR_PAYMENT — a fresh approval attempt is safe.Reintenta la misma llamadaSólo esta llamada
CART_ATTRIBUTE_WRITE_FAILEDAn attribute the enforcement layer depends on could not be written to the platform cart, so the step was refused rather than leaving a rule unable to fire. Retry shortly.Reintenta con espera crecienteSólo esta llamada
ENFORCEMENT_UNAVAILABLEThe enforcement layer could not be consulted — the signed policy snapshot was unreadable, or the evaluator itself errored. The operation was refused fail-closed rather than proceeding unprotected. Retry shortly.Reintenta con espera crecienteSólo esta llamada
INTERNAL_ERRORAn unexpected fault on our side. Retry with backoff; if it persists, report it with the tool name and arguments.Reintenta con espera crecienteSólo esta llamada
UPSTREAM_ERRORThe merchant's commerce platform returned an error for this read or write. Retry with backoff; if it persists the merchant's platform is at fault, not the request.Reintenta con espera crecienteSólo esta llamada
UPSTREAM_UNAVAILABLEA dependency this tool needs is temporarily unreachable. Retry with backoff.Reintenta con espera crecienteSólo esta llamada

Guía de Reintentos

No todos los errores vale la pena reintentar. Sigue estas reglas para construir integraciones resilientes.

Errores reintentables

429, 500, 503

Backoff: 1s → 2s → 4s → 8s (máx. 4 reintentos)

Errores no reintentables

400, 401, 403, 404, 409, 422

Corrige la petición antes de reintentar

Estrategia de backoff recomendada

// Backoff exponencial — máximo 4 reintentos
const REINTENTABLES = new Set([429, 500, 503]);

async function llamarConReintento(fn: () => Promise<Response>): Promise<Response> {
  let intento = 0;
  while (intento <= 4) {
    const res = await fn();
    if (res.ok || !REINTENTABLES.has(res.status)) return res;

    if (res.status === 429) {
      const reset = res.headers.get("X-RateLimit-Reset");
      const esperaMs = reset ? (Number(reset) * 1000 - Date.now()) : 1000;
      await esperar(Math.max(esperaMs, 0));
    } else {
      await esperar(1000 * 2 ** intento); // 1s → 2s → 4s → 8s
    }
    intento++;
  }
  return fn();
}

function esperar(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

Volver a la Documentación

Explora autenticación, herramientas MCP, webhooks y más.

Documentación para Desarrolladores
Referencia de Errores API | Desarrolladores Trusteed