Saltar al contenido
SendIt está en desarrollo y todavía no opera comercialmente · SendIt is in development and not yet commercially available.
SendItdocs
Español
Esc
navigateopen⌘Jpreview
En esta página

Idempotencia

El encabezado Idempotency-Key, opcional pero recomendado, reproduce una petición interrumpida sin riesgo de cargos duplicados.

Las redes fallan. La idempotencia garantiza que reintentar una petición interrumpida nunca duplique la operación ni el cargo.

Tú generas la llave

La llave de idempotencia la creas tú, del lado del cliente. El API nunca te entrega una. Antes de enviar la petición:

  1. Genera un valor único para esa operación de negocio. Recomendado: un UUID v4 (crypto.randomUUID() en Node.js, uuid.uuid4() en Python) o cualquier cadena con aleatoriedad suficiente para no repetirse (hasta 255 caracteres).
  2. Envíalo en el encabezado Idempotency-Key.
  3. Guárdalo junto a tu operación (la orden, el pedido) para que cualquier reintento use exactamente la misma llave.

Una llave representa un intento de negocio: la misma llave para los reintentos de esa operación, una llave nueva para cada operación distinta.

Cómo funciona

Toda mutación (POST, PUT, PATCH) acepta un encabezado Idempotency-Key (recomendado: UUIDv4, máximo 255 caracteres):

curl -X POST https://api.sendit.mx/v1/shipments/clxq1w2e3r4t5y6u7i8o9p0a/label \
  -H "X-API-Key: sk_test_..." \
  -H "Idempotency-Key: 1f0e6f0e-59a4-4a6f-9d2e-9b1a7b2c3d4e" \
  -H "Content-Type: application/json" \
  -d '{ "rateId": "ESTAFETA_economy_x9y8z7" }'

Reintentar con la misma llave dentro de una ventana de 24 horas reproduce el resultado original: mismo código de estado y mismo cuerpo, haya sido éxito o falla. La respuesta trae el encabezado Idempotent-Replayed: true y tu llave de vuelta.

Dos matices importantes:

  • Los errores de validación (400) no se almacenan: corrige el payload y reusa la misma llave sin problema.
  • Cualquier otra falla reproducida (p. ej. un 402) seguirá reproduciéndose: tras resolver la causa, reintenta con una llave nueva.

Dónde importa más

La llave es opcional en todos los endpoints. Si no mandas una, la petición corre normal, sin reproducción de reintento. Nunca recibes un 400 por falta de llave. Envíala sobre todo en las operaciones que mueven dinero:

Endpoint Operación
POST /v1/shipments/:id/label Compra de guía
POST /v1/shipments/:id/label/void Cancelación de guía
POST /v1/wallet/fund/card Fondeo con tarjeta
POST /v1/wallet/fund/paypal Fondeo con PayPal
POST /v1/shipments con purchase Compra en una llamada — reproduce la creación y la compra como una sola unidad

En los fondeos, la llave además garantiza que los reintentos reutilicen el mismo intento de pago. Nunca hay dos cobros a tu tarjeta.

Tu saldo queda protegido aunque no mandes llave. El monedero deduplica cada movimiento del lado del servidor, así que reintentar una compra o un fondeo interrumpido jamás genera un cargo doble. La llave agrega la reproducción del resultado original, con el mismo estado y el mismo cuerpo. Por eso la recomendamos en todo flujo de dinero.

Rastreadores: POST /v1/trackers no usa idempotencia y no la necesita. Registrar el mismo número dos veces devuelve el rastreador existente, sin cobro doble.

Conflictos

Código Cuándo Cómo resolverlo
409 IDEMPOTENCY_KEY_REUSED Reusaste una llave con otro cuerpo u otro endpoint Genera una llave nueva para cada operación distinta
409 IDEMPOTENCY_KEY_IN_USE Una petición concurrente con la misma llave sigue en vuelo Espera un momento y reintenta con la misma llave

Patrón recomendado

Genera la llave antes de la primera petición y guárdala junto a tu operación de negocio, como la orden o el pedido. Así cualquier reintento usa la misma llave, sea inmediato o después de reiniciar tu proceso:

// Al crear tu orden interna, genera y guarda la llave
const idempotencyKey = crypto.randomUUID();
await db.orders.update(orderId, { senditIdempotencyKey: idempotencyKey });

// Cualquier reintento reutiliza la misma llave
const res = await fetch(`https://api.sendit.mx/v1/shipments/${shipmentId}/label`, {
  method: "POST",
  headers: {
    "X-API-Key": process.env.SENDIT_API_KEY,
    "Idempotency-Key": idempotencyKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ rateId }),
});

¿Te ha resultado útil esta página?