API reference
OpenAI-compatible API
https://fullsendai.com/v1.Overview#
| Base URL | https://fullsendai.com/v1 |
|---|---|
| Authentication | Authorization: Bearer $FULLSEND_API_KEY (or x-api-key). See API keys. |
| Format | JSON request and response bodies; server-sent events when streaming. |
| Endpoints | POST /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 |
| Errors | OpenAI'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_tokensis accepted too. streamboolean- Send the answer as server-sent events. See Streaming.
stream_optionsobject- Accepted.
include_usageis always on, so the last chunk carriesusagewhether 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 | objectauto,none,required, or{"type": "function", "function": {"name": "…"}}.parallel_tool_callsis 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 }'{ "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.
contentis a string. userrolecontentis 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, andtool_callswhen it called tools. toolrole- A tool's result:
tool_call_id(the call'sid) andcontent.
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.nameandfunction.arguments(a JSON string). choices[].finish_reasonstringstop(finished),length(hitmax_tokensor the model's cap) ortool_calls(waiting for your tool results).usage.prompt_tokensinteger- Input tokens, as billed.
prompt_tokens_details.cached_tokenssays 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].
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#
| Header | Meaning |
|---|---|
x-ratelimit-limit-requests | Requests allowed in the current minute: the tighter of your key's and your account's limit |
x-ratelimit-remaining-requests | Requests left in this minute |
x-ratelimit-reset-requests | Time until the minute resets, like 23s |
retry-after | On a 429 rate_limit_exceeded: seconds to wait |
x-request-id | On every response: the call's ID, also in error bodies. Include it when contacting support; see Request IDs |
x-fullsend-model | With 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#
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