# Orders, account and usage

> The Markdown form of https://openfill.ai/docs/api/orders. The index of every docs page is https://openfill.ai/llms.txt, and every page in one file is https://openfill.ai/llms-full.txt.

Everything about a request after it is sent, and the two objects that stand behind every request: your account and its usage.

Set shell variables such as ORDER_ID, FILE_ID and BATCH_ID to ids returned by the API before running the corresponding command.

## List orders

**GET /v1/orders**

```bash
curl "https://api.openfill.ai/v1/orders?status=queued,executing&include=usage,totals,counts" -H "Authorization: Bearer $OPENFILL_API_KEY"
```

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| status | list | none | Comma-separated statuses. An unknown one is 400. |
| model | string | none | One served model id. |
| kind | string | none | chat, completion, responses or messages. |
| batch | string | none | A batch id for its lines, or none for requests sent outside any batch. |
| id | string | none | A full id, or a prefix of at least four characters. |
| from, to | date | none | Inclusive bounds on created_at. |
| include | list | none | usage, totals, counts, storage, batch, pricing. The orders page says what each adds. |
| limit | integer | `100` | Up to 500. |
| cursor | string | none | next_cursor from the previous page. |

```json
{"object": "list", "data": [ ...orders... ], "has_more": true, "next_cursor": "...",
 "total_orders": 123, "total_failed": 4, "total_charged_usd": 1.23, "total_at_bid_usd": 5.0, "total_saved_usd": 3.77,
 "counts": {"queued": 2, "executing": 1, "oldest_queued_at": "..."}}
```

The `total_*` fields arrive with `include=totals` on the first page only and are null on later pages; `counts` arrives with `include=counts` on every page. Newest first, by cursor. `total_at_bid_usd` and `total_saved_usd` cover the market orders in the set, and are null when it holds orders and none is a market order (a set with no orders answers 0); `total_charged_usd` covers every order.

### The order object

| Field | Meaning |
| --- | --- |
| id | The order id. |
| status | queued, executing, done, error, canceled or expired. |
| bid | What the order rests at: your price limit, or the lower of the quote and your price limit when locked. On a fixed-price model, its prices at the reference mix, in the price limit's unit. |
| kind | chat, completion, responses or messages: the endpoint the request came in on. |
| model | The model it runs on. |
| created_at | Submission, ISO 8601. |
| admitted_at | When it was admitted to run. Null while queued, and reset if it went back to the book. |
| finished_at | When it reached a terminal status. |
| expires_at | When it leaves the book unexecuted: your timeout, or the lock window. |
| level_at_execution | The price it was charged at: the level at dispatch, or the bid where that was lower. On a fixed-price model, the same figure as bid. Null until admitted. |
| queue_position | Its place in the book, from 1, while queued on a market model. Null otherwise, and always null on a fixed-price model, where accounts take turns. |
| error | The terminal reason on error, canceled and expired. Null otherwise. |

With `include=usage` each order also carries `usage`: `prompt_tokens`, `cached_tokens`, `output_tokens` and `charged_usd`, or null when no usage record exists. Charges include refunds; a settlement failure needs the error message and usage record checked together.

With `include=pricing` each order carries `price_lock` and `pricing`, `market` or `fixed`. An order on a fixed-price model also carries `usd_per_million`: the three prices it was submitted at, per 1M tokens of cache-hit input, cache-miss input and output, which stay on the order after the model's prices change.

## Get an order

**GET /v1/orders/{id}**

```bash
curl "https://api.openfill.ai/v1/orders/$ORDER_ID" -H "Authorization: Bearer $OPENFILL_API_KEY"
```

One order object. `include` takes `usage`, `storage`, `batch` and `pricing`. An id that is malformed or belongs to someone else answers `404`.

## Get and delete a result

**GET /v1/orders/{id}/result**

```bash
curl "https://api.openfill.ai/v1/orders/$ORDER_ID/result" -H "Authorization: Bearer $OPENFILL_API_KEY"
```

