Skip to main content
This page goes from nothing to a published decision and its receipt using only curl against the hosted sandbox. Every call below is a documented /v1 route; the API reference has the full request and response shapes and a playground that runs them for you.
1

Mint sandbox credentials

There is no sign-up. One call gives you a tenant of your own with a personal API key, OAuth client credentials and a webhook signing key.
Mint credentials
Response (abridged)
Save the api_key; the secrets are shown once. Everything you create is visible only to credentials from this tenant.
Keep it in your shell
2

Check you are in

The index
The index lists every route and reports "durable": true, which means your intents survive between calls. A missing or wrong key is a 401.
3

Create an intent

An intent is the decision Triage made, as a record. The payload is yours; composerID mints the intent_id.
Create
The 201 response is the intent record: an intent_id beginning itn_, intent_version: 1, and your payload. Keep the id.
Keep it in your shell
4

Plan and preflight

/plan tells you which destinations this intent would publish to. /preflight checks it against one destination’s required fields before anything is sent.
A 200 means the destination has everything it needs. A 422 means it does not, and the body carries an enrichment_request naming the missing_fields. Answer them and preflight again:
Answer the missing fields
Enrichment completes the same intent version; it does not create a new one.
5

See what would be written

Ask composerID for the exact body it would send, without sending it:
Dry run
Preview (abridged)
That is the record as the destination’s API would receive it: its own field names, with the Intent ID in the field that carries it. Nothing was stored and no event was recorded. Every destination answers a dry run, so this is how you see what composerID would post to any of them.
6

Publish, then publish again

Publish
Receipt (abridged)
The receipt carries the destination’s own record id and the payload that was written: the same body the dry run showed. Run the same publish a second time. You get the same receipt with "replayed": true and no second record. The idempotency key is built from the intent id, its version and the destination, so a retry can never create a duplicate. Change the intent with PATCH /intent/{id} and the version increments; publishing that is new, not a replay.
7

Read the timeline

Timeline
Every event so far, in order: created, planned, preflighted, enriched, published. Destination webhooks land here too, verified against your webhook_signing_key and correlated to the same intent_id. The timeline is append-only.
Destinations in the sandbox are mock tenants that behave the way each vendor’s published API says the real one does. The receipt you got is real in every respect except that no vendor system was written to. Each destination page states the field its Intent ID lands in.

Run it locally

The same API runs from the repository with no dependencies beyond Python 3.11.
Local sandbox
And the conformance pack, the eighteen claims this documentation makes, can be run against any deployment, including yours:
Conformance

Next steps

Authentication

OAuth 2.0 client credentials, scopes, and which scope each route needs.

Connect a destination

What a destination needs from you, and where the Intent ID lands.