Deribit’s API uses an OAuth 2.0 style authentication for all private API requests. This means you must obtain an access token (and accompanying refresh token) using your API key credentials before calling private endpoints. Public API methods (market data, etc.) do not require authentication, but authenticated connections have higher rate limits and more features (raw event feed).
This guide explains how to set up API keys, authenticate with the Deribit API, manage tokens (including fork_token usage), and handle access scopes for different permission levels.
Before authenticating, create an API key in your Deribit account. You can choose either a Deribit-generated key (for Client ID/Secret credentials authentication) or a self-generated key (for asymmetric signature authentication).
Tip
For detailed steps on generating API keys, see the Deribit Creating new API key on Deribit and Asymmetric API keys articles.
Certain private methods in the Deribit API (for example, withdrawals or security-related account actions) require Two-Factor Authentication (2FA). If your account has 2FA enabled, you must provide the second factor when calling these methods via API.
Note
API requests without the required 2FA confirmation will be rejected with the error security_key_authorization_error (code: 13668). Always ensure your application flow supports sending the second factor where required.
-
See the Security Keys section in the API docs for the technical details on confirming operations with 2FA or hardware keys.
-
For enabling and managing 2FA in your account, follow the steps in Two-Factor Authentication Article.
Deribit’s primary authentication endpoint is public/auth. Calling this will return a JSON object containing an access_token and a refresh_token, among other fields . There are three grant types you can use when calling public/auth:
-
Client Credentials: Use your Client ID and Client Secret directly to get a token (suitable for server-to-server API use). This is the simplest method – you supply
grant_type=client_credentials, along with yourclient_idandclient_secret. -
Client Signature: Use a cryptographic signature instead of sending the secret. You generate an HMAC-SHA256 signature of a string containing a timestamp, a random nonce, and optional data, using your Client Secret as the key . This method (often used with asymmetric API keys) requires
grant_type=client_signature, and you must provideclient_id,timestamp(current time in ms),nonce,signature, and (if desired) adatafield. Deribit verifies the signature instead of requiring the raw secret. (See the official docs for the exact signing formula or the Asymmetric API keys guide for setting up keys for this method.) -
Refresh Token: Use a previously obtained
refresh_tokento get a new access token . Setgrant_type=refresh_tokenand provide therefresh_tokenvalue. This returns a freshaccess_token(and a new refresh token), extending your session without needing the Client Secret again.
Example – Client Credentials Flow: Below is a sample request using client credentials, and the response structure:
GET /api/v2/public/auth?grant_type=client_credentials&client_id=<YOUR_CLIENT_ID>&client_secret=<YOUR_CLIENT_SECRET>
On success, you receive a JSON response like:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"access_token": "1582628593469.1MbQ-J_4.CBP-OqOw...uARm",
"expires_in": 31536000,
"refresh_token": "1582628593469.1GP4rQd0.A9Wa78...A9jM",
"scope": "connection mainaccount",
"token_type": "bearer"
}
}
The access_token is a long string (truncated above) which is used to authenticate subsequent requests . The expires_in field (in seconds) tells you how long the token is valid, and refresh_token can be stored to renew your access when needed . The scope shows the granted access scope of this token (more on scopes below), and token_type will be “bearer”.
Using the token: Once you have an access token, you must include it with any private API request. How to include it depends on the connection type:
-
HTTP REST requests: Include the token in the HTTP Authorization header:
Authorization: Bearer <access_token>.
-
WebSocket (JSON-RPC) requests: Include the token as a parameter in each JSON request: e.g., "params": { "access_token": "<access_token>", ... } for private methods . If you authenticated a WebSocket connection with a session token (see Connection Management - Best Practices), the server will remember your token, allowing you to omit the token in subsequent requests on that same WebSocket connection.
Tip
Manage your tokens securely: store refresh tokens if you need long-lived access, and treat access tokens like passwords (never expose them publicly).
Client Signature Authentication
To perform a client signature authentication:
1. Prepare the components:
-
grant_type– Must beclient_signature -
client_idandclient_secret– Can be found on the API page on the Deribit website after creating the API key -
timestamp– Time when the request was generated, given as milliseconds. It is valid for 60 seconds since generation; after that, any request with an old timestamp will be rejected -
signature– Value for the signature calculated as described below -
nonce– Single-use, user-generated initialization vector for the server token -
data– Optional field, which contains any user-specific value
2. Build the string to sign:
Deribit’s client-signature flow signs a very specific byte sequence. Use HMAC‑SHA256 with your Client Secret as the key and hex‑encode the digest.
Formula:
StringToSign = Timestamp + "\n" + Nonce + "\n" + Data Signature = HEX_STRING( HMAC-SHA256( ClientSecret, StringToSign ) )
Important details
-
Always include the two newline characters shown above.
If Data is omitted, treat it as an empty string, so the string still ends with \n after Nonce.
-
Use UTF‑8 for all strings.
-
Send the lowercase hex of the HMAC as signature.
-
timestamp is milliseconds since epoch. nonce should be unique per request.
Shell (OpenSSL) one‑liner
General form, works on Linux and macOS:
ClientId="YOUR_CLIENT_ID" ClientSecret="YOUR_CLIENT_SECRET" Timestamp="$(date +%s000)" # ms since epoch; on macOS this is fine Nonce="$(LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c8)" Data="" # or some context string Signature="$( printf "%s\n%s\n%s" "$Timestamp" "$Nonce" "$Data" \ | openssl dgst -sha256 -hmac "$ClientSecret" -r \ | cut -d' ' -f1 )" echo "$Signature"
Example
ClientId=AMANDA ClientSecret=AMANDASECRECT Timestamp=1576074319000 Nonce=1iqt2wls Data="" Signature="$( printf "%s\n%s\n%s" "$Timestamp" "$Nonce" "$Data" \ | openssl dgst -sha256 -hmac "$ClientSecret" -r \ | cut -d' ' -f1 )" echo "$Signature" # -> 56590594f97921b09b18f166befe0d1319b198bbcdad7ca73382de2f88fe9aa1
3.Send the request:
Call public/auth with grant_type=client_signature and include:
-
client_id -
timestamp -
nonce -
signature(the HMAC you calculated) -
data(if used in the signature)
Sample JSON-RPC request using values calculated before:
{
"jsonrpc": "2.0",
"id": 9929,
"method": "public/auth",
"params": {
"grant_type": "client_signature",
"client_id": "AMANDA",
"timestamp": 1576074319000,
"nonce": "1iqt2wls",
"data": "",
"signature": "56590594f97921b09b18f166befe0d1319b198bbcdad7ca73382de2f88fe9aa1"
}
}
On success, the server returns an access_token and refresh_token, the same as with client credentials authentication.
You can also use the following Python code to automatically generate the signature and complete the authentication process on test enviroment
import datetime
import random
import string
import hashlib
import hmac
import requests
from datetime import datetime
ClientId = ""
clientSecret = ""
Timestamp = round(datetime.now().timestamp() * 1000)
Nonce = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(8))
data = ""
def calcSignature(method, uri, secret, timestamp, nonce, body):
requestData = f'{method}\n{uri}\n{body}\n'
message = f'{timestamp}\n{nonce}\n{requestData}'
return hmac.new(
bytes(secret, "ascii"), # Changed to 'utf-8'
msg=bytes(message, "utf-8"), # Changed to 'utf-8'
digestmod=hashlib.sha256
).hexdigest().lower()
Signature = calcSignature("GET", "/api/v2/private/get_account_summary?currency=BTC&extended=true", clientSecret, Timestamp, Nonce, data)
headers = {
'Authorization': f'deri-hmac-sha256 id={ClientId},ts={Timestamp},nonce={Nonce},sig={Signature}',
'Content-Type': 'application/json' # Added Content-Type header
}
response = requests.get(
"https://test.deribit.com/api/v2/private/get_account_summary?currency=BTC&extended=true",
headers=headers
)
print(response.json())
print(ClientId, Timestamp, Nonce, Signature)
When you authenticate with public/auth (using client credentials or client signature), the response contains both an access_token and a refresh_token.
-
access_token– used to authorize your API calls (via Authorization: Bearer <token> in HTTP or as access_token in WebSocket requests). -
refresh_token– used to obtain a new access token once the current one expires.
Why use a refresh token?
Access tokens have a limited lifetime (defined in the expires_in field). Instead of re-supplying your Client ID and Client Secret each time, you can call public/auth again with grant_type=refresh_token and your stored refresh token. This extends the session securely without exposing your credentials.
Example:
{
"method": "public/auth",
"params": {
"grant_type": "refresh_token",
"refresh_token": "<1756301374726.1R2lPbsF.Q_Oqe7J-NpqHhhVV46NHvJuaidr5S1e3pdaO9pAvUoPmJFnSU9faJqxSiTp2Q4I_oT8XsiQo3mMu-0wFoqnY80Epz84XmRH-wQaCZ0jJEMFLUWZI-ILtUPMoPwvL9QFxhAX9sw8J-8559qNHjAJ_X3a_oGk8GTmIpEEF6Zenr00VWiPsMWxY17LmQf6xXd5q4kHk7cLsyoTSv76qrP-260xsshwomb6iJ7SMdTQYlG1D69mBBr1q_ECupVoOm0w9Wp0pxC0KSqyalhuNMLcKGFZveCA-pZQ2GH93WQptzVA-Mh0Gcw>"
}
}
Response contains a new access_token (and a new refresh_token).
Session behavior
-
If your token was issued with a session scope, refreshing keeps the same session active and does not consume extra session slots.
-
If you did not request a
sessionscope, each refresh generates a new connection-scoped token and invalidates the previous one.
Best practices
-
Always keep your refresh token secure. It can be used to mint new access tokens.
-
Implement automatic refresh shortly before expiry (check the
expires_invalue). -
Persist the latest refresh token if your application restarts.
Fork Token
Session tokens can be “cloned” using the public/fork_token method. This is an advanced feature to help manage multiple sessions. fork_token takes a valid refresh token from an existing session-scoped token and generates a new access token for a new session (with a name you specify). In other words, it lets you fork an existing session into another session without re-supplying your client secret. This is only allowed for session-scoped tokens (you cannot fork a connection-only token).
When to use fork token?
Suppose you have an application already authenticated on one server and you want to spin up a second client (or a sub-service) using the same account and API key. Instead of storing the Client Secret or asking for credentials again, you can take the refresh token from the first session and call public/fork_token to create a new session token for the second client. The new token will have the same scopes as the original (but tied to a different session name). Both sessions can operate concurrently under the same API key.
Exchange Token
public/exchange_token lets you turn a refresh token into a new access token for a different subaccount. A subject_id identifies the target subaccount, so this method is the standard way to switch between subaccounts without sending your Client Secret again. The resulting token keeps the same permissions unless you supply a scope override.
When to use exchange token?
You are authenticated on one subaccount and need to act on another subaccount with the same API key. Call public/exchange_token with:
-
refresh_tokenfrom your current session -
subject_idof the destination subaccount -
optional
scopeto override scopes and to set asession:nameif you want a session token created during the exchange. Scopes on the new token cannot exceed the permissions of the caller.
For convenience, Deribit also supports two alternative methods for HTTP requests: Basic Auth and HMAC Auth.
With Basic Auth, you can send: Authorization: Basic <base64(client_id:client_secret)> in your HTTP request, and Deribit will authenticate and execute the request in one step.
With HMAC Auth (Deribit Signature Credentials), you sign the request using your secret (as in the client_signature method) and include it in an Authorization: deri-hmac-sha256 ... header .
These methods eliminate the need for a prior token request, but are typically used in advanced scenarios or if you prefer not to handle token refresh separately. Most developers find it simplest to use public/auth to get a bearer token and use that for subsequent calls.
Finally, you can log out and invalidate tokens using private/logout (WebSocket only) if needed, but generally tokens will expire automatically after their expires_in duration.
Notice
Logging out with private/logout does not trigger Cancel on Disconnect. Any outstanding orders or quotes will remain active unless explicitly canceled.