Back to overview
api reference

Documentation for the app.nz AI agent cloud.

One control-plane API and one OpenAI-compatible model gateway, both authenticated with the same key. Launch coding agents on your repos, route chat across providers, and publish sites, all over HTTP. Every endpoint here maps to a live route in the Go server — click any one for its own reference page.

Use these docs with your AI agent

Every page here is machine-readable. Point a coding agent at /llms.txt for the index, or /llms-full.txt for a self-contained build-an-agent guide. Paste this prompt into any agent:

Build-an-agent prompt
Read https://app.nz/llms-full.txt and follow it to build an agent on app.nz: call the OpenAI-compatible gateway, launch a cloud coding agent, and ship a deploy.
Already have OpenAI code?
from openai import OpenAI

# Same OpenAI code — only the base URL and key change.
client = OpenAI(base_url="https://app.nz/v1", api_key="pk_live_...")
r = client.chat.completions.create(
    model="app/auto",  # router picks the model, or pin "provider/model"
    messages=[{"role": "user", "content": "Hello from app.nz"}],
)

Quick copy for any LLM

Give an agent a complete, safer brief.

Raw Markdown guide ↗
Read https://app.nz/llms-full.txt, especially “Launch a cloud coding agent”.

Use app.nz to complete this outcome: <describe the outcome>.

- Repository: <owner/repo>
- Constraints: preserve unrelated work; never expose secrets; ask before destructive or costly actions.
- Execution: choose an appropriate agent/model route, inspect existing instructions, implement the smallest coherent change, and run relevant tests.
- Visual changes: capture desktop and mobile evidence in VisualBench and inspect it.
- Return: summary, changed files, tests, remaining risks, and PR/deploy URL when created.

Also available offline as app guide agent and through the app.nz MCP server.

CLI + MCP handoff

Give any LLM the same platform context.

Generate a deployment brief offline, or connect the app.nz MCP server so an agent can retrieve instructions and use platform tools directly.

app — hand the platform to any LLM
Loading recording…

Authentication

Every API call authenticates with a bearer key created from your account. Pass it as an Authorization header. Browser sessions (cookie auth) work too, but keys are the right choice for servers, agents, and the CLI. Secrets are shown once at create/rotate time, so store them immediately.

basehttps://app.nz
Create a key and call the API
# Create a key (secret returned once)
curl -sX POST https://app.nz/api/keys \
  -H "Authorization: Bearer $APP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"deploy bot"}'

# Use it on every other request
curl -s https://app.nz/api/me \
  -H "Authorization: Bearer pk_live_..."

The app CLI

Every endpoint in these docs is scriptable from one small binary. The CLI shares keys with the API and web app, streams chat, deploys apps and sites, drives coding agents, and mirrors the gh command layout for repos, issues, PRs, and releases. Any command takes --json; anything without a dedicated command is reachable via app api. The full command reference lives at /cli.

Core commands
app login --api-key <key>authSave a key (or set APP_API_KEY); app whoami verifies.
app apps deploy [dir]hostingPackage + build + release an appnz.yaml app (static or server runtime) at <name>.app.nz.
app apps logs <slug>hostingBuild and runtime logs for the latest (or a given) deploy.
app apps marketplace [query]hostingBrowse apps and games built on or showcased by app.nz.
app apps publish [slug] --url <url>hostingInstantly enrich a hosted app card or publish an external community app with automatic OG metadata discovery.
app sites deploy <slug> <dir>hostingMirror a directory of static files to a hosted site.
app agent run --prompt "..." --repo o/nagentsLaunch a cloud coding agent; get/list/cancel manage tasks.
app chat "..." [--web] [--deep]modelsStreamed chat through the gateway; --model pins a route.
app api <METHOD> <path> [json]escape hatchCall any documented endpoint directly.
Install, build with an agent, deploy a game
curl -fsSL https://app.nz/cli.sh | sh
app login --api-key pk_live_...

# hand the build to a cloud agent
app agent run --prompt "build a neon snake HTML5 game" --repo you/neon-snake

# pull the agent's files, then ship to https://neon-snake.app.nz
app agent apply <task-id> --dir ./neon-snake
app apps deploy ./neon-snake

Models gateway

