# Create markets

> Creates player-prop markets on a scheduled event.

Source: https://docs.stxapp.io/apps/api/create-markets/

> **Availability.** Available on US demo now. See [Environments](https://docs.stxapp.io/environments/).

Creates player-prop markets on a scheduled event. Needs an OAuth app token (client credentials) carrying the `markets.write` scope, which STX grants on request, sent from an address on the client's IP allow-list; an API key is refused. Describe each market by its `rule` (`player_stat_line`) with a `player_id` from `GET /api/v1/events/{event_id}/players`, a `stat` from `GET /api/v1/types` and a positive half `line`. STX builds the title, rules and max price. Up to 25 markets per call. `markets` in the response has one outcome per entry, in request order, each with the entry's `index`: `created` or `exists` with the `market_id`, or `rejected` with a `reason`. `market_id` and `reason` are `null` where they do not apply. Resending a market, or repeating it in one request, answers `exists` and never creates a duplicate. With `dry_run: true` every check runs and nothing is created: a market that would be created, or a repeat of one, answers `valid`. The valid entries are saved together: if that save fails, each answers `rejected` with `not_created` and none is created, so the request can be resent as is.

```http
POST /api/v1/markets
```

Send it with your own demo key: [Try it](/quick-start/?op=markets_post#try-it).

:::note[For apps]
Call it with an OAuth app token (`client_credentials`) carrying `markets.write`. See [Creating markets](/apps/creating-markets/).
:::

:::tip[In the SDKs]
- TypeScript: [`STX.createMarkets()`](/sdks/typescript/reference/stx/#createmarkets)
- Python: [`STX.create_markets()`](/sdks/python/reference/stx/#create_markets)
- C#: [`STXClient.CreateMarketsAsync()`](/sdks/csharp/reference/stx-client/#markets-and-events)
:::

## Request body

| Field | Type | Required | Description |
|---|---|---|---|
| `dry_run` | boolean | no | `true` runs every check and creates nothing; a market that would be created, or a repeat of one, answers `valid`. Defaults to `false`. |
| `event_id` | string (uuid) | **yes** | The event to create the markets on, from `GET /api/v1/events`. |
| `markets` | object[] | **yes** | 1 to 25 markets. |
| `markets[].line` | number | **yes** | A positive half line, e.g. `19.5`. |
| `markets[].player_id` | string | **yes** | A `player_id` from `GET /api/v1/events/&#123;event_id&#125;/players`. |
| `markets[].rule` | `player_stat_line` | **yes** | The market rule; only `player_stat_line` is created. |
| `markets[].stat` | string | **yes** | A `stat` the event's type offers in `GET /api/v1/types`, e.g. `RUSH_YDS`. |

## Responses

| Status | Description | Schema |
|---|---|---|
| `200` | Success | object |
| `400` | A parameter was missing or invalid. | Error |
| `401` | Missing or invalid OAuth access token. Body: &#123;"error":"Missing or invalid OAuth access token"&#125; | Error |
| `403` | Not an OAuth app token carrying the `markets.write` scope (an API key or a member token included), or a call from outside the app's IP allow-list, which applies to calls that write (`&#123;"error":"ip_not_allowed"&#125;`). | Error |
| `404` | No such event. | Error |
| `422` | The whole request was refused: the event is not open for new markets (`event_not_open`: not scheduled, or already started), its type offers no player props (`unsupported_event`) or its rosters are not published yet (`roster_unavailable`). Body: &#123;"error":"&lt;reason&gt;"&#125; | Error |

## Example

Request:

```bash
curl --request POST \
  --url 'https://demo.stxapp.io/api/v1/markets' \
  --header 'Authorization: Bearer <app-access-token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "event_id": "24636b3d-f566-4dd3-8c8b-c1a6c2747789",
  "markets": [
    {
      "line": 3.5,
      "player_id": "3895074",
      "rule": "player_stat_line",
      "stat": "GOAL_SO"
    },
    {
      "line": 1.5,
      "player_id": "3895074",
      "rule": "player_stat_line",
      "stat": "ASSISTS"
    }
  ]
}'
```

Response `200`:

```json
{
  "event_id": "24636b3d-f566-4dd3-8c8b-c1a6c2747789",
  "markets": [
    {
      "index": 0,
      "market_id": "2a473aeb-10de-47e4-a7ce-dbb771094d84",
      "reason": null,
      "status": "created"
    },
    {
      "index": 1,
      "market_id": "e8dc3eab-8bd3-4801-8b20-0313e5f5f3e7",
      "reason": null,
      "status": "exists"
    }
  ]
}
```

### Response fields

| Field | Type | Description |
|---|---|---|
| `event_id` | uuid | The event. |
| `index` | integer | The entry's position in the request's `markets`, from 0. |
| `market_id` | uuid | The market, for `created` and `exists`; `null` otherwise. |
| `reason` | string | Why the market was rejected, `null` otherwise: an entry that is not an object, has no `rule` or `player_id`, or has a field its rule does not take (`invalid_market`), a `rule` the API does not create (`unsupported_rule`), a stat not on offer (`unsupported_stat`), a line that is not a positive half (`invalid_line`), a `player_id` not on the event's rosters (`unknown_player`), the event started while the request ran (`event_not_open`), or refused when created (`not_created`). |
| `status` | string | `created`, `exists` (already listed, so nothing new was created), `valid` (`dry_run`: would be created) or `rejected`. |
