Solicitudes idempotentes
Fiscalapi admite idempotencia para que reintentes una solicitud sin riesgo de ejecutar dos veces la misma operación. Si pierdes la respuesta por un error de red o un tiempo de espera, repite la solicitud con la misma llave de idempotencia: Fiscalapi no vuelve a timbrar ni a cobrar y te devuelve la respuesta original.
Cómo funciona
Para hacer una solicitud idempotente, envía en el encabezado Idempotency-Key una llave de idempotencia única que generes tú. Te recomendamos un UUID v4 o cualquier texto aleatorio con suficiente entropía para evitar colisiones. La llave de idempotencia admite de 1 a 64 caracteres ASCII visibles, sin espacios, y no debe contener datos personales como correos o RFC.
Fiscalapi guarda el código de estado y el cuerpo de la primera solicitud con esa llave de idempotencia en cuanto el endpoint empieza a ejecutarse, incluidos los errores 500. Cada reintento con la misma llave de idempotencia recibe esa respuesta tal cual, con el encabezado Idempotent-Replayed en true, y la operación no se repite. El traceIdentifier de una respuesta repetida es el de la ejecución original.
Cada llave de idempotencia pertenece a la persona autenticada en tu cuenta: la misma llave de idempotencia enviada por otra persona es otra operación. Una solicitud con llave de idempotencia termina de ejecutarse aunque tu cliente cierre la conexión, así que el reintento siempre recibe el resultado real.
Qué se compara en un reintento
Fiscalapi compara cada reintento con la solicitud original: el método, la ruta, los parámetros de consulta, el encabezado X-TIME-ZONE y el cuerpo exacto. Si algo cambia, la solicitud se rechaza para evitar que la misma llave de idempotencia se use por error en otra operación. Envía el reintento con los mismos bytes que la solicitud original.
Cuándo no se guarda el resultado
Si la solicitud no pasa la validación antes de ejecutarse, por ejemplo por un campo obligatorio vacío o un JSON mal formado, Fiscalapi responde 400 con sus fallas de validación y no guarda el resultado: corrige la solicitud y reintenta con la misma llave de idempotencia. Tampoco se guarda nada mientras otra solicitud con la misma llave de idempotencia sigue en proceso.
Cualquier otra respuesta queda guardada, incluido un 403 por saldo insuficiente o un 500. Para volver a intentar la operación después de resolver la causa, usa una llave de idempotencia nueva. Si la respuesta guardada es un 500, consulta primero el recurso para confirmar si la operación ocurrió.
Expiración
Las llaves de idempotencia expiran 24 horas después de la primera solicitud. A partir de ese momento, la misma llave de idempotencia se acepta como nueva y la operación se ejecuta otra vez.
Endpoints que la admiten
| Endpoint | Operación |
|---|---|
POST /api/v4/invoices | Crear factura de cualquier tipo, por valores o por referencias |
POST /api/v4/stamps | Transferir o retirar timbres |
POST /api/v4/tickets | Crear ticket |
Los demás endpoints ignoran el encabezado.
Errores
| Estado | Cuándo ocurre | Mensaje |
|---|---|---|
| 400 | La llave de idempotencia está vacía, pasa de 64 caracteres o tiene espacios o caracteres fuera de ASCII. | El encabezado Idempotency-Key debe tener de 1 a 64 caracteres ASCII visibles, sin espacios. |
| 409 | Otra solicitud con la misma llave de idempotencia sigue en proceso. Reintenta después de los segundos que indica el encabezado Retry-After. | Otra petición con esta Idempotency-Key sigue en proceso. Reintenta en unos segundos; si continúa, consulta el recurso y usa una Idempotency-Key nueva. |
| 413 | El cuerpo de la solicitud excede el tamaño máximo. | El cuerpo de la petición excede el tamaño máximo permitido. |
| 422 | La llave de idempotencia ya se usó con otra solicitud. | Esta Idempotency-Key ya se usó con otra petición. Usa una Idempotency-Key nueva para cada operación distinta. |
Ejemplo
Genera la llave de idempotencia una sola vez por operación y guárdala junto a la factura que estás emitiendo. Si la solicitud falla por red o por tiempo de espera, repítela con la misma llave de idempotencia y el mismo cuerpo. En los SDK, la factura se arma igual que en Crear factura y la llave de idempotencia es un argumento opcional.
Request
curl --location 'https://test.fiscalapi.com/api/v4/invoices' \
--header 'X-TENANT-KEY: <tenant_key>' \
--header 'X-API-KEY: <api_key>' \
--header 'X-TIME-ZONE: America/Mexico_City' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000' \
--data-raw '{ ... }'
Para transferir timbres con llave de idempotencia, pásala como segundo argumento al método de transferencia de cada SDK:
| SDK | Método |
|---|---|
| .NET | Stamps.TransferStamps(request, idempotencyKey) |
| Python | stamps.transfer_stamps(request, idempotency_key=...) |
| Node.js | stamps.transferStamps(request, idempotencyKey) |
| Java | getStampService().transferStamps(request, idempotencyKey) |
| PHP | getStampService()->transferStamps($data, $idempotencyKey) |