An OpenAI-compatible API in front of 15+ providers. Point any OpenAI or Anthropic client at the base URL and keep your code. Use app/auto to let the router pick a model from the prompt, or bias it with a variant, or pin a specific provider model. The same key meters usage across every call.

basehttps://app.nz/v1
Model routes (the model field)
app/autorouteDefault. Reads the prompt and picks the backend.
app/auto-coderouteBias toward strong coding models.
app/auto-fastrouteLowest latency for interactive use.
app/auto-cheaprouteBias toward lowest cost per token.
app/auto-reasoningrouteRoute reasoning depth automatically.
app/auto-visionrouteBias toward image-input models.
app/auto-imagerouteBias toward image-generation models.
routing_strategyparamprice by default; use config to preserve catalogue order or app/auto-fast for latency bias.
provider/modelpinPin a specific upstream model, e.g. anthropic/claude or openai/gpt.
Chat completion with auto routing
curl -s https://app.nz/v1/chat/completions \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "app/auto",
    "messages": [{"role": "user", "content": "Explain CRDTs in one paragraph."}],
    "reasoning_effort": "auto",
    "stream": false
  }'

Agents API

Run cloud coding agents against a repo and a prompt, then poll status, stream step events, inspect changed files, and cancel or retry. GET /api/agents/config returns the option lists (engines, models, reasoning efforts, machine types, providers, skills) and needs no auth so a UI can render the form before sign-in.

basehttps://app.nz
POST /api/agents/tasks body
prompt*stringWhat the agent should do (max 20k chars).
sourcestringProvider that runs it: openpaths (default, our cloud) | devin | cursor | codex-cloud. See the Agents SDK section.
repostringTarget repo as owner/name.
branchstringWorking branch to create or use.
baseBranchstringBranch to base the work on.
modelstringModel route, e.g. app/auto-code.
enginestringAgent engine (see /config).
reasoningEffortstringnone | low | medium | high | xhigh | auto.
machineTypestringWorker capability tier (see /config), e.g. auto, cpx32, gpu-a100, or win-cpx32 for a Windows worker.
providerstringExecution tier, e.g. shared (auto fleet), cloud CPU, or cloud GPU (see /config).
skillsstring[]Enabled skills, e.g. ["github","visualbench"].
autoMergePrbooleanAuto-merge the PR when checks pass.
autoNextStepsbooleanLet the agent queue follow-up steps.
spendCapUsdnumberHard spend ceiling for the task.
timeoutSecondsnumberWall-clock timeout.
projectIdstringProject to bill and scope to; defaults to your default project.
titlestringDisplay title; derived from the prompt if omitted.
Launch an agent
curl -sX POST https://app.nz/api/agents/tasks \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "add usage analytics to the dashboard",
    "repo": "acme/ai-dashboard",
    "model": "app/auto-code",
    "reasoningEffort": "high",
    "machineType": "auto",
    "provider": "shared",
    "skills": ["github", "visualbench"],
    "spendCapUsd": 2.00,
    "autoMergePr": false
  }'

Agents SDK — one API, every provider

The same /api/agents surface is a meta-agent router: set `source` to choose who runs the task. openpaths (the default) runs it on app.nz workers using our model credentials — which take precedence over any provider key when running in our cloud — and opens PRs through our GitHub app. devin, cursor, and codex-cloud launch the run on that vendor and the result (status, logs, diff, pull request) normalizes back into the same task — so every provider reads through one trace. GET /api/agents/config returns `sources` plus a `sourcesConfigured` map so a UI can disable providers that lack server credentials.

basehttps://app.nz
Source values
openpathssourceDefault. Runs on app.nz workers with our credentials; engine selects Claude Code / Codex / Gemini. Real PRs via our GitHub app.
devinsourceLaunches a Devin cloud session. Needs server DEVIN_API_KEY + DEVIN_ORG_ID.
cursorsourceLaunches a Cursor cloud agent with auto-PR. Needs server CURSOR_API_KEY.
codex-cloudsourceLaunches an OpenAI Codex Cloud task against a GitHub-connected repo. Needs CODEX_CLOUD_ENV_ID + the codex CLI.
Launch on Devin (or swap source for cursor / codex-cloud / openpaths)
curl -sX POST https://app.nz/api/agents/tasks \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "source": "devin",
    "prompt": "fix failing CI and open a pull request",
    "repo": "lee101/edukids",
    "baseBranch": "main",
    "autoMergePr": false
  }'

