# Idempotencia

> Repetir una petición con la misma Idempotency-Key devuelve la misma respuesta sin volver a emitir; cómo usar external_id y qué hacer tras un reinicio.

Fuente: https://platform.trevol.si/docs/idempotencia

Emitir un documento no se puede hacer «a ciegas dos veces»: duplicaría una factura. Por eso **`Idempotency-Key` es obligatoria** al crear o corregir un documento.

> **Evita los duplicados tras un reinicio:** La clave automática de un SDK protege los reintentos **de una misma llamada**. Si tu proceso muere y vuelves a llamar, el SDK genera otra clave y podrías duplicar el documento. **Manda siempre un `external_id` tuyo y una `idempotencyKey` derivada de tu venta** (por ejemplo `VENTA-2026-000123`). Si la API responde `external_id_in_use` o `duplicate_document`, usa `error.problem.existing_id` para seguir con el documento que ya existe.

## Cómo funciona

- Manda un UUID nuevo (o una clave derivada de tu venta, de 1 a 255 caracteres ASCII visibles) por cada documento.
- Repetir la **misma clave con el mismo cuerpo** (durante 7 días) devuelve la misma respuesta, con `Idempotent-Replayed: true`, sin volver a emitir.
- La misma clave con **otro cuerpo** es [`idempotency_key_reused`](/docs/errores#idempotency_key_reused): nunca te devolvemos otro documento en silencio.
- Si la primera petición no terminó (402, 503, o el 202 `processing`), el reintento con la misma clave sigue con el **mismo** documento y el mismo número. En la versión 2026-10-22, el reintento sobre un documento que Trevol está resolviendo no envía nada: responde otro 202 con el estado actual (o el 201 si ya se validó).
- Mientras la primera petición sigue en curso, la segunda recibe [`request_in_progress`](/docs/errores#request_in_progress) (409): consulta su estado en unos segundos.

## `external_id`

Tu identificador del documento, opcional. Repetido es [`external_id_in_use`](/docs/errores#external_id_in_use) con el `existing_id` del que ya existe. Es la forma de que dos procesos distintos no emitan lo mismo.

## En los SDK

Los SDK generan la `Idempotency-Key` si no la pasas y la repiten en todos los reintentos. Para controlarla, pásala tú:

`POST /v1/invoices` (`createInvoice`)

#### cURL

```bash
curl -X POST "https://api.trevol.si/v1/invoices" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "external_id": "VENTA-2026-000123",
  "customer": {
    "document_type": "31",
    "document_number": "900123456",
    "name": "COMERCIALIZADORA ANDINA SAS",
    "person_type": "legal",
    "email": "facturacion@comercializadoraandina.example",
    "address": "Calle 72 # 10-34, Oficina 501",
    "municipality_code": "11001"
  },
  "items": [
    {
      "code": "LIC-ANUAL",
      "description": "Licencia anual de software",
      "quantity": "2",
      "unit_price": "150000",
      "taxes": [
        {
          "code": "01",
          "rate": "19"
        }
      ]
    },
    {
      "code": "SOP-MES",
      "description": "Soporte técnico mensual",
      "quantity": "1",
      "unit_price": "80000",
      "taxes": [
        {
          "code": "01",
          "rate": "19"
        }
      ]
    }
  ],
  "payment": {
    "form": "credit",
    "term_days": 30
  },
  "notes": [
    "Gracias por su compra"
  ]
}'
```

[Probar en el Playground](https://platform.trevol.si/playground?op=createInvoice&ejemplo=venta)

En los fragmentos, el parámetro `idempotencyKey` (o su equivalente en cada lenguaje) viene comentado: descoméntalo con una clave derivada de tu venta. Las operaciones que no la declaran (por ejemplo `POST /v1/webhook_endpoints` o `…/send`) no la reciben.
