Betbird LogoBetbird

Betbird API

Bet placement and virtual ticket management endpoints

Betbird API

Betbird (Betting Engine) provides bet placement APIs for virtual ticket creation, management, and bet submission. All POST requests to these endpoints must be sent through Databird, which acts as a proxy and performs authentication and pre-bet validation.

Base URL

All endpoints are relative to the base URL:

{your-base-url}/v1/betplacement/{endpoint}

Overview

Betbird focuses exclusively on:

  • Bet construction and validation logic
  • Virtual ticket management
  • Betting calculations

Note: Betbird does NOT handle:

  • User authentication or registration
  • Deposits or withdrawals
  • Transaction processing
  • Pre-bet validation checks (balance, limits, etc.)

All bet placement requests must flow through Databird, which performs these checks before proxying to Betbird.

Endpoints

Get Virtual Ticket

Retrieve details of a virtual betting ticket by its ID.

Endpoint: GET /v1/betplacement/virtualTicket/{id}

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier

Query Parameters

ParameterTypeRequiredDescription
lnumberNoLanguage code (default: 0)

Response Schema

The response contains the virtual ticket details including:

  • id (string): Ticket identifier
  • markets (array): Array of market objects with betting information
  • systemTypes (object): System type information including total way count. Contains:
    • maxOverallOdds (number|null): Maximum overall odds allowed
    • totalWayCount (number): Total number of ways in the bet
    • systemDescription (object): System description containing:
      • wayDesc (string): Description of the way (e.g., "Einzel", "Doppel")
      • wayCount (number): Number of ways
    • maxOddsValue (number|null): Maximum odds value
    • systemType (string): System type (e.g., "SINGLES", "DOUBLES", "TREBLES")
  • stake (object): Stake information including stake per way and total possible win. Contains:
    • stakePerWay (number): Stake amount per way
    • ways (number): Number of ways
    • totalStake (number): Total stake amount (stakePerWay × ways)
    • totalPossibleWin (number): Total possible winnings
    • winningsPerStakeRatio (number): Winnings per stake ratio (odds multiplier)
  • bonusesResponses (array): Array of bonus responses
  • acceptOddsChanges (boolean): Whether odds changes are accepted
  • fee (object): Fee information. Contains:
    • original (number|null): Original fee amount before any adjustments
    • applicable (number|null): Applicable fee amount
    • percentage (number|null): Fee percentage
    • stakeToFeeRatio (number): Stake to fee ratio
  • errors (array): Array of error messages
  • csrfPreventionSalt (string): CSRF prevention token
  • reactions (array): Array of reactions
  • systemCombiTypes (array): Array of system combination types
  • feeInclusive (boolean): Whether fee is inclusive
  • betBuilderCandidates (array): Array of bet builder candidates
  • taxFreeBet (object|null): Tax-free bet information. When present, contains:
    • enabled (boolean): Whether tax-free bet is enabled
    • amount (number|null): Tax-free bet amount
    • type (string|null): Tax-free bet type (e.g., "free_bet", "bonus")

Example Request

{
    "url": "{your-base-url}/v1/betplacement/virtualTicket/1763795424810",
    "method": "GET",
    "queryString": "l=0"
}

Example Response

{
    "id": "1763795424810",
    "markets": [
        {
            "name": "Borussia Dortmund - VfB Stuttgart",
            "status": "normal",
            "market": "Über/Unter (3,5): Über 3,5",
            "odd": 2.25,
            "resultId": 195848960510,
            "eventId": 682869710,
            "index": 0,
            "liveEventTime": null,
            "scoreText": null,
            "error": null,
            "resultNamePostfix": "Über 3,5",
            "sportId": "soccer",
            "sportRadarMatchId": 61513790,
            "markets": {
                "195848960510": {
                    "name": "Über/Unter (3,5): Über 3,5",
                    "error": null
                }
            },
            "boostedOdd": 2.25,
            "oddsDisplayMode": null,
            "live": false,
            "outright": false,
            "banker": false,
            "combiError": false,
            "bankAvailable": false
        }
    ],
    "systemTypes": {
        "maxOverallOdds": null,
        "totalWayCount": 1,
        "systemDescription": {
            "wayDesc": "Einzel",
            "wayCount": 1
        },
        "maxOddsValue": null,
        "systemType": "SINGLES"
    },
    "stake": {
        "stakePerWay": 5.0,
        "ways": 1,
        "totalStake": 5.0,
        "totalPossibleWin": 11.25,
        "winningsPerStakeRatio": 2.25
    },
    "bonusesResponses": [],
    "acceptOddsChanges": false,
    "fee": {
        "original": null,
        "applicable": null,
        "percentage": null,
        "stakeToFeeRatio": 0.0
    },
    "errors": [],
    "csrfPreventionSalt": "T7OdEBgNUXxbOapxQXeM",
    "reactions": [],
    "systemCombiTypes": [
        {
            "combi": 0,
            "name": "Einzel",
            "count": 1,
            "selected": true,
            "last": true
        }
    ],
    "feeInclusive": false,
    "betBuilderCandidates": [],
    "taxFreeBet": null
}

