v3 Early Access · 2026-05-11

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:

  1. Sign in with your Clevora account at /.
  2. Open the Dashboard and click Activate Developer Account.
  3. Generate an API key. Copy it immediately — the key is shown only once.
  4. Use the key as a bearer token against any /v1 endpoint.
# 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"])
Tip. Treat API keys like passwords. Never embed them in client-side code or commit them to source control. Use environment variables and rotate keys via the Dashboard when in doubt.

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 Unauthorized on 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:

EndpointRateNotes
chat.completions$0.50 / 1k tokensIncludes both prompt and completion tokens.
embeddings$0.10 / 1k tokensCheapest endpoint. Useful for bulk indexing.
search$0.20 / 1k tokensCharged on query tokens.
scripts.generate$1.00 / 1k tokensHigher rate reflects longer generations.

How charges are applied

  1. Each successful /v1 request is billed once it completes.
  2. The cost is deducted atomically from your balance (Firestore FieldValue.increment(-cost)).
  3. A ledger entry is appended to clevora_developer_transactions with the endpoint, tokens, and dollar amount — visible in the Dashboard's Billing history table.
Block at $0, allow negative-of-one. An in-flight request is permitted to finish even if it drops your balance below zero. Subsequent requests will return 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:

TierRequests / minuteDaily tokens
preview601,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.

Heads up. Limits are enforced by API key, not by account. If you distribute one key across multiple services, expect them to share the same budget.

Models

The API exposes a small set of named models. Pick one with the model field:

ModelBest forNotes
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"
  }
}
StatusMeaningCommon cause
400Bad requestMissing or malformed body fields.
401UnauthorizedMissing, invalid, or revoked API key.
402Payment RequiredAccount not activated (< $15) or balance depleted. See Pricing & billing.
403ForbiddenAccount lacks developer access.
404Not foundUnknown route or resource.
429Too many requestsRate limit exceeded.
500Server errorRetry with exponential backoff.

Chat Completions

POST /v1/chat/completions

Generates a conversational completion from a list of messages. Compatible with the OpenAI-style chat schema for easy migration.

Request body

FieldTypeDescription
messagesrequiredarrayConversation history. Each item is { role, content }.
modelstringDefaults to clevora-1.0-turbo.
streambooleanWhen true, the response is delivered as server-sent events. Defaults to false.
temperaturenumberSampling temperature in [0, 2]. Defaults to 1.
max_tokensintegerUpper 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

POST /v1/embeddings

Returns a vector representation for the supplied text. Accepts either a single string or an array of strings for batched embedding.

Request body

FieldTypeDescription
inputrequiredstring | string[]The text(s) to embed.
modelstringDefaults 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"]}'

Script Generation

POST /v1/scripts/generate

Produces a structured script for video or audio content. Tuned for longer-form output than chat completions.

Request body

FieldTypeDescription
topicrequiredstringWhat the script should be about.
stylestringyoutube · podcast · tiktok. Defaults to youtube.
lengthstringshort · 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.

POST /v1/keys

Generate a new API key. Optionally provide a name for the key.

GET /v1/keys

List all keys owned by the signed-in user. Returns masked previews and usage metadata — never the raw secret.

DELETE /v1/keys/{keyId}

Revoke a key. Effect is immediate — subsequent requests using the key will return 401.

Usage Analytics

GET /api/developer/usage?range=30

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 fetch or axios.
  • Python: requests or httpx.
  • Go: net/http with a small wrapper.
  • Anywhere: curl for prototyping and CI scripts.

Changelog

VersionDateHighlights
v3-early-access2026-05-11Usage analytics dashboard, key revocation, expanded endpoint set, full developer docs.
v22026-04Unified developer portal + Firebase-based auth.
v12026-03Initial 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.