# Orders

Submit, view, and cancel orders on Turbine.

## Submit Order

Create a new order on the orderbook.

```
POST /api/v1/orders
```

### Request Body

```json
{
  "order": {
    "marketId": "0x1234...abcd",
    "trader": "0xYourAddress...",
    "side": 0,
    "outcome": 0,
    "price": 500000,
    "size": 10000000,
    "nonce": 1234567890,
    "expiration": 1735689600,
    "makerFeeRecipient": "0x0000000000000000000000000000000000000000"
  },
  "signature": "0x...",
  "permitSignature": {
    "nonce": 0,
    "value": "100000000",
    "deadline": 1735689600,
    "v": 27,
    "r": "0x...",
    "s": "0x..."
  }
}
```

### Order Fields

| Field               | Type    | Description                                                                   |
| ------------------- | ------- | ----------------------------------------------------------------------------- |
| `marketId`          | bytes32 | Market identifier                                                             |
| `trader`            | address | Your wallet address                                                           |
| `side`              | uint8   | `0` = BUY, `1` = SELL                                                         |
| `outcome`           | uint8   | `0` = YES, `1` = NO                                                           |
| `price`             | uint64  | Price in USDC (6 decimals, range 1–999999). `500000` = $0.50                  |
| `size`              | uint64  | Order size in shares (6 decimals). `10000000` = 10 shares                     |
| `nonce`             | uint64  | Unique nonce for the order                                                    |
| `expiration`        | uint64  | Unix timestamp when order expires (must be at least 60 seconds in the future) |
| `makerFeeRecipient` | address | Fee recipient (use zero address)                                              |

### Permit Signature (Optional)

For per-order gasless USDC approval. Include when buying without prior USDC approval.

{% hint style="info" %}
Recommended alternative: Use a one-time max permit via [`POST /api/v1/relayer/usdc-permit`](https://docs.ojolabs.xyz/markets/api/broken-reference) instead. This approves USDC once, and all future orders can omit `permitSignature`.
{% endhint %}

| Field      | Type   | Description                        |
| ---------- | ------ | ---------------------------------- |
| `nonce`    | uint64 | On-chain permit nonce              |
| `value`    | string | Amount to approve (as string)      |
| `deadline` | uint64 | Permit expiration (Unix timestamp) |
| `v`        | uint8  | Signature component                |
| `r`        | string | Signature component (32 bytes hex) |
| `s`        | string | Signature component (32 bytes hex) |

### Response

```json
{
  "orderHash": "0xabc123...",
  "status": "accepted",
  "matches": 2,
  "timestamp": 1735689000
}
```

| Field       | Type    | Description                                         |
| ----------- | ------- | --------------------------------------------------- |
| `orderHash` | string  | Unique order identifier (EIP-712 hash)              |
| `status`    | string  | `"accepted"` on success                             |
| `matches`   | integer | Number of immediate matches against existing orders |
| `timestamp` | uint64  | Server timestamp                                    |

### Validation Rules

* **Price**: Must be between 1 and 999999 (exclusive of 0 and 1000000)
* **Size**: Must be greater than 0
* **Expiration**: Must be at least 60 seconds in the future
* **Signature**: Must be a valid EIP-712 typed data signature (65 bytes)

### EIP-712 Signing

Orders must be signed using EIP-712 typed data:

```javascript
const domain = {
  name: "Turbine Settlement",
  version: "1",
  chainId: 137,
  verifyingContract: "0xSettlementAddress..."
};

const types = {
  Order: [
    { name: "marketId", type: "bytes32" },
    { name: "trader", type: "address" },
    { name: "side", type: "uint8" },
    { name: "outcome", type: "uint8" },
    { name: "price", type: "uint64" },
    { name: "size", type: "uint64" },
    { name: "nonce", type: "uint64" },
    { name: "expiration", type: "uint64" },
    { name: "makerFeeRecipient", type: "address" }
  ]
};

const signature = await wallet._signTypedData(domain, types, order);
```

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/orders \
  -H "Content-Type: application/json" \
  -d '{
    "order": {
      "marketId": "0x...",
      "trader": "0x...",
      "side": 0,
      "outcome": 0,
      "price": 500000,
      "size": 10000000,
      "nonce": 1234567890,
      "expiration": 1735689600,
      "makerFeeRecipient": "0x0000000000000000000000000000000000000000"
    },
    "signature": "0x..."
  }'