Example Response (With Tax-Free Bet):

{
    "id": "1763795424810",
    "markets": [
        {
            "name": "Borussia Dortmund - VfB Stuttgart",
            "status": "normal",
            "market": "Über/Unter (3,5): Über 3,5",
            "odd": 2.25,
            "resultId": 195848960510,
            "eventId": 682869710,
            "index": 0,
            "liveEventTime": null,
            "scoreText": null,
            "error": null,
            "resultNamePostfix": "Über 3,5",
            "sportId": "soccer",
            "sportRadarMatchId": 61513790,
            "markets": {
                "195848960510": {
                    "name": "Über/Unter (3,5): Über 3,5",
                    "error": null
                }
            },
            "boostedOdd": 2.25,
            "oddsDisplayMode": null,
            "live": false,
            "outright": false,
            "banker": false,
            "combiError": false,
            "bankAvailable": false
        }
    ],
    "systemTypes": {
        "maxOverallOdds": null,
        "totalWayCount": 1,
        "systemDescription": {
            "wayDesc": "Einzel",
            "wayCount": 1
        },
        "maxOddsValue": null,
        "systemType": "SINGLES"
    },
    "stake": {
        "stakePerWay": 5.0,
        "ways": 1,
        "totalStake": 5.0,
        "totalPossibleWin": 11.25,
        "winningsPerStakeRatio": 2.25
    },
    "bonusesResponses": [],
    "acceptOddsChanges": false,
    "fee": {
        "original": null,
        "applicable": null,
        "percentage": null,
        "stakeToFeeRatio": 0.0
    },
    "errors": [],
    "csrfPreventionSalt": "T7OdEBgNUXxbOapxQXeM",
    "reactions": [],
    "systemCombiTypes": [
        {
            "combi": 0,
            "name": "Einzel",
            "count": 1,
            "selected": true,
            "last": true
        }
    ],
    "feeInclusive": false,
    "betBuilderCandidates": [],
    "taxFreeBet": {
        "enabled": true,
        "amount": 10.0,
        "type": "free_bet"
    }
}

Create/Update Virtual Ticket with Market Picks

Create or update a virtual ticket with market picks and bet builder options.

Endpoint: POST /v1/betplacement/virtualTicketMarketPicksWithBetBuilder/{id}

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier

Request Body

FieldTypeRequiredDescription
singleOutcomesarray[number]YesArray of result IDs for single outcomes
betBuildersarrayYesArray of bet builder configurations
taxFreebooleanNoWhether the bet is tax-free

Response Schema

Same as Get Virtual Ticket response schema.

Example Request

{
  "url": "{your-base-url}/v1/betplacement/virtualTicketMarketPicksWithBetBuilder/1763795424810",
  "method": "POST",
  "body": {
    "singleOutcomes": [195848960510, 195848958410, 195848958510],
    "betBuilders": [],
    "taxFree": null
  }
}

Example Response

