Skip to content

Authorization

The Betting API uses OAuth 2.0 with the client credentials grant. You create a client_id and client_secret for your white label yourself in the Betting Backoffice. Exchange them for a short-lived Bearer access token at the token endpoint, then include this token in every API request.

Migrating from X.509 certificates

The Betting API previously required a mutual-TLS (mTLS) X.509 client certificate. It has since migrated to OAuth 2.0. Certificate-based access still works so existing integrations (and their generated clients) keep functioning, but it is deprecated — new integrations should use OAuth 2.0, and existing ones should migrate when convenient. See Legacy: mTLS authentication below.

Info

Replace {betting-api-host} with the environment host — integration: betting.int.databet.cloud, production: betting.databet.cloud.

1. Request an access token

1
2
3
curl -u 'CLIENT_ID:CLIENT_SECRET' \
     -d grant_type=client_credentials \
     https://{betting-api-host}/oauth/token
Response
1
2
3
4
5
6
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "*"
}

1
2
3
4
curl -d grant_type=client_credentials \
     -d client_id=CLIENT_ID \
     -d client_secret=CLIENT_SECRET \
     https://{betting-api-host}/oauth/token

The token endpoint accepts an application/x-www-form-urlencoded body (not JSON). Credentials may be sent either via HTTP Basic (recommended) or as client_id / client_secret body fields — use one method, not both.

2. Call the API with the token

Send the token in the Authorization header on every request:

1
2
3
curl -H 'Authorization: Bearer ACCESS_TOKEN' \
     https://{betting-api-host}/token/create \
     --data '{"locale": "en", "currency": "EUR"}'

Access tokens are short-lived (see expires_in, in seconds). When a token expires, request a new one — the client credentials grant has no refresh token.

3. Try it in the browser

On any Betting API page, click Authorize, enter your client_id / client_secret, and the docs fetch a token for you — then use Try it out on the endpoints. You can also issue a token directly below.

Token endpoint

Legacy: mTLS authentication (deprecated)

Deprecated

mTLS with an X.509 client certificate is the previous authentication method. It is still accepted so existing integrations are not broken, but it is deprecated — prefer OAuth 2.0 (above) for new work. With mTLS you present client.crt / client.key on the TLS connection and call the API directly — no access token is involved.

Check that the certificate works

Send a request via curl to create a demo user token (refer to the Token section for details).

1
2
3
4
curl --location https://{betting-api-host}/token/create \
     --cert client.crt \
     --key  client.key \
     --data '{"locale": "en", "currency": "EUR"}'
Response
1
2
3
{
  "token": "BRmOHaVLzmJ4_PiYfmWTlEJ3pNNYiM-JCPOQdkvcosixrwdFsV7CXiStzpgWE4n_WfswYN4Bf6BSe6QyaioMI5E1FDmEUqARuQ-4Js5vtVA9WV9fjDoEfq1Pzb1Dk6fnKqOPDRJuXwiBoRvIJsxYSg"
}

Put your client.crt and client.key in the project's directory.

Info

Make sure you've replaced {betting-api-host} with the environment host (see the note at the top of this page).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package main

import (
    "bytes"
    "crypto/tls"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

func main() {
    const bettingAPIHost = "{betting-api-host}"

    certificate, err := tls.LoadX509KeyPair("client.crt", "client.key")
    if err != nil {
        panic(fmt.Sprintf("Failed to read X509 key pair: %s", err))
    }

    httpClient := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                Certificates: []tls.Certificate{certificate},
            },
        },
    }

    type tokenRequest struct {
        Locale   string `json:"locale"`
        Currency string `json:"currency"`
    }

    body, err := createReaderForAny(tokenRequest{
        Locale:   "en",
        Currency: "EUR",
    })
    if err != nil {
        panic(fmt.Sprintf("Failed to create reader: %s", err))
    }

    url := fmt.Sprintf("https://%s/token/create", bettingAPIHost)

    resp, err := httpClient.Post(url, "application/json", body)
    if err != nil {
        panic(fmt.Sprintf("Failed to get response: %s", err))
    }

    data, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(fmt.Sprintf("Failed to read all body: %s", err))
    }

    fmt.Printf("%s\n", resp.Status)
    fmt.Printf("Body:\n%s", data)
}

func createReaderForAny(v any) (io.Reader, error) {
    data, err := json.Marshal(v)
    if err != nil {
        return nil, fmt.Errorf("marshal data: %w", err)
    }

    return bytes.NewBuffer(data), nil
}

1. Prerequisites.

Init a new project and add the required dependency:

1
2
npm init
npm install node-fetch

Make sure that your project type is module.

requirements.json
1
2
3
4
5
6
7
8
{
  ...
  "type": "module",
  "dependencies": {
    "node-fetch": "^3.3.2"
  }
  ...
}

2. Code example

Put your client.crt and client.key in the project's directory.

Put this code into an index.js file within the created project.

Info

Make sure you've replaced {betting-api-host} with the correct API host.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import fetch from 'node-fetch';
import fs from 'node:fs'
import https from 'https';

const bettingAPIHost = '{betting-api-host}'

const response = await fetch(`https://${bettingAPIHost}/token/create`, {
  method: 'POST',
  body: JSON.stringify({
    locale: 'en',
    currency: 'EUR'
  }),
  agent: new https.Agent({
    cert: fs.readFileSync('client.crt'),
    key: fs.readFileSync('client.key'),
  })
});

if (response.ok) {
  console.log(await response.json())
} else {
  console.error(`HTTP Error! Status: ${response.status}. Body: ${await response.text()}`)
}

3. Run

1
2
3
4
node index.js
{
  token: 'BRmOHaVLzmJ4_PiYfmWTlEJ3pNNYiM-JCPOQdkvcosixrwdFsV7CXiStzpgWE4n_WfswYN4Bf6BSe6QyaioMI5E1FDmEUqARuQ-4Js5vtVA9WV9fjDoEfq1Pzb1Dk6fnKqOPDRJuXwiBoRvIJsxYSg'
}