```

## Get User Orders

Retrieve open orders for a user.

```
GET /api/v1/orders
```

### Query Parameters

| Parameter | Type    | Required | Description           |
| --------- | ------- | -------- | --------------------- |
| `trader`  | address | Yes      | User's wallet address |
| `market`  | bytes32 | No       | Filter by market ID   |

### Response

```json
{
  "orders": [
    {
      "orderHash": "0xabc...",
      "marketId": "0x...",
      "side": 0,
      "price": 500000,
      "size": 10000000,
      "remainingSize": 5000000,
      "timestamp": 1735689000
    }
  ],
  "count": 1
}
```

| Field           | Type   | Description                                                   |
| --------------- | ------ | ------------------------------------------------------------- |
| `orderHash`     | string | Order identifier                                              |
| `marketId`      | string | Market identifier                                             |
| `side`          | uint8  | `0` = BUY, `1` = SELL                                         |
| `price`         | uint64 | Order price (6 decimals). `500000` = $0.50                    |
| `size`          | uint64 | Original order size (6 decimals)                              |
| `remainingSize` | uint64 | Unfilled portion (6 decimals). `5000000` = 5 shares remaining |
| `timestamp`     | uint64 | When order was placed                                         |

### Example

```bash
curl "https://api.turbinefi.com/api/v1/orders?trader=0xYourAddress"
```

## Cancel Order

Cancel an open order.

```
DELETE /api/v1/orders/{hash}
```

### Path Parameters

| Parameter | Type   | Description          |
| --------- | ------ | -------------------- |
| `hash`    | string | Order hash to cancel |

### Query Parameters

| Parameter  | Type    | Required | Description                            |
| ---------- | ------- | -------- | -------------------------------------- |
| `marketId` | bytes32 | Yes      | Market ID                              |
| `side`     | string  | No       | `"buy"` or `"sell"` (default: `"buy"`) |

### Response

```json
{
  "status": "cancelled",
  "orderHash": "0xabc..."
}
```

### Example

```bash
curl -X DELETE "https://api.turbinefi.com/api/v1/orders/0xabc...?marketId=0x...&side=buy"
```

## Get All User Orders

Returns all open orders for a user across all markets on a specific chain.

```
GET /api/v1/users/{address}/orders
```

### Path Parameters

| Parameter | Type    | Description           |
| --------- | ------- | --------------------- |
| `address` | address | User's wallet address |

### Query Parameters

| Parameter  | Type    | Required | Description            |
| ---------- | ------- | -------- | ---------------------- |
| `chain_id` | integer | Yes      | Chain ID (e.g., `137`) |

### Response

```json
{
  "orders": [
    {
      "orderHash": "0xabc...",
      "marketId": "0x...",
      "marketQuestion": "Will ETH reach $5000?",
      "side": 0,
      "outcome": 0,
      "price": 500000,
      "size": 10000000,
      "remainingSize": 5000000,
      "timestamp": 1735689000
    }
  ]
}
```

### Example

```bash
curl "https://api.turbinefi.com/api/v1/users/0xYourAddress/orders?chain_id=137"
```

## Failed Trades

Returns trades that failed settlement in the last 24 hours.

```
GET /api/v1/failed-trades
```

### Response

```json
{
  "failedTrades": [
    {
      "marketId": "0x...",
      "txHash": "0x...",
      "buyerAddress": "0x...",
      "sellerAddress": "0x...",
      "fillSize": 10000000,
      "fillPrice": 500000,
      "reason": "execution reverted",
      "timestamp": "2025-01-01T00:00:00Z",
      "batchIndex": 0
    }
  ],
  "count": 1
}
```

## Pending Trades

Returns trades waiting for blockchain confirmation.

```
GET /api/v1/pending-trades
```

### Response

```json
{
  "pendingTrades": [
    {
      "marketId": "0x...",
      "txHash": "0x...",
      "buyerAddress": "0x...",
      "sellerAddress": "0x...",
      "fillSize": 10000000,
      "fillPrice": 500000,
      "timestamp": "2025-01-01T00:00:00Z",
      "isBatch": false,
      "batchIndex": 0
    }
  ],
  "count": 1
}
```

## Settlement Status

Look up the status of a specific settlement transaction.

```
GET /api/v1/settlements/{txHash}
```

### Path Parameters

| Parameter | Type   | Description      |
| --------- | ------ | ---------------- |
| `txHash`  | string | Transaction hash |

### Response

```json
{
  "found": true,
  "txHash": "0x...",
  "status": "confirmed",
  "marketId": "0x...",
  "buyerAddress": "0x...",
  "sellerAddress": "0x...",
  "fillSize": 10000000,
  "fillPrice": 500000,
  "timestamp": "2025-01-01T00:00:00Z",
  "isBatch": false,
  "batchIndex": 0
}
```

If the transaction is not found, `found` will be `false` and all other fields will be omitted.

## Matching Behavior

{% stepper %}
{% step %}

### Price-time priority

Orders match against the best available price first.
{% endstep %}

{% step %}

### Same outcome only

BUY YES matches SELL YES, never SELL NO.
{% endstep %}

{% step %}

### Partial fills

Orders can partially fill; the remaining size stays on the book.
{% endstep %}

{% step %}

### Blockchain settlement

Matched trades are submitted to the blockchain for on-chain settlement.
{% endstep %}
{% endstepper %}

The `matches` field in the submit response indicates how many counter-orders were matched.
