Kalshi order-groups API

Order group management endpoints

OpenAPI Specification

kalshi-order-groups-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  title: Kalshi Trade API Manual Endpoints account order-groups API
  version: 3.19.0
  description: Manually defined OpenAPI spec for endpoints being migrated to spec-first approach
servers:
- url: https://external-api.kalshi.com/trade-api/v2
  description: Production Trade API server
- url: https://api.elections.kalshi.com/trade-api/v2
  description: Production shared API server, also supported
- url: https://external-api.demo.kalshi.co/trade-api/v2
  description: Demo Trade API server
- url: https://demo-api.kalshi.co/trade-api/v2
  description: Demo shared API server, also supported
tags:
- name: order-groups
  description: Order group management endpoints
paths:
  /portfolio/order_groups:
    get:
      operationId: GetOrderGroups
      summary: Get Order Groups
      description: ' Retrieves all order groups for the authenticated user.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      parameters:
      - $ref: '#/components/parameters/SubaccountQuery'
      responses:
        '200':
          description: Order groups retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetOrderGroupsResponse'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /portfolio/order_groups/create:
    post:
      operationId: CreateOrderGroup
      summary: Create Order Group
      description: ' Creates a new order group with a contracts limit measured over a rolling 15-second window. When the limit is hit, all orders in the group are cancelled and no new orders can be placed until reset.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderGroupRequest'
      responses:
        '201':
          description: Order group created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateOrderGroupResponse'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /portfolio/order_groups/{order_group_id}:
    get:
      operationId: GetOrderGroup
      summary: Get Order Group
      description: ' Retrieves details for a single order group including all order IDs and auto-cancel status.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      parameters:
      - $ref: '#/components/parameters/OrderGroupIdPath'
      - $ref: '#/components/parameters/SubaccountQuery'
      responses:
        '200':
          description: Order group retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetOrderGroupResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      operationId: DeleteOrderGroup
      summary: Delete Order Group
      description: ' Deletes an order group and cancels all orders within it. This permanently removes the group.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      parameters:
      - $ref: '#/components/parameters/OrderGroupIdPath'
      - $ref: '#/components/parameters/SubaccountQueryDefaultPrimary'
      - $ref: '#/components/parameters/ExchangeIndexQuery'
      responses:
        '200':
          description: Order group deleted successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmptyResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /portfolio/order_groups/{order_group_id}/reset:
    put:
      operationId: ResetOrderGroup
      summary: Reset Order Group
      description: ' Resets the order group''s matched contracts counter to zero, allowing new orders to be placed again after the limit was hit.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      parameters:
      - $ref: '#/components/parameters/OrderGroupIdPath'
      - $ref: '#/components/parameters/SubaccountQueryDefaultPrimary'
      - $ref: '#/components/parameters/ExchangeIndexQuery'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmptyResponse'
      responses:
        '200':
          description: Order group reset successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmptyResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /portfolio/order_groups/{order_group_id}/trigger:
    put:
      operationId: TriggerOrderGroup
      summary: Trigger Order Group
      description: ' Triggers the order group, canceling all orders in the group and preventing new orders until the group is reset.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      parameters:
      - $ref: '#/components/parameters/OrderGroupIdPath'
      - $ref: '#/components/parameters/SubaccountQueryDefaultPrimary'
      - $ref: '#/components/parameters/ExchangeIndexQuery'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmptyResponse'
      responses:
        '200':
          description: Order group triggered successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmptyResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /portfolio/order_groups/{order_group_id}/limit:
    put:
      operationId: UpdateOrderGroupLimit
      summary: Update Order Group Limit
      description: ' Updates the order group contracts limit (rolling 15-second window). If the updated limit would immediately trigger the group, all orders in the group are canceled and the group is triggered.'
      tags:
      - order-groups
      security:
      - kalshiAccessKey: []
        kalshiAccessSignature: []
        kalshiAccessTimestamp: []
      parameters:
      - $ref: '#/components/parameters/OrderGroupIdPath'
      - $ref: '#/components/parameters/ExchangeIndexQuery'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrderGroupLimitRequest'
      responses:
        '200':
          description: Order group limit updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmptyResponse'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    GetOrderGroupsResponse:
      type: object
      properties:
        order_groups:
          type: array
          items:
            $ref: '#/components/schemas/OrderGroup'
          x-go-type-skip-optional-pointer: true
    CreateOrderGroupResponse:
      type: object
      required:
      - order_group_id
      - subaccount
      properties:
        order_group_id:
          type: string
          description: The unique identifier for the created order group
        subaccount:
          type: integer
          minimum: 0
          description: Subaccount number that owns the created order group (0 for primary, 1-32 for subaccounts).
          x-go-type-skip-optional-pointer: true
        exchange_index:
          allOf:
          - $ref: '#/components/schemas/ExchangeIndex'
          x-go-type-skip-optional-pointer: true
    FixedPointCount:
      type: string
      description: Fixed-point contract count string (2 decimals, e.g., "10.00"; referred to as "fp" in field names). Requests accept 0–2 decimal places (e.g., "10", "10.0", "10.00"); responses always emit 2 decimals. Fractional contract values (e.g., "2.50") are supported on markets with fractional trading enabled; the minimum granularity is 0.01 contracts. Integer contract count fields are legacy and will be deprecated; when both integer and fp fields are provided, they must match.
      example: '10.00'
    ExchangeIndex:
      type: integer
      description: 'Identifier for an exchange shard. Defaults to 0 if unspecified. Note: currently only 0 supported.'
      example: 0
    CreateOrderGroupRequest:
      type: object
      properties:
        subaccount:
          type: integer
          minimum: 0
          description: Optional subaccount number to use for this order group (0 for primary, 1-32 for subaccounts)
          default: 0
          x-go-type-skip-optional-pointer: true
        contracts_limit:
          type: integer
          format: int64
          minimum: 1
          description: Specifies the maximum number of contracts that can be matched within this group over a rolling 15-second window. Whole contracts only. Provide contracts_limit or contracts_limit_fp; if both provided they must match.
          x-go-type-skip-optional-pointer: true
          x-oapi-codegen-extra-tags:
            validate: omitempty,gte=1
        contracts_limit_fp:
          $ref: '#/components/schemas/FixedPointCount'
          nullable: true
          description: String representation of the maximum number of contracts that can be matched within this group over a rolling 15-second window. Provide contracts_limit or contracts_limit_fp; if both provided they must match.
        exchange_index:
          allOf:
          - $ref: '#/components/schemas/ExchangeIndex'
          default: 0
          x-go-type-skip-optional-pointer: true
    EmptyResponse:
      type: object
      description: An empty response body
    ErrorResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
        message:
          type: string
          description: Human-readable error message
        details:
          type: string
          description: Additional details about the error, if available
        service:
          type: string
          description: The name of the service that generated the error
    OrderGroup:
      type: object
      required:
      - id
      - is_auto_cancel_enabled
      properties:
        id:
          type: string
          description: Unique identifier for the order group
          x-go-type-skip-optional-pointer: true
        contracts_limit_fp:
          $ref: '#/components/schemas/FixedPointCount'
          description: String representation of the current maximum contracts allowed over a rolling 15-second window.
          x-go-type-skip-optional-pointer: true
        is_auto_cancel_enabled:
          type: boolean
          description: Whether auto-cancel is enabled for this order group
          x-go-type-skip-optional-pointer: true
        exchange_index:
          allOf:
          - $ref: '#/components/schemas/ExchangeIndex'
          x-go-type-skip-optional-pointer: true
    GetOrderGroupResponse:
      type: object
      required:
      - is_auto_cancel_enabled
      - orders
      properties:
        is_auto_cancel_enabled:
          type: boolean
          description: Whether auto-cancel is enabled for this order group
        contracts_limit_fp:
          $ref: '#/components/schemas/FixedPointCount'
          description: String representation of the current maximum contracts allowed over a rolling 15-second window.
          x-go-type-skip-optional-pointer: true
        orders:
          type: array
          items:
            type: string
          description: List of order IDs that belong to this order group
          x-go-type-skip-optional-pointer: true
        exchange_index:
          allOf:
          - $ref: '#/components/schemas/ExchangeIndex'
          x-go-type-skip-optional-pointer: true
    UpdateOrderGroupLimitRequest:
      type: object
      properties:
        contracts_limit:
          type: integer
          format: int64
          minimum: 1
          description: New maximum number of contracts that can be matched within this group over a rolling 15-second window. Whole contracts only. Provide contracts_limit or contracts_limit_fp; if both provided they must match.
          x-go-type-skip-optional-pointer: true
          x-oapi-codegen-extra-tags:
            validate: omitempty,gte=1
        contracts_limit_fp:
          $ref: '#/components/schemas/FixedPointCount'
          nullable: true
          description: String representation of the new maximum number of contracts that can be matched within this group over a rolling 15-second window. Provide contracts_limit or contracts_limit_fp; if both provided they must match.
  parameters:
    OrderGroupIdPath:
      name: order_group_id
      in: path
      required: true
      description: Order group ID
      schema:
        type: string
    SubaccountQuery:
      name: subaccount
      in: query
      description: Subaccount number (0 for primary, 1-32 for subaccounts). If omitted, defaults to all subaccounts.
      schema:
        type: integer
    SubaccountQueryDefaultPrimary:
      name: subaccount
      in: query
      description: Subaccount number (0 for primary, 1-32 for subaccounts). Defaults to 0.
      schema:
        type: integer
    ExchangeIndexQuery:
      name: exchange_index
      in: query
      schema:
        $ref: '#/components/schemas/ExchangeIndex'
      x-go-type-skip-optional-pointer: true
  responses:
    UnauthorizedError:
      description: Unauthorized - authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFoundError:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    BadRequestError:
      description: Bad request - invalid input
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    kalshiAccessKey:
      type: apiKey
      in: header
      name: KALSHI-ACCESS-KEY
      description: Your API key ID
    kalshiAccessSignature:
      type: apiKey
      in: header
      name: KALSHI-ACCESS-SIGNATURE
      description: RSA-PSS signature of the request
    kalshiAccessTimestamp:
      type: apiKey
      in: header
      name: KALSHI-ACCESS-TIMESTAMP
      description: Request timestamp in milliseconds