POST /v1/chat/completions endpoint. If your application already uses the OpenAI SDK, you can switch to Swarms by changing two lines — the base_url and api_key — and everything else works unchanged.
Under the hood, every request is routed through the full Swarms agent infrastructure: model routing, token counting, billing, and logging all apply exactly as they do for the native /v1/agent/completions endpoint.
Code written for OpenAI’s Responses API (
client.responses.create) can use POST /v1/responses, and code written for the Anthropic SDK can use POST /v1/messages.Endpoint Information
- URL:
/v1/chat/completions - Method:
POST - Authentication: Required (
x-api-keyheader orAuthorization: Bearer <key>) - Rate Limiting: Subject to tier-based rate limits
Authentication
Two authentication methods are supported. Both work on all Swarms API endpoints.
The Bearer token method is what the OpenAI SDK sends by default, so it works out of the box.
Get your API key at swarms.world/platform/api-keys.
Request Schema
ChatCompletionRequest Object
ChatMessage Object
Each message in themessages array:
ContentPart (Multimodal)
Whencontent is an array, each element is a content part:
Text part:
url field accepts both HTTPS URLs and base64-encoded data URIs (data:image/png;base64,...).
Image parts from every message are attached to the run, including images in earlier turns, and each one is billed $0.25 on every request. Resending a chat history that contains images bills those images again.
Validation Rules
- At least one message with
role: "user"is required nmust be1— multiple completions per request are not supported (send separate requests instead)- Requests with zero messages or only system messages are rejected
stoptakes at most 4 sequencestool_choicerequirestools
invalid_request_error.
Example Request Body
Response Schema
ChatCompletionResponse Object (Non-Streaming)
Choice Object
CompletionUsage Object
Example Response
Streaming Response Schema
Whenstream: true is set, the response is returned as Server-Sent Events (SSE). Each event is a data: line containing a JSON chunk.
StreamChunk Object
StreamChoice Object
Stream Sequence
Example Stream
Errors During a Stream
Only an unknown model is rejected before the stream opens, with a 404 (see Error Types). Any error after that, including a premium-only model on a free-tier key or a provider failure, arrives on the open HTTP 200 stream as anerror event, followed by [DONE]:
error key before reading choices. Raw-HTTP clients see it directly; check what your SDK does with such an event before relying on it to raise.
Error Response Schema
Errors are returned in the standard OpenAI error format so the OpenAI SDK’s built-in error classes work correctly:Error Object
Errors raised by the authentication layer, before the request reaches this endpoint (a missing or invalid key, or too little credit), use the Swarms shape instead:
error.type, error.message, error.detail and error.status_code, with no code or param. A 402 also carries current_balance, minimum_required and upgrade_url.
Error Types
When the provider itself rejects the request, doesn’t serve the model, or rate limits it, the response is a 400, 404 or 429 with
type: "invalid_request_error" and a message that names the provider’s reason and ends “Nothing was charged.”
All request-body validation failures on this endpoint — including out-of-range Swarms extension fields passed via extra_body (e.g. max_loops: 0, which violates 1 <= max_loops <= 50) — are caught by a dedicated handler and returned as 400 invalid_request_error in the OpenAI error shape above, not the raw FastAPI/Pydantic {"detail": [...]} shape used elsewhere in the Swarms API.
Example Error Response
Code Examples
Non-Streaming Completion
- Python
- TypeScript
- Go
- Rust
- cURL
Streaming Completion
- Python
- TypeScript
- Go
- Rust
- cURL
Multi-Turn Conversation
- Python
- TypeScript
- Go
- Rust
Error Handling
- Python
- TypeScript
- Go
- Rust
Tool Calling
Pass function definitions intools, in the OpenAI function-calling schema. When the model calls a function, the response has finish_reason: "tool_calls", message.content: null and the calls in message.tool_calls. Run the function yourself, then send the conversation back with the assistant turn (including its tool_calls) and one tool message per result, and the model answers from them.
tool_choice:"auto","none","required", or{"type": "function", "function": {"name": "get_weather"}}to force one function. It needstools.- Streaming: with
stream: true, the calls arrive in a singledelta.tool_callschunk after the content chunks, then the final chunk hasfinish_reason: "tool_calls". The content chunks before it can carry a text rendering of the call (e.g.[tool call] get_weather {"city":"Paris"}), so read the call fromdelta.tool_calls, not from the streamed text. parallel_tool_callsis not a recognized field and is ignored.- The functions run on your side. To have the agent run tools itself, use
/v1/agent/completions.
Multi-Loop Reasoning
By default the agent runs a single pass (max_loops=1). To let the agent iterate on its own output — useful for complex reasoning, self-correction, or multi-step tasks — pass max_loops via the OpenAI SDK’s extra_body parameter:
- Python
- TypeScript
- cURL
max_loops is a Swarms extension field — it is not part of the OpenAI API spec. In the Python OpenAI SDK, use extra_body={"max_loops": N} to pass it. In cURL or raw HTTP, include it directly in the JSON body.How It Maps to Swarms Internals
For users already familiar with the native Swarms API, here is how the OpenAI request fields map toAgentCompletion and AgentSpec:
The agent is created with
max_loops set to the requested value (defaults to 1 for single-turn). For a non-streaming request the agent runs with streaming_on=False and the full response is returned in one JSON body. For stream: true, the agent config is rebuilt with streaming_on=True and the agent’s own token-by-token output is forwarded live, via a streaming callback, as SSE chunks — the same mechanism /v1/agent/completions uses when streaming_on is set directly.
Supported Models
Themodel field accepts any model supported by the Swarms API. Common options:
A free-tier key gets 403 for a premium-only model; see Premium-Only Models.
For the full list, call
GET /v1/models (standard OpenAI list format — works with client.models.list() in the OpenAI SDK) or GET /v1/models/available (Swarms format with a count field, one object per model with its model_name and price) with your API key. Both return the same catalog, filtered by your subscription tier:
data has the standard id, object, created and owned_by fields plus a pricing object with the model’s price per 1M input and output tokens (USD, 15% service fee included) and its price_source (openrouter, litellm, or fallback when there is no price data for the model). Prices change; this one is from the time of writing:
GET /v1/models/pricing?model_name=<model>. See Available Models for both endpoints.
Differences from the OpenAI API
Billing
Usage is metered and billed identically to the native/v1/agent/completions endpoint:
- Tokens are the input and output tokens the model provider reports, summed over every model call the agent makes (every loop, re-sent conversation history, and reasoning tokens)
- Price is the requested model’s own price per 1M input and output tokens plus a 15% service fee. Look it up with
GET /v1/models/pricing?model_name=<model>or in thepricingobject onGET /v1/models; see Pricing - Images cost $0.25 each, counted across every message in the request, earlier turns included, so resending a history with images bills them again
- Credits are deducted automatically after each completion
- The
usagefield in the response shows the provider-reported tokens that were billed. Image fees are not inusage /v1/chat/completionsis billable: it requires a purchased credit balance greater than $1.00, or the request is rejected with 402 before the agent runs
GET /v1/account/credits.