Si una escritura se corta a medio camino (la red se cae, tu proceso se reinicia), no sabes si watsi la aplicó. El encabezado Idempotency-Key te deja reintentarla sin miedo: si la primera ya se aplicó, el reintento te devuelve su resultado en lugar de escribir otra vez.
curl -X POST "https://api.watsi.ai/v1/actions/contacts/create" \
-H "Authorization: Bearer $WATSI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed" \
-d '{ "name": "María Pérez", "phone_number": "5215598765432" }'Qué rutas lo aceptan
Las escrituras que no son idempotentes por naturaleza. Las lecturas y las escrituras que dejan el mismo estado por más que las repitas (como cambiar el estado de una conversación) lo ignoran, porque ya son seguras de reintentar. Esta lista se genera del contrato:
| Método | Ruta | Alcances | Idempotency-Key |
|---|---|---|---|
POST | /v1/actions/agents/create | agents:write | Sí |
POST | /v1/actions/agents/knowledge | knowledge:write | Sí |
POST | /v1/actions/agents/knowledge/delete | knowledge:write | Sí |
POST | /v1/actions/agents/update | agents:write | Sí |
POST | /v1/actions/attachments/create-upload | agents:write | Sí |
POST | /v1/actions/attachments/finalize | agents:write | Sí |
POST | /v1/actions/attachments/import-url | agents:write | Sí |
POST | /v1/actions/contacts/create | contacts:write | Sí |
POST | /v1/actions/crm/tags | crm:write | Sí |
POST | /v1/actions/crm/tags/remove | crm:write | Sí |
POST | /v1/actions/lifecycle/attach-file | lifecycle:write | Sí |
POST | /v1/actions/voice/config | agents:write | Sí |
Cómo se comporta
| Caso | Respuesta |
|---|---|
| Primera solicitud con una clave | Se ejecuta normal |
| Misma clave, mismo cuerpo, dentro de 30 segundos | 200 con la respuesta guardada de la primera; no escribe nada |
| Misma clave, otro cuerpo, dentro de 30 segundos | 409 IDEMPOTENCY_KEY_REUSED |
| Misma clave pasados los 30 segundos | Se trata como una solicitud nueva |
| La primera solicitud falló | No se guardó nada: el reintento se ejecuta de nuevo |
- La clave vale por espacio de trabajo y por ruta: la misma clave en
contacts/createy encrm/tagsson dos claves distintas. - La comparación del cuerpo es por contenido: el orden de las propiedades del JSON no importa.
- La ventana de 30 segundos está pensada para el reintento inmediato de una solicitud que se cortó, no para deduplicar trabajos de horas. Para eso, guarda tú qué operaciones completaste.
Buenas prácticas
- Una clave por operación lógica, generada antes del primer intento (un UUID v4 sirve) y reusada en cada reintento de esa operación.
- Nunca la misma clave para dos operaciones distintas: el segundo cuerpo recibe
409. - Si recibes
409 IDEMPOTENCY_KEY_REUSED, es un error de tu código (dos operaciones compartieron clave), no algo que se arregle reintentando.
contacts/create además es un upsert: mandar el mismo teléfono, wa_id o correo actualiza el contacto existente en vez de duplicarlo, aun sin Idempotency-Key y fuera de la ventana. La respuesta lo dice con "created": false.