# Bet Placement Endpoint

Bet placement involves the submission of a betslip that contains one or more single bets. As visible in the Request Parameters table below, an array of single bets exists for the 'bets' parameter. When bet placement calls are made to this endpoint, the operator needs to take the following steps:

* validate the user session by looking up the user session based on userId and sessionToken and ensuring that session details are correct and not expired
* confirm that the user has a sufficient balance to cover the sum total of all the individual bet stakes
* confirm that the user is able to place each bet in light of any regulatory restrictions (could be cool down periods, max stakes, max liability per market type etc.)
* upon successfully completing all relevant checks, store all bet information for each bet in the bets array against the userId with a status equivalent to 'pending' to indicate that the bet is awaiting result. A `potentialPayout` amount should be calculated by multiplying the decimalPrice field by the stake. This should be saved alongside the bet to facilitate bet resulting. Here is the formula for clarity:

`potentialPayout = (stake * decimalPrice)`

* respond with a response matching the 'Response Parameters' schema as detailed below
* or alternatively.. upon unsuccessfully completing all relevant check, store none of the bets in the bet placement call and respond with a relevant error response, as detailed below

### Request Parameters

type: `POST`\
content-type: `application/json`

#### Idempotency

Request will contain a header `X-Idempotency-Key` in the form of a UUID string. See 'Idempotency' section for more information.

<table><thead><tr><th width="194">Parameter</th><th width="179">Type</th><th width="111">Required?</th><th>Example</th></tr></thead><tbody><tr><td>requestId</td><td>String/UUID</td><td>Yes</td><td>92e02ae9-a2a3-48e2-af0e-940aec4bbcfb</td></tr><tr><td>userId</td><td>String</td><td>Yes</td><td>user123</td></tr><tr><td>sessionToken</td><td>String</td><td>Yes</td><td>0bJV7oLNI0iMFl3rlomqQQ==</td></tr><tr><td>timestamp</td><td>String (epoch)</td><td>Yes</td><td>1640995200000</td></tr><tr><td>bets</td><td>Array &#x3C;BetDetails></td><td>Yes</td><td></td></tr></tbody></table>

### Response Parameters

accepts: `application/json`

<table><thead><tr><th>Parameter</th><th width="181">Type</th><th width="112">Required?</th><th></th></tr></thead><tbody><tr><td>requestId</td><td>String/UUID</td><td>Yes</td><td>Matches request's requestId</td></tr><tr><td>userId</td><td>String</td><td>Yes</td><td></td></tr><tr><td>sessionToken</td><td>String</td><td>Yes</td><td>Original or refreshed</td></tr><tr><td>timestamp</td><td>String (epoch)</td><td>Yes</td><td>Response timestamp</td></tr><tr><td>status</td><td>String ("PLACED")</td><td>Yes</td><td></td></tr><tr><td>bets</td><td>Array &#x3C;BetDetails></td><td>Yes</td><td></td></tr></tbody></table>

### Error Response

accepts: `application/json`

| Parameter    | Type               | Required?                             |
| ------------ | ------------------ | ------------------------------------- |
| status       | String ("FAILURE") | Yes                                   |
| errorCode    | String             | Yes                                   |
| errorMessage | String             | No                                    |
| failedBets   | Array \<FailedBet> | No (Except for INVALID\_STAKE errors) |

#### Errors

| Error Code             | Http Status |
| ---------------------- | ----------- |
| INVALID\_USER          | 400         |
| INVALID\_BET\_DETAILS  | 400         |
| INVALID\_STAKE         | 400         |
| INSUFFICIENT\_FUNDS    | 400         |
| USER\_BLOCKED          | 400         |
| MISSING\_PARAMETER     | 400         |
| INVALID\_SESSION       | 401         |
| AUTHENTICATION\_FAILED | 403         |
| GENERAL\_EXCEPTION     | 500         |
| REQUEST\_TIMED\_OUT    | 503         |

***

## Model Definitions

### BetDetails

<table><thead><tr><th>Parameter</th><th width="158">Type</th><th>Required?</th></tr></thead><tbody><tr><td>betId</td><td>String/UUID</td><td>Yes</td></tr><tr><td>sportId</td><td>String</td><td>Yes</td></tr><tr><td>sportName</td><td>String</td><td>Yes</td></tr><tr><td>sportDisplayName</td><td>String</td><td>Yes</td></tr><tr><td>eventId</td><td>String</td><td>Yes</td></tr><tr><td>eventAltId</td><td>String</td><td>No</td></tr><tr><td>eventName</td><td>String</td><td>Yes</td></tr><tr><td>eventDisplayName</td><td>String</td><td>Yes</td></tr><tr><td>eventStage</td><td>String/Stage</td><td>Yes</td></tr><tr><td>competitionId</td><td>String</td><td>Yes</td></tr><tr><td>competitionName</td><td>String</td><td>Yes</td></tr><tr><td>competitionDisplayName</td><td>String</td><td>Yes</td></tr><tr><td>marketTypeId</td><td>String</td><td>Yes</td></tr><tr><td>marketId</td><td>String</td><td>Yes</td></tr><tr><td>marketName</td><td>String</td><td>Yes</td></tr><tr><td>marketDisplayName</td><td>String</td><td>Yes</td></tr><tr><td>marketStage</td><td>String/Stage</td><td>Yes</td></tr><tr><td>selectionId</td><td>String</td><td>Yes</td></tr><tr><td>selectionName</td><td>String</td><td>Yes</td></tr><tr><td>selectionDisplayName</td><td>String</td><td>Yes</td></tr><tr><td>decimalPrice</td><td>Decimal/Double</td><td>Yes</td></tr><tr><td>stake</td><td>Decimal/Double</td><td>Yes</td></tr></tbody></table>

{% hint style="info" %}
`eventAltId` is an optional field that may contain an alternate eventId (eg a DDE id for golf bets)
{% endhint %}

### FailedBet

<table><thead><tr><th width="248">Parameter</th><th width="174">Type</th><th>Required?</th></tr></thead><tbody><tr><td>betId</td><td>String/UUID</td><td>Yes</td></tr><tr><td>sportId</td><td>String</td><td>Yes</td></tr><tr><td>eventId</td><td>String</td><td>Yes</td></tr><tr><td>marketId</td><td>String</td><td>Yes</td></tr><tr><td>selectionId</td><td>String</td><td>Yes</td></tr><tr><td>reason</td><td>BetFailureReason</td><td>Yes</td></tr></tbody></table>

#### BetFailureReason

<table><thead><tr><th width="248">Parameter</th><th width="174">Type</th><th>Required?</th></tr></thead><tbody><tr><td>maxStake</td><td>Decimal/Double</td><td>No</td></tr><tr><td>minStake</td><td>Decimal/Double</td><td>No</td></tr></tbody></table>

{% hint style="info" %}
the stake value returned within **BetFailureReason** should be the value of the limit breached
{% endhint %}

#### Stage

| Parameter Variables |
| ------------------- |
| IN\_PLAY            |
| PRE\_PLAY           |
