Fakturnia Developers Quickstart API reference Polski

Correcting documents

You issue corrections with the same endpoint as any other document, POST /external/v1/documents, using one of three types:

  • FakturaKorygujaca — correction of a regular invoice,
  • FakturaKorygujacaZaliczkowa — correction of an advance invoice,
  • FakturaKorygujacaRozliczeniowa — correction of a settlement invoice.

Every correction requires correctedInvoiceId (the id of the corrected invoice). It may carry correctionCause (the cause: an event after the sale or an error on the invoice), which decides the correction type in KSeF, and correctionReason (a description of the reason), see Cause of a correction and its effect in KSeF. Corrections are sent to KSeF like regular invoices (the KOR kind), see Sending to KSeF.

Shared numbering (per KSeF). All three correction types share one numbering counter. Whichever correction you issue, the next numbers come from the same pool within the period (e.g. the month). Numbering rules are described in Creating documents.

The delta principle: you send the "after" state

In every correction you send the target state of the document after the correction, and the backend computes the difference against the corrected invoice. You do not send "+/−" line items. The correction totals (netSum, vatSum, grossSum) are a delta and can be negative (when the correction lowers the value). Take them from the API response, don't recompute them.

A further correction of the same invoice

A document has at most one correction. You issue the next change as a correction of the latest correction (correctedInvoiceId is that correction's id). Its "before" state is then the state after the previous correction, so the amounts do not count it twice: after an invoice of 1000 PLN net and a correction down to 900 PLN, the next correction down to 700 PLN is −200 PLN net, not −300 PLN.

A new correction of a document that already has a correction gets 409 CORRECTED_INVOICE_HAS_CORRECTION. The message in errors[0] gives the number and the id of the latest correction of the chain, the one to correct:

{
  "success": false,
  "message": "CORRECTED_INVOICE_HAS_CORRECTION",
  "errors": ["Dokument FV/1/07/2026 ma już korektę. Ostatnia korekta to KOR/1/08/2026 (id 6820a1b2c3d4e5f6a7b8c9d1): kolejną zmianę wystaw jako korektę tej korekty, żeby stan przed korektą uwzględniał poprzednie zmiany."]
}

PUT and PATCH answer the same when you change a correction's correctedInvoiceId to a document that already has another correction.

In KSeF a correction of a correction names the original invoice in DaneFaKorygowanej (its number, issue date and KSeF number, or the NrKSeFN marker when it was issued outside KSeF), while its "before" lines and amounts follow the state after the previous correction. This is what the KSeF 2.0 manual, part II, section 2.13.3 asks for. On the printout "Korygowany dokument" is the original invoice and "Poprzednia korekta" names the correction the "before" state comes from.

Original invoice without a KSeF number

When the original invoice has no KSeF number, the correction goes to KSeF with the NrKSeFN marker, that is as a correction of an invoice issued outside KSeF. Fakturnia neither holds nor refuses such a send. On an account connected to KSeF, POST /documents/validate then gives one of these codes in preview.warnings:

Code When What to do
CORRECTION_ORIGINAL_KSEF_PENDING The original invoice was sent or waits in the queue and has no KSeF number yet. Send the correction once the invoice has its number.
CORRECTION_ORIGINAL_NOT_SENT_TO_KSEF The original invoice is issued today and was not sent. Send the invoice first, then the correction. A correction sent earlier is not linked in KSeF to the invoice sent later.
CORRECTION_ORIGINAL_OUTSIDE_KSEF The original invoice can no longer go to KSeF: Fakturnia sends an invoice only on its issue day, and some types never go to KSeF. Nothing. The NrKSeFN marker matches the facts.

Each entry has a code and a Polish message you can show to the user. The list is empty when there is nothing to note.

Cause of a correction and its effect in KSeF

A correction can say why you issue it. That decides the TypKorekty field of the XML sent to KSeF and the period in which the correction enters the app's reports (VAT register, JPK_V7, KPiR).

Field Values Meaning
correctionCause after_sale, mistake, null after_sale: an event after the sale (discount, return of goods, complaint, price or quantity changed after the sale). mistake: an error on the corrected invoice (price, quantity, VAT rate, amount or data, including an invoice issued to the wrong buyer or issued twice).
correctionType 1, 2, 3, null TypKorekty set by hand: 1 effect on the date the original invoice was recorded, 2 on the issue date of the correction, 3 on another date. Leave it out and Fakturnia works it out.
correctionReason text, at most 256 characters The reason printed on the PDF and sent to KSeF (PrzyczynaKorekty). Optional.
correctionEffectDate YYYY-MM-DD, null The day the correction takes effect for VAT when it is neither the date of the corrected invoice nor the date of the correction. For an increase after the sale it is the day the cause arose, e.g. a price rise was agreed (art. 29a ust. 17); with correctionType: 3 the day of the effect. KSeF has no field for it; the VAT report and JPK_V7 place the correction on this day.
correctionConfirmationDate YYYY-MM-DD, null A decreasing correction issued outside KSeF (e.g. to a consumer): the day the buyer's confirmation of receipt arrived. The decrease counts in the period of the confirmation (art. 29a ust. 13a), and the VAT report places it there.

When you leave out correctionType, Fakturnia works out TypKorekty when it sends the correction to KSeF:

correctionCause What the correction does to the amounts TypKorekty
after_sale or none raises the tax base, correctionEffectDate in another month than the correction 3
after_sale or none any other case 2
mistake raises the tax base or changes no amount 1
mistake lowers the tax base 2
mistake takes the whole invoice to zero (wrong buyer, duplicate) 1
mistake raises one rate and lowers another 3

The rule follows the Polish VAT Act: an increase belongs to the period its cause arose in (art. 29a ust. 17), so for an error the period of the original invoice and for an event after the sale the day in correctionEffectDate, a decrease issued in KSeF to the period of the correction (art. 29a ust. 13 and 14), and a correction to zero of an invoice that should not exist to the period of the original invoice (Ministry of Finance, 20 May 2026). In income tax an error correction goes back to the period of the original invoice (art. 14 ust. 1m of the PIT Act).

{
  "documentType": "FakturaKorygujaca",
  "issueDate": "2026-10-06",
  "correctedInvoiceId": "681a3b2c4d5e6f7a8b9c0d1e",
  "correctionCause": "mistake",
  "correctionReason": "Wrong unit price",
  "products": [
    { "name": "Service", "unitOfMeasure": "pcs", "quantity": 1, "netPrice": 150, "vatRate": 23 }
  ]
}

This correction fixes an error and raises the tax base, so it goes to KSeF with TypKorekty 1.

What the fields affect:

  • KSeF. TypKorekty in the correction's XML. Without correctionCause and correctionType we send 2, as before, so existing integrations keep working unchanged.
  • Reports in the app. The VAT register and JPK_V7 place a correction with TypKorekty 1 in the period of the corrected invoice, and the KPiR places a correction with the mistake cause in the revenue period of the corrected invoice. Both periods get a notice about the move.
  • Reading. GET /documents/{id} and the document.created and document.updated webhooks return both fields: null when not given, and correctionType: null means the type is worked out.
  • Changing. PUT and PATCH accept both fields until the correction is sent to KSeF. On documents that are not corrections the fields are ignored.
  • Sale date and period. A correction without subDate takes the sale date or period of the corrected invoice: FA(3) is filled in as it stands after the correction, and the supply happened when the original invoice says. A correction of an advance invoice has no sale date.
  • Exchange rate. A correction without exchangeRate takes the corrected invoice's rate with its NBP day and table number (art. 31b ust. 1), also when you name the same currency.
  • Issue date. A correction cannot have an issue date earlier than the corrected invoice (422 DOCUMENT_DATES_INVALID).
  • Validation. A value outside the dictionary and a reason longer than 256 characters are validation errors: 400 VALIDATION_ERROR on POST, 422 VALIDATION_ERROR on PUT and PATCH. A too long reason used to be rejected only by KSeF, when sending.

Invoice correction (FakturaKorygujaca)

The most common correction: a change of quantity, price, VAT rate or line data.

  • products is the full state of the lines after the correction (the whole document as it should look after the change).
  • Totals: grossSum = Σ(lines after) − grossSum of the corrected invoice (likewise netSum and vatSum).
{
  "documentType": "FakturaKorygujaca",
  "issueDate": "2026-06-04",
  "correctedInvoiceId": "681a3b2c4d5e6f7a8b9c0d1e",
  "correctionReason": "Quantity change",
  "products": [
    { "name": "Service", "unitOfMeasure": "szt.", "quantity": 2, "netPrice": 100, "vatRate": 23 }
  ]
}

Zeroing out / cancelling an invoice

To cancel a document (e.g. after an order is cancelled), issue a correction with the same lines but quantity: 0, keeping the netPrice/grossPrice from the original invoice. A line with quantity 0 has a value of 0, so the "after" state is 0 and the correction delta fully reverses the invoice down to zero.

{
  "documentType": "FakturaKorygujaca",
  "issueDate": "2026-06-04",
  "correctedInvoiceId": "681a3b2c4d5e6f7a8b9c0d1e",
  "correctionReason": "Order cancellation",
  "products": [
    { "name": "Service", "unitOfMeasure": "szt.", "quantity": 0, "netPrice": 100, "vatRate": 23 }
  ]
}

You keep the unit price on purpose. KSeF expects the "after" line with the pre-correction price and a quantity of 0, not an empty line. The line value is derived from the quantity, so with quantity: 0 it is 0.

Advance invoice correction (FakturaKorygujacaZaliczkowa)

Corrects a previously issued advance invoice (a change to the advance amount or to the linked order's lines).

Required fields:

  • correctedInvoiceId — the corrected advance invoice (it must have a linked order and advancePaymentAmount) or, for a further change, the latest advance correction of that invoice,
  • products — the order lines after the correction (the basis of the proportional split),
  • correctionAdvanceAmountAfter — the new advance amount after the correction (≥ 0).

Totals:

  • grossSum = correctionAdvanceAmountAfter − the advance before the correction (the advance invoice's advancePaymentAmount, or the previous advance correction's correctionAdvanceAmountAfter, whose lines are then the order before the correction),
  • netSum / vatSum are the difference of the proportional VAT splits of both amounts (see How taxes are calculated).
{
  "documentType": "FakturaKorygujacaZaliczkowa",
  "issueDate": "2026-06-04",
  "correctedInvoiceId": "6820a1b2c3d4e5f6a7b8c9d0",
  "correctionReason": "Lower advance",
  "correctionAdvanceAmountAfter": 500,
  "products": [
    { "name": "Item A", "unitOfMeasure": "szt.", "quantity": 10, "netPrice": 100, "vatRate": 23 }
  ]
}

Settlement invoice correction (FakturaKorygujacaRozliczeniowa)

Corrects a settlement (final) invoice.

Required fields:

  • correctedInvoiceId — the corrected settlement invoice,
  • products — the lines after the correction,
  • correctionSettlementAmountAfter — the new settlement amount after the correction (≥ 0).

Totals:

  • grossSum = correctionSettlementAmountAfter − the settlement amount before the correction,
  • netSum / vatSum are the difference of the proportional VAT splits (as above).
{
  "documentType": "FakturaKorygujacaRozliczeniowa",
  "issueDate": "2026-06-04",
  "correctedInvoiceId": "6830a1b2c3d4e5f6a7b8c9d0",
  "correctionReason": "Settlement correction",
  "correctionSettlementAmountAfter": 1230,
  "products": [
    { "name": "Item A", "unitOfMeasure": "szt.", "quantity": 10, "netPrice": 100, "vatRate": 23 }
  ]
}

Correcting an invoice downloaded from KSeF

A sales invoice issued in another system and downloaded from KSeF (source: "ksef", direction: "income") can be corrected like your own: pass its _id as correctedInvoiceId. The API reads its lines, totals and buyer address from the invoice XML itself (fetching it from KSeF when the invoice was never opened in the app), so the "before" state and the StanPrzed rows sent to KSeF match the original. In DaneFaKorygowanej the correction names the KSeF number of the original invoice.

Limits: only a sales invoice (a purchase invoice is corrected by its issuer) and only a plain VAT invoice; advance, settlement and correction invoices downloaded from KSeF carry no data in Fakturnia to build the "before" state from.

How taxes are calculated

A regular correction (FakturaKorygujaca) computes totals directly, as a difference of lines: (sum of lines after) − (sum of the corrected invoice), separately for net, VAT and gross.

Advance and settlement corrections work differently, because an advance and a settlement are a single gross amount that has to be split across VAT rates. A proportional split does this:

  1. The lines (the order's for an advance, the invoice's for a settlement) are grouped by VAT rate and summed by gross.
  2. Each rate gets a share of the amount proportional to its gross: share = rate gross / total gross. The last rate gets the remainder, which removes rounding cents.
  3. From the gross assigned to a rate, net and VAT are derived: net = gross / (1 + rate/100), VAT = gross − net. Special rates (zw, oo, np …, 0 …) have VAT = 0, net = gross.

A correction is the difference of two such splits: the split of the "after" amount minus the split of the "before" amount. That is why grossSum is simply the difference of the amounts, while netSum / vatSum follow from the difference of the proportional splits. Example: when an advance of 615 (rate 23%) drops to 500, grossSum = 500 − 615 = −115, and net and VAT are the difference of the two splits.

The proportional split is identical to the one used when issuing the advance or settlement invoice itself, so a correction always reconciles to the grosz against the original document.

Common errors

Status Code Cause
422 CORRECTED_INVOICE_REQUIRED Missing correctedInvoiceId.
409 CORRECTED_INVOICE_HAS_CORRECTION The corrected document already has a correction. Correct its latest correction, whose number and id are in errors[0].
404 CORRECTED_INVOICE_NOT_FOUND The corrected invoice was not found.
422 CORRECTION_ADVANCE_AMOUNT_REQUIRED Missing correctionAdvanceAmountAfter (≥ 0) for an advance correction.
422 CORRECTION_ADVANCE_BASE_MISSING The corrected advance invoice has no linked order / advancePaymentAmount (or the corrected advance correction has no lines or correctionAdvanceAmountAfter).
422 CORRECTION_SETTLEMENT_AMOUNT_REQUIRED Missing correctionSettlementAmountAfter (≥ 0) for a settlement correction.
400 / 422 VALIDATION_ERROR correctionCause or correctionType outside the dictionary, correctionReason longer than 256 characters (400 on POST, 422 on PUT and PATCH).
422 CORRECTED_INVOICE_NOT_INCOME The corrected invoice is a purchase invoice downloaded from KSeF; its issuer corrects it.
422 CORRECTED_INVOICE_TYPE_MISMATCH The corrected invoice's type does not match the correction type; for an invoice downloaded from KSeF only a VAT invoice is allowed.
422 CORRECTED_INVOICE_WITHOUT_POSITIONS The lines of the corrected invoice could not be read from KSeF (e.g. a KSeF outage); try again.

What's next