Getting started

Introduction

CanalAPI is a unified gateway over 600+ LLM, image, and audio models. Use any OpenAI-compatible client — point base_url at https://api.canalapi.com/v1, pass your key, and ship.

Ready in 60 seconds
Grab a key from the console, run the snippet below, done.
Get API key
Full documentation site
For in-depth guides, tutorials, and the full API reference, visit our dedicated docs site.
docs.canalapi.com →
→ Chat completions
OpenAI / Claude / Gemini and more — one consistent shape
→ Endpoints
Chat, Embeddings, Images, Audio, Moderations — full surface area
→ Authentication
Bearer token or x-api-key — both headers accepted
→ Streaming
SSE, token-by-token, OpenAI-compatible

Quickstart

You need two things: an API key (from the console) and a model slug. Here's the simplest possible request:

cURL
# Any OpenAI-compatible client works — just swap the base URL
curl https://api.canalapi.com/v1/chat/completions \
  -H "Authorization: Bearer $CANAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-6",
    "messages": [{"role":"user","content":"Hello"}]
  }'

Response

application/json
{
  "id": "chatcmpl_8K2m3",
  "object": "chat.completion",
  "created": 1745078400,
  "model": "claude-opus-4-6",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "Hi there!" },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 8, "completion_tokens": 3, "total_tokens": 11 }
}

Authentication

Authenticated endpoints accept either Authorization: Bearer <key> (OpenAI-style) or x-api-key: <key> (Anthropic SDK style); Authorization wins when both are present. Keys are prefixed with ca_sk_live_ — create separate keys per environment (dev / staging / prod) from the console.

i
Tip: Set your key in an environment variable (e.g. CANAL_KEY). Any OpenAI-compatible SDK just needs its base URL pointed at https://api.canalapi.com/v1 — no other code change required.

Chat completionsPOST/v1/chat/completions

Create a chat completion. Compatible with OpenAI's chat/completions — same parameters, same response shape, with automatic upstream-channel selection.

Request body

FieldTypeDescription
modelrequiredstringModel slug. Call /v1/models for the live list, or browse the pricing page.
messagesrequiredarrayConversation as an array of { role, content } objects. Roles: system, user, assistant.
streamoptionalbooleanIf true, tokens are streamed via SSE. Default false.
temperatureoptionalnumber0–2. Higher = more random. Default is model-dependent.
max_tokensoptionalintegerCap on completion tokens. Model-dependent default.
toolsoptionalarrayFunction-calling tool definitions. Request schema follows OpenAI / Anthropic native shapes.

Streaming example

Python · SSE
stream = client.chat.completions.create(
  model="claude-opus-4-6",
  messages=[{"role": "user", "content": "Write a haiku."}],
  stream=True,
)
for chunk in stream:
  print(chunk.choices[0].delta.content or "", end="")

Endpoints at a glance

All endpoints share the same key and auth scheme. The table below lists the OpenAI-compatible and vendor-native endpoints currently live:

MethodPathPurpose
POST/v1/embeddingsText embeddings (OpenAI Embeddings compatible)
POST/v1/images/generationsImage generation (DALL·E compatible; /edits and /variations also live)
POST/v1/audio/transcriptionsSpeech-to-text (Whisper compatible; /audio/translations also live)
POST/v1/audio/speechText-to-speech (TTS)
POST/v1/moderationsContent moderation (typically free)
POST/v1/responsesOpenAI Responses API compatible endpoint
POST/v1/messagesAnthropic Messages API — native endpoint for the Claude SDK; the count_tokens sub-route is free
GET/v1/modelsList available models (public, no auth required)
GET/v1/dashboard/billing/credit_grantsOpenAI-compatible account balance summary

Request parameters and vendor-specific fields follow the upstream API spec; CanalAPI forwards all standard fields.

