Skip to main content

Swipe Games Public Integration Adapter API

We use this integration adapter API to make reverse calls back to integrations. It's located in our cluster and sends requests to your endpoints on every game actions (mostly related to money processing) - like bets, wins, refunds, etc.

Setup and configuration

You need to provide us with the following information to set up the integration:

  • ExtCID — a unique identifier for your internal client (casino, operator, etc.). You can use any string, but it should be unique across all integrations. If you have multiple clients on your side, you can provide us with a list of ExtCIDs and we will set up all of them individually.
  • Base URL of your integration API (e.g., https://example.com/api/v1.0) — we will set up all the endpoints for you according to the API specification. Please make sure that you provide exact endpoints for each action. You can use our OpenAPI specification to generate the server stubs for your API. If you need different base URLs for different clients, you can provide a separate base URL per ExtCID.
  • Your Integration API key for authentication — we use it to sign all reverse calls to your API. You use this key to verify request signatures on incoming requests from us.

All settings (base URL, configuration, etc.) are done per ExtCID. So if you have multiple clients (casinos, operators, etc.), you need to provide us with the ExtCID for each of them. Each ExtCID can have its own base URL for reverse calls.

Verifying Request Signatures

Every request we send to your endpoints includes an X-REQUEST-SIGN header containing an HMAC-SHA256 signature. You must verify this signature to ensure the request is authentic and hasn't been tampered with.

The verification process differs slightly between GET and POST requests:

POST requests (Bet, Win, Refund)

POST request bodies are already sent in canonical JSON format (keys sorted alphabetically, no whitespace). You can use the raw request body directly to compute the signature — no additional transformation is needed.

Verification steps:

  1. Read the raw request body (do not parse and re-serialize — use the raw bytes)
  2. Compute HMAC-SHA256 of the raw body using your Integration API key
  3. Compare the result with the X-REQUEST-SIGN header value
const crypto = require('crypto');

function verifySignature(rawBody, signature, integrationApiKey) {
const expected = crypto
.createHmac('sha256', integrationApiKey)
.update(rawBody)
.digest('hex');
return expected === signature;
}

// In your HTTP handler:
app.post('/bet', (req, res) => {
const rawBody = req.rawBody; // make sure your framework preserves raw body
const signature = req.headers['x-request-sign'];

if (!verifySignature(rawBody, signature, integrationApiKey)) {
return res.status(401).json({ message: 'Invalid signature' });
}

const request = JSON.parse(rawBody);
// process bet...
});

GET requests (Balance)

GET requests don't have a body. To verify the signature, you need to convert the query parameters into a canonical JSON object first.

Verification steps:

  1. Collect all query parameters from the request URL
  2. Create a JSON object from the parameters with keys sorted alphabetically and no whitespace (canonical JSON)
  3. Compute HMAC-SHA256 of the canonical JSON string using your Integration API key
  4. Compare the result with the X-REQUEST-SIGN header value
const crypto = require('crypto');

function queryParamsToCanonicalJSON(queryParams) {
// Sort keys and create compact JSON
const sorted = Object.keys(queryParams).sort().reduce((obj, key) => {
obj[key] = queryParams[key];
return obj;
}, {});
return JSON.stringify(sorted);
}

function verifySignature(payload, signature, integrationApiKey) {
const expected = crypto
.createHmac('sha256', integrationApiKey)
.update(payload)
.digest('hex');
return expected === signature;
}

// In your HTTP handler:
app.get('/balance', (req, res) => {
const canonicalJSON = queryParamsToCanonicalJSON(req.query);
const signature = req.headers['x-request-sign'];

if (!verifySignature(canonicalJSON, signature, integrationApiKey)) {
return res.status(401).json({ message: 'Invalid signature' });
}

const sessionID = req.query.sessionID;
// return balance...
});

Tip: If you're using one of our Integration SDKs, signature verification is handled automatically by the parseAndVerify* methods — you don't need to implement it manually.

Please whitelist our IP addresses to allow requests from our servers to your API.

Staging environment

  • 18.185.156.20

Production environment

  • 3.65.138.8

Rounds, transactions and idempotency

Every game round usually consists of the sequence of actions:

  • bet - player places a bet in the game
  • win - player wins some money in the game (or 0 if no win)
  • refund - usually we send a refund request when the bet request failed.

Every round has a single RoundID identifier, which is used to identify the round across all actions. RoundID could be not unique across different games, so you should use it only in the context of the game.

Every action request contains a txID — a globally unique transaction identifier (UUID v4) generated on Swipe Games' side. It identifies the specific action (bet, win, or refund) within the round and is directly tied to money processing. We require integrations to send back their own txID in the response, representing the corresponding transaction ID on the integration side, for tracking and debugging purposes.

txID must be used as an idempotency key on your side. If we retry a request (e.g., a win or refund), it will contain the same txID as the previous attempt. If you have already processed this transaction, return the same successful response with a 200 (OK) status code so we stop retrying.

Uniqueness guarantees:

  • Swipe Games generates txID as UUID v4, which provides a near-zero probability of collision.
  • We enforce uniqueness internally for a rolling 3-month window via a unique constraint.
  • If you require a uniqueness guarantee beyond 3 months, use the composite key (txID + roundID) for all bet, win, and refund transactions on your side.

All requests from our platform must be processed in an idempotent way. This means that if we send the same request multiple times, the result should be the same as if we sent the request only once. This is crucial to avoid any issues within our integration in case of network problems or other issues.

Retry and refund policies

Bet

All error codes except 200 (OK) are considered as errors. We decline game's action in case of any error and player gets notification about it.

Timeout over than 5 seconds will be considered as an error as well and refund will be issued afterwards in this case. In case of any 500 error from your side we will issue refund as well. All other errors aren't refundable, so if you want some transaction to be refundable, please return 500 error code. We don't retry bet requests.

Win

All error codes except 200 (OK) are considered as errors. We don't decline bet action in case of win error, but we show this error to the end user. In case of any error we will retry win request as long as you respond to our request with error. All retrying wins will have the same txID and roundID, we don't use different txID for win retries. Timeout over than 5 seconds will be considered as an error as well and win will be retried as well. We don't send any refunds on win requests.

Refund

In case of any refund we will retry refund request as long as you respond to our request error. All retrying refunds will have the same txID and roundID, we don't use different txID for retries.

Note: Since we are waiting for a 200 OK response from your side on refund requests, you should not return any error codes if you don't have a matching transaction on your side. For example when we break connection in case of timeout we will retry the refund request and you should return a 200 OK response with a valid body, even if you don't have this transaction on your side. The balance can be set to 0 in this scenario.

Errors processing and client actions

In error your can return any useful information to our side, later this could be useful to track and debug some issues. Please notice that we don't show details to the end user, so you can return any error you want (for debugging purposes), but message could be shown to the end user, so it should be user-friendly and understandable. See more in API specification.

Also we have special actions which allow our client to execute some actions on client's side. See more in API specification.

Integration flow diagrams

Open game flow

The following diagram shows the flow when a player opens a game. The Integrator's backend calls the Swipe Games Core API to create a new game session, and then redirects the player to the game URL. Once the game loads, Swipe Games calls back the Integrator's GET /balance endpoint to display the player's current balance.

Game round (normal flow)

Each game round consists of a bet followed by a win. Swipe Games sends a POST /bet to the Integrator to deduct the player's balance, and after the round completes, sends a POST /win to credit winnings (amount is 0 if no win).

Error handling and refund flow

When a POST /bet fails (500 error or timeout > 5s), the game action is declined and the player is notified. Swipe Games then issues a POST /refund, retrying until a 200 OK is received.