Skip to main content
Most custodians should use scheduled downloads — see Audit Exports. This page is for the minority of custodians who need programmatic access: real-time accounting reconciliation or downstream systems that can’t consume batch exports.
Musubi’s backend exposes REST + SSE APIs that you can integrate directly. This page covers authentication, the proposal/quote workflow programmatically (as an alternative to the Console), and real-time settlement events.

When to use this

  • Your downstream systems are event-driven (real-time, not batch-ingested)
  • Your accounting system reconciles continuously and can’t wait for daily exports
  • You’re automating the accept/reject authorization decision itself
  • You need sub-second settlement notifications (most custodians do not)
If none of those apply, use the Console + Audit Exports — the integration is less work and covers the same ground.

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

Full endpoint shapes, request/response examples: API Reference.
Error handling worth adding: catch 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. For rejectQuote, surface UnprocessableEntity on 422 (rejection_detail too short) as a client-side validation bug — auditors expect ≥ 20 chars.

Real-time settlement events via SSE

Production notes

  • Idempotency. Handle SETTLED events idempotently — SSE reconnects can replay the latest event. Key your accounting write by intentId + transactionHash.
  • Ordering. order_updated events are per-contract — you may see EXECUTING then SETTLED for the same intent. Filter to SETTLED only if that’s the only state your accounting cares about.
  • Backpressure. If your downstream is slow, switch .doOnNext to .concatMap(ev -> Mono.fromCallable(() -> handle(ev)).subscribeOn(Schedulers.boundedElastic())) so slow handlers don’t starve the event loop.

Other stacks

Same shape, different clients:
  • Nodefetch for REST; EventSource (native) or eventsource package for SSE
  • Pythonhttpx or requests for REST; httpx-sse or sseclient-py for SSE
  • Kotlin — same WebClient as Java; or ktor-client-cio + SSE
The pattern in all cases: authenticate with JWT, filter SSE to order_updated with status == SETTLED, dispatch to your downstream handlers with idempotency keyed on intentId + transactionHash.