Authentication¶
Every authenticated Partner API call carries a bearer token that you obtain by exchanging the username and password your broker issued you. There is no interactive login and no session cookie — the token is the whole credential.
Your credentials¶
A broker creates your partner credentials in the Backoffice and gives you a username and a password. The password is shown once, at the moment it is created, and cannot be recovered afterward. Store it somewhere safe (a secrets manager, not source control). If you lose it, ask the broker to reset it.
The /token handshake¶
Exchange your credentials for a token at POST /token. Send a JSON body with two
fields (a form-encoded body is rejected):
{ "userName": "your-username", "password": "your-password" }
Both fields are required. On success you get back a token and its lifetime:
{ "Token": "eyJhbGciOi...your token...", "ExpiresIn": 82800 }
The token response uses different casing
The /token response fields are Token and ExpiresIn (capitalized).
The data endpoints return their fields in a different casing — parse each
response against the shapes in the Reference.
ExpiresIn is the token lifetime in seconds — 23 hours. The expiry is
enforced: once the token expires, the data endpoints return 401. Request a
fresh token from /token before the current one expires. There is no refresh
token; you re-authenticate with your username and password.
The bearer token¶
Send the token on every authenticated request in the Authorization header. The
Bearer prefix is required — a bare token is rejected with 401:
Authorization: Bearer eyJhbGciOi...your token...
Input field casing¶
Request fields are accepted in either casing — email and Email,
firstName and FirstName, userName and UserName all work. You do not need
to change the casing your integration already sends. Response fields use the
casing shown in the Reference; treat that as authoritative for
parsing.
Scopes¶
Each set of credentials carries a set of scopes that decide what the holder may do. Brokers set them in the Backoffice; a freshly issued partner is least privilege and can do almost nothing until scopes are granted.
| Scope | Values | Controls |
|---|---|---|
| Account visibility | Own, All |
Which accounts appear in reads — Own returns only the accounts this partner created; All returns every account under the brand |
| Transactions | None, Ftd, All, CustomFtd |
Access to /transactions and which fields return |
| Positions | on / off | Access to the positions endpoint |
| Creation scopes | a set of grants | Which account-creation methods are allowed |
How scopes affect a call:
- Reading positions or transactions without the scope returns
403. - Creating an account without the matching creation scope returns
403. - Listing accounts never returns
403for scope — a narrower visibility simply returns fewer rows.
See Querying data for how visibility interacts with filters, and Managing partners for how a broker configures each scope.
IP allow-list¶
A partner can be pinned to an IP allow-list of individual addresses or CIDR
ranges (both IPv4 and IPv6). When the list is non-empty, a request from any
address outside it is rejected — including the POST /token request itself.
After adding a new address to your allow-list, request a fresh token.
If the list is empty, there is no IP restriction — the allow-list is
opt-in, so a partner with no entries is reachable from anywhere. The client
address is resolved with a trusted-proxy-aware check, so a spoofed
X-Forwarded-For header from an untrusted source is ignored.
Brokers configure the allow-list per partner in the Backoffice.
What a rejected request looks like¶
Authentication failures deliberately collapse to one generic response. Invalid credentials, an unknown or expired token, a missing bearer header, and a request from an address outside the IP allow-list all return the same status without saying which condition failed:
- A failed
POST /tokenreturns401with a plain-text body. - A data endpoint with a missing, invalid, or expired token returns
401with a plain-text body.
The responses do not distinguish between these cases, so a caller cannot use
them to probe which credentials exist. Treat any 401 as "this credential
cannot make this call" and check the username, password, token, header, and
calling address.
Throttling¶
Requests are rate-limited per partner. When you exceed the limit, you get:
429 Too Many Requests
Every endpoint — including /token — can return 429. Design your integration
to tolerate it: retry with exponential backoff rather than hammering the
endpoint.