Cat. № SDK—2026@cueno/sdk

Pull a prompt into your app in one call.

The official SDK for the Cueno runtime API. Resolve a prompt by slug, render it with variables, or pin a specific version — from any JavaScript/TypeScript runtime with fetch (Node 18+, edge, Deno, browsers). Fully typed, zero runtime dependencies.

№ 01

Install

The package is published as @cueno/sdkwith no runtime dependencies — it's a thin, typed wrapper over global fetch.

terminal
npm install @cueno/sdk
№ 02

Quick start

Construct the client once with your API key and reuse it. The most common path is render— it resolves the version deployed to your key's environment, validates your variables server-side, and returns the interpolated string.

app/route.ts
import { Cueno } from "@cueno/sdk";

const cueno = new Cueno({
  apiKey: process.env.CUENO_API_KEY!, // cueno_live_… or cueno_test_…
  baseUrl: "https://cueno.dev",        // omit for http://localhost:3000
});

// the key's env picks the live version — the server renders it
const { prompt } = await cueno.prompts.render("welcome-support", {
  company: "Acme",
  customer: "Lee",
});

const reply = await model.run(prompt);
Keep the API key server-side. The key's environment is authoritative, so the secret is enough to read your production prompts — never ship it in a browser bundle or mobile client.
№ 03

Authentication

Every request authenticates with a Cueno API key, sent automatically as a bearer token. Keys are minted in the web app under Settings → API keys; the full secret is shown once at creation.

  • The key's environment is authoritative. There is no envparameter — a key only ever resolves what's deployed to its environment. To read a different environment, use a key minted for it.
  • Keys are workspace-scoped. A slug in another workspace returns 404, not 403.
Key prefixEnvironment
cueno_live_…production
cueno_test_…staging
№ 04

API reference

All prompt operations hang off cueno.prompts. Every method returns a typed response (the exported types mirror the server contract) and sets Authorization and Content-Type for you.

cueno.prompts.list()ListPromptsResponse

Every prompt with a version deployed to the key's environment, each carrying its live version label and declared variables. Bodies are omitted.

cueno.prompts.get(slug)ResolvedPrompt

Resolve a slug to its deployed version and return the raw, un-rendered body plus declared variables — render it yourself.

cueno.prompts.render(slug, vars?)RenderResponse

Resolve + interpolate. The server validates vars against the declared variables and returns the rendered prompt string. Throws on invalid input — see Errors.

cueno.prompts.versions(slug)VersionsResponse

The full version history for a prompt, newest first, so you can discover labels to pin to. Bodies omitted.

cueno.prompts.version(slug, label)VersionResponse

Fetch one specific version by label — regardless of what's deployed — including its body. The reproducibility path: pin to v3 and always get the same prompt back.

render accepts a Record<string, string | number | boolean>. Unknown keys are ignored; a declared-but-optional variable left out is rendered verbatim as its {{token}} rather than blanked.

№ 05

Errors

Any non-2xx response throws a CuenoApiError. Branch on code (stable), not message (human text that may change). For a failed render, the issues getter exposes the per-variable reasons.

error-handling.ts
import { CuenoApiError } from "@cueno/sdk";

try {
  await cueno.prompts.render("welcome-support", { company: 123 });
} catch (e) {
  if (e instanceof CuenoApiError) {
    e.code;    // "validation_failed" — branch on this
    e.status;  // 422
    e.issues;  // [{ variable: "company", message: "Expected a string value." }]
  }
}
codestatusMeaning
unauthorized401Missing, malformed, or unknown API key
not_found404Unknown slug, nothing deployed to the env, or unknown version label
invalid_request400Malformed JSON or a wrong-shaped variables payload
validation_failed422Variable values failed validation — see .issues
method_not_allowed405Wrong HTTP method for the route
№ 06

Configuration

The constructor takes a single options object: new Cueno(options).

OptionDefaultNotes
apiKeyRequired. Your cueno_live_… / cueno_test_… secret.
baseUrlhttp://localhost:3000API origin, without the /api/v1 suffix.
fetchglobalThis.fetchInject a custom fetch (Node <18, or for tests).

That's the whole SDK surface. Prefer to skip the client and call the endpoints yourself? See the REST API below — every method maps one-to-one onto /api/v1.

№ 07

REST API

The SDK is a thin wrapper — every method maps one-to-one onto an HTTP endpoint under /api/v1. If you're not on JavaScript, or just prefer raw fetch/curl, call the API directly. Same bearer auth, same environment semantics, and the same error envelope.

It's JSON in, JSON out. Authenticate with your key on every request; the v1 path segment is the contract version.

auth-header
Authorization: Bearer cueno_live_8Kd2_xxxxxxxxxxxx

Endpoints

GET/prompts
GET/prompts/{slug}
POST/prompts/{slug}/render
GET/prompts/{slug}/versions
GET/prompts/{slug}/versions/{label}

Resolve a prompt

The main read path — resolve a slug to the body deployed in your key's environment:

terminal
curl https://cueno.dev/api/v1/prompts/welcome-support \
  -H "Authorization: Bearer $CUENO_API_KEY"
200 — application/json
{
  "slug": "welcome-support",
  "title": "Welcome Support",
  "description": "Opening line for support chats.",
  "environment": "production",
  "version": { "label": "v3", "author": "kit", "createdAt": "2026-05-28T00:00:00.000Z" },
  "body": "You are {{agent_name}} for {{company}}. Greet {{customer}}.",
  "variables": [
    { "name": "company", "type": "string", "required": true, "note": null }
  ]
}

Render with variables

POST the values and let the server validate and interpolate. An empty body (or no variables) is treated as {}; unknown keys are ignored, and an optional token left unprovided stays verbatim.

terminal
curl https://cueno.dev/api/v1/prompts/welcome-support/render \
  -H "Authorization: Bearer $CUENO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "variables": { "company": "Acme", "customer": "Lee", "agent_name": "Ada" } }'
200 — application/json
{
  "slug": "welcome-support",
  "environment": "production",
  "version": "v3",
  "prompt": "You are Ada for Acme. Greet Lee."
}
Same key, same rules: the environment comes from the key, not the request, so there's no ?env= override. Errors use the shared envelope { "error": { "code", "message", "details"? } } — branch on error.code.