Skip to content

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 403 for 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 /token returns 401 with a plain-text body.
  • A data endpoint with a missing, invalid, or expired token returns 401 with 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.