API Reference
OpenClacky exposes a set of OpenAI-compatible HTTP APIs covering text chat, image generation, video generation, and text-to-speech. If you're already using the OpenAI, Anthropic, or any major SDK, just swap base_url to ours and api_key to a key you've topped up at OpenClacky — no other code changes required.
This page is for developers. It covers four things: how to authenticate, what endpoints exist, what each request/response looks like, and how to read errors.
Basics
| Item | Value |
|---|---|
| Base URL | https://api.openclacky.com |
| Auth | HTTP header: Authorization: Bearer <YOUR_API_KEY> |
| Content type | Content-Type: application/json |
| Get an API key | Top up at the OpenClacky dashboard and generate one |
| Billing | Pay-as-you-go from your credit balance. Only 200 OK responses are charged (4xx/5xx are free). |
Authentication
Pass the bearer token on every request:
curl https://api.openclacky.com/chat/completions \
-H "Authorization: Bearer sk-oc-xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ ... }'
x-api-key: sk-oc-xxxxxxxxxxxx is also accepted (some SDKs prefer this).
Endpoint catalog
| Endpoint | Purpose | Compatible protocol |
|---|---|---|
POST /chat/completions |
Text chat / tool use / multi-turn | OpenAI Chat Completions |
POST /images/generations |
Text-to-image | OpenAI Images |
POST /videos/generations |
Text/image-to-video | OpenAI-style (custom) |
POST /audio/speech |
Text-to-speech | OpenAI Audio Speech |
POST /model/{model}/converse |
Text chat (Bedrock-style) | AWS Bedrock Runtime |
POST /anthropic/v1/messages |
Text chat | Anthropic Messages |
POST /vertex/v1beta1/models/{model}:generateContent |
Native Gemini (multi-part, image edit, tools) | Google Gemini generateContent |
POST /vertex/v1beta1/models/{model}:streamGenerateContent |
Native Gemini (streaming) | Google Gemini streamGenerateContent |
POST /vertex/v1beta1/models/{model}:predictLongRunning |
Native Veo (video generation, async submit) | Google Veo predictLongRunning |
POST /vertex/v1beta1/models/{model}:fetchPredictOperation |
Native Veo (poll async result) | Google Veo fetchPredictOperation |
GET /models |
List available models | OpenAI Models |
GET /balance |
Check credit balance & quota | Custom |
The four most-used endpoints are documented below.
1. Chat — POST /chat/completions
Request body (standard OpenAI Chat Completions):
{
"model": "or-claude-sonnet-4-6",
"messages": [
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Hello!" }
],
"temperature": 0.7,
"stream": false
}
Response body (standard OpenAI shape + our cost_usd):
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"model": "or-claude-sonnet-4-6",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Hi there!" },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 4,
"total_tokens": 16
},
"cost_usd": 0.000084
}
Model alias rules
| Prefix | Upstream | Examples |
|---|---|---|
or-* |
OpenRouter / Vertex aggregator | or-claude-sonnet-4-6, or-gpt-5-1, or-gemini-3-pro, or-deepseek-v3-2, or-glm-4-7, or-qwen-3-coder, or-grok-4-3, or-kimi-k2 |
dsk-* |
DeepSeek direct | dsk-chat, dsk-reasoner |
abs-* |
AWS Bedrock direct (must use /model/{model}/converse) |
abs-claude-opus-4-7 |
The full model list lives at AI Key Supported Models. Newly launched models are added there.
Streaming
Set "stream": true and you'll get a standard OpenAI SSE stream (data: {...}\n\n … data: [DONE]\n\n). Works with the Python openai SDK, Vercel AI SDK, and similar clients out of the box.
2. Image generation — POST /images/generations
Request body (OpenAI Images standard):
{
"model": "or-gemini-3-pro-image",
"prompt": "a corgi astronaut on Mars, photo-realistic",
"n": 1,
"size": "1024x1024"
}
Response body (OpenAI Images standard):
{
"created": 1718465432,
"data": [
{ "b64_json": "iVBORw0KGgoAAAANSUhEU..." }
],
"model": "or-gemini-3-pro-image",
"cost_usd": 0.134
}
The image comes back as inline base64, not a URL. Buffer.from(b64_json, "base64") straight to disk.
Supported models
| Alias | Upstream | Use case |
|---|---|---|
or-gemini-3-pro-image |
Gemini 3 Pro Image Preview | Highest quality, default pick |
or-gemini-3-1-flash-image |
Gemini 3.1 Flash Image | Faster + cheaper, everyday use |
or-gpt-image-2 |
OpenAI GPT Image 2 | OpenAI flavor |
Image size
Accepts OpenAI-standard 1024x1024 / 1792x1024 / 1024x1792. We auto-map them to the upstream's supported aspect ratios (1:1 / 16:9 / 9:16); arbitrary pixel dimensions aren't supported.
Image editing (image input)
The same endpoint also does image editing: pass one or more input images alongside the prompt and the model edits them instead of generating from scratch. Best paired with the Gemini ("Nano Banana") models.
{
"model": "or-gemini-3-1-flash-image",
"prompt": "make the cat blue and add a party hat",
"image": "data:image/png;base64,iVBORw0KGgo..."
}
| Field | Type | Notes |
|---|---|---|
image |
string | A single input image: raw base64, or a data URL (data:image/png;base64,...). Bare base64 defaults to image/png. |
images |
string or array | One or more input images. Takes precedence over image when both are present. |
- No image → text-to-image generation (the default above).
- With image(s) → image edit. Response shape is identical (
{ data: [{ b64_json }] }).
# edit an existing PNG: turn its background to night
B64=$(base64 -i input.png)
curl https://api.openclacky.com/images/generations \
-H "Authorization: Bearer sk-oc-xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"or-gemini-3-1-flash-image\",
\"prompt\": \"change the background to a starry night sky\",
\"image\": \"$B64\"
}" | jq -r '.data[0].b64_json' | base64 -d > edited.png
3. Video generation — POST /videos/generations
Request body:
{
"model": "or-veo-3",
"prompt": "a golden retriever surfing a wave at sunset, cinematic",
"aspect_ratio": "16:9",
"duration_seconds": 8,
"image": null
}
| Field | Type | Required | Notes |
|---|---|---|---|
model |
string | yes | Veo alias, see table below |
prompt |
string | yes | Video description |
aspect_ratio |
string | no | 16:9 (default) or 9:16 |
duration_seconds |
int | no | 4 / 6 / 8 (default 8) |
image |
object | no | First frame for image-to-video: { "b64_json": "...", "mime_type": "image/png" } |
Response body (MP4 inline base64):
{
"created": 1718465432,
"data": [
{ "b64_json": "AAAAGGZ0eXBpc29t...", "mime_type": "video/mp4" }
],
"model": "or-veo-3",
"usage": { "duration_seconds": 8 },
"cost_usd": 1.344
}
Supported models
| Alias | Upstream | Default output |
|---|---|---|
or-veo-3 |
Veo 3 | Video + audio, 720p/1080p |
or-veo-3-fast |
Veo 3 Fast | Video + audio, 720p |
or-veo-3-1 |
Veo 3.1 | Video + audio, 720p/1080p |
or-veo-3-1-fast |
Veo 3.1 Fast | Video + audio, 720p |
Notes
- Video generation is a long-running task — expect 1–3 minutes per request. Set your client timeout to at least 8 minutes.
- We handle the submit + poll loop internally; from your perspective it's a single synchronous HTTP call.
- Veo always emits audio (
generateAudio=true); this can't be turned off.
4. Text-to-speech — POST /audio/speech
Request body:
{
"model": "or-tts-gemini-2-5-flash",
"input": "Hello, this is OpenClacky speaking.",
"voice": "Kore"
}
| Field | Type | Required | Notes |
|---|---|---|---|
model |
string | yes | TTS alias, see table below |
input |
string | yes | Text to read aloud |
voice |
string | no | Voice name, default Kore. Gemini TTS supports 30+ prebuilt voices (Kore/Puck/Charon/Fenrir/Aoede/Leda/Orus/Zephyr and more) |
Response body (WAV inline base64):
{
"created": 1718465432,
"data": [
{ "b64_json": "UklGRn...", "mime_type": "audio/wav" }
],
"model": "or-tts-gemini-2-5-flash",
"voice": "Kore",
"usage": {
"prompt_tokens": 9,
"completion_tokens": 33,
"total_tokens": 42
},
"cost_usd": 0.000281
}
The WAV is 24kHz / 16-bit / mono — natively playable in browsers and most players.
Supported models
| Alias | Upstream | Use case |
|---|---|---|
or-tts-gemini-2-5-flash |
Gemini 2.5 Flash TTS | Daily voiceover, notifications |
or-tts-gemini-2-5-pro |
Gemini 2.5 Pro TTS | Long-form narration, professional voiceover |
5. Native Vertex AI — POST /vertex/v1beta1/models/{model}:<method>
For full access to native Gemini / Veo capabilities (multi-part contents, inline image editing, tools, systemInstruction, structured output, video generation), call the native Vertex AI endpoints directly. Request and response bodies are raw Vertex AI format — we only handle auth and billing, the payload is passed through verbatim.
Supported methods:
| method | Purpose | Supported models |
|---|---|---|
generateContent |
Gemini text/multimodal synchronous generation | or-gemini-* |
streamGenerateContent |
Gemini streaming generation | or-gemini-* |
predictLongRunning |
Veo video async generation (submit) | or-veo-* |
fetchPredictOperation |
Veo async operation polling | or-veo-* |
Discussed separately below.
5.1 Gemini — :generateContent / :streamGenerateContent
The native Gemini surface, more flexible than the OpenAI-shaped endpoints above.
Path:
POST /vertex/v1beta1/models/{model}:generateContent # single response
POST /vertex/v1beta1/models/{model}:streamGenerateContent # SSE stream
{model} accepts our or-gemini-* aliases (e.g. or-gemini-3-1-pro, or-gemini-3-1-flash-image) or the real Gemini model id.
Request body (native Gemini generateContent):
{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Describe this image in one sentence." },
{ "inlineData": { "mimeType": "image/png", "data": "iVBORw0KGgo..." } }
]
}
],
"generationConfig": { "temperature": 0.7 }
}
Response body — the native Gemini shape, with our usageMetadata:
{
"candidates": [
{
"content": { "role": "model", "parts": [{ "text": "A corgi in a spacesuit on Mars." }] },
"finishReason": "STOP"
}
],
"usageMetadata": {
"promptTokenCount": 264,
"candidatesTokenCount": 11,
"totalTokenCount": 275
}
}
Image editing via native API
Image editing is just a generateContent call with image inlineData parts plus a text instruction — generation and editing share one interface:
B64=$(base64 -i cat.png)
curl "https://api.openclacky.com/vertex/v1beta1/models/or-gemini-3-1-flash-image:generateContent" \
-H "Authorization: Bearer sk-oc-xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d "{
\"contents\": [{
\"role\": \"user\",
\"parts\": [
{ \"text\": \"make the cat blue\" },
{ \"inlineData\": { \"mimeType\": \"image/png\", \"data\": \"$B64\" } }
]
}]
}"
The edited image comes back as an inlineData part inside candidates[].content.parts[].
Streaming
Use the :streamGenerateContent path for a native Gemini SSE stream (data: {...}\n\n chunks). Each chunk is a partial GenerateContentResponse; usage is reported on the final chunk.
Notes
- This endpoint is billed by token from
usageMetadata, using the same per-model rates and Vertex promotional discount as theor-gemini-*aliases. Unlike the OpenAI-shaped endpoints, the response does not carry acost_usdfield (it's the raw upstream body); the authoritative charge is recorded server-side and shown in your dashboard. - Only Gemini models we price are accepted; unknown models return
400. For Veo models, see section 5.2 below.
5.2 Veo — :predictLongRunning / :fetchPredictOperation
Veo video generation is an asynchronous long-running operation (typically 1–3 minutes), in two steps:
Step 1: Submit POST /vertex/v1beta1/models/{model}:predictLongRunning
{
"instances": [
{
"prompt": "a corgi riding a skateboard through a neon-lit Tokyo alley",
"image": { "bytesBase64Encoded": "...", "mimeType": "image/png" }
}
],
"parameters": {
"aspectRatio": "16:9",
"durationSeconds": 8,
"sampleCount": 1,
"generateAudio": true,
"personGeneration": "allow_adult"
}
}
Returns an operation object:
{
"name": "projects/your-project/locations/us-central1/publishers/google/models/veo-3.1-fast-generate-001/operations/abc123",
"metadata": { ... },
"done": false
}
Note: Billing occurs at submit time. Charge =
durationSeconds × per-second rate × 1.05 (service fee) × Vertex discount. The submit returns immediately; you are charged regardless of whether you poll the result.
Step 2: Poll POST /vertex/v1beta1/models/{model}:fetchPredictOperation
{
"operationName": "projects/.../operations/abc123"
}
Poll until done: true:
{
"name": "projects/.../operations/abc123",
"done": true,
"response": {
"videos": [
{
"bytesBase64Encoded": "AAAAIGZ0eXBpc29t...",
"mimeType": "video/mp4"
}
]
}
}
fetchPredictOperation has no additional charge (already billed at submit).
Supported models:
| Alias | Upstream model | Per-second rate |
|---|---|---|
or-veo-3 |
veo-3.0-generate-001 |
$0.40 |
or-veo-3-fast |
veo-3.0-fast-generate-001 |
$0.10 |
or-veo-3-1 |
veo-3.1-generate-001 |
$0.40 |
or-veo-3-1-fast |
veo-3.1-fast-generate-001 |
$0.10 |
If you prefer a synchronous call, use the OpenAI-shaped POST /videos/generations endpoint — it handles submit + poll internally and returns the MP4 inline as base64.
6. List models — GET /models
Returns the models available to the API key making the request.
Request: GET /models, authenticated with a Bearer Token.
Response:
{
"object": "list",
"data": [
{ "id": "abs-claude-sonnet-4-6", "object": "model", "owned_by": "openclacky" },
{ "id": "dsk-deepseek-v4-pro", "object": "model", "owned_by": "openclacky" }
]
}
- If the API key has
allowed_modelsconfigured, only the intersection is returned. - Without a whitelist, all available models are listed.
7. Balance & quota — GET /balance
Returns the account balance and key-level quota usage for the API key making the request.
Request: GET /balance, authenticated with a Bearer Token.
Response:
{
"is_available": true,
"balance_infos": [
{ "currency": "USD", "total_balance": "5.0" }
],
"quota": {
"enabled": true,
"amount": 10.0,
"used": 3.5,
"remaining": 6.5,
"reset_period": "monthly"
}
}
| Field | Description |
|---|---|
is_available |
Whether balance ≥ $1.00 (minimum threshold) |
balance_infos[].total_balance |
Account balance (string) |
quota.enabled |
Whether quota is enabled for this key |
quota.amount |
Total quota amount (USD) |
quota.used |
Amount currently used |
quota.remaining |
Amount remaining |
quota.reset_period |
Reset period: daily / weekly / monthly |
Note: The
quotafield only appears when quota is enabled andquota_amountis set on the key. Keys without quota will not include this field.
Pricing at a glance
Prices already include our 5% service markup. Vertex-hosted models (with or-gemini-*/or-veo-*/or-tts-* upstreams) currently get a 0.80x promotional discount (subject to change — actual charges in cost_usd are authoritative).
Chat (per-token)
Token rates vary per model. Look up the exact price at AI Key Supported Models before you commit; the cost_usd field on every response is the authoritative charge.
Image generation
| Model | Approximate price |
|---|---|
or-gemini-3-pro-image |
~$0.134 / 1024×1024 image |
or-gemini-3-1-flash-image |
~$0.067 / 1024×1024 image |
or-gpt-image-2 |
~$0.04–0.08 / image (token-based) |
Video generation (per output second)
| Model | Price |
|---|---|
or-veo-3 / or-veo-3-1 |
Video + audio, 720p/1080p: $0.40/s |
or-veo-3-fast / or-veo-3-1-fast |
Video + audio, 720p: $0.10/s |
A typical 8-second or-veo-3 clip: 8 × 0.40 × 1.05 ≈ $3.36, ~$1.34 after the Vertex discount.
Text-to-speech (per token; audio output = 25 tokens / second)
| Model | Input (text) | Output (audio) |
|---|---|---|
or-tts-gemini-2-5-flash |
$0.50 / 1M | $10.00 / 1M |
or-tts-gemini-2-5-pro |
$1.00 / 1M | $20.00 / 1M |
A 10-second Flash TTS clip is ~250 audio tokens, so about $0.0026.
Error codes
Every error returns this JSON envelope:
{
"error": {
"code": "invalid_api_key",
"message": "invalid api key",
"type": "auth_error"
},
"error_message": "invalid api key"
}
| HTTP | code | Meaning |
|---|---|---|
400 |
(various) | Bad field — missing model, empty prompt, unknown model alias |
401 |
invalid_api_key |
Key not found or malformed |
403 |
api_key_revoked |
Key has been revoked |
403 |
api_key_expired |
Key has expired |
402 |
insufficient_credit |
Account balance too low — top up at the dashboard |
429 |
quota_exceeded |
Per-key rate limit hit |
405 |
— | Wrong HTTP method (must be POST) |
502 |
— | Upstream model failure — safe to retry |
500 |
internal_error |
Internal error |
Retry guidance: 429 / 502 are safely retryable with exponential backoff (start at 1 s, max 3 attempts). Don't retry 400/401/402/403.
SDK examples
We're OpenAI-compatible — use the OpenAI SDK as-is, just swap base_url and api_key.
Python (openai SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://api.openclacky.com",
api_key="sk-oc-xxxxxxxxxxxx",
)
resp = client.chat.completions.create(
model="or-claude-sonnet-4-6",
messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)
Node.js (openai SDK)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.openclacky.com",
apiKey: process.env.OPENCLACKY_API_KEY,
});
const resp = await client.chat.completions.create({
model: "or-gpt-5-1",
messages: [{ role: "user", content: "Hello" }],
});
console.log(resp.choices[0].message.content);
curl (image generation)
curl https://api.openclacky.com/images/generations \
-H "Authorization: Bearer sk-oc-xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "or-gemini-3-1-flash-image",
"prompt": "a futuristic Tokyo street at night",
"size": "1024x1024"
}' | jq -r '.data[0].b64_json' | base64 -d > out.png
curl (TTS)
curl https://api.openclacky.com/audio/speech \
-H "Authorization: Bearer sk-oc-xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "or-tts-gemini-2-5-flash",
"input": "Welcome to OpenClacky.",
"voice": "Kore"
}' | jq -r '.data[0].b64_json' | base64 -d > out.wav
FAQ
Q: Do you support streaming?
A: Yes for /chat/completions (set stream: true) and for native Gemini via :streamGenerateContent. The other endpoints are single-response.
Q: Can I generate multiple images / videos in one call?
A: Images: n=1..4 (upstream-limited). Video: one clip per request.
Q: Are there rate limits?
A: Each key has a generous default RPM cap. Hitting it returns 429 quota_exceeded — back off and retry, or contact us for a higher quota.
Q: Can I get a URL instead of base64?
A: All media endpoints currently return inline base64. Persist it to S3/OSS yourself if needed.
Q: How do I reconcile costs?
A: Every response carries cost_usd — that's the authoritative charge for that call. Monthly invoices and per-call breakdown are in the dashboard.