Documentation

Everything you need to send your first request and read the response back.

Quickstart

Every request goes to one endpoint. Name the model you want in the model field and Switchyard patches it through to the right provider.

cURL
curl https://api.switchyardai.io/v1/chat/completions \
  -H "Authorization: Bearer sk-sy-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4-flash",
    "messages": [{"role": "user", "content": "Say hi in five words."}]
  }'

Authentication

Generate a key from the dashboard’s API Keys tab and send it as a bearer token on every request. Keys are scoped to your account, not to a single model.

Keys never expire on their own. Revoke a compromised key from the dashboard and traffic on it stops within seconds.

HeaderValue
AuthorizationBearer sk-sy-...

Request format

Switchyard speaks the same schema as OpenAI’s chat completions endpoint, so existing SDKs work by pointing their base URL here.

FieldTypeNotes
modelstringAny model slug from the models page.
messagesarrayStandard role/content message list.
streambooleanSet true for server-sent events.
max_tokensintegerOptional. See the note on reasoning tokens below.
mask_piibooleanOptional, Switchyard extension. Defaults to your account setting.

A note on reasoning models

Some models return a reasoning_content field alongside content — the model’s chain of thought. We pass it through unchanged. Two things to know: its tokens count toward completion_tokens, so you are billed for them; and a small max_tokens can be consumed entirely by reasoning, leaving content empty with finish_reason "length". Leave headroom.

Streaming

Set "stream": true to receive server-sent events as tokens are generated, identical in shape regardless of which provider is answering.

Node · OpenAI SDK
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.switchyardai.io/v1",
  apiKey: "sk-sy-...",
});

const stream = await client.chat.completions.create({
  model: "deepseek-v4-flash-0731",
  stream: true,
  messages: [{ role: "user", content: "Write a haiku about rail yards." }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

PII masking

Before a request leaves us, an inline filter replaces emails, phone numbers, and card numbers with placeholder tokens, then restores them in the response you receive. Providers never see the raw values.

Masking runs on message content. Code blocks are left alone so examples are not broken. Set "mask_pii": false on a request if your pipeline already handles this upstream, or change the default in Settings.

masking
sent to provider    "contact: [MASKED_EMAIL_1], card [MASKED_PAN_1]"
returned to you     "contact: ada@acme.co, card 4242 4242 4242 4242"

What we do not do

We do not store request or response bodies, and the placeholder map lives in memory for the duration of the request only — it is never written to disk or to logs.

Billing & credits

Accounts run on prepaid credit, deducted per token as responses stream back. Pricing for every model is published on the models page.

MethodStatus
Trial credit on signupAvailable now
CardComing soon
USDT / USDCComing soon

New accounts start with trial credit so you can send real requests before committing anything. Top-up options are being added — until then, reach out if you run out.

FAQ

Do I need a different key for each model?

No. One key routes to every model on the board — change the model field, not your credentials.

What happens if a provider goes down?

Requests to an affected model return a clear error rather than a silent fallback to a different model. You always know which model actually answered.

Can I set a spend limit?

Yes — a daily or monthly cap per key, set from the dashboard. Requests past the cap are rejected until it resets or you raise it.

Is there a free tier?

New accounts start with a small amount of credit to test real requests. There is no subscription tier.

Do you train on my data or keep my prompts?

No. We do not store request or response bodies. What we keep per call is metadata: model, token counts, latency, cost, and whether masking ran.

Why is a model marked "Coming soon"?

Because we cannot serve it reliably yet. We would rather mark it than let you integrate against something that fails.