Idempotencia, límites y reintentos
Repite escrituras sin duplicar efectos y respeta el límite de solicitudes.
Idempotency-Key
Las escrituras que cambian contactos o conversaciones, o que envían mensajes, exigen la cabecera Idempotency-Key. Con ella, repetir una solicitud no repite su efecto: un mensaje no sale dos veces y un contacto no se crea dos veces.
| Operación | Endpoint | Permiso |
|---|---|---|
| Create a contact | POST /contacts | contacts:write |
| Update a contact | PATCH /contacts/{contact_id} | contacts:write |
| Start a conversation | POST /conversations | messages:send |
| Assign a conversation | PATCH /conversations/{conversation_id}/assignment | conversations:write |
| Close a conversation | POST /conversations/{conversation_id}/close | conversations:write |
| Reopen a conversation | POST /conversations/{conversation_id}/reopen | conversations:write |
| Send a message | POST /conversations/{conversation_id}/messages | messages:send |
Crear o desactivar un webhook y reintentar una entrega no usan esta cabecera.
Reglas
- Genera un valor único por cada escritura lógica, por ejemplo un UUID v4. Debe tener entre 8 y 200 caracteres.
- La clave de idempotencia vale para tu clave de API. Otra clave de API puede usar el mismo valor sin conflicto.
- Ricky compara el método, la ruta y el cuerpo. Repite los tres exactamente iguales al reintentar.
- Sin la cabecera, o con un valor fuera de rango, la respuesta es
400 missing_idempotency_key. - Ricky valida la solicitud antes de leer la cabecera. Un cuerpo inválido o una conversación que no existe reciben su error aunque la cabecera falte.
curl https://getricky.ai/api/v1/contacts \
-H "Authorization: Bearer $RICKY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed" \
-d '{"first_name": "Ana", "last_name": "Pérez", "primary_phone": "+507 6000-1234"}'Qué responde Ricky al repetir una clave
| Primer intento | Repetición con la misma clave y la misma solicitud |
|---|---|
Terminó con 2xx | La misma respuesta y el mismo estado, con la cabecera Idempotency-Replayed: true. No hay efecto nuevo. |
| Sigue en proceso | 409 request_processing con Retry-After: 5. |
Terminó con 4xx | Ricky libera la clave. La repetición se procesa como una solicitud nueva. |
Terminó con 5xx o sin respuesta | 409 request_processing. El efecto puede haber ocurrido o no. |
La misma clave con otro método, otra ruta u otro cuerpo recibe 409 idempotency_conflict.
Estado desconocido
Después de un 5xx, Ricky no sabe si el efecto ocurrió, así que la misma clave sigue respondiendo 409 request_processing. Haz esto:
- Lee el recurso para saber si la escritura ocurrió. Por ejemplo, después de enviar un mensaje, lista los mensajes de la conversación.
- Si ocurrió, no hagas nada más.
- Si no ocurrió, repite la escritura con una
Idempotency-Keynueva.
Una clave nueva siempre crea un efecto nuevo. Úsala solo cuando sepas que el primer intento no ocurrió. Si no puedes saberlo, escribe a soporte con el X-Request-Id.
Límite de solicitudes
Cada clave de API admite 120 solicitudes por minuto. La ventana es el minuto del reloj: se reinicia en el segundo 0 de cada minuto.
Toda respuesta a una clave válida, exitosa o con error, incluye:
| Cabecera | Valor |
|---|---|
X-RateLimit-Limit | Solicitudes por minuto: 120. |
X-RateLimit-Remaining | Solicitudes que quedan en el minuto actual. |
X-RateLimit-Reset | Hora Unix, en segundos, en que se reinicia la ventana. |
Al superar el límite, la respuesta es 429 rate_limited con Retry-After, en segundos, y las mismas cabeceras X-RateLimit-*. Espera ese tiempo antes de enviar otra solicitud con esa clave.
Si tienes que procesar muchos registros, reparte las solicitudes en el tiempo y lee X-RateLimit-Remaining antes de cada lote.
Reintentos
Reintenta solo lo que puede tener éxito sin cambios. Espera más entre cada intento: retroceso exponencial con una variación aleatoria, por ejemplo 1, 2, 4, 8 y 16 segundos, hasta un máximo de 5 intentos. Si la respuesta trae Retry-After, espera al menos ese tiempo.
| Respuesta | Lectura (GET) | Escritura con Idempotency-Key |
|---|---|---|
| Error de red o tiempo de espera agotado | Reintenta. | Reintenta con la misma clave. |
429 rate_limited | Reintenta tras Retry-After. | Reintenta con la misma clave tras Retry-After. |
409 request_processing | No aplica. | Reintenta con la misma clave tras Retry-After. Si persiste, sigue Estado desconocido. |
500, 502 o 503 | Reintenta. | Sigue Estado desconocido. |
Otro 4xx | Corrige la solicitud. | Corrige la solicitud. |