Kuro API

Make images, clips, voice-overs and music, run recipes, and hear when they are done, from your own code. The same API serves Kuro Cloud at https://api.meetkuro.com and every studio you run yourself, at its own address.

Start

  1. Make a key in Settings → Connections. Choose what it may do: a key with chosen permissions works only here and with MCP.
  2. Send it as Authorization: Bearer KR_….
  3. Make something:
curl -X POST "https://api.meetkuro.com/v1/generations?wait=60" \
  -H "Authorization: Bearer $KURO_API_KEY" \
  -H "Idempotency-Key: lighthouse-1" \
  -H "Content-Type: application/json" \
  -d '{"type": "image", "prompt": "A lighthouse at dawn"}'

With wait, the answer is the finished generation when it is ready within the wait (up to 60 seconds); otherwise read it with GET /v1/generations/{id} until its status is ready. Work runs on your own provider keys when you hold one that can run it, exactly as in the app: your provider bills you, and Kuro charges no credits. Otherwise it spends credits. POST /v1/quotes prices a request before you spend anything.

TypeScript

@meetkuro/sdk is MIT licensed, has no dependencies, and is typed from this API's own document.

npm install @meetkuro/sdk

import { Kuro } from "@meetkuro/sdk";

const kuro = new Kuro(); // reads KURO_API_KEY
const image = await kuro.generations.createAndWait({
  type: "image",
  prompt: "A lighthouse at dawn",
});
console.log(image.output_url);

Retries and errors

Send an Idempotency-Key (any string) on every call that spends: the same key replays the first answer instead of spending again, and a different body under a used key is refused with 409. Every error has one shape, { "error": { "code", "message", "details" } }, and its code is stable. On 429, wait the Retry-After seconds.

Webhooks

Pass webhook_url (HTTPS) when you make a generation or run a recipe, and the server POSTs a signed event there when it settles: generation.ready, generation.failed, run.done, run.failed, or run.asks_you when a run waits on you. Events are signed the Standard Webhooks way with the signing secret in Settings → Connections, and retried for a day. Answer 2xx within ten seconds, and treat a repeated webhook-id as the same event.

import { verifyWebhook } from "@meetkuro/sdk";

export async function POST(request: Request) {
  const event = await verifyWebhook({
    body: await request.text(),
    headers: request.headers,
    secret: process.env.KURO_WEBHOOK_SECRET!,
  });
  if (event.type === "generation.ready") {
    // Read it with your key: GET /v1/generations/{id}
  }
  return new Response(null, { status: 204 });
}

Versions

Inside /v1 changes only add: new fields, new operations, new values where a description says so. Ignore what you do not recognise. The whole API is described at /v1/openapi.json, which you can import into Postman, generate a client from, or hand to an agent.

Account

Who a key belongs to and what it may spend.

Models

Every model the server runs, with its price, shapes and a guide to prompting it.

Generations

Make an image, clip, voice-over or music, and read it back.

Uploads

Bring your own pictures, clips and sounds to use as references.

Recipes

Run a recipe: a few answers in, a finished piece out.

Runs

The multi-step runs a recipe starts.

Subjects

The people and products Kuro keeps consistent.