Every carrier that has run ceded reinsurance for long enough has had the meeting. The claims director's large-loss report shows one net incurred on a hurricane claim. Finance's quarter-end pack shows another. The underwriting committee's view of the property book, net of the cat programme, shows a third. Each was built from a reasonable reading of the treaty, by a reasonable person, at a different time.

The fix is not a better reconciliation. It is a rule about ownership: one system derives net, and the others read it. In the Insight suite that system is InsightCede, and the rule is written into its README as a sentence rather than a preference.

InsightCede never writes back into UW or CW. Net premium, net incurred and ceded loss ratio are derived here and published as a read. The moment two systems both claim to own “net”, they disagree.

Why net cannot live in underwriting or claims

A cession is triggered by a policy transaction or a claim transaction. Put the engine inside underwriting and claims cannot cede; put it inside claims and policy cessions have no home. The organising dimension is different too: the workbenches think in policy years and accident years, the ceded side in treaty years and accounting periods. The counterparty is a reinsurer with its own credit risk, not an insured. And the consumers are Schedule F, the capital model and reinsurer billing, owned by the CFO and CRO rather than the chief underwriting officer or the head of claims.

So the two workbenches report what happened, and Cede decides what it means.

sequenceDiagram
    participant CW as InsightCW
    participant UW as InsightUW
    participant C as InsightCede
    participant P as InsightPulse
    CW->>C: claim.payment_issued (outbox, same transaction as the cheque)
    UW->>C: policy.bound / endorsed (outbox, same transaction)
    Note over C: intake is idempotent on event_id. The engine cedes, raises recoverables and explains
    CW->>C: read cede.claim_net for one claim
    C-->>CW: gross, ceded paid and outstanding, recoverable, net
    UW->>C: read cede.net_position
    C-->>UW: programme totals and one row per treaty year
    P->>C: read cede.net_position and cede.recoverable_aging
    C-->>P: the same sums, aged by reinsurer
    Note over CW,P: nothing flows back as a write
Events go in through each workbench's outbox, written in the same transaction as the business change. Net comes back out as a governed read. There is no arrow from Cede into another product's tables.

What goes in, and the two details that matter

The workbenches send events: policy.bound, policy.endorsed and policy.audited from underwriting; claim.reserve_movement and claim.payment_issued from claims. Each is written to an outbox in the same transaction as the business change, so if the cheque committed, the event exists. A publisher ships it afterwards and retries freely, because intake is idempotent on the event id.

Two payload rules carry more weight than they look. Premium is a delta, not a balance: a bind cedes the whole premium, an endorsement cedes only what it added, and sending a balance would re-cede the policy on every change. Loss is a position, not an increment: a claim event carries the ground-up incurred and paid after the movement, because an excess layer attaches on the size of the whole loss. The engine works out the movement itself, which is also why the same reserve sent twice cedes once.

Inbound
The inbound page listing events from InsightUW and InsightCW with their type, outcome and the engine's note, including events that ceded nothing
Find the rows that ceded nothing. They are kept with the reason — no treaty covers the line, a risks-attaching treaty needed an inception date the event did not carry — because “why was nothing ceded on this claim?” is the question the ceded team is asked most.

What comes out: three contracts

Net leaves Cede through insight-dataapi: named contracts, reviewed like code, served over HTTP to any caller with a Cede token or API key. Every call runs in a read-only transaction with a statement timeout, through a guard that refuses identity, secret, connection and audit tables whatever the SQL says, and is itself recorded.

ContractParameterOne row perRead byRow cap
cede.net_positionnonethe programme, each treaty year, and facultativeUW's reinsurance tab; Pulse's Reinsurance 360500
cede.claim_netclaim_number (optional)claim, largest gross incurred firstCW's reserve worksheet2,000
cede.recoverable_agingreinsurer_code (optional)reinsurer, largest outstanding firstPulse's Reinsurance 360500

The programme row of cede.net_position is the same sum as Cede's own /position route, and a test asserts it: the contract's row, run through the same measure definitions, must equal the route's answer on the same ledger. A change to one without the other fails the build. The two derived columns are defined once: net cost of reinsurance is ceded premium, less ceding commission, plus reinstatement premium; ceded loss ratio is ceded loss over ceded premium.

$52,588,347ceded loss, outstanding plus paid
$724,929.26reinstatement premium owed
$13,000,000loss a layer could not absorb, retained
$14,386,665.59net cost of reinsurance

