Szybka i prosta integracja z KSeF

Wysyłasz prosty JSON, a KSeF API przejmuje walidację, generowanie XML, wysyłkę i statusy faktur w środowisku testowym, demo i produkcyjnym.

Kontakt: [email protected]

Domena API

test.ksefapi.dev, demo.ksefapi.dev, real.ksefapi.dev

Środowiska testowe, demo i produkcyjne.

Autoryzacja

Bearer Token

Nagłówek: Authorization: Bearer KSEF_API_TOKEN (token przypisany do danej domeny API).

Format danych

application/json

Wszystkie requesty i odpowiedzi w JSON.

Szybki start

  1. 1. Wybierz domenę API (na start zwykle test.ksefapi.dev lub demo.ksefapi.dev, do produkcji real.ksefapi.dev).
  2. 2. Zarejestruj firmę przez POST /api/company (do rejestracji możesz użyć dowolnej domeny API).
  3. 3. Potwierdź rejestrację tokenem przez POST /api/company/confirm i odbierz ksef_api_tokens dla środowisk test, demo, real.
  4. 4. Wygeneruj token w systemie KSeF i podaj go przez PATCH /api/ksef_auth_tokens, autoryzując się tokenem API dla wybranej domeny.
  5. 5. Wyślij fakturę przez POST /api/invoices.
  6. 6. Sprawdź status przez GET /api/invoices/:process_id.

Domeny KSeF API

API rozpoznaje środowisko po domenie i przekazuje żądania do odpowiedniego środowiska KSeF.

Autentykacja

Chronione endpointy wymagają nagłówka Bearer Token.

Authorization: Bearer KSEF_API_TOKEN

Używaj tokenu API dopasowanego do domeny: test.ksefapi.dev -> ksef_api_tokens.test, demo.ksefapi.dev -> ksef_api_tokens.demo, real.ksefapi.dev -> ksef_api_tokens.real.

Uwaga: przed potwierdzeniem firmy endpointy wymagające tokenu zwrócą błąd.

Bezpieczeństwo tokenów

Tokeny ksef_auth_token i ksef_api_tokens.* są szyfrowane w bazie danych (encryption at rest).

W bazie nie jest przechowywana jawna wartość tokenów - odczyt wymaga kluczy aplikacji.

Rate limiting

Limity obowiązują per adres IP i resetują się co 3 minuty.

Proces rejestracji firmy

Limit: 10 requestów / 3 min.

  • POST /api/company
  • POST /api/company/confirm
  • GET /api/company
  • PATCH /api/company
  • PATCH /api/ksef_auth_tokens

Wystawianie i status faktur

Limit: 90 requestów / 3 min.

  • POST /api/invoices
  • GET /api/invoices/:process_id

Endpointy

POST /api/company

Rejestracja firmy (np. w domenie real.ksefapi.dev dla produkcji).

Parametry (JSON)

{
  "company": {
    "name": "Firma Sp. z o.o.",
    "tax_id": "1234567890",
    "street": "ul. Przykładowa 10",
    "postal_code": "00-001",
    "city": "Warszawa",
    "email": "[email protected]"
  }
}

cURL

curl -X POST "https://test.ksefapi.dev/api/company" \
  -H "Content-Type: application/json" \
  -d '{
    "company": {
      "name": "Firma Sp. z o.o.",
      "tax_id": "1234567890",
      "street": "ul. Przykładowa 10",
      "postal_code": "00-001",
      "city": "Warszawa",
      "email": "[email protected]"
    }
  }'

Możliwe odpowiedzi

201 Created

{
  "message": "Company created, check your email for confirmation token"
}

422 Unprocessable Entity

{
  "message": "Company validation error",
  "errors": ["Tax id is invalid", "Email is invalid"]
}
POST /api/company/confirm

Potwierdzenie rejestracji firmy i wygenerowanie tokenów API dla środowisk test/demo/real.

Token confirmation_token jest ważny 5 minut od momentu wysłania.

Wartości ksef_api_tokens są szyfrowane w bazie danych.

Parametry (JSON)

{
  "confirmation_token": "CONFIRMATION_TOKEN"
}

cURL

curl -X POST "https://test.ksefapi.dev/api/company/confirm" \
  -H "Content-Type: application/json" \
  -d '{
    "confirmation_token": "CONFIRMATION_TOKEN"
  }'

Możliwe odpowiedzi

200 OK

{
  "message": "Company confirmed",
  "ksef_api_tokens": {
    "test": "KSEF_API_TOKEN_TEST",
    "demo": "KSEF_API_TOKEN_DEMO",
    "real": "KSEF_API_TOKEN_REAL"
  }
}

400 Bad Request

{
  "message": "Confirmation token required"
}

404 Not Found

{
  "message": "Invalid confirmation token"
}

404 Not Found

{
  "message": "Confirmation token expired"
}
GET /api/company

Pobranie danych firmy przypisanej do tokenu API.

cURL

curl -X GET "https://test.ksefapi.dev/api/company" \
  -H "Authorization: Bearer KSEF_API_TOKEN"

Możliwe odpowiedzi

200 OK

