# TypeScript SDK — Predictions: Order Management

Place, cancel, and query prediction market orders. All methods are on `client.predictions`. Every order method requires authentication. See the [errors guide](/tools/typescript-sdk/errors) for error handling patterns.

### placeOrder

`POST /v1/prediction-markets/order` · Authenticated

Place a single prediction market order. This is a POST mutation — never automatically retried. This method performs **two pre-flight checks** before sending the request to the server:

1. **Client-side validation** — The request body is [validated client-side](/tools/typescript-sdk/deep-dives/request-validation). Invalid fields throw a `ValidationError` without making a network call.
2. **Terms acceptance check** — The SDK calls `getPredictionMarketsTermsStatus()` to verify you've accepted the latest prediction markets terms. If not, it throws `AcceptTermsRequired` instead of sending the order.

```ts
import { AcceptTermsRequired, ValidationError } from "gemini-markets/server";

try {
  const order = await client.predictions.placeOrder({
    symbol: "GEMI-FEDJAN26-DN25",
    orderType: "limit",
    side: "buy",
    quantity: "10",
    price: "0.65",
    outcome: "yes",
    timeInForce: "good-til-cancel",
    makerOrCancel: false,
  });

  console.log(order.orderId);  // bigint
  console.log(order.status);   // "open" | "filled" | "cancelled"
  console.log(order.symbol);
} catch (err) {
  if (err instanceof AcceptTermsRequired) {
    // Accept terms first, then retry
    await client.predictions.acceptPredictionMarketsTerms();
    // Retry the order...
  }
  if (err instanceof ValidationError) {
    console.log(err.field, err.rule, err.message);
  }
}
```

**Validated fields:**

| Field | Rule | Required |
| --- | --- | --- |
| `symbol` | string | Yes |
| `orderType` | `"limit"` or `"stop-limit"` | Yes |
| `side` | `"buy"` or `"sell"` | Yes |
| `quantity` | decimal string | Yes |
| `price` | decimal string, 0–1 | Yes |
| `outcome` | `"yes"` or `"no"` | Yes |
| `stopPrice` | decimal string, 0–1 | Required if `orderType` is `"stop-limit"` |
| `timeInForce` | `"good-til-cancel"`, `"immediate-or-cancel"`, `"fill-or-kill"` | No |
| `makerOrCancel` | boolean | Yes |

> **Caveat** — `price` and `quantity` must be decimal strings, not numbers. `price` and `stopPrice` must be between 0 and 1 inclusive.

See the [patterns guide](/tools/typescript-sdk/patterns) for the recommended terms-acceptance flow.

### placeOrderBatch

`POST /v1/prediction-markets/order/batch` · Authenticated

Place up to 20 orders in a single request. This is a POST mutation — never automatically retried. Like `placeOrder`, this method validates each order client-side and checks terms acceptance before sending. The request body is [validated client-side](/tools/typescript-sdk/deep-dives/request-validation).

```ts
const result = await client.predictions.placeOrderBatch({
  orders: [
    {
      symbol: "GEMI-FEDJAN26-DN25",
      orderType: "limit",
      side: "buy",
      quantity: "5",
      price: "0.60",
      outcome: "yes",
      makerOrCancel: false,
    },
    {
      symbol: "GEMI-FEDJAN26-DN25",
      orderType: "limit",
      side: "buy",
      quantity: "5",
      price: "0.35",
      outcome: "no",
      makerOrCancel: false,
    },
  ],
});

for (const entry of result.results) {
  if ("order" in entry) {
    console.log(entry.order.orderId, entry.order.status);
  } else {
    console.log(entry.error, entry.message);
  }
}
```

> **Validated** — The `orders` array must contain 1–20 items. Each order is validated with the same rules as `placeOrder`.

### cancelOrder

`POST /v1/prediction-markets/order/cancel` · Authenticated

Cancel a single active order by its ID. This is a POST mutation — never automatically retried. The `orderId` is [validated client-side](/tools/typescript-sdk/deep-dives/request-validation) as a non-negative integer identifier (number, bigint, or numeric string).

```ts
const result = await client.predictions.cancelOrder({
  orderId: 12345678n,
});

console.log(result.result);  // "ok"
console.log(result.message); // "Order 12345678 cancelled successfully"
```

### cancelOrderBatch

`POST /v1/prediction-markets/order/batch/cancel` · Authenticated

Cancel up to 20 orders in a single request. This is a POST mutation — never automatically retried. Each order ID is [validated client-side](/tools/typescript-sdk/deep-dives/request-validation).

```ts
const result = await client.predictions.cancelOrderBatch({
  orderIds: [12345678n, 98765432n],
});

for (const entry of result.results) {
  if ("result" in entry && entry.result === "ok") {
    console.log(entry.orderId, "cancelled");
  } else if ("error" in entry) {
    console.log(entry.orderId, entry.error, entry.message);
  }
}
```

> **Validated** — `orderIds` must contain 1–20 non-negative order identifiers.

> **Tip** — The response `orderId` fields are returned as `bigint`. See [Data Types](/tools/typescript-sdk/deep-dives/data-types) for int64 handling.

### getActiveOrders

`POST /v1/prediction-markets/orders/active` · Authenticated

Retrieve your currently active (open) prediction market orders. This is a POST mutation — never automatically retried. The body is optional — omit it to get all active orders. Returns an `OrdersResponse` with an `.orders` array.

```ts
// All active orders
const active = await client.predictions.getActiveOrders();

// Filter by contract symbol
const filtered = await client.predictions.getActiveOrders({
  symbol: "GEMI-FEDJAN26-DN25",
  limit: 50,
});

for (const order of active.orders) {
  console.log(order.orderId, order.side, order.price, order.outcome);
}
```

> **Tip** — The filter field is `symbol` (contract instrument symbol), not `eventTicker`. Response `orderId` values are `bigint`. See [Data Types](/tools/typescript-sdk/deep-dives/data-types).

### getOrderHistory

`POST /v1/prediction-markets/orders/history` · Authenticated

Retrieve your historical prediction market orders. This is a POST mutation — never automatically retried. The body is optional — omit it for the default history window. Returns an `OrdersResponse` with an `.orders` array.

```ts
// Recent order history
const history = await client.predictions.getOrderHistory();

// Filter by status and time range (timestamps are bigint-compatible)
const bounded = await client.predictions.getOrderHistory({
  status: "filled",
  symbol: "GEMI-FEDJAN26-DN25",
  from: 1700000000000n,
  to: 1700086400000n,
});

for (const order of history.orders) {
  console.log(order.orderId, order.status, order.side, order.outcome);
}
```

> **Tip** — The `from` and `to` fields accept `bigint` timestamps (epoch milliseconds). Response `orderId` values are `bigint`.

## What's next

- [Events & Discovery](/tools/typescript-sdk/reference/predictions/events-and-discovery) — browse and search prediction market events
- [Positions & Terms](/tools/typescript-sdk/reference/predictions/positions-and-terms) — open and settled positions, terms acceptance
- [Combos](/tools/typescript-sdk/reference/predictions/combos) — multi-leg combo instruments
- [Request Validation](/tools/typescript-sdk/deep-dives/request-validation) — how client-side validation works
- [Error Handling](/tools/typescript-sdk/errors) — error types and metadata
