OpenFill is in development. Inference is off, but is tested end to end, and will switch on at launch. All data currently on the site is for live testing: it will be erased at launch.

Skip to content
openfill

Chat and completions

Two endpoints, one handler. A chat request is the OpenAI shape with a max price; a completion request is the legacy shape, remapped to a single user message on the way to the model.

Create a chat completion

POST /v1/chat/completions
curl https://api.openfill.ai/v1/chat/completions \  -H "Authorization: Bearer $OPENFILL_API_KEY" \  -H "Content-Type: application/json" \  -d '{"model": "placeholder-large", "messages": [{"role": "user", "content": "hi"}], "max_price": 0.10}'

Request body

The OpenAI fields first, then the six OpenFill adds. A field absent from this table is forwarded to the model untouched.

FieldTypeDefaultMeaning
modelstringthe default modelA served model id. GET /v1/models lists them.
messagesarrayrequiredAt least one message with a role. Content is a string or an array of text parts.
streambooleanfalseServer-sent events. The response is 200 once the order is queued.
stream_optionsobjectnone{include_usage: true} adds a final chunk carrying usage and x_market.
max_tokensintegerthe model's max outputClamped down to the model's max output length. max_completion_tokens is read when this is absent.
temperaturenumbernone0 to 2.
top_pnumbernone0 to 1.
stopstring or arraynoneUp to four strings of up to 256 characters.
ninteger1Must be 1. Anything else is refused with 400.
tools, tool_choiceas OpenAInoneForwarded to the model. Calls are assembled from the stream and returned whole.
response_format, seed, useras OpenAInoneForwarded to the model untouched.
logprobs, top_logprobsas OpenAInoneForwarded. The response carries choices[0].logprobs.
max_pricenumberkey or accountThe most you will pay, in USD per 1M input tokens at the reference mix (90% cached, 2% output). 0 is legal and waits for a free market. None anywhere is 400 missing_bid.
price_lockbooleanaccount settingBid the published quote instead. Starts within 10 seconds or cancels with 429 capacity_unavailable.
max_waitintegeraccount settingSeconds the order may wait, 10 seconds to 30 days. Alias expires_after. Below the floor it is raised; above the ceiling it is 400.
detachedbooleanfalseAnswer 202 with an order id and run in the background. Refused with 400 alongside stream.
storebooleanaccount settingfalse keeps nothing durable for this request.
retention_daysintegeraccount settingKeep this request's data for fewer days. Clamped down to the account setting.

Response

The OpenAI chat.completion object with exactly one choice, and usage.x_market added. model echoes what you sent.

json
{  "id": "chatcmpl-...", "object": "chat.completion", "created": 1756700000, "model": "placeholder-large",  "choices": [{    "index": 0,    "message": {"role": "assistant", "content": "...", "reasoning_content": "..."},    "finish_reason": "stop",    "logprobs": null  }],  "usage": {    "prompt_tokens": 12, "completion_tokens": 40, "total_tokens": 52,    "prompt_tokens_details": {"cached_tokens": 8},    "x_market": {"level_at_execution": 0.0143, "bid": 0.1, "charged_usd": 0.0000174}  }}
FieldMeaning
message.contentThe answer. null for a turn that is only tool calls.
message.reasoning_contentA reasoning model's chain of thought, when the model sends one.
message.tool_callsPresent when the model called tools.
logprobs{content: [...]} when you asked for logprobs, else null.
usage.x_market.level_at_executionThe level the order was charged against.
usage.x_market.bidWhat the order rested at: your max price, or the quote when locked.
usage.x_market.charged_usdThe debit, in USD to nine decimal places.

Response with detached: true

json
202 {  "id": "<order_id>", "object": "order", "status": "queued", "expires_at": "...",  "result_url": "/v1/orders/<order_id>/result",  "result_stored": true, "result_retention_days": 7}

warning is added when nothing will be stored. The detached orders page has the collection semantics.

Response with stream: true

200 and a text/event-stream body: queue comments while the order waits, the model's chunks, a usage chunk when asked for, and data: [DONE]. Every frame is on the streaming page.

Statuses this endpoint answers

StatusWhen
200The completion, or a stream.
202detached: true, once the order is queued.
400Malformed body, n or best_of above 1, missing_bid, invalid_output_cap, model_deprecated, a bad X-Max-Price or X-Expires-After, or a request the model refused.
401, 403The key, or the account behind it.
402insufficient_balance at the current level.
404model_not_found.
408order_expired: the wait passed max_wait.
409order_canceled while it waited, or idempotency_error on a mismatched replay.
410result_unavailable on a replay of a finished order with nothing stored.
413The body is over the limit.
429rate_limit_error on a ceiling, capacity_unavailable on a missed lock window, result_pending on a replay still being stored.
500, 502, 503Our side, the backend mid-stream, or the backend unavailable. Only the 500 whose message says so was charged.

Create a completion

POST /v1/completions
curl https://api.openfill.ai/v1/completions \  -H "Authorization: Bearer $OPENFILL_API_KEY" \  -H "Content-Type: application/json" \  -d '{"model": "placeholder-large", "prompt": "Say hi", "max_price": 0.10}'

The same handler and the same extensions, with the legacy shape's differences:

FieldOn /v1/completions
promptA string, or an array of one string. It becomes a single user message. Absent, it is empty.
tools, tool_choice, functions, function_callRefused with 400: the response has nowhere to put a call.
logprobs, top_logprobs, echo, suffixRemoved before the model sees them. The response has logprobs: null.
max_completion_tokensRead as the output cap when present; a non-integer or a value under 1 is 400 invalid_output_cap.
json
{  "id": "cmpl-...", "object": "text_completion", "created": 1756700000, "model": "placeholder-large",  "choices": [{"index": 0, "text": "...", "finish_reason": "stop", "logprobs": null}],  "usage": {"prompt_tokens": 4, "completion_tokens": 2, "total_tokens": 6,            "x_market": {"level_at_execution": 0.0143, "bid": 0.1, "charged_usd": 0.0000012}}}

Streaming on this endpoint sends text_completion chunks with choices[0].text, and the same queue comments and usage chunk as chat.