Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions website/docs/getting-started/errors.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 7
sidebar_position: 8
---

import Tabs from '@theme/Tabs';
Expand Down Expand Up @@ -196,7 +196,7 @@ Esta lista es la referencia documentada de códigos raíz públicos de la API. P

| Código | Descripción |
| --- | --- |
| `idempotency_key_in_use` | La idempotency key ya está siendo usada. |
| `idempotency_key_in_use` | La `idempotency_key` está siendo procesada por otra solicitud o ya está asociada a un recurso. La API responde con HTTP `409` y no reproduce la respuesta original. Consulta [Idempotencia](/docs/getting-started/idempotency). |
| `rate_limit_exceeded` | Se excedió el límite de solicitudes. |
| `date_range_too_large` | El rango de fechas excede el límite permitido. |
| `image_file_required` | Se requiere un archivo de imagen. |
Expand Down
53 changes: 53 additions & 0 deletions website/docs/getting-started/idempotency.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
sidebar_position: 7
---

# Idempotencia

Los endpoints que aceptan `idempotency_key` usan este valor para evitar que una solicitud repetida o concurrente cree más de un recurso. La clave es opcional, puede tener hasta 100 caracteres y debe representar una sola operación lógica.

Genera la clave antes de enviar la solicitud y conserva el mismo valor para todos los reintentos de esa operación. Si reintentas con una clave nueva, Facturapi interpreta la solicitud como una operación distinta y podría crear un duplicado.

## Alcance de la clave

La unicidad de `idempotency_key` se evalúa por:

- organización;
- ambiente de API (`test` o `live`); y
- tipo de recurso, por ejemplo factura, recibo o retención.

Por lo tanto, una misma clave puede existir en organizaciones, ambientes o tipos de recurso diferentes. Una cadena vacía se ignora.

## Solicitudes concurrentes y repetidas

Facturapi impide que dos solicitudes con la misma clave creen el mismo recurso. Si otra solicitud está procesando esa clave, o si la clave ya está asociada a un recurso, la API responde con HTTP `409` y el código `idempotency_key_in_use`:

```json
{
"ok": false,
"message": "La clave de idempotencia (idempotency_key) ya está siendo usada.",
"status": 409,
"code": "idempotency_key_in_use"
}
```

La API no reproduce la respuesta de la primera solicitud. Un conflicto tampoco confirma que esa solicitud haya fallado: puede seguir procesándose o haber creado el recurso.

## Expiración después de un timeout

Un timeout del cliente no cancela la solicitud en Facturapi. La operación puede continuar procesándose aunque tu integración ya no esté esperando la respuesta.

Cuando Facturapi reserva temporalmente una clave durante la creación del recurso, libera la reserva en cuanto termina la solicitud. Si el procesamiento se interrumpe antes de poder liberarla, la reserva expira **10 minutos después de haberse creado**.

Al terminar ese periodo, Facturapi vuelve a comprobar la clave antes de aceptar un reintento:

- si no se creó ningún recurso, la misma clave puede volver a usarse; y
- si la solicitud original sí creó el recurso, la clave permanece asociada a éste y el reintento continúa respondiendo con `idempotency_key_in_use`.

Los 10 minutos corresponden únicamente a la reserva temporal de una solicitud interrumpida. No son el tiempo de expiración de una clave que ya está asociada a un recurso ni garantizan que la solicitud original haya fallado.

## Reintentos seguros

Si pierdes la respuesta por un timeout o un error de red, reintenta con la misma `idempotency_key`. Si recibes `idempotency_key_in_use`, verifica el resultado de la operación original antes de volver a intentarla o de generar otra clave.

Cuando una solicitud termina con error sin crear el recurso, la misma clave puede volver a usarse después de que la solicitud anterior haya terminado.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 7
sidebar_position: 8
---

import Tabs from '@theme/Tabs';
Expand Down Expand Up @@ -196,7 +196,7 @@ This list is the documented reference for public root API codes. We may add new

