Clevora AI API
A unified REST API for semantic media search, script generation, and chat completions.
Get up and running with a single API key and the /v1 namespace.
For coding agents
Building with a coding agent like Claude Code, Cursor, or Windsurf? Paste this URL into your agent to give it a self-contained spec of the entire API — models, endpoints, request/response schemas, errors, pricing, and an agent rule-of-thumb section:
https://developers.getclevora.xyz/docs/llms
The same payload is also served at /llms.txt and /llms.json for
agents that auto-discover those conventional paths. Response is JSON, cached for 5 minutes.
Introduction
The Clevora API is organized around predictable, resource-oriented URLs and returns
JSON-encoded responses. It uses standard HTTP response codes, authentication, and
verbs. Every endpoint lives under the /v1 namespace and shares a single
authentication scheme so you can mix and match capabilities with the same key.
The base URL during development is:
https://developers.getclevora.xyz/v1
In production, swap the host for your deployed Clevora Developer Platform URL. All other request semantics — auth, headers, payload shapes — stay identical.
Quickstart
You can make your first authenticated request in under five minutes:
- Sign in with your Clevora account at /.
- Open the Dashboard and click Activate Developer Account.
- Generate an API key. Copy it immediately — the key is shown only once.
- Use the key as a bearer token against any
/v1endpoint.
# Generate a script about quantum computing curl -X POST https://developers.getclevora.xyz/v1/chat/completions \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "messages": [ {"role": "user", "content": "Write a YouTube intro about quantum computing."} ] }'
const res = await fetch('https://developers.getclevora.xyz/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.CLEVORA_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ messages: [{ role: 'user', content: 'Write a YouTube intro about quantum computing.' }], }), }); const data = await res.json(); console.log(data.choices[0].message.content);
import os, requests res = requests.post( "https://developers.getclevora.xyz/v1/chat/completions", headers={ "Authorization": f"Bearer {os.environ['CLEVORA_API_KEY']}", "Content-Type": "application/json", }, json={"messages": [{"role": "user", "content": "Write a YouTube intro about quantum computing."}]}, ) print(res.json()["choices"][0]["message"]["content"])
Authentication
All /v1 endpoints require an API key supplied as a Bearer token in the
Authorization header. Keys look like sk_live_… and are
32 hex characters after the prefix.
Authorization: Bearer sk_live_2c4e9f1a0bc3...e7
The dashboard endpoints under /api/developer/* use a different auth scheme:
they accept a Firebase ID token from the signed-in session. You'll
typically only call those from the dashboard UI, not your server code.
API keys
Generate, list, and revoke keys from the Dashboard or via the
/v1/keys endpoints. A few important properties:
- Show-once. The full key value is only returned at creation. After that it's masked.
- Multiple keys. Use separate keys per environment (dev / staging / prod) so you can rotate one without affecting the others.
- Revocation is immediate. A revoked key returns
401 Unauthorizedon the next request — no grace period. - Per-key usage. Each key tracks its own request count and last-used timestamp.
Pricing & billing
The Clevora API uses prepaid, usage-based billing. You add credits to your account (powered by Dodo Payments), and each request deducts a small amount based on the endpoint and the number of tokens consumed.
Activation threshold
The first time your balance reaches $15, your developer account
becomes activated and the /v1 API will start accepting requests.
After activation, the gate becomes balance > 0 — you can let the
balance drop down to zero before needing to top up again.
Per-endpoint rates
Rates are quoted per 1,000 tokens:
| Endpoint | Rate | Notes |
|---|---|---|
chat.completions | $0.50 / 1k tokens | Includes both prompt and completion tokens. |
embeddings | $0.10 / 1k tokens | Cheapest endpoint. Useful for bulk indexing. |
search | $0.20 / 1k tokens | Charged on query tokens. |
scripts.generate | $1.00 / 1k tokens | Higher rate reflects longer generations. |
How charges are applied
- Each successful
/v1request is billed once it completes. - The cost is deducted atomically from your balance (Firestore
FieldValue.increment(-cost)). - A ledger entry is appended to
clevora_developer_transactionswith the endpoint, tokens, and dollar amount — visible in the Dashboard's Billing history table.
402 Payment Required until you top up.
Top-ups
Top-ups are processed through Dodo Payments hosted checkout. Use the Add credits button in the Dashboard, or call:
curl -X POST https://developers.getclevora.xyz/api/developer/topup \ -H "Authorization: Bearer <firebase-id-token>" \ -H "Content-Type: application/json" \ -d '{"amount": 50}' # => { "status": "success", "data": { "checkoutUrl": "https://checkout.dodopayments.com/..." } }
The response contains a checkoutUrl — redirect the user there to complete
payment. Once Dodo fires the payment.succeeded webhook at
/api/dodo/webhook, the balance is credited and (if it's the first time
crossing $15) the account flips to activated.
Top-up bounds: minimum $15, maximum $10,000 per transaction.
Usage tracking
Every billable request is recorded across four places in Firestore so the Dashboard can render at any granularity:
clevora_developer_usage/{uid}— running totals (requests, tokens, errors, lastUsed).clevora_developer_usage/{uid}/days/{YYYY-MM-DD}— per-day rollups with per-endpoint breakdown.clevora_developer_keys/{key}— per-key counters and lastUsed timestamp.clevora_developer_logs/{logId}— append-only request log used by the "Recent activity" table.
Token counts in the usage object reflect what the account was billed for
on each request. They're the source of truth for the per-day and per-key rollups shown
in the Dashboard.
Rate limits
Rate limits are applied per API key. In the current preview, all keys share a single tier:
| Tier | Requests / minute | Daily tokens |
|---|---|---|
preview | 60 | 1,000,000 |
When a limit is hit you'll receive 429 Too Many Requests with a
Retry-After header indicating how many seconds to wait.
Models
The API exposes a small set of named models. Pick one with the model field:
| Model | Best for | Notes |
|---|---|---|
clevora-1.0-turbo |
Chat completions, scripting | Default. Low-latency, balanced quality. |
clevora-embed-1 |
Embeddings for vector search | Returns a fixed-length vector per input. |
clevora-search-1 |
Semantic media retrieval | Optimized for video / podcast catalogs. |
clevora-script-1 |
YouTube / podcast scripting | Tuned for structured long-form output. |
Errors
Failures return a structured JSON body and a relevant HTTP status code:
{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"code": "invalid_api_key"
}
}| Status | Meaning | Common cause |
|---|---|---|
400 | Bad request | Missing or malformed body fields. |
401 | Unauthorized | Missing, invalid, or revoked API key. |
402 | Payment Required | Account not activated (< $15) or balance depleted. See Pricing & billing. |
403 | Forbidden | Account lacks developer access. |
404 | Not found | Unknown route or resource. |
429 | Too many requests | Rate limit exceeded. |
500 | Server error | Retry with exponential backoff. |
Chat Completions
Generates a conversational completion from a list of messages. Compatible with the OpenAI-style chat schema for easy migration.
Request body
| Field | Type | Description |
|---|---|---|
messagesrequired | array | Conversation history. Each item is { role, content }. |
model | string | Defaults to clevora-1.0-turbo. |
stream | boolean | When true, the response is delivered as server-sent events. Defaults to false. |
temperature | number | Sampling temperature in [0, 2]. Defaults to 1. |
max_tokens | integer | Upper bound on generated tokens. Billed tokens never exceed this. |
Example
curl -X POST https://developers.getclevora.xyz/v1/chat/completions \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "model": "clevora-1.0-turbo", "messages": [{"role": "user", "content": "Hello!"}] }'
{
"id": "chatcmpl-…",
"object": "chat.completion",
"created": 1736000000,
"model": "clevora-1.0-turbo",
"usage": { "prompt_tokens": 8, "completion_tokens": 32, "total_tokens": 40 },
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "Clevora API successfully processed your request." },
"finish_reason": "stop"
}]
}Streaming
Set "stream": true to receive the response as
server-sent events.
Each event is a data: line containing a JSON delta that follows the
OpenAI chat-stream schema, so existing SSE parsers work without changes. The stream
terminates with a literal data: [DONE] sentinel.
curl -N -X POST https://developers.getclevora.xyz/v1/chat/completions \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "model": "clevora-1.0-turbo", "stream": true, "messages": [{"role": "user", "content": "Hello!"}] }'
const res = await fetch("https://developers.getclevora.xyz/v1/chat/completions", { method: "POST", headers: { "Authorization": `Bearer ${process.env.CLEVORA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "clevora-1.0-turbo", stream: true, messages: [{ role: "user", content: "Hello!" }], }), }); const reader = res.body.getReader(); const decoder = new TextDecoder(); let buf = ""; while (true) { const { value, done } = await reader.read(); if (done) break; buf += decoder.decode(value, { stream: true }); for (const line of buf.split("\n").slice(0, -1)) { if (!line.startsWith("data: ")) continue; const payload = line.slice(6); if (payload === "[DONE]") return; const delta = JSON.parse(payload).choices[0].delta.content; if (delta) process.stdout.write(delta); } buf = buf.slice(buf.lastIndexOf("\n") + 1); }
// First chunk includes the role. data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]} // Subsequent chunks stream content tokens. data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]} data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]} // Final chunk carries finish_reason and (when available) usage. data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":8,"completion_tokens":32,"total_tokens":40}} data: [DONE]
Notes for client implementers: events are \n\n-delimited, so always buffer
partial lines across reads. Disconnecting before [DONE] still bills the
tokens already generated, and the request is logged with whatever the model produced
up to that point. The usage object is attached to the terminal chunk —
if you need it, read it from the last frame before the sentinel.
Embeddings
Returns a vector representation for the supplied text. Accepts either a single string or an array of strings for batched embedding.
Request body
| Field | Type | Description |
|---|---|---|
inputrequired | string | string[] | The text(s) to embed. |
model | string | Defaults to clevora-embed-1. |
curl -X POST https://developers.getclevora.xyz/v1/embeddings \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{"input": ["the cat sat", "on the mat"]}'
Semantic Search
Searches a media catalog using natural-language queries. Results are ranked by
semantic similarity score in [0, 1].
/v1/search queries the
shared Clevora demo catalog, which is useful for prototyping but not for production
traffic. To search your own media library, your catalog needs to be indexed against
your workspace first — email
developers@getclevora.xyz
with a sample of your metadata schema and we'll get you onboarded. Self-serve
catalog ingestion is on the roadmap.
Request body
| Field | Type | Description |
|---|---|---|
queryrequired | string | Natural-language query. |
limit | integer | Max results, defaults to 5. |
curl -X POST https://developers.getclevora.xyz/v1/search \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{"query": "underwater drone footage", "limit": 3}'
Script Generation
Produces a structured script for video or audio content. Tuned for longer-form output than chat completions.
Request body
| Field | Type | Description |
|---|---|---|
topicrequired | string | What the script should be about. |
style | string | youtube · podcast · tiktok. Defaults to youtube. |
length | string | short · medium · long. Controls token budget. |
curl -X POST https://developers.getclevora.xyz/v1/scripts/generate \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{"topic": "AI in 2026", "style": "youtube", "length": "medium"}'
Key Management
These endpoints authenticate with a Firebase ID token, not an API key.
Generate a new API key. Optionally provide a name for the key.
List all keys owned by the signed-in user. Returns masked previews and usage metadata — never the raw secret.
Revoke a key. Effect is immediate — subsequent requests using the key will return 401.
Usage Analytics
Powers the Dashboard. Returns a summary block, a per-day series for charts, an
endpoint breakdown, and the 20 most recent request log entries. The
range query param accepts an integer between 1 and 90 (days).
Response shape
{
"status": "success",
"data": {
"range": 30,
"summary": {
"totalRequests": 12480,
"totalTokens": 982341,
"rangeRequests": 3120,
"rangeTokens": 211400,
"requestsToday": 142,
"tokensToday": 8732,
"avgTokensPerRequest": 68,
"successRate": 99.4,
"lastUsed": "2026-05-11T14:21:08.531Z"
},
"dailySeries": [
{ "date": "2026-04-12", "requests": 94, "tokens": 5012, "errors": 0 }
],
"endpointBreakdown": {
"chat.completions": { "requests": 1840, "tokens": 118203 },
"embeddings": { "requests": 900, "tokens": 71200 }
},
"recentActivity": [
{ "endpoint": "chat.completions", "tokens": 42, "status": "success", "latencyMs": 128 }
]
}
}SDKs & libraries
Official SDKs are on the roadmap. In the meantime the API is plain HTTP/JSON, so any HTTP client works. Recommended starters:
- JavaScript / TypeScript: built-in
fetchoraxios. - Python:
requestsorhttpx. - Go:
net/httpwith a small wrapper. - Anywhere:
curlfor prototyping and CI scripts.
Changelog
| Version | Date | Highlights |
|---|---|---|
v3-early-access | 2026-05-11 | Usage analytics dashboard, key revocation, expanded endpoint set, full developer docs. |
v2 | 2026-04 | Unified developer portal + Firebase-based auth. |
v1 | 2026-03 | Initial preview of the /v1/chat/completions endpoint. |
Support
Found a bug or want to request a feature? Open an issue in the platform repository or reach out via your usual Clevora support channel. Include the response body and a request ID where possible to speed up diagnosis.