> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reap.global/llms.txt
> Use this file to discover all available pages before exploring further.

# Keeping Your Ledger in Sync

> Reconcile your ledger against the asynchronous transaction lifecycle after you approve.

In External mode you own the per-user ledger, so you also own reconciliation. The [authorization request](/transactions/external-authorization/authorization-request) places a provisional reservation; the asynchronous [transaction lifecycle](/transactions/lifecycle) is what tells you the transaction actually cleared, was reversed, or was refunded. This page is how you keep the two aligned.

## The lifecycle is your source of truth

After an approval, Reap emits the standard transaction webhooks:

* `CARD_TRANSACTION_CREATED` - a transaction is recorded for the first time.
* `CARD_TRANSACTION_UPDATED` - an existing transaction gains a new event (clearing, reversal, or refund).

Each webhook carries the **full transaction object**. The [`events` array](/transactions/amounts#per-event-amounts) is the authoritative record you reconcile against: every `AUTHORIZATION`, `CLEARING`, `REVERSAL`, and `REFUND`, each with its own `amount`. Post those to your ledger - they, not the authorization request, tell you what actually settled. The request only ever told you what you approved.

Reap also surfaces an aggregate [`amount` breakdown](/transactions/amounts) (`authorized`, `reversed`, `cleared`, `refunded`, and the net `current`) computed over those same events. It is a convenient mirror of Reap's own view - useful to cross-check your position against.

## Correlate with the authorization request

The `eventId` you received in the authorization request appears again as `triggerEventId` on the `CARD_TRANSACTION_CREATED` webhook for the approved transaction, and inside the transaction's `events` array. Use it to tie the reservation you placed at authorization to the transaction it became, then follow that transaction's `id` for every subsequent update.

## Process events idempotently

Update your ledger as events arrive. Deliveries can repeat and are not guaranteed to arrive in order, so make your handling idempotent - key on the event id and skip anything you have already applied.

Expect the settled amounts to differ from what you approved: partial clearings release the unused portion, over-clearings settle more than authorized, and reversals release the hold entirely. Release your provisional reservation and post the actual amounts as those events arrive. See the [lifecycle](/transactions/lifecycle) for each scenario.

## Handle events with no prior authorization

Reap forwards **every** presentment the card network sends, including ones that never passed through your authorization endpoint. Your reconciliation must not assume a matching authorization always exists:

* **Offline and direct clearing.** Transit gates and in-flight purchases clear without a real-time authorization. You receive `CARD_TRANSACTION_CREATED` with `status: CLEARED` and a single `CLEARING` event - a charge with no hold to release. Book it as debt directly.
* **Standalone (unrelated) refund.** A tax refund, goodwill credit, or a return long after the purchase arrives as `CARD_TRANSACTION_CREATED` with `status: CLEARED` and a single `REFUND` event, with no preceding transaction. Credit the cardholder.
* **A clearing after a decline or reversal.** The network can still present a clearing for a transaction you never approved or that was already reversed. Reap books it as debt; mirror the charge and reconcile.

Treating the lifecycle as authoritative - rather than only settling transactions you remember approving - is what keeps your ledger correct when the network behaves this way.

<Note>
  These are the same edge cases Reap handles internally when it owns the ledger in Managed mode. In External mode the responsibility moves to you, which is why your ledger, not the authorization request, is the system of record.
</Note>
