Idempotentność

POST /v1/invoices wymaga nagłówka Idempotency-Key. Dzięki niemu ponawianie wysyłki faktury jest bezpieczne i nie tworzy zduplikowanych wysyłek.

Idempotency-Key

Nagłówek Idempotency-Key jest wymagany przy każdym żądaniu POST /v1/invoices.

Wymagany nagłówek
Idempotency-Key: inv-submit-sandbox-fv-0001

Ponownie używasz tego samego klucza tylko wtedy, gdy ponawiasz to samo żądanie wysyłki faktury.

Porównywanie żądań

API sprawdza, czy żądanie wysłane ponownie z tym samym kluczem idempotentności ma taką samą treść jak żądanie pierwotne. Porównywane są:

  • znormalizowane external_id,
  • zdekodowane surowe invoice_xml,
  • posortowane metadane zawierające wyłącznie ciągi znaków,
  • w trybie testowym również znormalizowanego scenariusza sandboxa.

Brak nagłówka Ksef-Sandbox-Scenario oraz jawne accepted to semantycznie to samo żądanie sandboxa.

Powtórzenie

Powtórzenie tego samego Idempotency-Key z tym samym żądaniem zwraca dokładnie ten sam zapisany status HTTP i treść odpowiedzi.

Jeśli pierwotna udana wysyłka zwróciła 201 Created, powtórzenie również zwróci 201 Created.

Powtórzenie zwraca zapisaną odpowiedź POST
{  "id": "inv_2kCYq4m4G7YbUjvH0kC1dg",  "object": "invoice",  "mode": "test",  "status": "processing",  "organization_id": "org_2kCYq4m4G7YbUjvH0kC1dg",  "external_id": "fv-2026-0001",  "created_at": "2026-05-31T10:15:30Z",  "updated_at": "2026-05-31T10:15:30Z",  "ksef_number": null,  "upo_available": false,  "retrying": false,  "next_retry_at": null,  "last_error": null,  "metadata": {    "order_id": "ord_123"  }}

Konflikt

Ponowne użycie tego samego Idempotency-Key z innym żądaniem zwraca idempotency_conflict.

idempotency_conflict
{  "error": {    "type": "conflict_error",    "code": "idempotency_conflict",    "message": "The same idempotency key was used with a different request.",    "param": "Idempotency-Key",    "request_id": "req_0Y9a6cW9xQz9xwWzYxA0fY",    "retryable": false  }}

Żądanie w toku

Jeśli ten sam klucz jest wciąż przetwarzany, API może zwrócić idempotency_request_in_progress.

idempotency_request_in_progress
{  "error": {    "type": "conflict_error",    "code": "idempotency_request_in_progress",    "message": "The same idempotency key is already being processed.",    "param": "Idempotency-Key",    "request_id": "req_0Y9a6cW9xQz9xwWzYxA0fY",    "retryable": true  }}

Poprzednia próba w trybie live nie powiodła się

Jeśli poprzednia próba w trybie live nie powiodła się przed wysyłką do KSeF, wyślij to samo żądanie ponownie z nowym Idempotency-Key.

idempotency_previous_attempt_failed
{  "error": {    "type": "conflict_error",    "code": "idempotency_previous_attempt_failed",    "message": "The previous live submission attempt failed before KSeF submission. Submit the same request again with a new Idempotency-Key.",    "param": "Idempotency-Key",    "request_id": "req_0Y9a6cW9xQz9xwWzYxA0fY",    "retryable": false  }}

Wymagane uzgodnienie

Jeśli wynik poprzedniej wysyłki live jest niejednoznaczny, API zwraca idempotency_reconciliation_required. Nie ponawiaj automatycznie tego samego klucza.

idempotency_reconciliation_required
{  "error": {    "type": "conflict_error",    "code": "idempotency_reconciliation_required",    "message": "The previous live submission outcome is not safe to retry automatically. Operator reconciliation is required before using this idempotency key again.",    "param": "Idempotency-Key",    "request_id": "req_0Y9a6cW9xQz9xwWzYxA0fY",    "retryable": false  }}

Żądania odczytu

Operacje odczytu nie wymagają nagłówka Idempotency-Key:

  • GET /v1/invoices/{id}
  • GET /v1/invoices/{id}/upo