{
  "company": {
    "name": "Firma Sp. z o.o.",
    "tax_id": "1234567890",
    "street": "ul. Przykładowa 10",
    "postal_code": "00-001",
    "city": "Warszawa",
    "email": "[email protected]"
  }
}

400 Bad Request

{
  "message": "Company confirmation required"
}

401 Unauthorized

{
  "message": "Invalid token"
}
PATCH /api/company

Aktualizacja danych firmy.

Parametry (JSON)

{
  "company": {
    "name": "Firma Sp. z o.o.",
    "tax_id": "1234567890",
    "street": "ul. Przykładowa 11",
    "postal_code": "00-001",
    "city": "Warszawa",
    "email": "[email protected]"
  }
}

cURL

curl -X PATCH "https://test.ksefapi.dev/api/company" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer KSEF_API_TOKEN" \
  -d '{
    "company": {
      "city": "Warszawa"
    }
  }'

Możliwe odpowiedzi

200 OK

{
  "message": "Company updated"
}

422 Unprocessable Entity

{
  "message": "Company validation error",
  "errors": ["Email is invalid"]
}
PATCH /api/ksef_auth_tokens

Ustawienie lub aktualizacja tokenu autoryzacyjnego KSeF dla firmy.

Wartość ksef_auth_token jest szyfrowana w bazie danych.

Parametry (JSON)

{
  "ksef_auth_token": "KSEF_AUTH_TOKEN"
}

cURL

curl -X PATCH "https://test.ksefapi.dev/api/ksef_auth_tokens" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer KSEF_API_TOKEN" \
  -d '{
    "ksef_auth_token": "KSEF_AUTH_TOKEN"
  }'

Możliwe odpowiedzi

200 OK

{
  "message": "KSeF auth token has been updated"
}

422 Unprocessable Entity

{
  "message": "KSeF auth token cannot be blank"
}
POST /api/invoices

Wysyłka faktury do asynchronicznego przetworzenia w KSeF.

Wszystkie możliwe parametry (JSON)

{
  "invoice": {
    "number": "FV/2026/02/001",
    "issue_date": "2026-02-19",
    "trade_date": "2026-02-19",
    "payment_date": "2026-02-26",
    "unit_price_type": "net",
    "currency": "PLN",
    "paid_amount": "0",
    "vat_free_reason": "Sprzedaż opodatkowana",
    "buyer": {
      "name": "Nabywca Sp. z o.o.",
      "tax_id": "PL1234567890",
      "street": "ul. Kupiecka 5",
      "postal_code": "00-100",
      "city": "Warszawa",
      "country_code": "PL",
      "ksef_jst": false
    },
    "recipient": {
      "name": "Odbiorca Sp. z o.o.",
      "tax_id": "PL0987654321",
      "street": "ul. Odbiorcza 2",
      "postal_code": "30-002",
      "city": "Kraków",
      "country_code": "PL"
    },
    "items": [
      {
        "name": "Usługa A",
        "unit": "szt",
        "amount": "2",
        "unit_price": "100.00",
        "vat_rate": "23"
      }
    ],
    "notes": [
      "Płatność przelewem 7 dni",
      "Dziękujemy za współpracę"
    ]
  }
}

Dozwolone wartości unit_price_type: net, gross.

Dozwolone wartości vat_rate: 23, 22, 8, 7, 5, 4, 3, 0 KR, 0 WDT, 0 EX, zw, oo, np I, np II.

cURL

curl -X POST "https://test.ksefapi.dev/api/invoices" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer KSEF_API_TOKEN" \
  -d '{
    "invoice": {
      "number": "FV/2026/02/001",
      "issue_date": "2026-02-19",
      "trade_date": "2026-02-19",
      "unit_price_type": "net",
      "currency": "PLN",
      "buyer": {
        "name": "Nabywca Sp. z o.o.",
        "tax_id": "PL1234567890",
        "street": "ul. Kupiecka 5",
        "postal_code": "00-100",
        "city": "Warszawa",
        "country_code": "PL"
      },
      "items": [
        {
          "name": "Usługa A",
          "unit": "szt",
          "amount": "2",
          "unit_price": "100.00",
          "vat_rate": "23"
        }
      ]
    }
  }'

Możliwe odpowiedzi

202 Accepted

{
  "message": "Invoice accepted for creation in KSeF",
  "process_id": "PROCESS_ID"
}

400 Bad Request

{
  "message": "JSON validation error",
  "errors": ["invoice.number is missing"]
}

422 Unprocessable Entity

{
  "message": "Invoice validation error",
  "errors": ["Buyer tax id is invalid"]
}
GET /api/invoices/:process_id

Pobranie statusu i szczegółów przetwarzania faktury.

cURL

curl -X GET "https://test.ksefapi.dev/api/invoices/PROCESS_ID" \
  -H "Authorization: Bearer KSEF_API_TOKEN"

Możliwe odpowiedzi

200 OK

{
  "invoice": {
    "number": "FV/2026/02/001",
    "issue_date": "2026-02-19",
    "status": "accepted",
    "status_description": null,
    "ksef_number": "KSEF_NUMBER",
    "upo_url": "https://...",
    "ksef_env": "test",
    "qr_code_url": "..."
  }
}

