> ## Documentation Index
> Fetch the complete documentation index at: https://docs.55-tech.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Place futures orders (not yet implemented)

> Place one or more **futures** orders. **Returns HTTP 501** — see below.

The payload is the fixtures payload with the selection swapped: `futureId` + `futureOutcomeId` + `participantId` instead of `fixtureId` + `outcomeId` + `playerId`. Everything else (`requestUuid`, `orderPrice`, `orderStake`, `userRef`, `testOrder`, `bookmakers`, `orderCurrency`, `back`, `expiresAt`, `acceptBetterOdds`, `acceptPartialStake`, `meta`) is identical, including the `requestUuid` idempotency rule.

**The body is fully validated before the 501.** A malformed `futureId`, a selection pair that names nothing (`futureOutcomeId=0` with `participantId=0`), a duplicate `requestUuid` within the batch, or a fixture key (`fixtureId`/`outcomeId`/`playerId`) sent here all answer **422** — so you can integrate against this endpoint today and only the 501 will change.

**Why 501:** the `orders` table has no futures identity columns (`orders.fixtureId` is `TEXT NOT NULL`, and a futureId is not a fixtureId). Writing a futures selection into a fixture's column is exactly the conflation this surface split removes, so placement waits for the migration.



## OpenAPI

````yaml /zh/abp-api/openapi.json post /futures/place-orders
openapi: 3.1.0
info:
  title: ABP v2 - Automated Bet Placing API
  description: >

    Place bets across 36 bookmakers through a single API.


    ## Authentication


    All endpoints require the `x-api-key` header (except `/health`, `/ready`,
    `/status`, `/metrics`).


    **Swagger UI**: Click the **Authorize** button (lock icon) at the top right,
    enter your API key, and click **Authorize**.


    ## Two surfaces: fixtures and futures


    Selections come in two kinds and each has its own path prefix, so no
    endpoint has to guess which identifiers it was given:


    | | Fixtures | Futures (outrights) |

    |---|---|---|

    | Prefix | `/fixtures/*` | `/futures/*` |

    | Selection | `fixtureId` + `outcomeId` + `playerId` | `futureId` +
    `futureOutcomeId` + `participantId` |

    | Status | fully live | reads live; placement and order/bet reads answer
    `501` |


    Each surface **rejects the other's identifiers** with `422`. The pre-split
    unprefixed paths (`/betslip`, `/place-orders`, `/orders`, `/bets`,
    `/markets`, …) still work unchanged and are listed here as deprecated
    aliases of their `/fixtures/*` equivalents.


    `/accounts`, `/bookmakers`, `/positions` and `/pnl` name no selection and
    stay unprefixed.


    ## Quick Start


    1. **List your accounts**: `GET /accounts`

    2. **Get live odds**: `GET
    /fixtures/betslip?fixtureId=...&outcomeId=...&playerId=0`

    3. **Place an order**: `POST /fixtures/place-orders`

    4. **Track results**: `GET /fixtures/orders` or subscribe to WebSocket
    updates


    ## WebSocket


    Connect to `/ws` for real-time order, bet, and settlement updates.


    ```json

    {"type": "login", "apiKey": "your-api-key", "channels": []}

    ```


    Send an empty `channels` array to receive all updates. Available channels:
    `orders`, `bets`, `settlements`, `accounts`, `balance`, `betslip`,
    `fixtures`, `currencies`, `status`, `emergency`.


    Send `{"type": "ping"}` every 30 seconds to keep the connection alive.
  version: '2.0'
servers:
  - url: https://v2.55-tech.com
    description: Production
security:
  - apiKey: []
tags:
  - name: Orders
    description: Place, retrieve, and cancel betting orders on fixtures
  - name: Bets
    description: Query individual bets placed with bookmakers
  - name: Betslip
    description: Get live odds and metadata for fixtures
  - name: Markets
    description: Get available markets and odds types
  - name: Futures
    description: >-
      Outright markets, keyed by futureId + (futureOutcomeId, participantId).
      Reads are live; placement and order/bet reads answer 501 for now.
  - name: Accounts
    description: Manage bookmaker accounts
  - name: Bookmakers
    description: List supported bookmakers
  - name: Analytics
    description: Positions and profit/loss analytics