# CLI equivalent:
#   app agents-sdk run "fix failing CI and open a PR" --source devin --repo lee101/edukids
#   app agents-sdk providers      # see which providers are configured
#   app agents-sdk logs <id>      # read the normalized trace

Local workers — run agent tasks on your own machines

Run `app worker` on any computer after `app login` and it becomes a private worker for your account: it polls app.nz, leases agent tasks created with provider "local", executes them with local engines (our codex fork with automatic fallback to mainline codex, claude, cursor-agent, gemini, grok), and reports steps/diffs/PRs into the normal task trace. Leasing is user-scoped: your workers authenticate every /api/worker call with your API key and only ever see jobs whose user matches your account; fleet workers use the shared X-Worker-Token and never lease provider=local jobs. Job payloads and logs pass through secret redaction, and only allowlisted engines execute. By default a local worker takes only your provider=local jobs; --any-provider opts it into all of your jobs.

basehttps://app.nz
GET/api/agents/workersList your registered machines with online state and activeJobssession
POST/api/worker/registerWorker announces itself (Bearer API key for user workers; X-Worker-Token for the fleet)API key
POST/api/worker/heartbeatLiveness + active job count; drives the online indicatorAPI key
POST/api/worker/leaseAtomically claim the oldest runnable job you ownAPI key
POST/api/worker/completeReport a leased job resultAPI key
POST/api/worker/job-credsShort-lived credentials for a leased jobAPI key
app worker flags
--name <name>stringMachine display name; defaults to the hostname.
--dir <path>stringWorking directory for repo checkouts.
--engines <list>stringComma-separated engine allowlist, e.g. codex,claude. Defaults to every installed engine.
--any-providerbooleanAlso lease your non-local (cloud-queued) jobs, not just provider=local.
--poll <dur>durationPoll interval for the lease loop.
--lease <n>integerMax jobs to run concurrently.
--oncebooleanLease at most one job, run it, exit (cron-friendly).
--dry-runbooleanShow what would be leased and run without executing.
app worker statuscommandList your machines, online state, and active jobs from the CLI.
Turn a desktop into a worker, then fire a task at it from anywhere
# on the machine that will do the coding
app login
app worker --name desktop --dir ~/agent-work --engines codex,claude

# from any device (or the /agent composer with provider "Your machine")
app agent run --prompt "add a /health endpoint with a test" \
  --repo you/api --provider local --model app/auto-code

# see your machines (same data as the studio chips)
app worker status
curl -s https://app.nz/api/agents/workers -H "Authorization: Bearer pk_live_..."

Artifacts API

Create, update, list, share, and delete user artifacts. Supported kinds are drawing, doc, sheet, pdf, image, and file. Documents store Markdown text and open in /write; sheets store JSON grid data and open in /sheets, so agents can produce editable office documents directly.

basehttps://app.nz
Artifact body
kind*stringdrawing | doc | sheet | pdf | image | file.
title*stringDisplay title.
mimestringMIME type, e.g. text/markdown for doc or application/json for sheet.
datastringInline data. Documents use Markdown; sheets use JSON grid data.
urlstringOptional https:// or app-relative URL for binary artifacts.
teamIdstringOptional team visibility scope.
Create editable document and sheet artifacts
curl -sX POST https://app.nz/api/artifacts \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"kind":"doc","title":"Runbook","mime":"text/markdown","data":"# Runbook\n\nShip it."}'

curl -sX POST https://app.nz/api/artifacts \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"kind":"sheet","title":"Budget","mime":"application/json","data":"[{"name":"Sheet1","rows":{"0":{"cells":{"0":{"text":"Item"},"1":{"text":"Cost"}}}}}]"}'

Media optimizer API

Cloudflare-style image resizing and AV1-first video re-encoding over your app.nz artifact filesystem. Optimize an existing artifact or a public HTTPS URL, save generated variants back into /artifacts, and serve best-size images through a dynamic URL that negotiates AVIF, WebP, JPEG, or PNG from the Accept header. The same optimizer is available as a Cog image for isolated GPU worker pools.

