openapi: 3.2.0 info: title: Gemini Prediction Markets Trading API description: 'API for trading prediction market contracts on Gemini. **Note:** Only fields documented in this specification are considered stable. Undocumented fields in API responses may change or be removed without notice.' version: 1.0.0 contact: name: Gemini API Support servers: - url: https://api.gemini.com description: Production - url: https://api.sandbox.gemini.com description: Sandbox tags: - name: Trading description: Authenticated REST endpoints for placing and managing orders. Treat REST order placement as payload reference or a one-off server workflow; for active trading and market making, prefer WebSocket order.place. paths: /v1/prediction-markets/order: post: tags: - Trading summary: Place order description: 'Place a new prediction market order. Supports limit and stop-limit order types. Requires authentication and NewOrder permission. Before sending orders, check `GET /v1/prediction-markets/terms/status`. If `hasAcceptedLatest` is `false`, display `GET /v1/prediction-markets/terms` and call `POST /v1/prediction-markets/terms/accept`, then retry the order. Validate each order''s quantity and price against the instrument-specific `quantityIncrement`, `quantityMinimum`, `priceIncrement`, and `priceMinimum` returned in the contract metadata. Do not assume a fixed quantity or price grid across instruments. ### Stop-Limit Orders A stop-limit order is an order type that allows for order placement when a price reaches a specified level. Stop-limit orders take in both a `price` and a `stopPrice` as parameters. The `stopPrice` is the price that triggers the order to be placed on the continuous live order book at the `price`. For buy orders, the `stopPrice` must be greater than or equal to the last trade price and less than or equal to the `price`; for sell orders, the `stopPrice` must be less than or equal to the last trade price and greater than or equal to the `price`. Both `price` and `stopPrice` must be in the 0-1 range.' operationId: placeOrder security: - apiKey: [] payloadAuth: [] signatureAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/OrderRequest' examples: buyYes: summary: Buy YES contract description: Place a limit order to buy 100 YES contracts at 0.65 value: symbol: GEMI-FEDJAN26-DN25 orderType: limit side: buy quantity: '100' price: '0.65' outcome: 'yes' timeInForce: good-til-cancel sellNo: summary: Sell NO contract description: Place a limit order to sell 50 NO contracts at 0.35 value: symbol: GEMI-FEDJAN26-DN25 orderType: limit side: sell quantity: '50' price: '0.35' outcome: 'no' timeInForce: good-til-cancel makerOnly: summary: Maker-only order (post-only) description: Place a maker-only order that will be cancelled if it would match immediately. Useful for ensuring you provide liquidity and qualify for maker rebates. value: symbol: GEMI-FEDJAN26-DN25 orderType: limit side: buy quantity: '100' price: '0.55' outcome: 'yes' timeInForce: good-til-cancel makerOrCancel: true buyYesStopLimit: summary: Buy YES stop-limit description: Place a stop-limit order to buy 100 YES contracts at 0.70 once the market reaches the stop trigger of 0.65. value: symbol: GEMI-FEDJAN26-DN25 orderType: stop-limit side: buy quantity: '100' price: '0.70' stopPrice: '0.65' outcome: 'yes' timeInForce: good-til-cancel sellNoStopLimit: summary: Sell NO stop-limit description: Place a stop-limit order to sell 50 NO contracts at 0.40 once the market falls to the stop trigger of 0.45. value: symbol: GEMI-FEDJAN26-DN25 orderType: stop-limit side: sell quantity: '50' price: '0.40' stopPrice: '0.45' outcome: 'no' timeInForce: good-til-cancel responses: '201': description: Order created successfully content: application/json: schema: $ref: '#/components/schemas/OrderResponse' examples: orderPlaced: summary: Order successfully placed value: orderId: 12345678901 status: open symbol: GEMI-FEDJAN26-DN25 side: buy outcome: 'yes' orderType: limit quantity: '100' filledQuantity: '0' remainingQuantity: '100' price: '0.65' avgExecutionPrice: null createdAt: '2025-12-15T10:30:00.000Z' updatedAt: '2025-12-15T10:30:00.000Z' cancelledAt: null contractMetadata: contractId: contract_123 contractName: FEDJAN26-DN25 contractTicker: FEDJAN26-DN25 eventTicker: FEDJAN26 eventName: Will Fed Funds Rate drop at least 0.25% at January 2026 meeting? category: economics contractStatus: active imageUrl: https://example.com/fed.png expiryDate: '2026-01-31T23:59:59.000Z' resolvedAt: null description: Resolves YES if Federal Reserve lowers the target rate by 0.25% or more at the January 2026 FOMC meeting stopLimitOrderPlaced: summary: Stop-limit order successfully placed value: orderId: 12345678902 status: open symbol: GEMI-FEDJAN26-DN25 side: buy outcome: 'yes' orderType: stop-limit quantity: '100' filledQuantity: '0' remainingQuantity: '100' price: '0.70' stopPrice: '0.65' avgExecutionPrice: null createdAt: '2025-12-15T10:30:00.000Z' updatedAt: '2025-12-15T10:30:00.000Z' cancelledAt: null '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '422': description: Order rejected (e.g., insufficient funds) content: application/json: schema: $ref: '#/components/schemas/Error' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' /v1/prediction-markets/order/batch: post: tags: - Trading summary: Place a batch of orders description: 'Place between 1 and 20 prediction market orders in one authenticated request. The complete payload is signed once using the standard private REST authentication headers. Each entry accepts the same fields as `POST /v1/prediction-markets/order`. The operation is synchronous and non-atomic. Gemini validates the entire batch before submitting any orders. If the batch or any entry fails up-front validation, the request fails and no orders are submitted. After validation succeeds, orders are submitted sequentially and each result is returned in request order. An exchange rejection for one order does not stop later orders from being submitted; it appears as an `error` and `message` for that entry in the `200` response.' operationId: placeOrderBatch security: - apiKey: [] payloadAuth: [] signatureAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PlaceOrderBatchRequest' examples: twoOrders: summary: Place two orders value: orders: - symbol: GEMI-FEDJAN26-DN25 orderType: limit side: buy quantity: '100' price: '0.65' outcome: 'yes' timeInForce: good-til-cancel - symbol: GEMI-FEDJAN26-DN25 orderType: limit side: sell quantity: '50' price: '0.35' outcome: 'no' timeInForce: good-til-cancel responses: '200': description: Batch processed. Results are returned in request order and may contain both successful orders and per-entry errors. content: application/json: schema: $ref: '#/components/schemas/PlaceOrderBatchResponse' examples: partialSuccess: summary: One order accepted and one order rejected value: results: - order: orderId: 12345678901 status: open symbol: GEMI-FEDJAN26-DN25 side: buy outcome: 'yes' orderType: limit timeInForce: good-til-cancel quantity: '100' filledQuantity: '0' remainingQuantity: '100' price: '0.65' createdAt: '2025-12-15T10:30:00.000Z' updatedAt: '2025-12-15T10:30:00.000Z' - error: InsufficientFunds message: Insufficient funds '400': description: Invalid payload, empty batch, more than 20 entries, or an invalid order. No orders are submitted. content: application/json: schema: oneOf: - $ref: '#/components/schemas/AuthErrorResponse' - $ref: '#/components/schemas/PredictionMarketsError' '401': description: Authentication is missing or invalid. content: application/json: schema: $ref: '#/components/schemas/AuthErrorResponse' '403': description: The account is not permitted to place orders or has not accepted the current Prediction Markets terms. No orders are submitted. content: application/json: schema: oneOf: - $ref: '#/components/schemas/AuthErrorResponse' - $ref: '#/components/schemas/AccountGroupBlockedError' - $ref: '#/components/schemas/TermsNotAcceptedError' - $ref: '#/components/schemas/RestrictedSellOnlyError' '409': description: The request nonce conflicts with a previously submitted request. content: application/json: schema: $ref: '#/components/schemas/AuthErrorResponse' '422': description: An order failed an up-front risk check. No orders are submitted. content: application/json: schema: $ref: '#/components/schemas/PredictionMarketsError' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/PredictionMarketsError' '503': description: Prediction markets or batch orders are temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/PredictionMarketsError' /v1/prediction-markets/order/cancel: post: tags: - Trading summary: Cancel order description: Cancel an existing prediction market order. Requires authentication and CancelOrder permission. operationId: cancelOrder security: - apiKey: [] payloadAuth: [] signatureAuth: [] requestBody: required: true content: application/json: schema: type: object required: - orderId properties: orderId: type: integer format: int64 description: The order ID to cancel example: 12345678 responses: '200': description: Order cancelled successfully content: application/json: schema: type: object properties: result: type: string example: ok message: type: string example: Order 12345678 cancelled successfully '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': description: Order not found content: application/json: schema: $ref: '#/components/schemas/Error' '422': description: Order cannot be cancelled (e.g., already filled) content: application/json: schema: $ref: '#/components/schemas/Error' '500': $ref: '#/components/responses/InternalError' '503': $ref: '#/components/responses/ServiceUnavailable' /v1/prediction-markets/order/batch/cancel: post: tags: - Trading summary: Cancel a batch of orders description: 'Cancel between 1 and 20 prediction market orders in one authenticated request. The complete payload is signed once using the standard private REST authentication headers. Each order ID may be a JSON integer or a quoted numeric string. The operation is synchronous and non-atomic. Gemini validates all order IDs before attempting any cancellation. If the batch is empty, contains more than 20 entries, or contains an invalid ID, the request fails and no orders are cancelled. After validation succeeds, cancellations are attempted sequentially and each result is returned in request order. A rejection for one cancellation does not stop later cancellations from being attempted; it appears as an `error` and `message` for that entry in the `200` response.' operationId: cancelOrderBatch security: - apiKey: [] payloadAuth: [] signatureAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CancelOrderBatchRequest' examples: twoOrders: summary: Cancel two orders value: orderIds: - 12345678 - '12345679' responses: '200': description: Batch processed. Results are returned in request order and may contain both successful cancellations and per-entry errors. content: application/json: schema: $ref: '#/components/schemas/CancelOrderBatchResponse' examples: partialSuccess: summary: One order cancelled and one order not found value: results: - orderId: 12345678 result: ok - orderId: 12345679 error: OrderNotFound message: Order 12345679 not found '400': description: Invalid payload, empty batch, more than 20 entries, or an invalid order ID. No orders are cancelled. content: application/json: schema: oneOf: - $ref: '#/components/schemas/AuthErrorResponse' - $ref: '#/components/schemas/PredictionMarketsError' '401': description: Authentication is missing or invalid. content: application/json: schema: $ref: '#/components/schemas/AuthErrorResponse' '403': description: The account is not permitted to cancel orders. content: application/json: schema: $ref: '#/components/schemas/AuthErrorResponse' '409': description: The request nonce conflicts with a previously submitted request. content: application/json: schema: $ref: '#/components/schemas/AuthErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/PredictionMarketsError' '503': description: Prediction markets or batch orders are temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/PredictionMarketsError' components: schemas: CancelOrderBatchSuccessResult: type: object additionalProperties: false required: - orderId - result properties: orderId: type: integer format: int64 description: Order ID from the corresponding request entry. example: 12345678 result: type: string enum: - ok TermsNotAcceptedError: type: object additionalProperties: false required: - error - message properties: error: type: string enum: - TERMS_NOT_ACCEPTED message: type: string enum: - Prediction markets terms must be accepted before placing orders OrderSide: type: string enum: - buy - sell PlaceOrderBatchResponse: type: object required: - results properties: results: type: array minItems: 1 maxItems: 20 description: One result for each submitted order, in request order. items: $ref: '#/components/schemas/PlaceOrderBatchResult' PlaceOrderBatchResult: description: Exactly one outcome is present. Accepted entries contain `order`; rejected entries contain `error` and `message`. oneOf: - $ref: '#/components/schemas/PlaceOrderBatchSuccessResult' - $ref: '#/components/schemas/PlaceOrderBatchErrorResult' PlaceOrderBatchRequest: type: object required: - orders properties: orders: type: array minItems: 1 maxItems: 20 description: Orders to submit. Every entry is validated before any order is submitted. All orders use the account associated with the authenticated request. items: $ref: '#/components/schemas/OrderRequest' Outcome: type: string enum: - 'yes' - 'no' description: The outcome being traded (Yes or No) CancelOrderBatchResult: description: Exactly one outcome is present. Successful entries contain `orderId` and `result`; rejected entries contain `orderId`, `error`, and `message`. oneOf: - $ref: '#/components/schemas/CancelOrderBatchSuccessResult' - $ref: '#/components/schemas/CancelOrderBatchErrorResult' OrderStatus: type: string enum: - open - filled - cancelled Error: type: object properties: error: type: string description: Error code example: InvalidInput message: type: string description: Human-readable error message example: orderId is required PlaceOrderBatchSuccessResult: type: object additionalProperties: false required: - order properties: order: $ref: '#/components/schemas/BatchOrderResponse' BatchOrderResponse: type: object description: An accepted order returned for one batch entry. required: - orderId - status - symbol - side - outcome - orderType - timeInForce - quantity - filledQuantity - remainingQuantity - price - createdAt - updatedAt properties: orderId: type: integer format: int64 example: 12345678 hashOrderId: type: string description: Hashed order ID; omitted when unavailable clientOrderId: type: string description: Client-provided order ID; omitted when unavailable globalOrderId: type: string description: Global order ID; omitted when unavailable status: type: string enum: - open - filled - cancelled - closed symbol: type: string side: $ref: '#/components/schemas/OrderSide' outcome: $ref: '#/components/schemas/Outcome' orderType: $ref: '#/components/schemas/OrderType' timeInForce: type: string enum: - good-til-cancel - immediate-or-cancel - fill-or-kill - maker-or-cancel quantity: type: string description: Original order quantity filledQuantity: type: string description: Amount filled so far remainingQuantity: type: string description: Amount remaining to fill price: type: string description: Limit price stopPrice: type: string description: Stop trigger price; omitted unless populated for a `stop-limit` order avgExecutionPrice: type: string description: Average price of fills; omitted when unavailable createdAt: type: string format: date-time updatedAt: type: string format: date-time cancelledAt: type: string format: date-time description: Cancellation time; omitted unless the order was cancelled contractMetadata: $ref: '#/components/schemas/ContractMetadata' promoCashApplied: type: string description: Promotional cash reserved or applied to the order; omitted when unavailable fundsOnHold: type: string description: Cash reserved for the unfilled portion of a resting buy order; omitted when unavailable AccountGroupBlockedError: type: object additionalProperties: false required: - error - code properties: error: type: string enum: - This account is not permitted to trade prediction markets code: type: string enum: - ACCOUNT_GROUP_BLOCKED CancelOrderBatchRequest: type: object required: - orderIds properties: orderIds: type: array minItems: 1 maxItems: 20 description: Order IDs to cancel. Each ID may be an integer or a quoted numeric string. All IDs are validated before any cancellation is attempted. items: oneOf: - type: integer format: int64 example: 12345678 - type: string pattern: ^\d+$ example: '12345678' CancelOrderBatchErrorResult: type: object additionalProperties: false required: - orderId - error - message properties: orderId: type: integer format: int64 description: Order ID from the corresponding request entry. example: 12345678 error: type: string description: Error class for a rejected cancellation example: OrderNotFound message: type: string description: Human-readable detail for a rejected cancellation example: Order 12345678 not found RestrictedSellOnlyError: type: object additionalProperties: false required: - error - message properties: error: type: string enum: - ACCOUNT_RESTRICTED_SELL_ONLY message: type: string enum: - Your account is restricted to selling existing positions; buying is not permitted. AuthErrorResponse: type: object additionalProperties: false required: - result - reason - message properties: result: type: string enum: - error reason: type: string description: Authentication or authorization error class example: MissingNonce message: type: string description: Human-readable authentication or authorization detail example: Must provide unique monotonic increasing 'nonce' field in payload OrderResponse: type: object properties: orderId: type: integer format: int64 example: 12345678 hashOrderId: type: - string - 'null' clientOrderId: type: - string - 'null' globalOrderId: type: - string - 'null' status: $ref: '#/components/schemas/OrderStatus' symbol: type: string side: $ref: '#/components/schemas/OrderSide' outcome: $ref: '#/components/schemas/Outcome' orderType: $ref: '#/components/schemas/OrderType' quantity: type: string description: Original order quantity filledQuantity: type: string description: Amount filled so far remainingQuantity: type: string description: Amount remaining to fill price: type: string description: Limit price stopPrice: type: - string - 'null' description: Stop trigger price (populated for `stop-limit` orders) avgExecutionPrice: type: - string - 'null' description: Average price of fills createdAt: type: string format: date-time updatedAt: type: string format: date-time cancelledAt: type: - string - 'null' format: date-time contractMetadata: $ref: '#/components/schemas/ContractMetadata' OrderType: type: string enum: - limit - stop-limit description: Order type. `stop-limit` orders require a `stopPrice` that triggers a limit order at `price` when the market reaches the trigger. TimeInForce: type: string enum: - good-til-cancel - immediate-or-cancel - fill-or-kill default: good-til-cancel description: 'Order execution behavior: - `good-til-cancel` - Order remains active until filled or cancelled (default) - `immediate-or-cancel` - Fill immediately or cancel remaining - `fill-or-kill` - Fill entire order immediately or cancel ' CancelOrderBatchResponse: type: object required: - results properties: results: type: array minItems: 1 maxItems: 20 description: One result for each requested cancellation, in request order. items: $ref: '#/components/schemas/CancelOrderBatchResult' PredictionMarketsError: type: object additionalProperties: false required: - error properties: error: type: string description: Prediction Markets error class example: InvalidInput field: type: string description: Request field associated with the error, when available example: orders message: type: string description: Human-readable error detail, when available example: orders must contain between 1 and 20 entries OrderRequest: type: object required: - symbol - orderType - side - quantity - price - outcome properties: symbol: type: string description: Contract instrument symbol example: GEMI-FEDJAN26-DN25 orderType: $ref: '#/components/schemas/OrderType' side: $ref: '#/components/schemas/OrderSide' quantity: type: string format: decimal description: Number of contracts example: '100' price: type: string format: decimal description: Limit price (0-1 range) example: '0.65' stopPrice: type: string format: decimal description: The price to trigger a stop-limit order (0-1 range). Only available for stop-limit orders. See [Stop-Limit Orders](#operation/placeOrder) above for `stopPrice`/`price` constraints. example: '0.60' outcome: $ref: '#/components/schemas/Outcome' timeInForce: $ref: '#/components/schemas/TimeInForce' makerOrCancel: type: boolean description: Set to `true` to require maker-only behavior. If the order would immediately take liquidity, the order is cancelled instead of filling. default: false PlaceOrderBatchErrorResult: type: object additionalProperties: false required: - error - message properties: error: type: string description: Error class for a rejected entry example: InsufficientFunds message: type: string description: Human-readable detail for a rejected entry example: Insufficient funds ContractMetadata: type: object properties: contractId: type: string contractName: type: string contractTicker: type: string eventTicker: type: string eventName: type: string category: type: string contractStatus: type: string eventType: type: string description: Event type ("binary" or "categorical") expiryDate: type: - string - 'null' format: date-time resolvedAt: type: - string - 'null' format: date-time resolutionSide: type: - string - 'null' description: Winning outcome if resolved ("yes" or "no") parentEventTicker: type: - string - 'null' description: Parent event ticker for sub-events startTime: type: - string - 'null' format: date-time description: Start datetime (ISO 8601) responses: ServiceUnavailable: description: Prediction markets feature is temporarily unavailable content: application/json: schema: $ref: '#/components/schemas/Error' BadRequest: description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/Error' InternalError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/Error' securitySchemes: apiKey: type: apiKey in: header name: X-GEMINI-APIKEY description: Gemini API key with appropriate permissions payloadAuth: type: apiKey in: header name: X-GEMINI-PAYLOAD description: Base64-encoded private REST payload. See Gemini private REST authentication. signatureAuth: type: apiKey in: header name: X-GEMINI-SIGNATURE description: Hex HMAC-SHA384 signature of the payload using the API secret.