When you’d use this
The everyday case is a broker (a regulated counterparty that owns the client relationship) serving multiple customer organizations through a single platform integration. Each customer has their own org, accounts, balances, and funding methods. The broker holds an API key and operates on each customer’s behalf one request at a time. Examples:- A private-broker program where each high-net-worth client has their own org but is operated by the broker’s desk.
- A platform that white-labels nxos for partner firms, each managing their own clients.
- A treasury operations team that consolidates several legal entities under one operating team.
The model
With an LOA, one organization is authorized to act on behalf of another via the platform API. The granting organization (the customer) signs the LOA; the authorized organization (the broker) holds it. Once active, the broker sends requests with theNxos-On-Behalf-Of header set to the customer’s org id, and the platform scopes the request to the customer’s data.
Signing happens as part of the customer’s verification flow. Revoking ends access; re-establishing it requires a new grant.
Lifecycle
KYB gating
AnACTIVE LOA is necessary but not sufficient. The granting organization must also currently be in good standing on KYB (verification status APPROVED, no past-due expiry). If the granter’s verification moves to PENDING, ON_HOLD, REJECTED, or RESUBMISSION_REQUIRED, the LOA is suspended for that period and the broker’s requests return 403 authorization_required. Access resumes automatically when the granter returns to APPROVED.
From the broker’s perspective, this is indistinguishable from a missing LOA: the response is the same 403 authorization_required. The granter’s compliance status is not leaked to a third party.
Reading a customer’s accounts and transactions
Reads are not gated. AGET on /v1/accounts, /v1/transactions or /v1/reports (and the routes under them) accepts any LOA the customer has not revoked, PENDING or ACTIVE, whatever the customer’s KYB status, and even when the customer’s organization is blocked or archived. A broker keeps seeing the history and balances of a customer it represents while that customer is on hold or under review.
Everything else stays gated as described above: writes on those routes, and every other delegation-enabled route. Funding methods in particular are not opened, so a blocked customer’s deposit instructions are not handed out.
The verification routes are deliberately exempt, because they are how the customer gets approved in the first place. They accept a PENDING LOA and do not require the customer’s KYB to be APPROVED. Their authority comes from a different check: you may only use them on an organization you created.
Using Nxos-On-Behalf-Of
Once an LOA between customer org_cust... and broker org_brkr... is ACTIVE and the customer’s KYB is APPROVED, the broker calls any delegation-enabled endpoint by setting the header:
Which routes accept the header
Each route opts in to delegation individually. Self-only routes (creating a child org, signing) omit it: a broker cannot sign an LOA on a customer’s behalf, nor create a customer’s children. Routes that read or operate on accounts, balances, beneficiaries, quotes, payouts, and NXOS-to-NXOS transfers all accept the header. If you sendNxos-On-Behalf-Of to a route that doesn’t accept delegation, the header is silently ignored and the request stays scoped to your own org. The default posture is default-deny: a route only sees data the caller has direct authority over unless it explicitly opts in.
Possible 403 responses
Revoking an authorization
Either side of the grant can callPOST /v1/authorizations/revoke: the granting customer or the authorized broker. The caller’s organization (from the API key) must be one of the two parties. Otherwise the call returns 403 forbidden.
Idempotency
A second revoke of the same(granter, authorized, type) tuple returns 404 authorization_not_found. The row is already REVOKED and excluded from the active set. There is no separate already_revoked error code. “Already revoked” and “never existed” surface identically by design.
You can also supply an Idempotency-Key header for client-side dedup of network retries. See Idempotency.
Possible errors
Summary
Related
- Authentication: how API keys work
- Verification: bringing a customer org through KYB
- Accounts: what scopes by organization