basehttps://app.nz
Optimization body
artifactIdstringSource artifact to read. Required unless url is supplied.
urlstringPublic HTTPS source URL. Private/reserved network targets are rejected.
kindstringimage | video. Inferred from MIME/extension when omitted.
widthsint[]Image widths to generate. Default: [320,640,960,1280].
heightsint[]Video ladder heights. Default: [360,720,1080].
formatsstring[]Image: webp | avif | jpeg | png. Video: webm | av1 | mp4.
qualityint1-100 quality target; defaults to 85 for images.
outputPathstringArtifact directory for generated variants; defaults to /optimized.
dryRunbooleanReturn the plan and estimated credits without encoding.
Generate responsive variants and build the Cog image
# Save responsive image variants back into /artifacts.
curl -sX POST https://app.nz/api/media/optimize \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "artifactId": "artifact_123",
    "kind": "image",
    "widths": [320, 640, 1280],
    "formats": ["webp"],
    "outputPath": "/optimized"
  }'

# Dynamic best-size image URL.
curl -L "https://app.nz/api/media/image/artifact_123?w=640&format=auto&q=85" \
  -H "Authorization: Bearer pk_live_..."

# CLI equivalents.
app media optimize --artifact-id artifact_123 --width 640 --width 1280 --format webp
app media pricing
app builds media-optimizer-cog

Character chat API

Start chats with any character by url_name or id, pin a model for that chat, and stream replies over the same server-sent-events shape as the OpenAI-compatible gateway. User-created characters can include long-form text or Markdown documents; app.nz strips image links, chunks the text, stores it in the character vector-search boundary, and retrieves relevant excerpts for each turn.

basehttps://app.nz
Character and chat bodies
name*stringPOST /api/characters display name.
system_promptstringOptional persona prompt; generated from name/description/greeting if omitted.
documentsarrayOptional long-form docs: [{ "name": "lore.md", "content": "# Markdown..." }]. Alias: knowledge_docs.
character_url_name*stringPOST /api/assistant/chats target character slug.
modelstringModel or route for this chat, e.g. app/auto or app/auto-fast.
reasoning_effortstringauto | off | low | medium | high | xhigh.
content*stringMessage text for POST /messages.
Create a documented character and talk to it with a model
# Create a character with long-form Markdown knowledge.
curl -sX POST https://app.nz/api/characters \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "GPU Brain Operator",
    "description": "Helps operate the gpu-brain search stack.",
    "voice": "Kore",
    "documents": [{
      "name": "runbook.md",
      "content": "# Runbook\nUse gobed for low-latency KNN over text chunks. Never ingest image links."
    }]
  }'

# Start a chat with a given model.
CHAT=$(curl -sX POST https://app.nz/api/assistant/chats \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "character_url_name": "gpu-brain-operator",
    "model": "app/auto-fast",
    "reasoning_effort": "auto"
  }' | jq -r .chat.id)

# Send a message. The response is text/event-stream; relevant doc excerpts are
# retrieved server-side before the model call.
curl -N -sX POST https://app.nz/api/assistant/chats/$CHAT/messages \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"content":"What should I check if KNN search looks stale?"}'

Repos API — git & GitHub parity