Native GeminiPOST/v1beta/models/*:generateContent

Alongside the OpenAI-compatible /v1, CanalAPI exposes the native Gemini surface at /v1beta. Just point your Gemini SDK (@google/generative-ai) base_url at https://api.canalapi.com/v1beta and authenticate with your CanalAPI key — generateContent and streamGenerateContent work with zero code changes.

i
Auth: Two headers are accepted and equivalent: Authorization: Bearer <key> and x-goog-api-key: <key>. For security, the ?key= query parameter is not supported (it would leak the key into access logs).

Generate content

cURL
# 把 Gemini SDK 的 base_url 指向 CanalAPI 的 /v1beta,用 CanalAPI 密钥鉴权
curl "https://api.canalapi.com/v1beta/models/gemini-3.1-pro-preview:generateContent" \
  -H "x-goog-api-key: $CANAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "Hello" }] }]
  }'

Streaming

cURL · SSE
# 流式:streamGenerateContent + ?alt=sse;鉴权头同样可用 Authorization: Bearer
curl "https://api.canalapi.com/v1beta/models/gemini-3.1-pro-preview:streamGenerateContent?alt=sse" \
  -H "Authorization: Bearer $CANAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "Write a haiku." }] }]
  }'

Gemini SDK

TypeScript
import { GoogleGenerativeAI } from "@google/generative-ai";

// 把 SDK 的 baseUrl 指向 CanalAPI 的 /v1beta,apiKey 用 CanalAPI 密钥
const genAI = new GoogleGenerativeAI(process.env.CANAL_KEY, {
  baseUrl: "https://api.canalapi.com/v1beta",
});

const model = genAI.getGenerativeModel({ model: "gemini-3.1-pro-preview" });
const result = await model.generateContent("Hello");
console.log(result.response.text());

Image editsPOST/v1/images/edits

Edit an existing image from a prompt (with an optional mask). Requests use multipart/form-data and are compatible with OpenAI Images Edit; billed per generated image.

FieldTypeDescription
imagerequiredfileSource image file to edit (image/jpeg · image/png · image/webp, ≤ 25MB each).
promptrequiredstringText instruction describing the desired edit.
maskoptionalfileOptional mask image; transparent areas mark the region to repaint.
modeloptionalstringModel slug, defaults to dall-e-2. You can also pass an image model such as gpt-image-1.
noptionalintegerNumber of images to generate (1–10), default 1.
sizeoptionalstringOutput image size, e.g. 1024x1024.
cURL
# multipart/form-data:image + prompt 必填,mask 可选
curl https://api.canalapi.com/v1/images/edits \
  -H "Authorization: Bearer $CANAL_KEY" \
  -F image="@source.png" \
  -F prompt="Add a red hat to the cat" \
  -F model="gpt-image-1" \
  -F n=1 \
  -F size="1024x1024"

Image variations/v1/images/variations

Create variations of a source image with no prompt. Also multipart/form-data — only the image field is required (model / n / size optional).

cURL
# multipart/form-data:仅需 image
curl https://api.canalapi.com/v1/images/variations \
  -H "Authorization: Bearer $CANAL_KEY" \
  -F image="@source.png" \
  -F n=2 \
  -F size="1024x1024"
i
Supported formats: image and mask accept only image/jpeg, image/png, and image/webp, up to 25MB per file.

Errors & retries

CanalAPI uses conventional HTTP status codes; errors follow the OpenAI shape { error: { message, type, code } }. On 5xx upstream failures we auto-retry across healthy channels — you only see an error after the routing pool is exhausted.

CodeMeaningWhat to do
400bad_requestCheck request body — likely a bad model or malformed messages.
401unauthenticatedMissing, invalid, or revoked key. Create a new one in the console.
402insufficient_balanceInsufficient balance — top up and retry.
429rate_limitedRate limit exceeded. Back off using the Retry-After and X-RateLimit-* headers.
502/503upstream_errorAll upstreams unavailable and already retried. Open a support ticket if it persists.
Auto-retry: CanalAPI automatically retries 5xx upstream failures across healthy channels in the routing pool. Clients only need standard exponential backoff for 429 / 502 / 503.

SDK integration

CanalAPI ships no proprietary SDK — it's a drop-in replacement for the major vendor SDKs. Swap the base URL and your existing code keeps working.

OpenAI Official SDK
Use for /v1/chat/completions, /v1/embeddings, /v1/images/*, /v1/audio/*, /v1/moderations, /v1/responses. Just set base_url to https://api.canalapi.com/v1.
pip install openai • npm i openai
Anthropic Official SDK
Use for the native /v1/messages endpoint. Set base_url to https://api.canalapi.com and pass your CanalAPI key via x-api-key.
pip install anthropic • npm i @anthropic-ai/sdk
Ready to build?
Grab your first API key and make a request in under 2 minutes.
Get API key
IntroductionChat completions