Broker API HubMenu

Deriv API quickstart: token to first REST call

Make a first Deriv REST call: a health check with no credentials, then your Options accounts with a bearer token, in Python, JavaScript or curl. Deriv's trading and market data run over WebSocket and are not covered here. The samples were written from Deriv's documentation and have not been run against Deriv.

Independent and unofficialChecked Code not yet run on a demo account

Risk warning: CFDs and spread bets are complex instruments and come with a high risk of losing money rapidly due to leverage. You can lose money on these products, and each provider publishes its own loss figure under FCA rules. You should consider whether you understand how they work and whether you can afford to take the high risk of losing your money. Automated and API trading can amplify losses through bugs, connectivity failures and runaway orders.

Demo accounts only. Credentials are read from environment variables on your own machine. No field on this site asks for a key, a username or a password.

Steps

  1. What this page covers, and what it does not

    Deriv splits its API in two. REST, on https://api.derivws.com, handles account creation and management. Trading itself (proposals, buy and sell) and live market data run over WebSocket. This quickstart covers the REST calls only, so it stops at reading your accounts and does not show a trade. Deriv says each user receives a default demo account at signup, so there is a demo account to read without creating one. You need a Deriv login and one of Python 3 with the requests package, Node 18 or later, or curl.

    developers.deriv.comchecked

  2. A call with no credentials: the health check

    GET /v1/health needs no authentication, no parameters and no body, so it tells you that your machine can reach Deriv's REST gateway before any token is involved. Deriv's page gives 200 as the reply status. The fields in the reply body were not read for this page, so the samples print the status and the raw body and nothing more.

    Python
    # No credentials are needed for this call.
    # Written from Deriv's documentation. Not run against Deriv.
    import requests
    
    BASE_URL = "https://api.derivws.com"
    
    resp = requests.get(BASE_URL + "/v1/health", timeout=10)
    print("HTTP", resp.status_code)
    print(resp.text)
    
    JavaScript
    // No credentials are needed for this call.
    // Written from Deriv's documentation. Not run against Deriv.
    // Node 18 or later. Save as a .mjs file so top level await works.
    const BASE_URL = "https://api.derivws.com";
    
    const res = await fetch(`${BASE_URL}/v1/health`, { method: "GET" });
    console.log("HTTP", res.status);
    console.log(await res.text());
    
    curl
    # No credentials are needed for this call.
    # Written from Deriv's documentation. Not run against Deriv.
    curl -i "https://api.derivws.com/v1/health"
    

    developers.deriv.comchecked

  3. Choose how you will get a token

    Deriv describes two routes. An OAuth 2.0 app sends the user to Deriv's sign in page and receives an access token without ever seeing a password. A Personal Access Token app has the user generate a token in Deriv and enter it into the application by hand. For a script that only you run, the Personal Access Token is the shorter route. The page opened for this step does not say where in Deriv the token is generated or where the application ID comes from, so those clicks are not given here: this site has not verified them. Whichever route you use, keep the token in an environment variable. The first authenticated call below needs a token carrying the trade scope.

    developers.deriv.comchecked

  4. Send the token as a bearer header

    Every authenticated REST request carries Authorization: Bearer followed by the token, which may be an OAuth 2.0 access token or a Personal Access Token. With a Personal Access Token you must also send a Deriv-App-ID header holding your application ID. Leave it out and Deriv answers 401 with the message Deriv-App-ID header is required for PAT tokens. With an OAuth 2.0 token the header is not needed, because the token already identifies the application. Deriv names four scopes: trade, account_manage, payment and application_read. The samples read the token from DERIV_TOKEN and the application ID from DERIV_APP_ID.

    developers.deriv.comchecked

  5. First real call: list your Options accounts

    GET /trading/v1/options/accounts lists your Options trading accounts. It is read only and Deriv lists the scope it needs as trade. The samples send both headers, which is what a Personal Access Token needs. If you are using an OAuth 2.0 token, remove the Deriv-App-ID line.

    Python
    # Set DERIV_TOKEN and DERIV_APP_ID as environment variables first. Never paste real values into code or into this site.
    # Written from Deriv's documentation. Not run against Deriv.
    import os
    import requests
    
    BASE_URL = "https://api.derivws.com"
    headers = {
        "Authorization": "Bearer " + os.environ["DERIV_TOKEN"],
        "Deriv-App-ID": os.environ["DERIV_APP_ID"],  # needed with a Personal Access Token
    }
    
    resp = requests.get(BASE_URL + "/trading/v1/options/accounts", headers=headers, timeout=10)
    print("HTTP", resp.status_code)
    resp.raise_for_status()
    for account in resp.json()["data"]:
        print(account["account_id"], account["account_type"], account["balance"], account["currency"], account["status"])
    
    JavaScript
    // Set DERIV_TOKEN and DERIV_APP_ID as environment variables first. Never paste real values into code or into this site.
    // Written from Deriv's documentation. Not run against Deriv.
    // Node 18 or later. Save as a .mjs file so top level await works.
    const BASE_URL = "https://api.derivws.com";
    
    const res = await fetch(`${BASE_URL}/trading/v1/options/accounts`, {
      method: "GET",
      headers: {
        "Authorization": `Bearer ${process.env.DERIV_TOKEN}`,
        "Deriv-App-ID": process.env.DERIV_APP_ID // needed with a Personal Access Token
      }
    });
    console.log("HTTP", res.status);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const body = await res.json();
    for (const account of body.data) {
      console.log(account.account_id, account.account_type, account.balance, account.currency, account.status);
    }
    
    curl
    # Set DERIV_TOKEN and DERIV_APP_ID as environment variables first. Never paste real values into code or into this site.
    # Written from Deriv's documentation. Not run against Deriv.
    # The Deriv-App-ID header is needed with a Personal Access Token.
    curl -s "https://api.derivws.com/trading/v1/options/accounts" \
      -H "Authorization: Bearer $DERIV_TOKEN" \
      -H "Deriv-App-ID: $DERIV_APP_ID"
    

    developers.deriv.comchecked

  6. Read the reply

    The reply is an object with two parts. data is a list, one entry per account, each with account_id, balance, currency, group, status (active or inactive) and account_type, which is demo or real. meta repeats the endpoint and the method and gives a timing figure. The field to read first is account_type: anything you do next should use the account_id of an entry whose account_type is demo. A token can see real accounts as well as demo ones, and no host name stands between the two on REST, so your code has to check.

    developers.deriv.comchecked

  7. The limits to respect

    Deriv's limits page gives three REST figures: 300 requests a minute and 1,000 requests in 10 minutes per IP address, and 80 requests a minute per logged in user. Deriv says that once you are logged in you reach the 80 a minute limit first, and that spreading requests across several IP addresses does not raise it. The page opened does not say what reply comes back when a limit is passed. WebSocket calls have their own budgets, counted per connection, on the same page. This site's limits register holds one Deriv row, 80 a minute per logged in user on REST, with the status verified and a check date of 22 September 2026: it is in the table below this list.

    developers.deriv.comchecked

  8. The errors you are likely to meet first

    A REST error arrives as an object with an errors list and the same meta block as a success. Each entry in errors has a status, a code and a message, so print all three. Deriv's page gives 401 for a missing or invalid token or a missing Deriv-App-ID header, 403 for a valid token that lacks the scope, 400 for a request that fails validation and 429 for too many requests. The codes it lists include InvalidToken, Unauthorized, ValidationError, NotFound and RateLimit. Deriv's advice is to retry read only GET calls with a growing delay between attempts and not to retry trades blindly. This site keeps a page for each recorded Deriv code under /errors/deriv, linked in the block at the foot of this page.

    developers.deriv.comchecked

  9. What to read next: the step to WebSocket

    The bridge from REST to trading is POST /trading/v1/options/accounts/{accountId}/otp. It exchanges your bearer token for a one time WebSocket address for one account, with the one time password already in the address. Deriv's overview gives separate demo and real WebSocket endpoints, and the address you receive follows the account you asked for, which is one more reason to pass a demo account_id. How long the address stays usable was not on the page opened. What you send once connected and what arrives, from ticks and proposal to buy, sell, portfolio and balance, is recorded message by message on this site at /brokers/deriv/messages, so read those pages beside Deriv's own and keep to the demo account while you do.

    developers.deriv.comchecked

Deriv limits to pace against

LimitValueScopeSource
Headline limit80/min per logged in user (REST)Sources conflict developers.deriv.com states 60, checked . Deriv's API overview in the text form it publishes for AI tools gives REST 60 requests a minute per token, where its Limits page gives 80 a minute per logged in user. The same overview also gives 100 WebSocket requests a second per connection, 100 active subscriptions per connection and 5 concurrent WebSocket connections per user, none of which the Limits page mentions. Deriv's own pages disagree; the conflict is labelled, not resolved. Pace against 60.user, RESTdevelopers.deriv.comchecked

Sources

Sections