Fakturnia Developers Quickstart API reference Polski

Errors

The API uses standard HTTP status codes and a consistent error envelope. Every error carries a stable, machine-readable message (the error code) and, where it matters, details in errors.

Error shape

{
  "success": false,
  "data": null,
  "message": "AMBIGUOUS_PARTY",
  "executionTime": 5,
  "errors": ["Podaj albo buyerId, albo buyer, ale nie oba."]
}

Always branch on message (the code), never on the human-readable text. The text may change, the code will not. errors has two shapes: for field validation it is a list of { field, code?, message } objects, otherwise a list of explanatory sentences, e.g. ["REST API wymaga planu MAX."].

Status codes

Status Meaning
200 / 201 success
400 invalid query or path parameters, an operation not allowed for the state of the document, and when creating documents also a malformed request body (e.g. a missing documentType, issueDate, products or buyer)
401 missing, invalid or expired token, or a revoked API account
403 authenticated but not allowed: scope, MAX plan, IP allowlist
404 resource not found (also when it belongs to another account)
409 conflict (e.g. the document number already exists, a webhook for that URL is already registered)
422 request body failed validation: missing field, bad format, type-dependent rules, conflicting annotations (when creating documents some of these checks answer 400, see VALIDATION_ERROR)
429 rate limit exceeded or the PDF rendering queue is full
500 unexpected server error
503 an external register is temporarily unavailable (company lookup in GUS); retry in a moment

Error codes

Code Status When
UNAUTHORIZED 401 missing or invalid token; also a token of a revoked API account
TOKEN_EXPIRED 401 the token expired, get a new one from /v1/oauth/token
NO_PERMISSIONS 403 the token lacks the required scope (errors[0] names it)
SUBSCRIPTION_REQUIRED 403 the account has no active MAX plan (the whole REST API is a MAX module)
FORBIDDEN 403 the caller IP is outside the allowlist of the API account
DOCUMENT_LIMIT_EXCEEDED 403 the plan does not allow issuing or editing documents (errors[0] starts with "Subskrypcja nieaktywna" or "Subskrypcja wygasła")
VALIDATION_ERROR 422 / 400 the request body failed validation; details in errors. Usually 422, but creating documents (POST /documents, POST /documents/validate) and warehouse documents (POST /warehouse/documents, POST /warehouse/documents/validate) answers 400 for request-shape problems (a missing documentType, issueDate or products, a bad date format, an invalid line). Treat both statuses with this code as a validation failure
PARTIAL_PAYMENTS_INVALID 422 partial payments do not match the amount or the payment status
DOCUMENT_DATES_INVALID 422 the document's dates contradict each other or the VAT Act (sale period, a sale date more than 60 days after the issue, a payment after the issue, a correction before the corrected invoice)
PAYMENT_INSTALLMENTS_INVALID 422 instalments do not match the amount due, the due dates or the payment status, or paymentInstallmentsSplit cannot be made (e.g. the amount is too small for that many instalments)
PARTY_IDENTIFIER_INVALID 422 the identifiers of a buyer or receiver given as data on a document contradict each other (e.g. nip with a DE… number, vatEu with a PL… or XI… number, a wrong NIP check digit, idWew for a buyer); errors names the field, e.g. buyer.vatUE. Contractors (/clients) report these as VALIDATION_ERROR. See Contractor identifiers
ADVANCE_RECEIPTS_INVALID 422 receipts on an advance invoice do not match the advance amount, the dates or the rates
INVALID_PARAMS 400 invalid query parameters (e.g. unknown documentType, bad date)
BAD_REQUEST 400 a required part of the request is missing, outside field validation
AMBIGUOUS_PARTY 400 both buyerId and buyer given (or receiverId and receiver)
BUYER_REQUIRED 400 neither buyerId nor buyer given
NOT_FOUND / DOCUMENT_NOT_FOUND 404 no such resource
DOCUMENT_NUMBER_EXISTS 409 the number is taken in its series, or another document on the account already has the same full number
CONFLICT 409 the resource state does not allow the operation (the only warehouse, a webhook for that URL exists, a finished recurring rule)
KSEF_CONFIRMED 400 deleting/editing a document already confirmed in KSeF (it has a KSeF number)
KSEF_SENT 400 deleting/editing a document sent to KSeF and awaiting confirmation
DOCUMENT_CORRECTED 409 editing or deleting an invoice that has a correction (another correction changes it)
CORRECTED_INVOICE_HAS_CORRECTION 409 a new correction of a document that already has one (issue the next change as a correction of its latest correction, number and id in errors[0])
ADVANCE_INVOICE_SETTLED 409 editing or deleting an advance invoice settled by a settlement invoice
ORDER_HAS_ADVANCE_INVOICES 400 editing or deleting an order that has advance invoices
WAREHOUSE_LINES_LOCKED 409 changing the lines of a warehouse document with PUT/PATCH (delete it and issue a new one)
STOCK_SHORTAGE 422 a WZ/RW/MM would take stock below zero (allowNegativeStock: true issues it anyway)
WAREHOUSE_INVALID 422 unknown or foreign warehouse, MM without a target or with the same warehouse twice
PRODUCT_NOT_FOUND 404 a warehouse document line references an unknown product
KSEF_CONNECTION_REQUIRED 409 a send without a configured KSeF connection
KSEF_CONNECTION_NOT_AUTHORIZED 422 the connection exists but did not pass authorization
KSEF_ALREADY_PROCESSING / KSEF_SEND_NOT_ALLOWED 409 a send is in progress, or the document is in a state that cannot be sent
INVALID_PAYMENT_STATUS / PAYMENT_STATUS_UPDATE_NOT_ALLOWED 400 bad receivedPayment value, or the document is not "Do zapłaty"
EMAIL_TAKEN / EMPLOYEE_LIMIT_REACHED 409 the employee e-mail is taken, or the limit of 20 accounts is reached
INVALID_NIP / COMPANY_NOT_FOUND 400 / 404 company lookup by NIP
GUS_UNAVAILABLE 503 the GUS register did not answer the company lookup by NIP; retry in a moment
RATE_LIMIT_EXCEEDED 429 rate limit exceeded, retry after Retry-After (see Rate limits)
WAIT_PDF_QUEUE 429 the PDF rendering queue is full, retry after Retry-After (see PDF rendering queue)
INTERNAL_SERVER_ERROR 500 unexpected, safe to retry idempotently

The full table of codes with statuses is also at the top of the OpenAPI specification (info.description).

Response headers

Every response carries an X-Request-ID header with a unique request id. Log it in your integration and quote it in support requests: it lets Fakturnia find that exact call. The X-RateLimit-* and Retry-After headers are described in Rate limits, Idempotent-Replayed in Idempotency.

Handling errors

const res = await fetch(url, opts);
const body = await res.json();

if (!body.success) {
  switch (body.message) {
    case 'TOKEN_EXPIRED':           // refresh the token and retry once
    case 'UNAUTHORIZED':            // re-authenticate; a revoked API account needs a new one
    case 'SUBSCRIPTION_REQUIRED':   // the account needs the MAX plan; tell the user, do not retry
    case 'RATE_LIMIT_EXCEEDED':     // wait Retry-After seconds, then retry
    case 'DOCUMENT_NUMBER_EXISTS':  // pick a new number or let the API auto-number
    case 'VALIDATION_ERROR':        // 400 or 422: inspect body.errors
    default:
      throw new Error(`${body.message} [${res.headers.get('X-Request-ID')}]: ${JSON.stringify(body.errors ?? [])}`);
  }
}

5xx and 429 errors are safe to retry with a backoff when the request carried an Idempotency-Key. See Idempotency.