Idempotencia y reintentos
Toda llamada en tiempo real debe llevar un Idempotency-Key. No es una cortesía del límite de tasa — es lo que hace seguro un reintento. Las redes fallan después de que ya se consultó al proveedor; sin una clave, la única forma de saber si una verificación se ejecutó es ejecutarla de nuevo y pagarla dos veces.
La regla
Sección titulada «La regla»Envía un valor que puedas regenerar: un UUID, un ID de pedido o un hash del trabajo que realizas. El servidor lo limita a tu cuenta, así que dos usuarios no pueden colisionar.
| Misma clave | Payload | Resultado |
|---|---|---|
| Clave nueva | cualquiera | Se ejecuta normalmente, se cobra |
| Misma clave | idéntico | Se devuelve la respuesta almacenada; replayed=true. Sin cobro nuevo. |
| Misma clave | diferente | 409 idempotency_conflict — una clave queda ligada al payload que llevó por primera vez |
| Misma clave | idéntico, la primera llamada aún en ejecución | 409 request_in_progress con Retry-After |
Idempotency-Key está limitado a 191 bytes y los registros de reproducción se conservan 30 días por defecto.
replayed no es cached
Sección titulada «replayed no es cached»Se parecen en una respuesta pero significan cosas distintas:
| Campo | Dónde | Significa |
|---|---|---|
replayed | nivel superior | Esta llamada nunca llegó a un proveedor — reproduciste una clave. |
cached | dentro de cada resultado | El veredicto de este producto se sirvió desde la caché de resultados. |
Una llamada reproducida reproduce la respuesta original, incluido el valor cached de cada entrada. Ninguna de las dos marcas cambia lo que se te cobró: una reproducción nunca mueve dinero, y un acierto de caché igual se cobra al precio por verificación del producto.
Solo los resultados liquidados se almacenan como hechos. Los resultados fallidos y unknown no se almacenan en caché — una verificación posterior del mismo identificador contra el mismo producto volverá a preguntar al proveedor en lugar de reproducir una respuesta no concluyente.
Reintentar después de un fallo
Sección titulada «Reintentar después de un fallo»| Lo que viste | Qué hacer |
|---|---|
| Timeout, o HTTP 500 | Reenvía el cuerpo original con la clave original. El resultado es incierto; este es el caso para el que existe la clave. |
409 request_in_progress | Espera Retry-After y luego reenvía el mismo cuerpo con la misma clave. |
409 idempotency_conflict | La clave ya lleva un payload diferente. Genera una clave nueva — no edites el cuerpo y reutilices la anterior. |
429 realtime_rate_limited | Espera Retry-After. No se envió nada, así que la misma clave sigue sin usar y es seguro enviarla. |
503 realtime_route_unavailable | No se envió nada. Reintenta más tarde, con la misma clave. |
Lo único que nunca debes hacer tras un timeout es enviar una clave nueva con el mismo trabajo: si la primera llamada sí llegó, acabas de pagar la verificación dos veces.
Errores que se producen aquí
Sección titulada «Errores que se producen aquí»| HTTP | code |
|---|---|
| 400 | idempotency_key_required — falta el encabezado |
| 409 | request_in_progress — la llamada original aún está en ejecución |
| 409 | idempotency_conflict — la clave se usó por primera vez con un payload diferente |