# Multiples Bet Placement Endpoint

### Request

Multiples bet placement involves the submission of a betslip that contains one or more accumulator bets. As visible in the Request Parameters table below:

* An array of multiple bets exists in the 'bets' parameter.
* An array of selections exists in the 'selections' parameter. Within a bet there is a list of 'betSelections' which contain an identifier for each selection present in the bet. These selections within the bet should be extracted from the 'selections' list in the betslip level

When multiple bet placement calls are made to this endpoint, the operator needs to perform the following validations and checks:

* 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 multiple 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
* Store all selections and associate them with betIds based on the betSelections identifiers list (for display and resulting)
* Assign 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) 
```

### Response

**Successfully placed:** Respond with a response matching the 'Response Parameters' schema as detailed below or alternatively

**Not placed:** After failing a check or experiencing an error 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>betSlipId</td><td>String/UUID</td><td>Yes</td><td>92e02ae9-a2a3-48e2-af0e-940aec4bbcfc</td></tr><tr><td>bets</td><td>Array &#x3C;BetDetails></td><td>Yes</td><td></td></tr><tr><td>selections</td><td>Array &#x3C;SelectionDetails></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>betSlipId</td><td>String/UUID</td><td>Yes</td><td>Matches requests betSlipId</td></tr><tr><td>processedBets</td><td>Array &#x3C;ProcessedBet></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                                  |
| errorBetDetails | Array \<ErrorBetDetail> | No (Except for INVALID\_BET errors) |

#### Errors

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

#### ErrorBetDetail <a href="#errorbetdetail" id="errorbetdetail"></a>

| Parameter    | Type                   | Required?                                            |
| ------------ | ---------------------- | ---------------------------------------------------- |
| betId        | String/UUID            | Yes                                                  |
| detailReason | `ErrorBetDetailReason` | Yes                                                  |
| stake        | Decimal/Double         | Only for INVALID\_MAX\_STAKE and INVALID\_MIN\_STAKE |

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

#### ErrorBetDetailReason <a href="#errorbetdetailreason" id="errorbetdetailreason"></a>

| Parameter Value     |
| ------------------- |
| INVALID\_BET\_TYPE  |
| INVALID\_MAX\_STAKE |
| INVALID\_MIN\_STAKE |

{% hint style="info" %}
The above are listed in order of priority. If a single bet is both an invalid type *and* violates a stake value, only invalid bet should be returned.
{% endhint %}

## Model Definitions

### BetDetails

<table><thead><tr><th width="265">Parameter</th><th width="201">Type</th><th>Required?</th></tr></thead><tbody><tr><td>betId</td><td>String/UUID</td><td>Yes</td></tr><tr><td>betType</td><td>String/BetType</td><td>Yes</td></tr><tr><td>betStage</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><tr><td>betSelections</td><td>Array &#x3C;SelectionIdentifiers></td><td>Yes</td></tr></tbody></table>

### SelectionIdentifiers <a href="#selectionidentifiers" id="selectionidentifiers"></a>

| Parameter   | Type   | Required? |
| ----------- | ------ | --------- |
| selectionId | String | Yes       |
| marketId    | String | Yes       |

### SelectionDetails <a href="#selectiondetails" id="selectiondetails"></a>

<table><thead><tr><th>Parameter</th><th width="158">Type</th><th>Required?</th></tr></thead><tbody><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>marketTypeName</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></tbody></table>

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

### ProcessedBet <a href="#hardbreak-processedbet" id="hardbreak-processedbet"></a>

| Parameter     | Type        | Required? | Note                                            |
| ------------- | ----------- | --------- | ----------------------------------------------- |
| betId         | String/UUID | Yes       | the betId from BetDetails                       |
| transactionId | String/UUID | Yes       | a unique id for the bet in the operators system |

#### BetType

| Parameter Value |
| --------------- |
| FIFTEEN\_FOLD   |
| FOURTEEN\_FOLD  |
| THIRTEEN\_FOLD  |
| TWELVE\_FOLD    |
| ELEVEN\_FOLD    |
| TEN\_FOLD       |
| NINE\_FOLD      |
| EIGHT\_FOLD     |
| SEVEN\_FOLD     |
| SIX\_FOLD       |
| FIVE\_FOLD      |
| FOUR\_FOLD      |
| TREBLE          |
| DOUBLE          |
| SINGLE          |

#### Stage

| Parameter Value |
| --------------- |
| IN\_PLAY        |
| PRE\_PLAY       |