paths:
  /futures/place-orders:
    post:
      tags:
        - Futures
      summary: Place futures orders (not yet implemented)
      description: >-
        Place one or more **futures** orders. **Returns HTTP 501** — see below.


        The payload is the fixtures payload with the selection swapped:
        `futureId` + `futureOutcomeId` + `participantId` instead of `fixtureId`
        + `outcomeId` + `playerId`. Everything else (`requestUuid`,
        `orderPrice`, `orderStake`, `userRef`, `testOrder`, `bookmakers`,
        `orderCurrency`, `back`, `expiresAt`, `acceptBetterOdds`,
        `acceptPartialStake`, `meta`) is identical, including the `requestUuid`
        idempotency rule.


        **The body is fully validated before the 501.** A malformed `futureId`,
        a selection pair that names nothing (`futureOutcomeId=0` with
        `participantId=0`), a duplicate `requestUuid` within the batch, or a
        fixture key (`fixtureId`/`outcomeId`/`playerId`) sent here all answer
        **422** — so you can integrate against this endpoint today and only the
        501 will change.


        **Why 501:** the `orders` table has no futures identity columns
        (`orders.fixtureId` is `TEXT NOT NULL`, and a futureId is not a
        fixtureId). Writing a futures selection into a fixture's column is
        exactly the conflation this surface split removes, so placement waits
        for the migration.
      operationId: place_future_orders
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlaceFutureOrdersRequest'
            example:
              orders:
                - requestUuid: eb45b192-317b-42d5-9f65-af497b9fa8c1
                  futureId: id1012639310001
                  futureOutcomeId: 0
                  participantId: 7193
                  orderPrice: 4
                  orderStake: 25
                  userRef: bettor1234
                  testOrder: false
                  bookmakers: polymarket,kalshi
      responses:
        '401':
          description: Unauthorized — missing or invalid API key
        '422':
          description: >-
            Invalid payload — malformed futureId, a selection pair that names
            nothing, fixture keys present, or a duplicate requestUuid in the
            batch
          content:
            application/json:
              example:
                detail:
                  - loc:
                      - body
                      - orders
                      - 0
                    msg: >-
                      Value error, fixtureId, outcomeId belong to fixtures, not
                      futures. Post fixture orders to /fixtures/place-orders.
                    type: value_error
        '501':
          description: >-
            Not implemented — futures placement awaits futures identity columns
            on `orders`
          content:
            application/json:
              example:
                detail: >-
                  Futures order placement is not yet implemented. The `orders`
                  table has no futures identity columns (`orders.fixtureId` is
                  NOT NULL and a futureId is not a fixtureId), so this endpoint
                  answers 501 rather than storing a futures selection in a
                  fixture's column. Futures identifiers ARE validated here: a
                  malformed payload is a 422 even today.
components:
  schemas:
    PlaceFutureOrdersRequest:
      type: object
      required:
        - orders
      description: >-
        A batch of futures orders. Every `requestUuid` must be unique within the
        batch.
      properties:
        orders:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/PlaceFutureOrderRequest'
    PlaceFutureOrderRequest:
      type: object
      required:
        - requestUuid
        - futureId
        - orderPrice
        - orderStake
        - userRef
        - testOrder
      description: >-
        A **futures** order. The fixtures payload with the selection swapped:
        `futureId` + `futureOutcomeId` + `participantId` instead of `fixtureId`
        + `outcomeId` + `playerId`. Everything else is identical, including the
        `requestUuid` idempotency rule. There is **no `playerId`** on futures —
        `participantId` names a team or a player alike — and no period. The
        fixture keys `fixtureId`, `outcomeId` and `playerId` are rejected with
        `422`.
      properties:
        requestUuid:
          type: string
          description: >-
            Unique idempotency key (UUID format). Normalised to the canonical
            lower-case hyphenated form, so the value echoed back may differ in
            spelling from the one you sent (`{braces}`, upper-case and
            un-hyphenated forms all land on the same key). A duplicate within 30
            minutes is skipped; the request returns 409 only if every order is a
            duplicate.
          example: eb45b192-317b-42d5-9f65-af497b9fa8c1
        futureId:
          type: string
          description: Future identifier (e.g., 'id1012639310001').
          example: id1012639310001
        futureOutcomeId:
          type: integer
          default: 0
          description: >-
            `0` (the default) is the **participant-keyed** sentinel — the
            participant IS the selection (outright winner, topscorer,
            relegation, mvp) — and then `participantId` must be a real id. A
            real id (>= 100001) means a **decomposed** market (prediction
            Yes/No, season totals Over/Under), where `participantId` may stay
            `0`.
          example: 0
        participantId:
          type: integer
          default: 0
          description: >-
            The team or player you back (participant-keyed), or the entity a
            line is about (decomposed). Required (non-zero) when
            `futureOutcomeId` is 0.
          example: 7193
        orderPrice:
          type: number
          exclusiveMinimum: 0
          description: >-
            Minimum acceptable decimal odds. Bets will only be placed at this
            price or better.
          example: 1.95
        orderStake:
          type: number
          exclusiveMinimum: 0
          description: >-
            Stake amount in orderCurrency. Must be within bookmaker min/max
            limits.
          example: 10
        userRef:
          type: string
          minLength: 1
          description: >-
            Your reference string for grouping/filtering orders (e.g., user ID,
            session ID)
          example: bettor1234
        testOrder:
          type: boolean
          description: >-
            If true, order is validated and persisted but NOT placed with
            bookmaker. Use for testing.
          example: false
        bookmakers:
          type: string
          nullable: true
          description: >-
            Comma-separated bookmaker slugs to target (e.g., 'pinnacle,bet365').
            Use '*' or omit for automatic selection.
          example: pinnacle,vertex
        orderCurrency:
          type: string
          default: USD
          description: >-
            ISO 4217 currency code for orderStake. Converted to bookmaker
            currency at placement.
          example: USD
        back:
          type: boolean
          default: true
          description: >-
            Bet direction. true = back (win if selection wins), false = lay (win
            if selection loses).
          example: true
        expiresAt:
          type: string
          nullable: true
          description: >-
            ISO 8601 timestamp when order expires. Defaults to 5 seconds from
            now. Capped at 24 hours maximum.
          example: '2026-01-15T12:00:05Z'
        acceptBetterOdds:
          type: boolean
          default: true
          description: Accept odds better than orderPrice.
          example: true
        acceptPartialStake:
          type: boolean
          default: true
          description: Allow partial stake fills when full stake exceeds bookmaker limit.
          example: true
        meta:
          type: object
          nullable: true
          description: Custom metadata object. Stored with order but not sent to bookmaker.
          example:
            strategy: value
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: API key for authentication. Contact contact@55-tech.com to obtain a key.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.