Ingestion is idempotent by external id, because webhooks retry and exports overlap. Nothing posts to the ledger on arrival, because the revenue treatment of a deal is an accounting judgement, not a CRM field.
Every inbound record carries an external id. Re-running a sync creates nothing — a finance system that double-books on a retry is worse than one that never synced.
A closed-won deal becomes a draft contract for a person to review and activate. The ledger is reached by approval, never by webhook.
The same code path runs against a live API, a nightly file or a test fixture, so what you test is what runs.
Closed-won deals become draft revenue contracts with their performance obligations mapped from line items — or one ratable obligation when the deal has no split.
Charges and invoices deduplicated on arrival, with voided records rejected at the boundary rather than reconciled away later.
Statement lines deduplicated and handed to the reconciliation and categorisation engines, which decide nothing on their own that a person would want to see.
Runs ingested with gross, employer taxes, net and headcount, validated before they can become entries.
Per-connector counts of what was ingested, what was skipped as a duplicate and what was rejected with the reason.
A record that fails validation is returned with its reason rather than dropped. Silent partial syncs are how ledgers quietly go wrong.
The demo runs on a seeded company with a live close waiting — two real blockers and agents holding proposals.