One key. Every AI tool.
Voice, images, thumbnails, video, transcripts, research, kloudie and your workspace from Claude Code, scripts or CI. One API key, one AI credit balance. No OpenAI, ElevenLabs or Google accounts to set up.
Quickstart in three steps
- 1
Create a key
Settings > API > Create key. Pick its scopes; you see the secret once.
- 2
Store it
Put it in KLOUDBOARD_API_KEY (a .env file, your shell, or CI secrets).
- 3
Connect or call
Add it to Claude Code with one command, or call any tool over HTTPS.
Claude Code
Every tool in your terminal, billed to this workspace's AI credits. No provider keys, no browser sign-in (good for CI).
claude mcp add --transport http kloudboard https://app.kloudboard.com/mcp \
--header "Authorization: Bearer $KLOUDBOARD_API_KEY".env
Keep the key in an environment variable; every example here reads it.
KLOUDBOARD_API_KEY=kbk_your_key_herecurl
Check the balance (free), then run any tool by name with its arguments as JSON.
curl https://app.kloudboard.com/api/v1/credits \
-H "Authorization: Bearer $KLOUDBOARD_API_KEY"
curl -X POST https://app.kloudboard.com/api/v1/tools/generate_audio \
-H "Authorization: Bearer $KLOUDBOARD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"capability":"tts","prompt":"Hello from kloudboard."}'TypeScript
Plain fetch, no SDK needed. Paid calls report their cost in X-Credits-Charged.
const res = await fetch("https://app.kloudboard.com/api/v1/tools/web_search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KLOUDBOARD_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({ query: "best time to post on YouTube" }),
});
const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data, res.headers.get("X-Credits-Charged"));Python
requests, with the same envelope: ok, data, error.code.
import os, uuid, requests
res = requests.post(
"https://app.kloudboard.com/api/v1/tools/web_search",
headers={
"Authorization": f"Bearer {os.environ['KLOUDBOARD_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={"query": "best time to post on YouTube"},
)
body = res.json()
if not body["ok"]:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["data"], res.headers.get("X-Credits-Charged"))What one key reaches
Every tool is POST /api/v1/tools/<tool> with its arguments as JSON. GET /api/v1/tools lists them with their schemas; the tool reference has every one.
LLM text
POST /api/v1/text: drafts, summaries and rewrites on fast, standard or writer models. No model provider key.
Voice, music and sound
ElevenLabs voiceovers with word timestamps, sound effects, music, and translating or dubbing a video into other languages.
generate_audiolist_voicestranslate_videodub_video
Images and thumbnails
Nano Banana images, Pikzels thumbnails, scores and title ideas.
generate_imagegenerate_thumbnailscore_thumbnailgenerate_titles
Video
Veo clips and YouTube rough cuts, as jobs you poll.
generate_videocreate_youtube_video
Transcripts
YouTube, TikTok, Instagram and your own files, timestamped.
transcriberead_url
Research
The open web and YouTube, with cited reports.
web_searchdeep_researchsearch_youtubefind_outlier_videos
An AI teammate
Scripts, plans and answers from the assistant that knows your workspace.
ask_kloudie
Your workspace
Boards, cards, tasks, Drive and the Brain.
list_cardscreate_cardsearch_drivesearch_brain
Authentication and scopes
Send Authorization: Bearer $KLOUDBOARD_API_KEY. A key belongs to one workspace, acts as the member who created it, and stops working when it is revoked or they leave. The same key works as a Bearer header on the MCP server, so headless Claude Code and CI need no browser sign-in.
read | Read | Boards, cards, Drive, Brain, jobs and balances. |
write | Write | Create and change cards, tasks, files; publish and invite. |
spend | Spend AI credits | Voice, images, video, research and every other paid tool (ask_kloudie also needs Write). |
Credits and pricing
Paid calls hold their estimate in AI credits first, refund what they do not use, and report the charge in cost and the X-Credits-Charged and X-Credits-Remaining headers. Reads are free; get_pricing quotes any plan before you run it. What credits cost is on the pricing page.
| Job | Tool | Credits |
|---|---|---|
| Voiceover1,000 characters, about a minute of speech (ElevenLabs) | generate_audio | about 50 |
| Sound effectOne effect (ElevenLabs) | generate_audio | about 40 |
| Music30-second track (ElevenLabs) | generate_audio | about 50 |
| ImageNano Banana 2, per image | generate_image | about 50 |
| Image, sharperNano Banana Pro, per image | generate_image | about 95 |
| Video clip8 seconds, Veo 3.1 Lite | generate_video | about 398 |
| Video clip8 seconds, Veo 3.1 Fast | generate_video | about 596 |
| Video clip8 seconds, Veo 3.1 | generate_video | about 1,986 |
| YouTube thumbnailPikzels pkz_3 (the default model) | generate_thumbnail | about 120 |
| Title ideas3 to 5 titles (Pikzels) | generate_titles | about 55 |
| Thumbnail score0 to 100 grade with a suggestion (Pikzels) | score_thumbnail | about 20 |
| TranscriptOne YouTube video with captions | transcribe | about 10 |
| Transcript from audioPer minute: TikTok, Instagram, Facebook, Drive files, uncaptioned video | transcribe | about 15 |
| Web searchOne search, 5 sources | web_search | about 8 |
| Read a web pageOne page or captioned video | read_url | about 10 |
| Deep researchCited report from up to 12 sources | deep_research | about 300 |
| Translate a videoPer minute of video, per language, in the speaker's voice (plus a one-time part per video) | translate_video | about 60 |
| DubbingPer minute of video, per language (ElevenLabs, no watermark) | dub_video | about 295 |
| Dubbing, watermarkedPer minute of video, per language (ElevenLabs) | dub_video | about 195 |
Responses and errors
Every answer is { ok, data } or { ok: false, error: { code, message, hint, request_id } } with a real status code and an X-Request-Id header. Switch on error.code.
// 200
{ "ok": true, "tool": "generate_audio", "data": { "asset": { "url": "https://…" } },
"cost": { "credits": 60, "balance": 12250 } }
// 402
{ "ok": false, "error": { "code": "insufficient_credits",
"message": "This costs about 60 AI credits and the workspace has 12 left.",
"hint": "Nothing was charged. Top up AI credits, then retry with the same Idempotency-Key.",
"top_up_url": "https://app.kloudboard.com/settings?tab=billing",
"request_id": "req_5f0c6a1b2c3d4e5f6a7b8c9d" } }| 400 | invalid_request | Bad JSON, a missing field, or arguments the tool refused. Fix the request; retrying as-is fails again. |
| 401 | unauthenticated | No key, a mistyped key, or a revoked one. |
| 402 | insufficient_credits | The workspace cannot cover the call. Nothing was charged; error.top_up_url is where the owner buys credits. |
| 403 | permission_denied | The key acts as its creator, who lacks this permission in the workspace. |
| 403 | scope_missing | The key was created without the scope this call needs (read, write or spend). |
| 404 | not_found | Unknown tool, card, job or other id. |
| 409 | conflict | The resource changed underneath you since you read it. |
| 409 | idempotency_in_progress | A request with the same Idempotency-Key is still running. Retry after it finishes. |
| 422 | idempotency_key_reused | The Idempotency-Key was used with different arguments. Use a new key. |
| 429 | rate_limited | Too many calls. Wait Retry-After seconds. |
| 500 | internal_error | Failed on our side. Retry with the same Idempotency-Key; quote request_id to support. |
| 502 | upstream_error | A provider failed. Nothing was charged; retrying is safe. |
Safe retries
Send an Idempotency-Key (a UUID) on every POST. A retry with the same key returns the first success for 24 hours instead of charging twice; failures stay retryable.
Long jobs
Video, long transcripts and long assistant turns answer 202 with a Location of /api/v1/jobs/<id>. Poll it every Retry-After seconds until data.done.
Rate limits
600 requests an hour per key (tool calls, reads and job polls) and 120 an hour on POST /api/v1/text, counted across every server; MCP has its own 1,000 tool calls an hour per connection. A 429 carries Retry-After and RateLimit headers, and every response names its quota in RateLimit-Policy. Spend is capped by credits, never by surprise invoices.
Versioning and deprecation
- v1 (/api/v1) is the current, stable version.
- Additive changes (new endpoints, tools, optional fields and error codes) ship without a new version, so clients should ignore fields they do not know.
- Breaking changes ship only as a new version path (/api/v2); the old version keeps working side by side.
- Before an endpoint or version is removed, its responses carry a Deprecation header (RFC 9745) and a Sunset header (RFC 8594) with the shutdown date, at least 6 months ahead, and the changelog announces it.
- A deprecated endpoint keeps working until its Sunset date.