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

# Asynchronous operations

> Which steps complete after the response, and how to observe them

Most Korint endpoints are synchronous: the response tells you the outcome. A few are not, and they are
concentrated exactly where a new-business integration spends its time — signature, payment, document
processing, and activation.

For those, a `2xx` means *accepted*, not *done*. Completion happens elsewhere: a customer signs in
their browser, Stripe confirms a mandate, a scheduled job reaches a start date. You observe it by
polling the resource that carries the state.

<Warning>
  Korint does not currently send outbound webhooks to API clients. The webhooks in the platform are
  inbound — Stripe and the signature provider notifying us. There is no event subscription you can
  register, so polling is the only way to observe completion today.
</Warning>

## What is synchronous

These return the outcome, and you can act on the response directly:

* Creating and editing customers, policies and assets.
* `POST /policies/{policyId}/calculate-quote` and `POST /policies/{policyId}/quote` — pricing is
  computed during the request. A price that cannot be produced fails the call or is recorded as a
  quote failure; it does not arrive later.
* `POST /policies/{policyId}/confirm` — validation is immediate.
* Registry lookups: `GET /siren`, `GET /vehicle-information/*`, `GET /address-autocomplete/suggest`.
  These need an actor with the right permissions — `GET /siren` is refused to an anonymous session
  (`403`), so a public funnel collects a typed SIRET and lets enrichment happen server-side on the
  `PATCH` instead.

<Note>
  Products whose pricing the carrier keeps — rather than delegating it to a Korint pricing engine — are the
  exception. Their quote depends on an external response, so treat it as a step whose result you re-read
  rather than one you assume.
</Note>

## What you have to observe

### Signature

`POST /policies/{policyId}/signature` creates the request and returns the signers with their links. It
does not wait for anyone to sign. Poll the signature requests for the policy:

```bash theme={null}
curl 'https://api.sandbox.korint.io/signature/by-external-id/<policyId>' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'tenant: <tenant>'
```

```json Response theme={null}
{ "signatureRequests": [ /* ... */ ] }
```

<Warning>
  This endpoint returns `200` with an empty `signatureRequests` array when nothing matches — an empty
  list is not an error and not a "not yet created" signal you can distinguish from a bad id. Confirm you
  are passing the policy id as `externalId`.
</Warning>

The policy itself also moves as signing completes, so `GET /policies/{policyId}` is the better signal
for "may I proceed?", and the signature requests are the better signal for "who still has to sign?".

A signer who has lost the email needs a fresh nudge rather than a new request:
`POST /signature/{signatureId}/policy/{policyId}/signers/{signerCustomerId}/resend`, or fetch their
link again with the matching `/link` endpoint.

**Poll every 10–15 seconds while a signing session is open in front of you, every few minutes
otherwise.** Signature is a human action: expect minutes to days, and never block a request thread
waiting for it.

### A payment method after the browser setup

Confirming a SetupIntent happens between the customer's browser and Stripe. We learn about it from
Stripe's webhook, so the payment method appears on our side shortly after — not at the moment the
browser reports success.

Poll `GET /customers/{customerId}/payment-methods` until the method appears, **every 2–3 seconds for
the first half-minute**, then back off. If it never appears, the setup did not actually succeed;
re-check the browser-side result rather than retrying the secret.

### Documents

`POST /policies/{policyId}/documents` returns an upload URL; you then upload the file to that URL
directly. The document exists once that upload finishes, but nothing has looked at it yet.

Processing is a call you make, and it is the exception to this page: `GET /documents/validate?key=…`
scans, classifies and extracts, streaming progress as Server-Sent Events. Consume the stream instead of
polling. Settled results live on `GET /policies/{policyId}/documents/validity` and
`GET /policies/{policyId}/document-extractions`.

Fields configured with `autoFill` are populated from a successful extraction (see
[Read the product configuration](/get-started/product-configuration#document-extracted-fields-autofill-extractionsources)),
so re-read the entity rather than assuming your earlier values survived.

### Coming into force

Activation is driven by time and by payment, not by your call. A signed contract comes into force when
its start date arrives, and — on products with `requireFirstPaymentToActivate` — once the first
premium has been collected.

Poll `GET /policies/{policyId}` **at whatever cadence your business needs, minutes at most**. A
future-dated contract will sit signed-but-not-in-force until its start date; that is not a state you
should poll tightly.

### Renewals, repricing and recurring billing

These are driven by scheduled jobs on our side, on the product's own cycle. Nothing is triggered by an
API call you make, and nothing notifies you. Read the current state when you need it — a renewal
appears as a new branch on the policy.

## How to poll well

* **Back off.** Start at the intervals above, then widen. A tight loop on a step that takes a human
  minutes is wasted on both sides.
* **Set a ceiling and surface it.** A signature that has not completed in days is a business problem
  for someone to chase, not a request to keep retrying forever.
* **Poll the resource, not the action.** Re-reading the policy or the payment method tells you the
  truth; re-issuing the original call may create a second signature request or a second setup.
* **Re-read after every asynchronous step.** Extraction and registry enrichment both change values you
  sent. Working from your local copy is how integrations drift out of step with the contract.

<Note>
  There is no published rate limit on the endpoints in this guide. A few endpoints are individually
  limited and say so in the reference — starting an anonymous session and the claim lookup routes are each
  capped at 100 per hour. Treat the absence of a limit elsewhere as a courtesy rather than a
  guarantee: poll at the intervals above rather than as fast as your client allows.
</Note>

## Timestamps you control

Most commands accept a `whenAt` query parameter — the business time at which the action is recorded,
rather than the moment the request arrives. Contracts are event-sourced, so `whenAt` is how you
backdate an action, replay a historical journey, or keep a migrated contract's own chronology.

Read endpoints have the mirror-image parameter, `simulatedAt`: the state of the contract as at that
date. Together they let you ask "what did this contract look like then?" without mutating anything —
and they are the reason a read that ignores them can look stale when it is simply answering about now.
