Skip to main content
POST
Partner API. This endpoint is intended for platform integrators. Standard Fire customers do not have direct access — contact your account manager if you need this integration.
Records a shift close and has Fire compare it against what it says should be in the drawer. Fire computes the difference (SHORTAGE, OVERAGE or MATCH).
v1 stays alive, with no sunset date. If your integration already consumes it, you don’t have to do anything. Migrate to v2 whenever you want — no coordinated deploy needed.

What changes

One thing only, and it isn’t a new field: who does the arithmetic changes. discrepancy is the same subtraction in both versions: declaredCash − systemCash. Under v2 the float sits on both sides, so the difference means exactly the same thing and a v1 row and a v2 row compare with no conversion.
The step that doesn’t announce itself. If you point at v2 and keep subtracting the float from declaredCash, the request goes through with no error at all and every close comes back short by exactly the float — every day, with the cashier showing as owing money they never took. Fire cannot tell a net count from a gross one: only you know which you sent.Before migrating, check against a test day that the discrepancy Fire returns is the one you compute yourself.

Authentication and tenancy

string
required
Your Fire API key, with the cash-management:write scope.It must be vendor-scoped: it has to carry both account and vendor. Missing either one returns 403.
Here the key is the tenant. The storeId is looked up inside your key’s scope; if the store belongs to another account or vendor, the response is 404 without revealing whether it exists.That is a real difference from v1, which accepts any valid storeId. If you post to v1 today with a key shared across accounts, that key cannot use v2 — you’ll need one of your own.

One close per shift

Two rules, and both are worth understanding before you integrate:
string
required
Your POS’s identifier for the shift. It is the idempotency key: re-sending the same close returns 409 instead of duplicating it.Unique per store forever, not per day. It carries no date, so a counter that resets daily (T01-1, T01-2, …) collides with yesterday’s close. If your shift id resets, prefix it with the business day: T01-20260901-1.A shift handling two currencies sends two POSTs with the same sessionExternalId and a different currency: the key includes the currency, so both go through.
And the other one, which is the surprising one: a shift closes once, regardless of the id. If you send a second close for the same day, store, operator, currency and shiftStart under a different sessionExternalId, the response is 409. Generating a fresh id per send is not a retry — it is a new close, and Fire treats it as one.

Request body

string
required
Store UUID. It must belong to your API key’s scope.
string
required
3-character ISO 4217 code (USD, BRL, ARS, CLP, COP, VES).
number
required
The cash counted in the drawer, gross — float included. Decimal with at most 2 places, non-negative.This is the field whose meaning changed from v1. Read the warning above.
number
required
The float the register was opened with for this shift, in this currency. Decimal with at most 2 places, non-negative. Always send it, even when it is 0.
string
required
Shift start, ISO 8601 with offset (2026-09-01T13:00:00-05:00). Fire uses the window to attribute the shift’s sales.
string
required
Shift end, same format. Must be later than shiftStart.
string
required
Categorical cause of the difference. One of: WRONG_CHANGE_GIVEN, COUNTING_ERROR, INCOMPLETE_CUSTOMER_PAYMENT, MINOR_UNIDENTIFIED_DIFFERENCE, THEFT_SUSPECTED, UNRECORDED_PAYMENT, OTHER.Required even when the close matches. On an overage the only accepted value is OTHER — anything else returns 400: extra cash is not explained by a customer’s counting error.
array
Cash that left the drawer during the shift. Up to 100 entries. They are subtracted from what’s expected; the per-withdrawal detail is stored for audit.
string
Business day as YYYY-MM-DD. Defaults to the store’s current business day. Use it to record a close for a past day — Fire flags the result with details.post_close: true when the day is already closed.
string
The shift’s cashier. Optional: omit it when the close covers the whole store.With a cashier, Fire counts only that person’s sales — and rejects an operator who had no transactions and still declares money from sales.
string
Cashier’s name, shown on the reconciliation screens.
string
The physical register for the shift. Lets the report group closes by register.
string
Free text, up to 2000 characters.
string
UUID of an authorization token, when the close needed a supervisor’s sign-off.

Response fields

The same ones as v1, plus these:
number
2 for rows that came in through this endpoint. v1 rows carry 1. Fire’s UI branches on this field to show both in a comparable way.
number
The float, as you sent it.
number
The sum of withdrawals[]. The per-withdrawal detail lives in details.withdrawals.
string
Echo of the request. null on v1 rows.
string | null
Echo of the request.
number
What Fire computed should be in the drawer: openingBalance + cash sales − withdrawalsTotal.
number
declaredCash − systemCash. Negative is a shortage, positive is an overage.

Errors

Migrating from v1

  1. Change the URL: /api/v1/adapters/xmart/cash-management/reconciliations → /api/v2/external/cash-management/reconciliations. If your key isn’t vendor-scoped, request a new one.
  2. Stop subtracting the float from declaredCash. Send the counted cash as is.
  3. Always send openingBalance — even 0 — and the shiftStart / shiftEnd pair.
  4. Always send sessionExternalId, unique per store forever.
  5. If you take cash out during the shift, declare it in withdrawals[].
  6. Check against a test day that the discrepancy Fire returns is the one you compute yourself.
There is no GET on v2. The v1 listing already returns every row for the day regardless of which version wrote it — that’s where you’ll see a v1 close and a v2 close side by side.