Dla statusu accepted pole status_description zwykle jest puste (null).

200 OK (status rejected/error)

{
  "invoice": {
    "number": "FV/2026/02/001",
    "issue_date": "2026-02-19",
    "status": "rejected",
    "status_description": "Validation failed: buyer tax id is invalid",
    "ksef_number": null,
    "upo_url": null,
    "ksef_env": "test",
    "qr_code_url": null
  }
}

Dla statusów rejected lub error pole status_description zawiera opis ostatniego błędu z logów przetwarzania.

404 Not Found

{
  "message": "Invoice not found",
  "errors": []
}

Krok po kroku: rejestracja firmy i wysyłka faktury

Krok 1: Rejestracja firmy w domenie produkcyjnej

curl -X POST "https://test.ksefapi.dev/api/company" \
  -H "Content-Type: application/json" \
  -d '{
    "company": {
      "name": "Firma Sp. z o.o.",
      "tax_id": "1234567890",
      "street": "ul. Przykładowa 10",
      "postal_code": "00-001",
      "city": "Warszawa",
      "email": "[email protected]"
    }
  }'

Krok 2: Potwierdzenie firmy i odbiór tokenów API

curl -X POST "https://test.ksefapi.dev/api/company/confirm" \
  -H "Content-Type: application/json" \
  -d '{
    "confirmation_token": "CONFIRMATION_TOKEN"
  }'

Z odpowiedzi wybierz ksef_api_tokens.test dla test.ksefapi.dev (analogicznie demo i real).

Krok 3: Ustawienie tokenu autoryzacyjnego KSeF (dla wybranej domeny)

curl -X PATCH "https://test.ksefapi.dev/api/ksef_auth_tokens" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer KSEF_API_TOKEN" \
  -d '{
    "ksef_auth_token": "KSEF_AUTH_TOKEN"
  }'

Krok 4: Wysyłka faktury i odbiór process_id

curl -X POST "https://test.ksefapi.dev/api/invoices" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer KSEF_API_TOKEN" \
  -d '{
    "invoice": {
      "number": "FV/2026/02/001",
      "issue_date": "2026-02-19",
      "trade_date": "2026-02-19",
      "unit_price_type": "net",
      "currency": "PLN",
      "buyer": {
        "name": "Nabywca Sp. z o.o.",
        "tax_id": "PL1234567890",
        "street": "ul. Kupiecka 5",
        "postal_code": "00-100",
        "city": "Warszawa",
        "country_code": "PL"
      },
      "items": [
        {
          "name": "Usługa A",
          "unit": "szt",
          "amount": "2",
          "unit_price": "100.00",
          "vat_rate": "23"
        }
      ]
    }
  }'

Krok 5: Sprawdzenie statusu faktury

curl -X GET "https://test.ksefapi.dev/api/invoices/PROCESS_ID" \
  -H "Authorization: Bearer KSEF_API_TOKEN"

FAQ KSeF API

Najczęstsze pytania o rejestrację firmy, autoryzację i obsługę faktur przez API.

Czy muszę generować XML faktury samodzielnie?

Nie. Wysyłasz dane faktury jako JSON, a KSeF API odpowiada za walidację i generowanie XML zgodnego z KSeF.

Czy API obsługuje środowiska testowe i produkcyjne?

Tak. Używasz dedykowanych domen: test.ksefapi.dev, demo.ksefapi.dev oraz real.ksefapi.dev.

Od czego zacząć rejestrację firmy w API?

Najpierw wywołujesz POST /api/company i przesyłasz dane firmy, np. nazwę, NIP, adres i email.

Jak potwierdzić rejestrację i odebrać tokeny API?

Wywołujesz POST /api/company/confirm z confirmation_token. W odpowiedzi otrzymujesz ksef_api_tokens z kluczami test, demo i real.

Jak ustawić token autoryzacyjny KSeF w systemie?

Użyj PATCH /api/ksef_auth_tokens i przekaż ksef_auth_token, autoryzując request nagłówkiem Bearer tokenem środowiskowym z ksef_api_tokens.

Jak wygląda autentykacja chronionych endpointów?

Chronione endpointy wymagają nagłówka Authorization: Bearer KSEF_API_TOKEN.

W jakim formacie mam wysyłać dane?

Wszystkie requesty i odpowiedzi są w formacie application/json.

Jakie limity zapytań obowiązują?

Limity są per IP i resetują się co 3 minuty: 10 requestów dla procesu rejestracji firmy oraz 90 requestów dla wystawiania i statusu faktur.

Co dostanę po wysłaniu faktury przez POST /api/invoices?

Przy poprawnym zgłoszeniu otrzymasz 202 Accepted z process_id, który służy do monitorowania dalszego przetwarzania.

Jak monitorować status wysłanej faktury?

Po wysyłce odbierasz process_id i sprawdzasz postęp przez endpoint GET /api/invoices/:process_id.

Co oznacza odpowiedź 404 przy sprawdzaniu statusu?

Odpowiedź 404 Not Found oznacza, że faktura o podanym process_id nie została znaleziona.