GitHub-parity repo hosting on real bare git repositories: clone and push over standard git smart HTTP (git clone https://app.nz/{owner}/{name}.git), plus issues, pull requests with inline line-anchored review comments, a git-backed wiki, releases, labels, Actions-style secrets/variables, and branch-protection rulesets. Read endpoints (repo detail, git browsing, issues/pulls/releases/labels/rulesets, wiki) work with no key at all for public repos — the same code path renders the showcase browser for signed-out visitors — and need a key with read access (owner or a team member) for private ones. Everything that mutates state needs a key with write access, except fork and star, which only need any signed-in reader. Mentioning @agent (or @codex, @claude, @bot, /agent, /fix, /review) in a pull-request comment launches a coding agent on that PR's branch and posts a bot reply linking the task.

basehttps://app.nz
GET/api/reposList your reposAPI keyPOST/api/reposCreate a repo (name, description, visibility, org)API keyGET/api/repos/explorePublic repos for the showcase grid (?kind=code|dataset|model&sort=stars|recent)publicGET/api/repos/searchSearch public repos by name/description (?q=)publicGET/api/repos/lookup/{owner}/{name}Resolve owner/name to a repo (for pretty URLs)publicGET/api/repos/{id}Repo detail — issues, pulls, branches, recent commitspublicPATCH/api/repos/{id}Edit name, description, visibility, defaultBranch, imageUrlAPI keyDELETE/api/repos/{id}Archive (soft-delete) a repoAPI keyPOST/api/repos/{id}/forkFork into your namespace (real bare-git clone, full history)API keyGET/api/repos/{id}/starViewer’s star state and total countpublicPUT/api/repos/{id}/starStar the repoAPI keyDELETE/api/repos/{id}/starUnstar the repoAPI keyGET/api/repos/{id}/git/branchesList branchespublicGET/api/repos/{id}/git/treeDirectory listing (?ref=&path=&withCommits=1)publicGET/api/repos/{id}/git/pathsFlat file-path list for a fuzzy finder (?ref=)publicGET/api/repos/{id}/git/blobFile content, size, language, latest commit (?ref=&path=)publicGET/api/repos/{id}/git/rawRaw file bytes with a sniffed content-type (?ref=&path=)publicGET/api/repos/{id}/git/logCommit history (?ref=&path=&limit=)publicGET/api/repos/{id}/git/commit/{sha}Commit metadata plus its file diffpublicGET/api/repos/{id}/git/diffDiff and commit range between two refs (?base=&head=)publicGET/api/repos/{id}/git/readmeRendered README lookup for a ref/pathpublicGET/api/repos/{id}/git/searchCode search — semantic by default, ?mode=keyword for git grep (?q=&limit=)publicPOST/api/repos/{id}/branchesCreate a branch (name, from)API keyPOST/api/repos/{id}/commitsRecord a commit entry (branch, message) — bookkeeping only, not a real git commitAPI keyGET/api/repos/{id}/issuesList issues (?state=open|closed|all)publicGET/api/repos/{id}/issues/{number}Issue detail with its comment threadpublicPOST/api/repos/{id}/issuesOpen an issue (title, body)API keyPATCH/api/repos/{id}/issues/{number}Set state (state: open|closed)API keyPOST/api/repos/{id}/issues/{number}/commentsComment on an issue (body)API keyGET/api/repos/{id}/pullsList pull requests (?state=open|closed|all)publicGET/api/repos/{id}/pulls/{number}Pull request detail with its comment threadpublicPOST/api/repos/{id}/pullsOpen a PR (title, body, sourceBranch, targetBranch)API keyPATCH/api/repos/{id}/pulls/{number}Set state (state: open|closed|merged — merged performs a real git fast-forward or merge commit)API keyGET/api/repos/{id}/pulls/{number}/commentsList PR comments, including line-anchored review commentspublicPOST/api/repos/{id}/pulls/{number}/commentsPost a PR comment, optionally anchored to a diff line (body, filePath, lineStart, lineEnd, side)API keyGET/api/repos/{id}/wikiList wiki pagespublicGET/api/repos/{id}/wiki/pages/{slug}Get a wiki pagepublicGET/api/repos/{id}/wiki/pages/{slug}/historyPage history from the wiki git repopublicGET/api/repos/{id}/wiki/searchSearch wiki pages (?q=)publicPUT/api/repos/{id}/wiki/pages/{slug}Create or update a page (title, body, message)API keyDELETE/api/repos/{id}/wiki/pages/{slug}Delete a pageAPI keyGET/api/repos/{id}/releasesList releasespublicGET/api/repos/{id}/releases/{tag}Get one releasepublicPOST/api/repos/{id}/releasesCreate a release (tag, name, body, target, prerelease, draft)API keyPATCH/api/repos/{id}/releases/{tag}Update a releaseAPI keyDELETE/api/repos/{id}/releases/{tag}Delete a releaseAPI keyGET/api/repos/{id}/labelsList labelspublicPOST/api/repos/{id}/labelsCreate a label (name, color, description)API keyDELETE/api/repos/{id}/labels/{name}Delete a labelAPI keyGET/api/repos/{id}/secretsList secret names — values are write-only and never returnedAPI keyPOST/api/repos/{id}/secretsSet a secret (name, value)API keyDELETE/api/repos/{id}/secrets/{name}Delete a secretAPI keyGET/api/repos/{id}/variablesList variables (values are readable)API keyPOST/api/repos/{id}/variablesSet a variable (name, value)API keyDELETE/api/repos/{id}/variables/{name}Delete a variableAPI keyGET/api/repos/{id}/rulesetsList branch-protection rulesetspublicPOST/api/repos/{id}/rulesetsCreate a ruleset (name, targetBranch, requirePr, requireChecks, blockForcePush)API keyDELETE/api/repos/{id}/rulesets/{name}Delete a rulesetAPI key
GEThttps://app.nz/{owner}/{name}.git/info/refsgit clone/pull ref advertisement (git clone https://app.nz/{owner}/{name}.git)public
POSThttps://app.nz/{owner}/{name}.git/git-receive-packgit push — HTTP Basic auth, an API key as the passwordAPI key
Access levels
readlevelAnyone, for public repos; owner + team viewers for private ones. Covers repo detail, git browsing, issues/pulls/releases/labels/rulesets, and wiki reads.
writelevelOwner, global admins, or a team member/admin on the repo’s governing org. Required for branches, commits, issues, pulls, wiki writes, labels, secrets, variables, rulesets, releases.
fork / starlevelAny signed-in reader — no write access required.
adminlevelOwner or global admin. Required to edit or delete the repo itself.
Create a repo, push real git, open a PR, ask an agent to fix something
# Create the repo (private by default)
curl -sX POST https://app.nz/api/repos \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"my-app","description":"demo","visibility":"public"}'
# -> {"repo":{"id":"repo_...","fullName":"you/my-app",...}}

# Real git — clone/push over smart HTTP, an API key as the Basic-auth password
git clone https://app.nz/you/my-app.git
cd my-app && git checkout -b feature/x && git commit --allow-empty -m x
git push https://token:[email protected]/you/my-app.git feature/x

# Open a PR against main
curl -sX POST https://app.nz/api/repos/repo_.../pulls \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"title":"Add feature x","sourceBranch":"feature/x","targetBranch":"main"}'

# @mention an agent on the PR thread — it launches on the PR branch and replies
curl -sX POST https://app.nz/api/repos/repo_.../pulls/1/comments \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"body":"@agent add input validation and a test for the empty case"}'

Sites API

Host a static site straight from the control plane. Create a slug, push files (index.html + assets, text or binary), and it is published instantly at both app.nz/sites/<slug>/ and its own subdomain <slug>.app.nz. No build step, no DNS wait. The subdomain is the right home for SPAs — bundlers emit absolute /assets/… paths that only resolve from a site root — and it is served straight from Cloudflare R2 at the edge, so static traffic never touches an origin. A fresh site is seeded with a working starter (index.html, styles.css, app.js). Slugs are 2–40 chars: lowercase letters, numbers, and hyphens, and a few reserved names are blocked. Files are up to 8 MB each; binary assets (images, fonts, audio) are stored too.

basehttps://app.nz
Request bodies
slug*stringPOST /api/sites — public name; normalized to a valid slug.
titlestringPOST /api/sites — display title (max 120 chars).
path*stringPUT files — file path, e.g. index.html or css/app.css.
contentstringPUT files — UTF-8 file contents (max 8 MB). Use for text files.
contentBase64stringPUT files — base64 bytes for binary files (images, fonts, audio).
contentTypestringPUT files — overrides the type inferred from the extension.
Deploy a built site with the CLI (or raw curl)
# Easiest: push a whole build directory with the app CLI. It creates the
# site on first run, uploads every text file, and prunes anything removed.
app login --api-key pk_live_...
npm run build                         # e.g. Vite -> dist/
app sites deploy my-app dist --title "My app"
#   Live at https://app.nz/sites/my-app/
#     and  https://my-app.app.nz/

# Or drive the REST API directly:
SITE=$(curl -sX POST https://app.nz/api/sites \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"slug":"my-landing","title":"My landing"}')

ID=$(echo "$SITE" | jq -r .site.id)

# Publish index.html — live at /sites/my-landing/ and my-landing.app.nz
curl -sX PUT https://app.nz/api/sites/$ID/files \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"path":"index.html","content":"<!doctype html><h1>Hi</h1>"}'

Cogs API — GPU model hosting

Run an arbitrary Cog (Replicate-style) container as an autoscaling, scale-to-zero GPU inference endpoint. Register a model once (image, hardware, optional input schema); the first prediction cold-starts a GPU pod (RunPod on-demand instances under the hood, or free local GPU headroom when the host opts in), proxies to the container’s /predictions endpoint, and an idle reaper scales it back to zero — an idle model costs nothing. Every prediction is billed at machine time times the same platform markup used across app.nz. GET /api/cogs/config is public so the studio can render before sign-in. One-click deploy: link (or badge) any cog with https://app.nz/deploy?image=…&name=…&hardware=… — the studio opens pre-filled, one press to register. Media in and out ride the JSON body as data: URIs or https URLs, so audio-to-audio models work first-class: the audex-s2s template (NVIDIA Nemotron-Labs-Audex-2B, open source at replicatecog/audex) takes a spoken turn and returns transcript, reply text, and reply audio in one prediction — it powers /spaces/audio-to-audio.

basehttps://app.nz
POST /api/cogs body
name*stringModel display name.
image*stringContainer image, e.g. r8.im/owner/model or your own registry image.
hardwarestringA GPU machine id (gpu-t4, gpu-rtx3090, gpu-rtx4090, gpu-a40, gpu-l40s, gpu-a100, gpu-h100), or "auto"/omitted to pick the cheapest GPU that fits minVramGb.
schemaobjectOptional { inputs: [{name,type,description,default,required,choices,min,max,order}], outputKind }. Omitted schemas are introspected from the container’s /openapi.json on first warm-up.
idleSecondsintegerIdle window before scale-to-zero (default 120).
minVramGbintegerModel’s VRAM floor, used for auto hardware selection.
Register fast-vfx and run a prediction
curl -sX POST https://app.nz/api/cogs \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"fast-vfx","image":"r8.im/lee101/fast-vfx","hardware":"gpu-rtx4090"}'
# -> {"model":{"id":"cog_...","status":"idle",...}}

curl -sX POST https://app.nz/api/cogs/cog_.../predict \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"input":{"video":"https://example.com/clip.mp4","num_levels":25}}'
# -> {"prediction":{"id":"pred_...","status":"starting"}}

# Poll for the result (a cold start can take a couple of minutes)
curl -s https://app.nz/api/cogs/predictions/pred_... \
  -H "Authorization: Bearer pk_live_..."

# Audio-to-audio (audex-s2s template): one spoken turn per prediction
curl -sX POST https://app.nz/api/cogs/cog_.../predict \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"input":{"task":"converse","audio":"data:audio/webm;base64,...","system_prompt":"You are a cheerful pirate captain."}}'
# -> output: {"transcript":"...","response_text":"...","audio":"data:audio/mpeg;base64,..."}

Notebooks & datasets

Hosted marimo notebooks run free in the browser (Pyodide) or on per-minute cloud machines that stop when idle. Datasets accept csv, json, jsonl (agent traces auto-detected), parquet, sqlite .db files, images, and browser-playable video; binary formats stream from the CDN and table previews open in the Sheets editor. Machine rates include the platform margin — what /api/notebooks/pricing returns is what you pay.

basehttps://app.nz
Create a notebook and run it on a GPU
curl -sX POST https://app.nz/api/notebooks \
  -H "Authorization: Bearer pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"fraud analysis"}'

curl -sX POST https://app.nz/api/notebooks/nb-1a2b3c4d/sessions \
  -H "Authorization: Bearer pk_live_..." \
  -d '{"machineType":"gpu-rtx3090"}'
# -> {"session":{"id":"...","status":"provisioning","priceHourly":"$0.264"}}

Billing & plans

Everything is paid from one prepaid credit balance (credits are ~$0.001 each). On top of pay-as-you-go, a Pro ($20), Ultra ($60), or Max ($200) plan grants monthly credits, a guaranteed number of concurrent machines, and per-product free quotas. Plan credits are used before purchased credits and roll over for one month.

basehttps://app.nz
Plan tiers
freeplan$0 — pay-as-you-go credits, shared worker pool.
proplan$20/mo — 25,000 credits, 1 guaranteed machine.
ultraplan$60/mo — 80,000 credits, 3 machines + priority.
maxplan$200/mo — 280,000 credits, 6 machines + top priority.
Check your plan and subscribe from the CLI
# Inspect the catalog
curl -s https://app.nz/api/plans | jq

# From the CLI (app login first)
app plan show
app plan subscribe ultra
app billing usage

Payments — let your app earn

Accept payments in anything you build on app.nz. Under the hood it is Stripe Connect with direct charges: you are the merchant of record on your own connected account, Stripe handles KYC/verification and risk, and app.nz white-labels the whole experience. You pay one flat retail rate per plan (Free 5% + 30¢, Pro 4%, Ultra 3.5%, Max 3% — see /api/payments/config), collected automatically as an application fee on each charge. Standard payouts are free; instant payouts cost 1.5% (min 50¢). Earnings can be converted into app.nz credits so an app that earns pays for its own hosting.

basehttps://app.nz
Checkout body
amount*intUnit price in cents (50 – 5,000,000).
descriptionstringWhat the customer is buying; shows on the checkout page.
recurringstringOmit for one-time; "month"/"year"/"week"/"day" for a subscription.
currencystringISO currency, default usd.
quantityintLine-item quantity, default 1.
successUrlstringWhere the buyer lands after paying (your app).
cancelUrlstringWhere the buyer lands if they abandon checkout.
metadataobjectYour own keys (order id, plan) echoed back on the sale.
Enable once, then sell a $29/mo plan from your backend
# One-time setup: onboard (opens Stripe-hosted KYC, bank account)
app payments enable --country NZ --description "Pro subscriptions"

# From your app's server (never expose the key in browser code):
curl -sX POST https://app.nz/api/payments/checkout \
  -H "Authorization: Bearer $APP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 2900, "description": "Pro plan", "recurring": "month",
       "successUrl": "https://myapp.app.nz/thanks"}'
# → redirect the buyer to the returned "url"

app payments sales            # who paid
app payments balance          # available / pending / instant
app payments payout --amount 100.00 --instant   # ~30 min, 1.5% fee
app payments offset --amount 50.00              # $50 earnings → 50,000 hosting credits

Open animation and spatial asset API

Search the public motion, VFX, terrain, procedural-object, and image-to-3D index by stable ID. Agents can inspect source and license metadata, download portable JSON recipes, fetch OBJ meshes, build deterministic terrain, or prepare an image reconstruction job without parsing the web gallery.

basehttps://app.nz
Search and download parameters
qstringSubstring matched against stable id, name, description, and tags.
kindenumpose, motion, vfx, terrain, object, or image3d.
formatenumjson for every asset; obj for terrain, object, and image3d.
target_polycountintegerRequested reconstruction budget, clamped to 500,000.
Agent search → inspect → download
# Find downloadable image-to-3D assets
curl -s 'https://app.nz/api/animation-library?q=product&kind=image3d&limit=10' | jq

# Download portable geometry
curl -L 'https://app.nz/api/animation-library/image3d-sneaker/download?format=obj' -o sneaker.obj

# Equivalent CLI flow
app animation search product --kind image3d
app animation download image3d-sneaker --format obj --output sneaker.obj

# MCP tools: search_animation_library, download_animation_asset,
# create_image_to_3d_recipe, generate_terrain_recipe

First-party products

RA1 art generation, paper search, and agentic search are first-party APIs metered against the same balance. Plan subscribers get a monthly free quota per product, consumed before any credits are charged. All three accept a Bearer key or a signed-in session.

basehttps://app.nz
Call the products from the CLI
app chat "research R2-backed model hosting" --web --deep --papers
app ra1 generate --prompt "a cat astronaut" --count 2
app papers search "diffusion transformers" --limit 5
app search "best vector database 2026" --depth 2

Conventions

  • • Auth: Authorization: Bearer pk_live_... on every non-public route.
  • • Bodies and responses are JSON; successful writes return { "success": true, ... }.
  • • Errors return a non-2xx status with { "error": "message" }.
  • • Get a key with the CLI: app keys create --name "deploy bot".