Skip to main content
POST
Record lost sale
A lost sale is money that moved at the counter and was never recorded as a sale. The register charged, something prevented the order from being created, and you gave the money back right there.
Without this call, that sale exists nowhere. No order, no event and —depending on the cause— no record in the domain that failed either. The cash close cannot explain it and nobody finds out that a store stopped selling.
This is not a void. A void has an order, a credit note and an order.reversed event. Here the sale never came to exist.
You are not the one deciding to report. Fire decides and tells you in policy.numberingFailure.action of Issue receipt: REFUND means give the money back and report here; CONTINUE means carry on and report nothing. The rule is set by the account per vendor, so it can differ between two stores of the same customer — which is why it is asked on every sale and never cached.

The body is the injection body

Do not build a new payload. Send exactly the same JSON you were about to send to Create order, and add two keys at the same level: reason and detail. This is not convenience: inside, the same injection mapping runs, so the lost sale is stored in the same shape as a sold one — same lines, same totals, same payment methods. That is what later lets you reconcile the day by adding both together.
string
required
Why the sale never became an order.Do not derive it: we return it in policy.numberingFailure.lostSaleReason of the numbering response. Copy it. The day we add a cause, you touch nothing.It is a closed enum and there is no endpoint to query it: the table above is the whole catalog, and the value you need already came in the response that brought you here. While it stays this small, an extra call to discover it buys you nothing. If it grows, it becomes an endpoint and you will see it announced here — the field does not change.Any other value comes back 400.
object
Whatever the cause carries. For FISCAL_NUMBERING_FAILED copy from the numbering response:Optional on purpose: the worst case —a configuration error, which cuts before the fiscal request is created— has none of this, and requiring it would leave out precisely the hardest case to detect.
string
required
From the injection payload. Together with the vendor it is the key that makes retrying safe.
string
required
From the injection payload. Without it there is no way to reconcile the drawer or tell who stopped selling.
Everything else in the payload —client, order.products, payments, createdAt, orderCode…— travels as-is and we interpret it with the same mapping as always.

Authentication

string
required
Your Fire API key with scope orders:write. The key must be vendor-scoped — keys without a vendorId are rejected with 403.

Retrying is safe

It is idempotent by orderId + vendor, the same key Fire uses to identify an order. If your register loses connectivity right here —a bad moment, with the customer in front of you— queue it and resend. No Idempotency-Key header: there are no two different losses of the same sale.

Example

Request
201

Errors

An extra field is not rejected, and neither is a closed business day: the money already moved, and that same closed day may be the cause of the next loss. We would rather store too much than lose the trace of a sale.