Skip to content

API reference

OpenAI-compatible API

A drop-in for OpenAI's Chat Completions API. Anything built on the OpenAI SDKs, or that asks for an “OpenAI-compatible” base URL, works by setting it to https://fullsendai.com/v1.

Overview#

Base URLhttps://fullsendai.com/v1
AuthenticationAuthorization: Bearer $FULLSEND_API_KEY (or x-api-key). See API keys.
FormatJSON request and response bodies; server-sent events when streaming.
EndpointsPOST /v1/chat/completions, GET /v1/models, POST /v1/embeddings, POST /v1/rerank and GET /v1/key
OpenAPI spec/openapi.json (OpenAPI 3.1), for code generators and API clients
ErrorsOpenAI's error shape, so the SDKs raise their usual exceptions. See Errors.

Create a chat completion#

POST/v1/chat/completions

Request body

modelstringrequired
A model ID from Models, like deepseek-v4.1-flash.
messagesarrayrequired
The conversation so far, oldest first. See Messages.
max_tokensinteger
The most tokens to generate. Capped at the model's maximum output; when left out, the model may use all of it. max_completion_tokens is accepted too.
streamboolean
Send the answer as server-sent events. See Streaming.
stream_optionsobject
Accepted. include_usage is always on, so the last chunk carries usage whether or not you ask.
temperature, top_p, stop, seed, presence_penalty, frequency_penaltynumber | string | array
Sampling controls, passed to the model as sent. Ranges and support follow the model.
toolsarray
Functions the model may call, as {"type": "function", "function": {name, description, parameters}}. See Tool calling.
tool_choicestring | object
auto, none, required, or {"type": "function", "function": {"name": "…"}}. parallel_tool_calls is passed through too.
response_formatobject
{"type": "json_schema", "json_schema": {…}} or {"type": "json_object"}. See Structured output.
reasoning_effortstring
For models marked reasoning. See Reasoning.

Other fields are passed to the model unchanged. service_tier and prompt_cache_options are ignored: every request runs at the same tier and price.

curl https://fullsendai.com/v1/chat/completions \  -H "Authorization: Bearer $FULLSEND_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "deepseek-v4.1-flash",    "messages": [      {"role": "system", "content": "You are a senior Go engineer."},      {"role": "user", "content": "Refactor this handler to use context cancellation: ..."}    ],    "temperature": 0.2,    "max_tokens": 1024  }'
Response
{  "id": "chatcmpl-ed1a50752eb09f27899afda3",  "object": "chat.completion",  "created": 1792116871,  "model": "deepseek-v4.1-flash",  "choices": [    {      "index": 0,      "message": {        "role": "assistant",        "content": "func handler(w http.ResponseWriter, r *http.Request) {\n  ctx := r.Context() …",        "reasoning_content": null,        "tool_calls": null      },      "finish_reason": "stop"    }  ],  "usage": {    "prompt_tokens": 42,    "completion_tokens": 318,    "total_tokens": 360,    "prompt_tokens_details": { "cached_tokens": 0 },    "completion_tokens_details": { "reasoning_tokens": 0 }  }}

Messages#

systemrole
Instructions for the whole conversation. content is a string.
userrole
content is a string, or an array of parts: {"type": "text", "text": "…"} and, for models that read images, {"type": "image_url", "image_url": {"url": "https://… or data:image/png;base64,…"}}. See Images.
assistantrole
An earlier answer: content, and tool_calls when it called tools.
toolrole
A tool's result: tool_call_id (the call's id) and content.

The response#

A chat.completion object, as OpenAI returns it, with model set to the FullsendAI model ID.

idstring
Unique per response, like chatcmpl-….
choices[].message.contentstring | null
The answer. null when the model only called tools.
choices[].message.reasoning_contentstring | null
What a reasoning model thought before answering, when it shares it. See Reasoning.
choices[].message.tool_callsarray | null
Calls to your tools, each with an id (call_…), function.name and function.arguments (a JSON string).
choices[].finish_reasonstring
stop (finished), length (hit max_tokens or the model's cap) or tool_calls (waiting for your tool results).
usage.prompt_tokensinteger
Input tokens, as billed. prompt_tokens_details.cached_tokens says how many came from the model's prompt cache.
usage.completion_tokensinteger
Output tokens, as billed, reasoning included (completion_tokens_details.reasoning_tokens).
usage.total_tokensinteger
The two together.

What a call cost is on its row in Logs; how it's worked out is on Pricing and billing.

Streaming#

With "stream": true the response is text/event-stream: one data: line per chat.completion.chunk, each with a delta holding the new content, reasoning_content or tool_calls fragments. The chunk with finish_reason comes next to last; the last carries usage and an empty choices array; then data: [DONE].

Events
data: {"id":"chatcmpl-c6ff…","object":"chat.completion.chunk","created":1792116872,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}data: {"id":"chatcmpl-c6ff…","object":"chat.completion.chunk","created":1792116872,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":"One, two"},"finish_reason":null}]}data: {"id":"chatcmpl-c6ff…","object":"chat.completion.chunk","created":1792116872,"model":"deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":", three."},"finish_reason":"stop"}]}data: {"id":"chatcmpl-c6ff…","object":"chat.completion.chunk","created":1792116872,"model":"deepseek-v4.1-flash","choices":[],"usage":{"prompt_tokens":8,"completion_tokens":6,"total_tokens":14}}data: [DONE]

Errors before the first token come back as an ordinary JSON error with its status. More on stopping early, mid-stream errors and the SDK helpers: Streaming.

List models#

GET/v1/models

The live models your key may call, with prices, context window, output limit, capabilities, grade and serving precision. Chat models by default; add ?kind=embedding, ?kind=rerank or ?kind=all for the others. Fields are listed on Models.

Response headers#

HeaderMeaning
x-ratelimit-limit-requestsRequests allowed in the current minute: the tighter of your key's and your account's limit
x-ratelimit-remaining-requestsRequests left in this minute
x-ratelimit-reset-requestsTime until the minute resets, like 23s
retry-afterOn a 429 rate_limit_exceeded: seconds to wait
x-request-idOn every response: the call's ID, also in error bodies. Include it when contacting support; see Request IDs
x-fullsend-modelWith fullsend/auto: the model that answered. See fullsend/auto

The rate-limit headers come with every chat completion that gets past the account checks, refusals for rate included. Access-Control-Allow-Origin: * is set, but keep keys on your server: see Keeping keys safe.

SDKs#

import osfrom openai import OpenAIclient = OpenAI(base_url="https://fullsendai.com/v1", api_key=os.environ["FULLSEND_API_KEY"])

The Vercel AI SDK, LangChain, LlamaIndex and LiteLLM work too: SDKs and frameworks.

Not supported#

FullsendAI serves Chat Completions, Embeddings and the model list. OpenAI's Responses, Assistants, Batch, Files, Images, Audio and Moderation endpoints aren't served, and n above 1 and logprobs aren't guaranteed. A tool that needs one of those endpoints needs another provider for that part.

Unknown fields

Fields this page doesn't list are passed to the model as sent. Models ignore or reject what they don't understand; a rejection comes back as 400 invalid_request_error with the model's message.

Stuck? Email [email protected]System statusChangelog