{
    "id": "1763795424810",
    "markets": [
        {
            "name": "Borussia Dortmund - VfB Stuttgart",
            "status": "normal",
            "market": "Über/Unter (3,5): Über 3,5",
            "odd": 2.25,
            "resultId": 195848960510,
            "eventId": 682869710,
            "index": 0,
            "liveEventTime": null,
            "scoreText": null,
            "error": null,
            "resultNamePostfix": "Über 3,5",
            "sportId": "soccer",
            "sportRadarMatchId": 61513790,
            "markets": {
                "195848960510": {
                    "name": "Über/Unter (3,5): Über 3,5",
                    "error": null
                }
            },
            "boostedOdd": 2.25,
            "oddsDisplayMode": null,
            "live": false,
            "outright": false,
            "banker": false,
            "combiError": false,
            "bankAvailable": false
        }
    ],
    "systemTypes": {
        "maxOverallOdds": null,
        "totalWayCount": 1,
        "systemDescription": {
            "wayDesc": "Einzel",
            "wayCount": 1
        },
        "maxOddsValue": null,
        "systemType": "SINGLES"
    },
    "stake": {
        "stakePerWay": 5.0,
        "ways": 1,
        "totalStake": 5.0,
        "totalPossibleWin": 11.25,
        "winningsPerStakeRatio": 2.25
    },
    "bonusesResponses": [],
    "acceptOddsChanges": false,
    "fee": {
        "original": null,
        "applicable": null,
        "percentage": null,
        "stakeToFeeRatio": 0.0
    },
    "errors": [],
    "csrfPreventionSalt": "T7OdEBgNUXxbOapxQXeM",
    "reactions": [],
    "systemCombiTypes": [
        {
            "combi": 0,
            "name": "Einzel",
            "count": 1,
            "selected": true,
            "last": true
        }
    ],
    "feeInclusive": false,
    "betBuilderCandidates": [],
    "taxFreeBet": null
}

Submit/Place Bet

Submit a virtual ticket to place a bet. This endpoint finalizes the bet and processes the transaction.

Endpoint: POST /v1/betplacement/virtualTicket/{id}/submit

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier

Request Body

FieldTypeRequiredDescription
stakePerWaynumberYesStake amount per way
acceptOddsChangesbooleanNoWhether to accept odds changes (default: false)
systemTypestringNoSystem bet type (e.g., "SINGLES", "DOUBLES")

Response Schema

Returns a bet confirmation object containing:

  • betId (string): Unique bet identifier
  • ticketId (string): Virtual ticket identifier
  • status (string): Bet status (placed, pending, rejected)
  • stake (object): Stake information. Contains:
    • stakePerWay (number): Stake amount per way
    • totalStake (number): Total stake amount
    • ways (number): Number of ways
  • potentialWin (number): Potential winnings amount
  • placedAt (string): Timestamp when bet was placed
  • errors (array): Array of error messages if bet failed
  • betSlip (object): Final bet slip details. Contains:
    • markets (array): Array of market objects, each containing:
      • eventId (number): Event identifier
      • marketId (number): Market identifier
      • odd (number): Odds value
      • name (string): Market name
    • systemType (string): System bet type (e.g., "SINGLES", "DOUBLES")
    • stake (object): Stake information (same structure as above)
    • potentialWin (number): Potential winnings amount

Example Request

{
  "url": "{your-base-url}/v1/betplacement/virtualTicket/1763795424810/submit",
  "method": "POST",
  "body": {
    "stakePerWay": 5.0,
    "acceptOddsChanges": false,
    "systemType": "SINGLES"
  }
}

Example Response

{
    "betId": "bet_1234567890",
    "ticketId": "1763795424810",
    "status": "placed",
    "stake": {
        "stakePerWay": 5.0,
        "totalStake": 5.0,
        "ways": 1
    },
    "potentialWin": 11.25,
    "placedAt": "2024-01-15T14:30:00Z",
    "errors": [],
    "betSlip": {
        "markets": [
            {
                "eventId": 682869710,
                "marketId": 195848960510,
                "odd": 2.25,
                "name": "Über/Unter (3,5): Über 3,5"
            }
        ],
        "systemType": "SINGLES",
        "stake": {
            "stakePerWay": 5.0,
            "totalStake": 5.0,
            "ways": 1
        },
        "potentialWin": 11.25
    }
}

Update Stake on Virtual Ticket

Update the stake amount on an existing virtual ticket.

Endpoint: PUT /v1/betplacement/virtualTicket/{id}/stake

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier

Request Body

FieldTypeRequiredDescription
stakePerWaynumberYesNew stake amount per way

Response Schema

Same as Get Virtual Ticket response schema, with updated stake information.

Example Request

{
  "url": "{your-base-url}/v1/betplacement/virtualTicket/1763795424810/stake",
  "method": "PUT",
  "body": {
    "stakePerWay": 10.0
  }
}

Remove Selection from Virtual Ticket

