Handling Auth Tokens
This guide explains the integration tokens system within Mesh API, encompassing the processes of token generation, renewal, and storage. It can be used to better understand the system so that developers can follow best practices when integrating with Mesh APIs.
What is a “token”
AccessToken
or AuthToken
is a generated secret (sequence of symbols) that is returned by Mesh API upon successful account authentication and used in subsequent requests to access the user’s data.
Each token represents a connection between a particular user (typically, an end user of a client) and the user’s brokerage/exchange/wallet account.
The token grants access to the user’s data and enables the execution of read and (based on the integration) write operations. Therefore, it is essential to store the token with utmost security measures in place.
Types of tokens
There are 2 types of tokens provided by the Mesh API:
AccessToken
A token that allows performing read and write operations with the connected account.
Can be obtained in the following ways:
- in a Link JS callback upon successful authentication managed authentication - recommended
- by calling /api/v1/linkToken
- by refreshing the token using the refreshToken in the following request - /api/v1/token/refresh
RefreshToken
A token that is returned by some integrations and needs to be used to refresh the access token before it expires.
Provided typically by OAuth and username password integrations, it is critical that it is handled correctly in order to ensure continued connections to accounts.
Can be obtained in the following ways:
— in a Link JS callback upon successful authentication managed authentication - recommended
-
by calling /api/v1/authenticate
-
by refreshing the token using the refreshToken in the following request - /api/v1/token/refresh
-
by refreshing the refresh token using the refreshToken in the following request - /api/v1/token/refresh and providing
CreateNewRefreshToken
parameter
General design
An important difference between Mesh and similar platforms is that Mesh does not store authentication tokens generated by integrations. Instead, Mesh API gets tokens from integrations, encrypts them and then returns back to API clients.
The main benefit of this approach is security. Even having access to Mesh’s system does not make it possible to manipulate customer accounts. Even Mesh employees are not able to use connections to integrations to perform operations with accounts.
Considering that Mesh supports critical write
actions (trading and transfers) this approach makes the platform way safer compared to similar platforms that store tokens on their side.
However, there are also several disadvantages:
- Clients have to manage tokens on their side - store and refresh them when necessary
- Tokens are of different lengths
- Different integrations return tokens in different formats - each with its own Time-To-Live (TTL), some of them require to be refreshed while other ones do not, and so on
- There are some exceptions that have to be handled manually - for example,
Delay
authentication approach (Interactive Brokers) or the requirement to refresh theRefreshToken
in some integrations
Data model
Successful Authenticate
or RefreshToken
call result (only relevant fields are shown):
Field | Type | Description | Note |
---|---|---|---|
AccessToken | string (can be null) | The access token that is used to access user’s data | Provided when the connection contains only one account |
RefreshToken | string (can be null) | The refresh token that is used to refresh the access token | Optional and depends on the specific integration. Some integrations do not provide refresh tokens |
ExpiresInSeconds | number (can be null) | Specifies the duration, measured in seconds, after which the Access token expires and becomes unavailable | Optional, depends on the integration. If not provided, it indicates that the token associated with that integration does not have an expiration time and can be used indefinitely |
RefreshTokenExpiresInSeconds | number (can be null) | Specifies the duration, measured in seconds, after which the Refresh token expires and becomes unavailable | Optional, depends on the integration. If not provided, it indicates that the Refresh token associated with that integration does not have an expiration time and can be used indefinitely |
AccountTokens | Array (can be null) | Contains the list of account tokens if the integration provides multiple accounts | Optional, used only if the integration provides multiple accounts or “subaccounts”. If provided, AccessToken and RefreshToken are not provided |
Account | BrokerAccount | General information about the connected account (AccountId, AccountName and so on) |
BrokerAccount
model:
Field | Type | Description | Note |
---|---|---|---|
AccessToken | string (can be null) | The access token that is used to access user’s data | |
RefreshToken | string (can be null) | The refresh token that is used to refresh the access token | |
Account | BrokerAccount | General information about the connected account | eg. (AccountId, AccountName and so on) |
Structure of token responses by integration types
API key integrations
Typically, API key integrations do not have an “access token” concept. Authentication is based on constant ApiKey
and ApiSecret
values that are obtained by users and provided to Mesh API during authentication. Mesh API does not store these values, instead, the API concatenates and encrypts them. The result is returned in the AccessToken
field. Since the accessToken contains encrypted ApiKey and ApiSecret values and not actual integration’s tokens, there is no need to refresh them. That’s why the RefreshToken is typically not returned for such integrations.
Kraken API Example
Please note:
RefreshToken
is not provided (there’s no need to refresh this token)ExpiresInSeconds
is not provided (the token never expires)RefreshTokenExpiresInSeconds
is not provided (there’s no refresh token)
Email-password integrations
Token data of username-password integrations may vary, based on specific implementations of underlying APIs of brokerage integrations. In most of the cases they follow a JWT token authentication approach and require to refresh the accessToken
.
Robinhood Example:
Please note:
ExpiresInSeconds
is provided, the value 734000 indicates that the access token will be expired after 734000 seconds (approximately 8 days)RefreshToken
is provided, and should be used to refresh the access token before access token expiresRefreshTokenExpiresInSeconds
is not provided, it means that the refresh token never expires, and can be used even after the access token is expired
OAuth integrations
OAuth implementations may also vary. For example, Alpaca does not provide the RefreshToken. They provide the AccessToken only which means that the AccessToken never expires.
But generally, typical token response contains both Access and Refresh tokens and requires only the AccessToken to be refreshed.
Coinbase Example:
ExpiresInSeconds
is provided, the value 7200indicates that the access token will be expired after 2 hours, so in this case it has to be refreshed oftenlyRefreshToken
is provided, and should be used to refresh the access token before access token expiresRefreshTokenExpiresInSeconds
is not provided, it means that the refresh token never expires, and can be used even after the access token is expired
Self Custody Wallets
Because of the nature of DeFi wallets, Mesh API never receives any sensitive information related to a wallet connection, like the private key or the seed/mnemonic phrase of the wallet. So technically, there’s no need to use secret tokens. But in order to follow the approach that is used with other integrations, Mesh generates the accessToken for DeFi wallet connections and uses the token to identify the connected chain type and connected address. Since there’s nothing to refresh, Mesh API returns the accessToken
only:
Subaccounts and multiple accounts
Integrations have different structure of accounts. For example:
- Robinhood and Coinbase allow to have one account only
- Kraken allows multiple accounts, but each should be registered using a different email, so every account is completely separate
- Binance account contains several subaccounts by default - “Spot” account and “Margin” account
- Some exchanges have a concept of “Funding” account (that is used to deposit and withdraw fiat and crypto) and “Trading” account (that is used for trading only).
Because of a completely different nature of account handling by integrations, Mesh API does not have a concept of subaccounts. Instead, for integrations that support multiple accounts, Mesh API returns them on the same level, as completely equal accounts.
Binance Example:
Note that:
- top level
AccessToken
andRefreshToken
fields are empty, and both pairs ofAccessToken
andRefreshToken
are provided inaccountTokens
field.
Refresh Token Implementation
Best Practices
Suggested logic on how to implement the flow to refresh tokens to cover all possible scenarios properly:
- Check if
expiresInSeconds
value is present - If
expiresInSeconds
is present, it means that theaccessToken
should be refreshed before it is expired - Create a logic that registers the timestamp when the
accessToken
is obtained, records theexpiresInSeconds
and uses therefreshToken
to refresh the token beforetimestamp
+expiresInSeconds
comes - If
refreshTokenExpiresInSeconds
is also provided, create the same logic for therefreshToken
- it should be refreshed using/api/v1/token/refresh
call withCreateNewRefreshToken: true
parameter beforetimestamp
+refreshTokenExpiresInSeconds
time comes - Check the documentation for the exceptions and implement them for the required integrations.
Bad Practices
It’s a bad practice to rely on 401 responses and update Access and Refresh tokens after they have expired. Integrations may track this behavior and block clients that do not refresh tokens properly.
The proper approach is to handle expiresInSeconds
and refreshTokenExpiresInSeconds
values properly and refresh token/tokens before tokens expire.
Exceptions
There are some exception related to token flows related to limitations of specific integrations.
They are mostly related to the refreshToken and described in the documentation.
Interactive Broker: Delayed Authentication
Interactive Brokers API has a limitation. The problem is that when user is authenticated against the API for the first time before 16:55 EST, the IBKR API does not return information about user’s accounts (number of available accounts, their IDs etc.). This information becomes available only the next day (after the “nightly” refresh of the API).
This happens with accounts that were never connected to the API before.