Skip to content

Request signing

Every request made via any Sportsbook API must be signed by the sending side. Request receiver must validate the sign before handling request payload.

The signature attached to request with x-sign-jws header. For example:

x-sign-jws: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..UXwjHxU3tFlrzPMupG04zROiEcHFQpCg3l7J4Axr1fE

The signature format (Detached JWS) is basically a JWT token but without a middle (payload) part. The actual payload will be passed as request body (therefore there is no GET endpoints in Sportsbook API). The sign part for JWT is signed using HS256 with PARTNER_SECRET as a secret.

INFO

The Account Manager provides the PARTNER_SECRET parameter along with other credentials.

Check incoming request signature

To check request signature you need to perform following steps:

  • Get x-sign-jws HTTP header.
  • Get request body and encode it as base64url.
    • Hint: when you work with request body it's important to get a raw body instead of converting parsed body back to JSON string representation.
  • Put the generated base64url string into the Payload section (put encoded string between two dots in signature abc123.{GENERATED_BASE64}.def456) of the x-sign-jws signature.
  • Perform JWT token validation with any lib available for your language. You need to use HS256 algorithm with PARTNER_SECRET as a secret for verification.

TIP

You can find a lib suitable for your language on a dedicated section of jwt.io website.

Difference between base64 and base64url:

Do not confuse base64url with base64. In order to get a valid base64url you should first get base64 encoded string and then perform the following replacements:

  • Remove all = symbols.
  • Replace + with -.
  • Replace / with _.

Signature verification examples

Suppose we have the following inputs:

  • Secret (provided by account manager):
    PARTNER_SECRET: testdemo
  • Header:
    x-sign-jws: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..lvUiCPXIUDKlCk5Zb6QsNUeIbhqL95V_AyFSGNcLGAU
  • Request body:
    {"transactionId":"24a533a3-3ffc-4fbc-8cd6-c5c836f2da88","currency":"USD","amount":9.1,"userId":"cd233d8d-6b73-4098-ad65-972be20014f6","type":2,"coefficient":1.82,"token":"e18bed4abedab830b8f0d196df9b018eb5f72b51","requestId":"c1a97784-f32a-4329-9ac7-a2b3d957eb44","resultType":"won","bonusId":null,"bonusTemplateId":null,"gameType":"sportsbook"}

An example using firebase/php-jwt package:

php
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$PARTNER_SECRET = 'testdemo';
$headers = [
  'x-sign-jws' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..lvUiCPXIUDKlCk5Zb6QsNUeIbhqL95V_AyFSGNcLGAU',
];
$body = '{"transactionId":"24a533a3-3ffc-4fbc-8cd6-c5c836f2da88","currency":"USD","amount":9.1,"userId":"cd233d8d-6b73-4098-ad65-972be20014f6","type":2,"coefficient":1.82,"token":"e18bed4abedab830b8f0d196df9b018eb5f72b51","requestId":"c1a97784-f32a-4329-9ac7-a2b3d957eb44","resultType":"won","bonusId":null,"bonusTemplateId":null,"gameType":"sportsbook"}';

if (isValidSignature($headers['x-sign-jws'], $body, $PARTNER_SECRET)) {
  echo 'Valid signature';
} else {
  echo 'Invalid signature';
}

function isValidSignature(string $sign, string $body, string $secret): bool {
  $signParts = explode('.', $sign);

  try {
    JWT::decode(
      implode('.', [
        $signParts[0],
        JWT::urlsafeB64Encode($body),
        $signParts[2]
      ]),
      new Key($secret, 'HS256')
    );

    return true;
  } catch (\Throwable $error) {
    return false;
  }
}

Signature generation

INFO

You will need to create signature when you sending request to Sportsbook backend. This will be required for Freebets integration or Extra APIs usage.

To generate JWS Detached, take the following steps:

  • Generate a standard JWT with any library available for your language. You need to use HS256 algorithm with PARTNER_SECRET as a secret key.
  • Drop the middle part (payload) of the resulting JWT, e.g. abc.123.def => abc..def.
  • The result is a signature that you should send in x-sign-jws HTTP header together with request payload.

TIP

You can find a lib suitable for your language on a dedicated section of jwt.io website.

Signature generation examples

An example using firebase/php-jwt and guzzlehttp/guzzle packages:

php
use Firebase\JWT\JWT;
use GuzzleHttp\Client;

$PARTNER_SECRET = 'testdemo';
$payload = [
    'foo' => 'bar'
];

$jwtParts = explode('.', JWT::encode($payload, $PARTNER_SECRET, 'HS256'));
$signature = implode('.', [$jwtParts[0], '', $jwtParts[2]]);

// x-sign-jws=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..84eLXX28HS9Is1DNCIYa1js6Mr7XKPmaSjUf1waRIzc
echo "x-sign-jws=$signature";

// send the request
$body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

$client = new Client();
$response = $client->request('POST', $url, [
    'body' => $body,
    'headers' => [
        "Content-type" => "application/json",
        "x-sign-jws" => $signature
    ]
]);

echo $response->getBody()->getContents();