Remove a market pick from the virtual ticket. This can also be done by updating the ticket with a new selection list via the POST endpoint.

Endpoint: DELETE /v1/betplacement/virtualTicket/{id}/selections/{selectionId}

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier
selectionIdnumberYesThe result ID or selection identifier to remove

Response Schema

Same as Get Virtual Ticket response schema, with the selection removed.

Example Request

{
  "url": "{your-base-url}/v1/betplacement/virtualTicket/1763795424810/selections/195848960510",
  "method": "DELETE"
}

Alternative Approach: You can also remove selections by updating the virtual ticket via POST /v1/betplacement/virtualTicketMarketPicksWithBetBuilder/{id} with an updated singleOutcomes array that excludes the selection to be removed.

Clear Virtual Ticket

Clear all selections from a virtual ticket, effectively resetting it.

Endpoint: DELETE /v1/betplacement/virtualTicket/{id}

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier

Response Schema

Returns a confirmation object:

  • success (boolean): Whether the ticket was cleared
  • ticketId (string): The cleared ticket identifier

Example Request

{
  "url": "{your-base-url}/v1/betplacement/virtualTicket/1763795424810",
  "method": "DELETE"
}

Example Response

{
    "success": true,
    "ticketId": "1763795424810"
}

Validate Virtual Ticket

Validate a virtual ticket before submission to check for errors or issues.

Endpoint: POST /v1/betplacement/virtualTicket/{id}/validate

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe virtual ticket identifier

Response Schema

Returns a validation result object:

  • valid (boolean): Whether the ticket is valid
  • errors (array): Array of validation error messages
  • warnings (array): Array of validation warnings
  • ticket (object): Current ticket state. Contains the same structure as Get Virtual Ticket response, including:
    • id (string): Ticket identifier
    • markets (array): Array of market objects
    • stake (object): Stake information (see Get Virtual Ticket schema)
    • systemTypes (object): System type information (see Get Virtual Ticket schema)
    • errors (array): Array of error messages

Example Request

{
  "url": "{your-base-url}/v1/betplacement/virtualTicket/1763795424810/validate",
  "method": "POST"
}

Example Response

{
    "valid": true,
    "errors": [],
    "warnings": [],
    "ticket": {
        "id": "1763795424810",
        "markets": [
            {
                "name": "Borussia Dortmund - VfB Stuttgart",
                "status": "normal",
                "market": "Über/Unter (3,5): Über 3,5",
                "odd": 2.25,
                "resultId": 195848960510,
                "eventId": 682869710,
                "index": 0,
                "liveEventTime": null,
                "scoreText": null,
                "error": null,
                "resultNamePostfix": "Über 3,5",
                "sportId": "soccer",
                "sportRadarMatchId": 61513790,
                "markets": {
                    "195848960510": {
                        "name": "Über/Unter (3,5): Über 3,5",
                        "error": null
                    }
                },
                "boostedOdd": 2.25,
                "oddsDisplayMode": null,
                "live": false,
                "outright": false,
                "banker": false,
                "combiError": false,
                "bankAvailable": false
            }
        ],
        "systemTypes": {
            "maxOverallOdds": null,
            "totalWayCount": 1,
            "systemDescription": {
                "wayDesc": "Einzel",
                "wayCount": 1
            },
            "maxOddsValue": null,
            "systemType": "SINGLES"
        },
        "stake": {
            "stakePerWay": 5.0,
            "ways": 1,
            "totalStake": 5.0,
            "totalPossibleWin": 11.25,
            "winningsPerStakeRatio": 2.25
        },
        "fee": {
            "original": null,
            "applicable": null,
            "percentage": null,
            "stakeToFeeRatio": 0.0
        },
        "errors": [],
        "acceptOddsChanges": false
    }
}

Example Response (Invalid Ticket):

{
    "valid": false,
    "errors": [
        "Insufficient balance",
        "Odds have changed"
    ],
    "warnings": [
        "One or more selections have odds below minimum threshold"
    ],
    "ticket": {
        "id": "1763795424810",
        "markets": [...],
        "stake": {
            "stakePerWay": 5.0,
            "ways": 1,
            "totalStake": 5.0,
            "totalPossibleWin": 11.25,
            "winningsPerStakeRatio": 2.25
        },
        "errors": [
            "Insufficient balance",
            "Odds have changed"
        ]
    }
}