Skip to main content
Writing a contract and reading one back are different problems. Writing is a fixed sequence, and the rest of this guide walks it. Reading is a set of questions that arrive in no particular order — which cover did they buy, what will actually be debited, is this waiting on a payment, which draft is live — and the answers are spread across three endpoints and nested a few levels into their responses.

Questions to understand a contract

Every amount is an integer number of cents.

The cover is on the asset, not the policy

Cover is chosen per insured item, so the chosen tier is on the asset — not on the policy:
The policy carries the priced result — quote.basePrice, quote.components, quote.totalPremium — but not the choice that produced it. A policy covering several items has a tier per item, so read them from the assets you already fetched rather than looking for one contract-level value.
Do not recover the tier from quote.provider.id. It is a pricing-engine identifier whose shape varies per product, so parsing it works on the product you tested and breaks on the next one.

What will actually be debited

The premium on the quote is the contract total. It is almost never the first amount charged, and showing it on a payment screen tells the customer the wrong number at the worst moment. Two fields answer the real question:
object
On the policy and on each asset, alongside quote. Same shape as quote, holding the amount for the period actually being charged rather than for the whole contract. This is what to show next to a payment authorisation.
GET /policies/{policyId}/premium-schedule gives the full schedule as a list of intervals, each entry carrying startAt, endAt, premium and components — use it to show what will be paid and when rather than computing a schedule yourself from invoicingConfig. The gap is wide enough to matter: a contract billed monthly debits a twelfth of the annual premium first, and an early-payment arrangement debits several months at once. Deriving which from frequency, timing, firstPayment and earlyPayment by hand is possible and easy to get wrong; both fields above give it to you directly.

Whether it is waiting on money

boolean
On the policy. True when the contract is signed and its start date reached, but the first premium has not been collected and the product requires it before cover begins.
This is the field behind the state described in Collect payment: a signed contract with a start date in the past that is still not in force. Read the boolean rather than inferring the state from a status plus a date comparison.

Which draft is live

A contract can have several branches, and a closed one still appears in some listings. Filter on status rather than taking the first entry:
BRANCH_OPEN is the work in progress. This matters most when resuming a visitor: see Anonymous quoting.

Dates you read are not dates you display

startedAt and endedAt come back as instants, and they are Paris-day boundaries expressed in UTC — so a contract starting 1 September reads as 2026-08-31T22:00:00.000Z. Slicing that string gives the wrong calendar day, and rehydrating a date input from it corrupts the contract on every resume. Convert through Europe/Paris before displaying a date or loading one into an input. The rule and the worked example are in Reading dates back.

What create calls return

Writes are deliberately thin. POST /assets returns { type, id }; POST /policies/{policyId}/quote returns an empty body; PATCH calls return little or nothing. None of them echoes the stored entity. So after any write whose result you intend to show, read the entity back. That is not only an asynchronous-step precaution — registry enrichment, document extraction, defaults and calculated pricing fields all mean the stored values differ from what you sent.