Nodaro Docs
DocumentationNode ReferenceModelsAI Agents (MCP)DevelopersSelf-hostingResearch
TypeScript SDK

Apps and templates

Browse and run published Nodaro apps from TypeScript, read their run history, clone workflow templates into a project, and list the tutorials.

client.apps browses and runs published apps: workflows wrapped in a simple form of inputs and outputs. client.templates browses the template marketplace and clones a template into one of your projects, and client.tutorials lists the tutorial videos and tutorial workflows. See Apps and Tutorials and templates for the concepts.

Methods

MethodWhat it does
apps.list(params?)Browse published apps
apps.get(slug)Read an app with its inputs and outputs
apps.run(slug, inputs?, opts?)Run an app
apps.listRuns(slug, params?)List your runs of an app
apps.getRun(slug, runId)Read one run
apps.deleteRun(slug, runId)Archive a run
templates.browse(params?)Browse the template marketplace
templates.get(slug)Read a template with its workflow
templates.clone(slug, params)Copy a template into a project
tutorials.list()List the tutorials by category

client.apps

list() and get() are public. run() and the run history act as the signed-in caller.

apps.list(params?)

Browses published apps, a page at a time.

list(params?: { search?: string; category?: string; limit?: number; cursor?: string }): Promise<{
  data: PublishedApp[]
  nextCursor?: string | null
}>

Prop

Type

const { data: apps, nextCursor } = await client.apps.list({ search: "headshot", limit: 20 })

A PublishedApp has id, slug, name, description, creatorId, creatorName, thumbnailUrl, category, isFeatured, runCount, createdAt and updatedAt.

apps.get(slug)

Reads one app, with its inputSchema, the fields end users fill in, and outputs, what it returns.

get(slug: string): Promise<{ data: PublishedAppDetail }>

Prop

Type

const { data: app } = await client.apps.get("pro-headshot")
console.log(app.inputSchema, app.outputs) // outputs: [{ nodeId, label, type }]

apps.run(slug, inputs?, opts?)

Runs an app and returns at once with { executionId, status, runId? }. Poll client.executions.get(executionId) for the result.

run(slug: string, inputs?: Record<string, unknown>, opts?: {
  inputOverrides?: Record<string, Record<string, unknown>>
}): Promise<{ executionId: string; status: "pending" | "running"; runId?: string }>

Prop

Type

const { executionId } = await client.apps.run("pro-headshot", { photo: photoUrl })

// Add hidden text before the app's prompt, for this run only
await client.apps.run(
  "pro-headshot",
  { photo: photoUrl },
  { inputOverrides: { n1: { promptPrefix: "Studio portrait of" } } },
)

inputOverrides is an advanced option. It can set, for example, a node's pre and post text (promptPrefix and promptSuffix). It cannot set a destination of an output node, such as a Webhook Output URL, a publishing account or a scraper's target. Such an override is refused with 400 locked_field.

apps.listRuns(slug, params?)

Lists your runs of an app, a page at a time.

listRuns(slug: string, params?: { limit?: number; cursor?: string }): Promise<{ data: AppRun[]; nextCursor?: string | null }>

Prop

Type

const { data: runs } = await client.apps.listRuns("pro-headshot", { limit: 10 })
for (const run of runs) console.log(run.status, run.outputs)

An AppRun has id, appSlug, executionId, status (pending, running, completed, failed or cancelled), inputs, outputs (each { nodeId, type, url?, text? }), startedAt and finishedAt.

apps.getRun(slug, runId)

Reads one run of an app.

getRun(slug: string, runId: string): Promise<{ data: AppRun }>

Prop

Type

const { data: run } = await client.apps.getRun("pro-headshot", runId)

apps.deleteRun(slug, runId)

Archives a run. Restoring a run and deleting it permanently are only available in the Nodaro app, so a script cannot destroy data.

deleteRun(slug: string, runId: string): Promise<{ success: true; archived: true }>

Prop

Type

await client.apps.deleteRun("pro-headshot", runId)

client.templates

The template marketplace, public by design: browse it, read a template with its whole workflow, and clone it into your project for free.

templates.browse(params?)

Browses the marketplace, a page at a time (GET /v1/templates/browse). No sign-in is needed.

browse(params?: BrowseTemplatesParams): Promise<{ data: TemplateBrowseCard[]; nextCursor: string | null }>

Prop

Type

const page = await client.templates.browse({ sort: "popular", search: "trailer" })

templates.get(slug)

Reads one public template with its full workflow snapshot: snapshotNodes, snapshotEdges and snapshotSettings (GET /v1/templates/:slug).

get(slug: string): Promise<Template>

Prop

Type

const template = await client.templates.get("noir-trailer")
console.log(template.snapshotNodes.length)

Throws NotFoundError when the slug is unknown, unlisted or inactive.

templates.clone(slug, params)

Copies a template into one of your projects as a new workflow (POST /v1/templates/:slug/clone). It costs no credits.

clone(slug: string, params: { projectId: string; name?: string }): Promise<{ workflowId: string; projectId: string }>

Prop

Type

const { workflowId } = await client.templates.clone("noir-trailer", { projectId })
await client.workflows.run(workflowId)

client.tutorials

tutorials.list()

Lists every tutorial category with its tutorial videos and tutorial workflows (GET /v1/tutorials). It is public and read-only.

list(): Promise<{ categories: TutorialCategory[] }>
const { categories } = await client.tutorials.list()
for (const category of categories) {
  console.log(category.name, category.videos.length, category.flows.length)
}

Each category has id, name, slug, sortOrder, videos and flows. A video has a title, a videoUrl and a thumbnailUrl. A flow is a template marked as a tutorial: it has a title, a complexity, estimatedCredits, the node types and models it uses, and a slug you can pass to templates.get() and templates.clone().

Frequently asked questions

Last updated on

On this page