Most custodians should use scheduled downloads — see Audit Exports. This page is for the minority of custodians who need programmatic access: custom compliance rails, real-time accounting reconciliation, or downstream systems that can’t consume batch exports.
When to use this
- Your compliance archive is real-time (event-driven, not batch-ingested)
- Your accounting system reconciles continuously and can’t wait for daily exports
- You’re automating the authorization decision itself behind a risk engine
- You need sub-second settlement notifications (most custodians do not)
Authentication
JWT bearer token, refreshed roughly every hour. Full details in Authentication. Typical pattern: cache the token, refresh ~60 s before expiry, retry once on 401 after forcing a refresh.Proposal + quote workflow via REST
| Endpoint | Purpose |
|---|---|
GET /api/v1/orders?status=PENDING | List incoming proposals awaiting your accept/reject |
POST /api/v1/orders/{intent_id}/accept | Sender custodian accepts the proposal — proceeds to quoting |
GET /api/v1/orders/{intent_id}/quotes | Review competing market maker quotes |
POST /api/v1/orders/{intent_id}/quotes/{quote_id}/accept | Sender custodian co-signs the chosen quote |
GET /api/v1/orders/events (SSE) | Real-time order_updated and quote_received events |
WebClientResponseException.Unauthorized on 401 → force-refresh the token and retry once; surface Conflict on 409 (expired quote, order already advanced) back to whatever subsystem triggered the call.
Real-time settlement events via SSE
Production notes
- Idempotency. Handle
SETTLEDevents idempotently — SSE reconnects can replay the latest event. Key your accounting write byintentId + transactionHash. - Ordering.
order_updatedevents are per-contract — you may seeEXECUTINGthenSETTLEDfor the same intent. Filter toSETTLEDonly if that’s the only state your accounting cares about. - Backpressure. If your downstream is slow (compliance archive is commonly the bottleneck), switch
.doOnNextto.concatMap(ev -> Mono.fromCallable(() -> handle(ev)).subscribeOn(Schedulers.boundedElastic()))so slow handlers don’t starve the event loop.
Other stacks
Same shape, different clients:- Node —
fetchfor REST;EventSource(native) oreventsourcepackage for SSE - Python —
httpxorrequestsfor REST;httpx-sseorsseclient-pyfor SSE - Kotlin — same
WebClientas Java; orktor-client-cio+SSE
order_updated with status == SETTLED, dispatch to your downstream handlers with idempotency keyed on intentId + transactionHash.