openapi: 3.1.0 info: title: Bullet Account Trading API description: REST API for the Bullet exchange. Provides Binance FAPI-compatible endpoints for trading, account management, and market data. contact: name: Bullet url: https://bullet.xyz license: name: Proprietary version: 0.1.0 servers: - url: / description: Current server - url: https://tradingapi.mainnet.bullet.xyz description: Mainnet - url: https://tradingapi.testnet.bullet.xyz description: Testnet - url: https://tradingapi.staging.bullet.xyz description: Staging tags: - name: Trading paths: /fapi/v1/openOrder: get: tags: - Trading summary: Query Current Open Order operationId: query_open_order parameters: - name: symbol in: query required: true schema: type: string - name: orderId in: query required: false schema: type: - integer - 'null' format: int64 minimum: 0 - name: clientOrderId in: query required: false schema: type: - integer - 'null' format: int64 minimum: 0 - name: triggerOrderId in: query description: 'look up a user trigger order (STOP / TAKE_PROFIT) by its TriggerOrderId. mutually exclusive with `orderId` / `clientOrderId` — trigger orders use an independent id counter from regular orders in the rollup' required: false schema: type: - integer - 'null' format: int64 minimum: 0 - name: address in: query required: true schema: type: string responses: '200': description: Open order information content: application/json: schema: $ref: '#/components/schemas/BinanceOrder' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '404': description: Market not found content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '502': description: Upstream service unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' /fapi/v1/openOrders: get: tags: - Trading summary: Query All Open Orders operationId: query_open_orders parameters: - name: symbol in: query description: Trading pair symbol — optional, omit to return open orders across all markets required: false schema: type: - string - 'null' - name: address in: query description: Account address required: true schema: type: string responses: '200': description: List of open orders content: application/json: schema: type: array items: $ref: '#/components/schemas/BinanceOrder' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '404': description: Market not found content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '502': description: Upstream service unavailable content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' components: schemas: BinanceOrder: type: object required: - orderId - symbol - marketId - status - price - avgPrice - origQty - executedQty - cumQty - cumQuote - timeInForce - orderType - reduceOnly - closePosition - side - positionSide - workingType - priceProtect - origType - priceMatch - selfTradePreventionMode - goodTillDate - updateTime - isTrigger properties: avgPrice: type: string format: decimal clientOrderId: type: - string - 'null' closePosition: type: boolean cumQty: type: string format: decimal cumQuote: type: string format: decimal executedQty: type: string format: decimal goodTillDate: type: integer format: uint64 minimum: 0 isTrigger: type: boolean description: 'bullet extension: true when this row is a user trigger order (STOP / TAKE_PROFIT). `orderId` for triggers is drawn from the `TriggerOrderId` namespace, which is independent of the regular `OrderId` counter — use `(orderId, isTrigger)` as the composite key' marketId: type: integer format: uint16 minimum: 0 orderId: type: integer format: uint64 minimum: 0 orderType: type: string description: 'one of: `LIMIT`, `STOP`, `TAKE_PROFIT`' origQty: type: string format: decimal origType: type: string description: same as `orderType` pendingTpsl: oneOf: - type: 'null' - $ref: '#/components/schemas/PendingTpsl' description: 'reserved TP/SL pair attached to this parent limit order. only present while the parent is unfilled — once filled, the trigger orders are activated and listed independently' positionSide: type: string price: type: string format: decimal priceMatch: type: string priceProtect: type: boolean reduceOnly: type: boolean selfTradePreventionMode: type: string side: type: string status: type: string description: 'one of: NEW, PARTIALLY_FILLED, FILLED' stopPrice: type: - string - 'null' format: decimal symbol: type: string timeInForce: type: string updateTime: type: integer format: int64 workingType: type: string ApiErrorDetail: oneOf: - $ref: '#/components/schemas/JsonValidationErrorDetail' - type: object description: 'Typed details body. Variant order is important for untagged deserialization: keep the more-specific shape (`JsonValidation`) before more-permissive ones. `Upstream` holds the upstream payload verbatim (object, string, array, number, etc.) so pre-PR clients reading `details.error` (or `details` directly) keep working.' TpslLeg: type: object required: - triggerOrderId - orderPrice - triggerPrice - priceCondition - orderType - timeInForce properties: orderPrice: type: string format: decimal orderType: type: string description: 'LIMIT (bullet''s TPSL legs are always limit orders — see `time_in_force` for the actual TIF behaviour)' priceCondition: type: string description: MARK_PRICE | ORACLE_PRICE | LAST_PRICE timeInForce: type: string description: 'GTC | GTX (post-only) | FOK | IOC — matches the parent BinanceOrder''s `timeInForce` shape' triggerOrderId: type: integer format: uint64 description: the reserved TriggerOrderId this leg will activate as minimum: 0 triggerPrice: type: string format: decimal JsonValidationErrorDetail: type: object description: 'One JSON shape failure: machine-readable `rule` + full serde message including line/column. Surfaced under `details` on the wire.' required: - rule - message properties: message: type: string example: 'invalid type: integer `24500000`, expected a string at line 4 column 30' rule: type: string example: wrong_type PendingTpsl: type: object required: - dynamicSize properties: dynamicSize: type: boolean description: 'if true, the activated trigger orders track the parent''s filled size; otherwise they use the size baked in at placement' sl: oneOf: - type: 'null' - $ref: '#/components/schemas/TpslLeg' tp: oneOf: - type: 'null' - $ref: '#/components/schemas/TpslLeg' ApiErrorResponse: type: object description: 'Structured API error response matching Bullet API format. All error responses from the trading API conform to this schema.' required: - status - message properties: details: oneOf: - type: 'null' - $ref: '#/components/schemas/ApiErrorDetail' description: Structured per-failure details. Shape depends on the variant. error_id: type: - string - 'null' description: Error identifier for support. example: 8b2e4d9f-7a1c-4f0e-9c5d-3e6a8b1c2d4f message: type: string description: Human-readable error message. example: 'Transaction validation failed: insufficient funds' status: type: integer format: uint16 description: HTTP status code. example: 400 minimum: 0