Kontrahenci
Kontrahent to nabywca lub odbiorca na Twoich dokumentach. API udostępnia pełny CRUD pod /clients, a przy tworzeniu dokumentów możesz wskazać kontrahenta po id zamiast przesyłać jego dane za każdym razem.
Wymagane zakresy uprawnień: clients:browse, clients:read, clients:create, clients:update, clients:delete (osobno dla każdej operacji).
Lista kontrahentów
curl -s "https://prod.api.fakturnia.pl/external/v1/clients?searchQuery=Kowalski¤tPage=1&itemsPerPage=20" \
-H "Authorization: Bearer $TOKEN"
searchQuery filtruje po nazwie. Lista jest paginowana: odpowiedź zawiera totalCount i totalPages.
Tworzenie kontrahenta
Kontrahent jest firmą (type: "company") albo osobą (type: "person"). Firma wymaga name, osoba wymaga firstName i lastName.
curl -s -X POST https://prod.api.fakturnia.pl/external/v1/clients \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "company",
"name": "Przykład Sp. z o.o.",
"identifierType": "nip",
"nip": "5252248481",
"street": "ul. Prosta 1",
"postalCode": "00-001",
"city": "Warszawa",
"countryCode": "PL",
"email": "biuro@przyklad.pl"
}'
Pole identifierType mówi, którym identyfikatorem kontrahent jest wskazany w KSeF; zasady opisuje sekcja Identyfikatory kontrahenta.
Pozostałe pola są opcjonalne: regon, krs, bdo, pesel, idNumber, dane adresowe (street, postalCode, city, country, countryCode), kontaktowe (phoneNumber, email, emailAddresses, www, fax) oraz description.
Dane polskiej firmy możesz pobrać automatycznie z GUS przez wyszukiwanie po NIP, zamiast przepisywać je ręcznie.
Identyfikatory kontrahenta
Faktura w KSeF wskazuje nabywcę (i odbiorcę) dokładnie jednym identyfikatorem. identifierType wybiera, którym, a API sprawdza i zapisuje go w postaci, którą przyjmie KSeF. Te same zasady obowiązują kontrahentów (POST i PUT /clients) oraz nabywcę i odbiorcę podanych danymi przy tworzeniu dokumentów (POST /documents, POST /documents/validate, PUT i PATCH /documents/{id}).
identifierType |
Kontrahent | Wymagane pola | Przykład | W KSeF |
|---|---|---|---|---|
nip |
polska firma | nip |
"nip": "5261040828" |
NIP |
vatEu |
firma z innego kraju UE | vatUE z prefiksem kraju |
kontrahent z Niemiec: "identifierType": "vatEu", "vatUE": "DE123456789" |
KodUE + NrVatUE |
other |
firma spoza UE albo z UE bez numeru VAT UE | countryCode, otherTaxIdentifier |
"countryCode": "US", "otherTaxIdentifier": "12-3456789" |
KodKraju + NrID |
idWew |
jednostka wewnętrzna, tylko jako odbiorca dokumentu | idWew |
"idWew": "5252248481-16006" |
IDWew |
none |
osoba prywatna albo brak identyfikatora | brak | "type": "person" |
BrakID |
Jak API zapisuje identyfikatory:
- NIP to 10 cyfr: spacje, myślniki i prefiks
PLsą usuwane (PL 526-104-08-28zapisuje się jako5261040828), a cyfra kontrolna musi się zgadzać. - Numer VAT UE jest zapisywany w
vatUEz prefiksem kraju, wielkimi literami i bez spacji (de 123 456 789toDE123456789). Numer bez prefiksu dostaje prefiks zcountryCode. Grecja ma w numerach VAT prefiksEL(podanyGRzamieniamy naEL), acountryCodepozostajeGR. Po prefiksie dozwolone są cyfry, wielkie litery,+i*, od 1 do 12 znaków. Polenipnigdy nie przechowuje zagranicznego numeru. - Polska firma z numerem VAT UE (np. do faktur WDT) ma
identifierType: "nip", NIP wnipiPLz tym samym NIP-em wvatUE. - Irlandia Północna (
XI) nie jest krajem UE w KSeF: podaj ją jakootherzcountryCode: "XI". otherwymaga kraju (countryCode, kod ISO, np.US,CH,GB,UA) i identyfikatora do 50 znaków; identyfikator zostaje zapisany tak, jak go podasz.idWewma postaćNIP-NNNNNi przysługuje tylko odbiorcy: nabywca zidWewdostaje błąd.
Gdy nie podasz identifierType
API ustala typ z danych, a każde ustalenie zwraca w data.warnings, żeby integracja mogła zacząć wysyłać typ jawnie:
| Dane | Ustalony typ | Co zapisuje API |
|---|---|---|
nip z polskim NIP-em (10 cyfr, także z PL, spacjami albo myślnikami) |
nip |
NIP jako 10 cyfr |
nip z numerem VAT UE kraju UE, np. DE123456789 |
vatEu |
numer w vatUE, pusty nip, countryCode z prefiksu, gdy brak |
nip z numerem bez prefiksu i countryCode kraju UE innego niż Polska, np. 123456789 i DE |
vatEu |
vatUE = DE123456789 |
vatUE przy countryCode kraju UE innego niż Polska, albo sam vatUE z prefiksem kraju UE |
vatEu |
numer w vatUE |
sam vatUE z prefiksem PL |
nip |
NIP z numeru VAT UE |
nip albo vatUE z numerem kraju spoza UE (np. GB…, XI…) albo nip przy countryCode spoza UE |
other |
numer w otherTaxIdentifier |
sam otherTaxIdentifier |
other |
bez zmian |
sam idWew |
idWew |
bez zmian |
| brak identyfikatora | none |
bez zmian |
Polski NIP z błędną cyfrą kontrolną jest odrzucany także wtedy, gdy typ został ustalony.
Ostrzeżenia w odpowiedzi
POST i PUT /clients zwracają data.warnings obok data.client, a dokumenty obok data.document (przy validate obok data.preview). Lista jest pusta, gdy identyfikatory podano jawnie i poprawnie.
{
"success": true,
"data": {
"client": { "identifierType": "vatEu", "nip": null, "vatUE": "DE123456789", "countryCode": "DE" },
"warnings": [
{ "code": "IDENTIFIER_TYPE_INFERRED", "field": "identifierType", "message": "Nie podano identifierType: przyjęto vatEu (numer VAT UE). Podawaj identifierType jawnie." },
{ "code": "IDENTIFIER_MOVED", "field": "vatUE", "message": "Numer DE123456789 przeniesiono z pola nip do vatUE: pole nip jest tylko na polski NIP." },
{ "code": "COUNTRY_CODE_INFERRED", "field": "countryCode", "message": "Nie podano countryCode: przyjęto DE z prefiksu numeru VAT UE DE123456789." }
]
}
}
code |
Znaczenie |
|---|---|
IDENTIFIER_TYPE_INFERRED |
nie podano identifierType, API je ustaliło |
IDENTIFIER_MOVED |
numer z niewłaściwego pola przeniesiono do vatUE albo otherTaxIdentifier |
IDENTIFIER_IGNORED |
pole niepasujące do typu pominięto (np. nip przy vatEu) |
COUNTRY_CODE_INFERRED |
countryCode przyjęto z prefiksu numeru |
VAT_UE_PREFIX_NORMALIZED |
grecki prefiks GR zamieniono na EL |
Przy dokumentach field ma prefiks strony, np. buyer.vatUE.
Sprzeczne dane
Sprzeczności API odrzuca z nazwą pola w errors: kontrahenci z kodem 422 VALIDATION_ERROR, dokumenty z kodem 422 PARTY_IDENTIFIER_INVALID (pole z prefiksem buyer. albo receiver.). Przykłady: identifierType: "nip" z numerem DE123456789, vatEu z numerem PL… albo XI…, numer VAT UE bez prefiksu i bez kraju UE, NIP o złej długości albo z błędną cyfrą kontrolną, różne numery VAT UE w nip i vatUE, other bez kraju, idWew u nabywcy, nieznana wartość identifierType.
Kontrahent zapisany wcześniej z danymi, których dziś API by nie przyjęło, pozostaje edytowalny: PUT nie sprawdza ponownie identyfikatorów równych zapisanym. Nabywca podany danymi z takim samym błędnym NIP-em jak zapisany kontrahent jest brany z kartoteki.
Pobieranie, aktualizacja i usuwanie
# Szczegóły
curl -s https://prod.api.fakturnia.pl/external/v1/clients/{id} \
-H "Authorization: Bearer $TOKEN"
# Aktualizacja (PUT, pełne zastąpienie pól)
curl -s -X PUT https://prod.api.fakturnia.pl/external/v1/clients/{id} \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "type": "company", "name": "Przykład Sp. z o.o.", "email": "faktury@przyklad.pl" }'
# Usunięcie
curl -s -X DELETE https://prod.api.fakturnia.pl/external/v1/clients/{id} \
-H "Authorization: Bearer $TOKEN"
PUT działa jak pełna aktualizacja: prześlij komplet pól, które kontrahent ma mieć po zmianie. Usunięcie kontrahenta nie zmienia wystawionych wcześniej dokumentów, dane nabywcy są na nich utrwalone.
Webhooki
Operacje zapisu emitują zdarzenia webhook: client.created, client.updated, client.deleted.