Those are the demo programme's figures from the live position read — a demo US property-casualty carrier, not a customer. The net cost checks by hand: $14,168,774.93 of ceded premium, less $507,038.60 of commission, plus $724,929.26 of reinstatement premium.

Ceded position
The ceded position page: a gross-to-net waterfall, the cost of cover against what it has paid back, recoverables ageing, the layers closest to exhaustion, and an alert for loss that had no cover behind it
Start with the red alert at the top. $13,000,000 of ceded loss had no cover behind it — a layer was exhausted. Every consumer that reads net_position gets that figure as uncovered_retained, not a net that quietly assumes the cover was there.

One flow, end to end

Use case detailsA claim's net on the reserve worksheet
TriggerAn adjuster opens a claim's reserve worksheet in InsightCW
Actor(s)The adjuster or claims finance; InsightCW calling Cede as a client
AgentNone. This is a governed read, not an agent's work
Grounded incede.claim_net: Cede's register of the claim, the loss cessions and the recoverables
PreparesGross incurred, ceded outstanding and paid, the treaties that responded, recoverable outstanding, net incurred, net paid
Checkpoint & default levelNone; a read changes nothing
What a person decidesThe reserve. The net is information for it, not an input CW stores
What is recordedThe call, in Cede's dataapi_call: who asked, which contract, how long it took

Nothing in that example required the three products to agree on a formula. They stopped computing net at all. The worksheet's sentence is generated from the read — “$23,435,097 of $28,435,097 incurred is ceded across 1 treaty; … net incurred $5,000,000” — and when Cede has nothing on a claim it says so in words (“Nothing ceded on this claim”) rather than showing a zero as if it were a fact.

Why a read and not a copy

The tempting alternative is a nightly copy: push Cede's figures into each product's own tables and let them query locally. It fails in three quiet ways. The copy is stale by design, so the claims worksheet disagrees with Cede for up to a day after every payment. The copy has to be re-derived when the engine writes a contra row, which is exactly when a hand-written query is most likely to be wrong. And the copy brings its own column types.

The last one is not hypothetical. The ledger's first home was MySQL, where the ORM's floating-point type mapped to single precision, about seven significant digits: a $28,435,097 loss was stored as 28,435,100. The engine now computes in Decimal and stores Numeric(18, 2), and converts to a number only at the API boundary. A consumer that reads the contract gets those figures as they were computed. A consumer that keeps its own copy gets whatever its own schema does to them.

The clients are deliberately small. Each product discovers the contract keys from Cede's catalogue by their last segment, caches the catalogue for five minutes, sends a platform API key as a bearer and never logs it, and can be switched off with one environment flag.

What a consumer does when Cede does not answer

Each product's client turns every failure into a one-line reason a page can show: not configured, unreachable, refused, or the contract not published yet. Claims shows the reason and notes that events still go to Cede through the outbox. Underwriting falls back to its own local reinsurance rows and labels them as local. Pulse keeps the figures it had and records that Cede was unreachable as the data source. None of them invents a net to fill the gap.

Integrations
The data integrations page: the inbound contracts for InsightCW claim events and InsightUW policy events with their event types and required fields, then five flows with health, direction, count and success rate, including cede.dataapi, Cede to UW, CW and Pulse net position reads
Find the row named cede.dataapi. It is the outbound flow this post is about: net position reads from Cede to UW, CW and Pulse. Above it, the inbound contracts list every event type the workbenches may send and the fields each must carry. In the demo the intake flow shows red — one call in 24 hours, and it failed — which is the page doing its job.

What it does not do

  • No point-in-time read. The contracts are live: they answer as the ledger stands now. There is no as_of parameter, so “what was net at 30 September” is answered by the period's struck bordereaux or an export taken at the time, not by asking the contract.
  • Everyone signed in sees the whole programme. All three contracts are public to any Cede caller and no tenancy column is applied to the rows. Narrowing one means adding roles to the contract, which nobody has needed yet.
  • Not every consumer is fully on it. Pulse's Reinsurance 360 reads its ceded figures and ageing from Cede, but its panel, large-loss list and narrative are still sample data until Cede publishes them, and the page says so block by block.
  • Net is not stored on the policy or the claim. That is the point, and it has a cost: a report that joins underwriting data to net has to call Cede, or read an export, rather than run one query in one database.

Why InsightCede →

← All posts   Request a demo