# Nodaro SDK — agent primer # Paste this whole file into your coding agent (Claude, Cursor, ...) and ask # for what you want built. Canonical copy of the primer in the @nodaro/sdk # README — keep the two in sync when editing. You are building against @nodaro/sdk (npm), the typed client for the Nodaro AI video platform (https://app.nodaro.ai). Setup: npm install @nodaro/sdk Auth: the user creates a token at https://app.nodaro.ai/settings/api and sets NODARO_ACCESS_TOKEN. Never hardcode tokens. Core pattern (all generation is async; runAndWait submits + polls + resolves): import { createClient, StaticTokenAuth } from "@nodaro/sdk" const client = createClient({ baseUrl: "https://app.nodaro.ai", auth: new StaticTokenAuth(process.env.NODARO_ACCESS_TOKEN!), }) const img = await client.nodes.runAndWait("generate-image", { prompt: "…", provider: "nano-banana-2", // fast + cheap, great default }) const vid = await client.nodes.runAndWait("generate-video", { prompt: "…", imageUrl: img.imageUrl, provider: "seedance-2-fast", duration: 4, // platform default; 4/8/12/15s }) // outputs: .imageUrl / .videoUrl / .audioUrl on the resolved object Models available (full lists with credit costs, as raw markdown): image: https://nodaroai.github.io/app.nodaro.ai/nodes/ai-image/generate-image.md video: https://nodaroai.github.io/app.nodaro.ai/nodes/ai-video/generate-video.md (or at runtime: client.nodes.get(type) → data.providers + credits.modelCosts) Model choice: - Omitting `provider` uses the platform's default model for that node — fine for a v1. To offer users a model picker: const { data } = await client.nodes.get("generate-video") // data.providers const costs = await client.credits.modelCosts(data.providers) Render provider options with their credit costs next to them. UX rules (generation takes seconds-to-minutes — never block silently): - Show intermediate results immediately: render the image as soon as generate-image resolves, WHILE the video step is still running. - Show live progress: pass onProgress to runAndWait — it receives the lean job status on every poll: await client.nodes.runAndWait("generate-video", { … }, { onProgress: (s) => setBar(s.progress ?? 0), // 0–100 when reported }) For manual loops use client.jobs.getStatus(jobId) (id/status/progress). - Let the user cancel: pass { signal } (AbortSignal) in the same options. Rules: - Generations cost credits; catch InsufficientCreditsError (has .required / .available). All errors are typed classes exported from @nodaro/sdk. - Prefer client.nodes.runAndWait over hand-rolled polling; for manual loops use client.jobs.getStatus(id) (lean poll endpoint). - 22 resources on the client (workflows, characters, voices, pipelines, …): full reference https://nodaroai.github.io/app.nodaro.ai/sdk-reference.md - Node catalog + per-node params: https://nodaroai.github.io/app.nodaro.ai/nodes/ (all pages exist as .md)