The stored response body of an order, or its state on the way there. Every successful response carries `id`, `status`, `created_at`, `expires_at` and `result_expires_at`; the shapes per status are on the [detached orders page](https://openfill.ai/docs/detached#collect). The body is rendered in the shape of the endpoint the request came in on; for a Responses or Messages order the fields that echo the request carry their defaults, since the request itself is gone by then. A body read counts against the hourly download allowance.

**DELETE /v1/orders/{id}/result**

```bash
curl -X DELETE "https://api.openfill.ai/v1/orders/$ORDER_ID/result" -H "Authorization: Bearer $OPENFILL_API_KEY"
```

```json
{"id": "<order_id>", "object": "order.result", "deleted": true}
```

Idempotent. `409 result_write_pending` while the body is still being written, and `409 batch_in_progress` for a line of a running batch.

## Reprice queued orders

**POST /v1/orders/price**

```bash
curl https://api.openfill.ai/v1/orders/price -H "Authorization: Bearer $OPENFILL_API_KEY" -H "Content-Type: application/json" \
  -d '{"ids": ["'"$ORDER_ID"'"], "price_limit": 0.05}'
```

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| ids | array | required | 1 to 500 order ids. Duplicates are folded. |
| price_limit | number | required | The new price limit, for every id. See the shared price bound below. |

```json
{"object": "list", "price_limit": 0.05, "changed": 1,
 "data": [{"id": "...", "changed": true, "code": null, "reason": null}]}
```

The new price_limit accepts 0 to 1000000000. A repriced order rejoins the book at its new price behind the orders already resting there. An item that changed carries a `code` of null. One that did not carries a `reason` and a `code`: `not_queued`, `price_locked`, `too_large`, `fixed_price_model` for an order on a fixed-price model, which is charged its published prices, or `unavailable` when the market could not apply the change just now, with the order still queued, so a retry can apply it. `503` with `Retry-After` if the market did not confirm the change in time: the request is still queued and the next tick applies it with whatever result it has by then, so read the order back rather than resending.

## Cancel an order

**POST /v1/orders/{id}/cancel**

```bash
curl -X POST "https://api.openfill.ai/v1/orders/$ORDER_ID/cancel" -H "Authorization: Bearer $OPENFILL_API_KEY"
```

```json
{"id": "<order_id>", "status": "canceled"}
```

Queued orders only. `409 order_not_cancelable` once it is executing or finished. Never charged.

## Your account

**GET /v1/account**

```bash
curl https://api.openfill.ai/v1/account -H "Authorization: Bearer $OPENFILL_API_KEY"
```

```json
{"object": "account", "account_id": "...", "balance_usd": 12.34,
 "default_price_limit": {"market-preview": 0.10}, "price_lock": false, "order_timeout_seconds": 10,
 "storage": {"retention_days": 0, "log_payloads": false},
 "orders": {"queued": 0, "executing": 0}}
```

**PATCH /v1/account**

```bash
curl -X PATCH https://api.openfill.ai/v1/account -H "Authorization: Bearer $OPENFILL_API_KEY" -H "Content-Type: application/json" \
  -d '{"default_price_limit": {"market-preview": 0.10}}'
```

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| default_price_limit | object | none | Model id to price limit. Merged: a number sets that model's default, null clears it, models not named are untouched. An unknown model is 400. A number for a fixed-price model is 400 fixed_price_model; null clears a value stored for one. The response lists market models only. |
| price_lock | boolean | none | The default for price_lock on every interactive request to a market model; on only for a caller who needs the price known before sending. Batch lines never lock. |
| order_timeout_seconds | integer | none | The default for max_wait, 10 seconds to 30 days. |

The response is the account as stored after the change. `storage` is read-only here; unknown PATCH fields are refused with 400. Storage is changed in [Settings](https://openfill.ai/settings), as are billing and API keys.

## Usage

**GET /v1/usage**

```bash
curl "https://api.openfill.ai/v1/usage?limit=50" -H "Authorization: Bearer $OPENFILL_API_KEY"
```

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| model | string | none | One served model id. |
| from, to | date | none | Inclusive bounds on the settlement time. |
| limit | integer | `50` | Up to 200. |
| cursor | string | none | next_cursor from the previous page. |

```json
{"object": "list", "balance_usd": 12.34, "total_charged_usd": 0.000005272, "total_requests": 1,
 "has_more": false, "next_cursor": null,
 "data": [{"id": "...", "order_id": "...", "created_at": "...", "model": "...",
           "prompt_tokens": 12, "cached_tokens": 8, "output_tokens": 40,
           "level_at_execution": 0.0143, "charged_usd": 0.000005272, "pricing": "market"}]}
```

One record per settled order, newest first. The totals cover the whole filtered set and are null on pages after the first. The rows sum to the charges on your balance. Each row carries `pricing`, `market` or `fixed`.

Previous: [Messages API](https://openfill.ai/docs/api/messages). Next: [Files and batches](https://openfill.ai/docs/api/batches).