| Code | Description |
| --- | --- |
| `idempotency_key_in_use` | The idempotency key is already being used by another request. |
| `idempotency_key_in_use` | The `idempotency_key` is being processed by another request or is already associated with a resource. The API responds with HTTP `409` and does not replay the original response. See [Idempotency](/docs/getting-started/idempotency). |
| `rate_limit_exceeded` | The request exceeded the allowed rate limit. |
| `date_range_too_large` | The requested date range exceeds the allowed limit. |
| `image_file_required` | An image file is required. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
sidebar_position: 7
---

# Idempotency

Endpoints that accept `idempotency_key` use this value to prevent a repeated or concurrent request from creating more than one resource. The key is optional, can contain up to 100 characters, and must represent a single logical operation.

Generate the key before sending the request and keep the same value for every retry of that operation. If you retry with a new key, Facturapi treats the request as a different operation and may create a duplicate.

## Key scope

The uniqueness of `idempotency_key` is evaluated by:

- organization;
- API environment (`test` or `live`); and
- resource type, such as invoice, receipt, or retention.

The same key may therefore exist in different organizations, environments, or resource types. An empty string is ignored.

## Concurrent and repeated requests

Facturapi prevents two requests with the same key from creating the same resource. If another request is processing that key, or if the key is already associated with a resource, the API responds with HTTP `409` and the `idempotency_key_in_use` code:

```json
{
"ok": false,
"message": "The idempotency key is already being used by another request.",
"status": 409,
"code": "idempotency_key_in_use"
}
```

The API does not replay the first request's response. A conflict also does not confirm that the first request failed: it may still be processing or may have created the resource.

## Expiration after a timeout

A client-side timeout does not cancel the request in Facturapi. The operation may continue processing even after your integration stops waiting for the response.

When Facturapi temporarily reserves a key while creating the resource, it releases the reservation as soon as the request finishes. If processing is interrupted before the reservation can be released, it expires **10 minutes after it was created**.

After that period, Facturapi checks the key again before accepting a retry:

- if no resource was created, the same key can be used again; and
- if the original request did create the resource, the key remains associated with it and the retry continues to return `idempotency_key_in_use`.

The 10-minute period applies only to the temporary reservation left by an interrupted request. It is not an expiration time for a key already associated with a resource, and it does not guarantee that the original request failed.

## Safe retries

If you lose the response because of a timeout or network error, retry with the same `idempotency_key`. If you receive `idempotency_key_in_use`, reconcile the original operation's outcome before retrying again or generating another key.

