Developer guide
Connect your own applications to SEADS AI. Requests made with an API key follow the same rules as your organization’s members: the models you allow, your sensitive data rules, your usage limits, and a record of every request.
API address
https://api.seads.io/v1Before you start
- Your organization’s plan must include the developer API; the plans page shows which plans do. Without it, keys cannot be created and existing keys are refused.
- An owner or administrator signs in to the administration console with their SEADS account and creates a key under API keys. The key starts with
seads_. There is no password sign in to the console; the key is the only credential your application uses. - Copy the key when it is created. It is shown once. SEADS AI stores only a fingerprint of it and cannot show it again.
- Keep the key on your server, in a secret store or an environment variable. Never put it in a web page or a mobile application: anyone who reads it can spend your organization’s usage.
For each key, an administrator can choose which models it may use, set a monthly budget, replace it with a new one (rotate), and revoke it. A revoked or replaced key stops working at once.
A key acts for your organization with the rights of the person who created it. If that person leaves the organization or is suspended, the key stops working.
Authentication
Send the key in the Authorization header of every request, after the word Bearer.
curl https://api.seads.io/v1/models \
-H "Authorization: Bearer $SEADS_API_KEY"All requests go over HTTPS to the API address shown at the top of this page, under /v1.
Your first request
curl https://api.seads.io/v1/chat/completions \
-H "Authorization: Bearer $SEADS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seads-auto",
"messages": [
{"role": "system", "content": "You answer in one sentence."},
{"role": "user", "content": "What is a purchase order?"}
]
}'{
"id": "chatcmpl-5f0c...",
"object": "chat.completion",
"created": 1760380000,
"model": "seads-auto",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "A purchase order is ..." },
"finish_reason": "stop"
}
]
}import os
import requests
answer = requests.post(
"https://api.seads.io/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['SEADS_API_KEY']}"},
json={
"model": "seads-auto",
"messages": [{"role": "user", "content": "Hello"}],
},
timeout=120,
)
answer.raise_for_status()
print(answer.json()["choices"][0]["message"]["content"])const answer = await fetch("https://api.seads.io/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SEADS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "seads-auto",
messages: [{ role: "user", content: "Hello" }],
}),
});
if (!answer.ok) throw new Error(`SEADS AI answered ${answer.status}`);
const data = await answer.json();
console.log(data.choices[0].message.content);Requests and answers follow the shape of the OpenAI chat completions API, so a client written for that shape can usually be pointed at this address. Only the fields described on this page are supported.
Models and SEADS One
GET /v1/models lists the chat models your key may use: the models your organization has enabled, narrowed to the key’s own list when it has one, and to what the key’s creator is allowed. Each model carries context_window and max_output (in tokens) when they are known, so you can size what you send; for seads-auto they are the smallest of the models it may pick, or absent when one of them is not known.
{
"object": "list",
"data": [
{ "id": "seads-auto", "object": "model", "created": 0, "owned_by": "seads" },
{ "id": "<a-model-id>", "object": "model", "created": 0, "owned_by": "seads" }
]
}- Use
seads-autoto let SEADS One choose a model for each request, keeping simple requests on less costly models. It is the same automatic choice your members get in chat. The earlier identifierseads-onestill works. - Use a model identifier from the list to always get that model.
- With SEADS One, if the chosen provider fails before any text is sent, another eligible model answers instead. A model you name yourself is not replaced when its provider fails; you receive the error.
seads-autoappears in the list only when your organization has automatic choice switched on.- The
createdfield is always 0. It is there because some clients require it.
Chat completions
POST /v1/chat/completions sends a conversation and returns the model’s answer.
| Field | Type | Required | Meaning |
|---|---|---|---|
model | text | Yes | seads-auto, or an identifier from GET /v1/models. |
messages | list | Yes | The conversation so far, oldest first. At least one message. |
messages[].role | text | Yes | system, user or assistant. |
messages[].content | text | Yes | The text of the message. Text only, not empty. |
stream | true or false | No | Send the answer as it is written. False when left out. |
Other fields, such as temperature or max_tokens, are accepted and ignored. The API keeps no memory between requests: send the whole conversation each time.
In the answer, model repeats what you asked for. When your organization shows which model answered, an extra field served_model names it. The answer carries usage (prompt_tokens, completion_tokens, total_tokens, and source, which is reported when the model provider gave the counts and estimated when SEADS counted words instead), and finish_reason is stop, or length when the output limit cut the answer. GET /v1/key shows what your key may still spend this month: its name, environment, monthly cap, what it has spent and what remains (in US cents once your organization uses the prepaid API balance, in usage units before), with no key material. Your usage is also shown in the administration console.
Streaming
With "stream": true the answer arrives as server sent events. Each event is a line starting with data: and holds a piece of the answer in choices[0].delta.content. The stream ends with data: [DONE].
curl -N https://api.seads.io/v1/chat/completions \
-H "Authorization: Bearer $SEADS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "seads-auto", "stream": true,
"messages": [{"role": "user", "content": "Hello"}]}'data: {"id":"chatcmpl-5f0c...","object":"chat.completion.chunk","created":1760380000,"model":"seads-auto","choices":[{"index":0,"delta":{"content":"Hel"},"finish_reason":null}]}
data: {"id":"chatcmpl-5f0c...","object":"chat.completion.chunk","created":1760380000,"model":"seads-auto","choices":[{"index":0,"delta":{"content":"lo."},"finish_reason":null}]}
data: [DONE]A streamed answer has already started with status 200 when a problem occurs, so the problem arrives inside the stream, as an event holding error instead of choices, followed by data: [DONE]. Check every event for error.
data: {"error": {"code": "PROVIDER_TIMEOUT", "message": "The model provider took too long to respond"}}
data: [DONE]A stream that finishes ends with one more event, before data: [DONE]: an empty delta, finish_reason set to stop (or length when the output limit cut the answer) and the usage of the request. A stream that fails ends with the error event and no finish_reason.
Limits and budgets
- Each key may send 60 requests per minute to chat completions. Its answers carry
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Reset(the time, in seconds since 1970, when the count starts again). - A key with a monthly budget is refused once the budget is used, until the first day of the next month.
- Requests count against the monthly usage allowance of the seat of the person who created the key, and against your organization’s spending limits, as chat does. Different models use the allowance at different rates.
- When a seat has used its allowance, requests to premium models are answered by a standard model until the next month. This also applies to a premium model you name yourself: the request succeeds, and
served_modelnames the model that answered when your organization shows it. - When a seat reaches 125% of its allowance, it pauses until the next month, and requests are refused with 429.
- Credits that SEADS has added to your account keep a seat working after its allowance is used.
- A conversation that is too long for the chosen model is refused before it is sent.
When you receive 429 with RATE_LIMITED, wait until the time in X-RateLimit-Reset, then try again. The other 429 codes will not clear by waiting a minute: an administrator has to raise a budget, or the period has to end.
Errors
A refused request returns a status code and a body that names the reason.
{
"error": {
"code": "RATE_LIMITED",
"message": "API key rate limit reached"
}
}When you send an X-Request-Id header, some errors repeat it as request_id.
| Status | Code | What happened | What to do |
|---|---|---|---|
| 402 | BILLING_REQUIRED | Your organization’s subscription is not active. | An owner settles it in Billing. |
| 403 | MODEL_NOT_ALLOWED | The key or your organization does not allow this model, or SEADS One is switched off or has no model to choose. | Pick a model from GET /v1/models. |
| 409 | MODEL_SELECTION_REQUIRED | Your organization has not yet chosen its models. | An administrator chooses them in AI access. |
| 422 | CONTEXT_LIMIT | The conversation is too long for the model. | Send less text, or use a model with a larger context. |
| 422 | SENSITIVE_DATA_BLOCKED | The text holds a kind of data your organization blocks. | Remove it. The rule is set in Governance. |
| 429 | RATE_LIMITED | More than 60 requests in the minute. | Wait until X-RateLimit-Reset. |
| 429 | BUDGET_EXCEEDED | The key’s monthly budget or a spending limit is reached. | An administrator raises it, or wait for the next period. |
| 402 | API_BALANCE_EMPTY | The organization’s prepaid API balance is empty (once the balance is in place). | An owner or administrator tops it up in Billing. |
| 429 | API_KEY_CAP_REACHED | The key’s monthly cap in US dollars is spent. | An administrator raises it, or wait for the next month. |
| 429 | API_CAP_REACHED | The organization’s monthly cap over all keys is spent. | An administrator raises it, or wait for the next month. |
| 429 | ALLOCATION_EXHAUSTED | The usage allowance for the subscription month is used. | Wait for the next month or change plan. |
| 503 | CONTEXT_COUNT_UNAVAILABLE | The length of the conversation could not be checked. | Try again shortly. |
| 503 | PROVIDER_UNAVAILABLE | The model’s provider could not answer. | Try again, or use seads-auto. |
| 504 | PROVIDER_TIMEOUT | The model’s provider took too long. | Try again, or use seads-auto. |
A few refusals use a different body, with a single detail field instead of error.
{ "detail": "Invalid API key" }| Status | detail | What happened |
|---|---|---|
| 401 | Invalid API key | The key is missing, mistyped, revoked or replaced, or its creator no longer has access. |
| 403 | API access is not included in this plan | Your organization’s plan does not include the developer API. |
| 403 | This account is unavailable | Your organization is not active. |
| 422 | a list | The request body is not valid: a required field is missing, a role is unknown, or a message is empty. Each entry names the field. |
Your organization’s rules apply
- Sensitive data: the text you send is checked as it is in chat. Depending on your organization’s choice for each kind of data, it is sent as it is, masked before it reaches the model, or refused. Card numbers and secrets are always masked at least.
- Model access: a key can never reach a model your organization or its creator’s role does not allow.
- Records: every request is written to your organization’s audit log and counted in its usage, with the key that made it.
- Provider names: answers do not say which provider answered unless your organization chooses to show it.
What the API does not do yet
The developer API covers text conversations. These are available in the application but not through the API today:
- image generation;
- documents attached to a conversation, and images as input;
- company knowledge and assistants;
- tools and function calling;
- embeddings.
AI and your data
Answers are generated by AI models and can be wrong. Check anything important before you rely on it. SEADS AI sends each request to the provider of the model that answers; the companies involved are listed on the subprocessors page, and the terms of service describe what is stored and for how long.
Providers that receive requests today, and where each company is based. Image generation is not part of the API, so API requests do not reach Black Forest Labs. An administrator can exclude providers by country of origin in AI access.
| Provider | Based in |
|---|---|
| OpenAI | United States |
| Anthropic | United States |
| Google (Gemini) | United States |
| xAI | United States |
| Mistral | France |
| Black Forest Labs (images) | Germany |
| DeepSeek | China |
| Moonshot | China |