When a request ends with an error without creating the resource, the same key can be used again after the previous request has finished.
56 changes: 39 additions & 17 deletions website/openapi_v2.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3542,6 +3542,8 @@ paths:
$ref: "#/components/responses/Unauthenticated"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/IdempotencyKeyInUse"
"429":
$ref: "#/components/responses/RateLimited"
"500":
Expand Down Expand Up @@ -5820,6 +5822,8 @@ paths:
$ref: "#/components/responses/Unauthenticated"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/IdempotencyKeyInUse"
"429":
$ref: "#/components/responses/RateLimited"
"500":
Expand Down Expand Up @@ -7246,6 +7250,8 @@ paths:
$ref: "#/components/responses/Unauthenticated"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/IdempotencyKeyInUse"
"429":
$ref: "#/components/responses/RateLimited"
"500":
Expand Down Expand Up @@ -12581,6 +12587,17 @@ components:
application/json:
schema:
$ref: "#/components/schemas/GenericError"
IdempotencyKeyInUse:
description: The `idempotency_key` is being processed by another request or is already associated with a resource. Facturapi does not replay the original response.
content:
application/json:
schema:
$ref: "#/components/schemas/GenericError"
example:
message: The idempotency key is already being used by another request.
status: 409
ok: false
code: idempotency_key_in_use
NotFound:
description: Resource not found
content:
Expand Down Expand Up @@ -17665,7 +17682,8 @@ components:
description: Identifier that you can use to relate this invoice to your records to later search by this number.
idempotency_key:
type: string
description: Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.
maxLength: 100
description: Key that identifies one operation to prevent duplicate resources. See [Idempotency](/docs/getting-started/idempotency).
payment_form:
type: [string, "null"]
description: Payment form code according to the [Payment Form catalog](#payment-form).
Expand Down Expand Up @@ -18122,10 +18140,11 @@ components:
Optional identifier that you can use to relate this invoice to your records and later search by this number. Facturapi does not validate that this field is unique.
idempotency_key:
type: string
maxLength: 100
description: |
Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.

If left blank, it will not be taken into account.
Key that identifies one operation to prevent duplicate resources from repeated or concurrent requests. It must be unique within the same organization, environment, and resource type.
If another request is processing the key or it is already associated with a resource, the API responds with HTTP `409` and `code: idempotency_key_in_use`; it does not replay the original response.
An empty value is ignored. See [Idempotency](/docs/getting-started/idempotency).
- $ref: "#/components/schemas/InvoiceableCommonInput"
InvoiceCommonEditInput:
allOf:
Expand Down Expand Up @@ -18164,10 +18183,11 @@ components:
Optional identifier that you can use to relate this invoice to your records and later search by this number. Facturapi does not validate that this field is unique.
idempotency_key:
type: string
maxLength: 100
description: |
Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.

If left blank, it will not be taken into account.
Key that identifies one operation to prevent duplicate resources from repeated or concurrent requests. It must be unique within the same organization, environment, and resource type.
If another request is processing the key or it is already associated with a resource, the API responds with HTTP `409` and `code: idempotency_key_in_use`; it does not replay the original response.
An empty value is ignored. See [Idempotency](/docs/getting-started/idempotency).
- $ref: "#/components/schemas/InvoiceableCommonEditInput"
InvoiceDraftCommonInput:
allOf:
Expand Down Expand Up @@ -19018,10 +19038,9 @@ components:
Optional identifier that you can use to relate this receipt to your records and later search by this number. Facturapi does not validate that this field is unique.
idempotency_key:
type: string
maxLength: 100
description: |
Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.

If left blank, it will not be taken into account.
Key that identifies one operation to prevent duplicate resources. See [Idempotency](/docs/getting-started/idempotency).
- $ref: "#/components/schemas/ReceiptCommonProperties"
ReceiptInput:
allOf:
Expand Down Expand Up @@ -19065,10 +19084,11 @@ components:
properties:
idempotency_key:
type: string
maxLength: 100
description: |
Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.

If left blank, it will not be taken into account.
Key that identifies one operation to prevent duplicate resources from repeated or concurrent requests. It must be unique within the same organization, environment, and resource type.
If another request is processing the key or it is already associated with a resource, the API responds with HTTP `409` and `code: idempotency_key_in_use`; it does not replay the original response.
An empty value is ignored. See [Idempotency](/docs/getting-started/idempotency).
ReceiptCommonProperties:
type: object
properties:
Expand Down Expand Up @@ -19562,10 +19582,10 @@ components:
Optional identifier that you can use to relate this retention to your records and later search by this number. Facturapi does not validate that this field is unique.
idempotency_key:
type: [string, 'null']
maxLength: 100
description: |
Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.

If left blank, it will not be taken into account.
Key that identifies one operation to prevent duplicate resources. An empty value is ignored.
See [Idempotency](/docs/getting-started/idempotency).
complements:
type: array
default: []
Expand Down Expand Up @@ -19778,8 +19798,10 @@ components:
Optional identifier that you can use to relate this retention to your records and later search by this number. Facturapi does not validate that this field is unique.
idempotency_key:
type: string
maxLength: 100
description: |
Unique identifier that you can use to avoid duplicates when retrying a request. It can be any text string, as long as it is unique for each document.
Key that identifies one operation to prevent duplicate resources from repeated or concurrent requests. It must be unique within the same organization, environment, and resource type.
If another request is processing the key or it is already associated with a resource, the API responds with HTTP `409` and `code: idempotency_key_in_use`; it does not replay the original response. See [Idempotency](/docs/getting-started/idempotency).
complements:
type: array
default: []
Expand Down
Loading
Loading