For agents
If you are a coding agent, this page is the whole onboarding. Fetch the files
below instead of crawling the site — they are the same files the SDK ships in
node_modules, so they never disagree with the installed version.
The three-step version
Section titled “The three-step version”# 1. What exists, and where. ~700 B.curl https://nitida.gofuture.space/llms.txt
# 2. The consumer guide — every gotcha that bit a real migration. ~22 kB.curl https://nitida.gofuture.space/agents/skill.md
# 3. Only if you need the exact signature of something. ~340 kB, generated from the types.curl https://nitida.gofuture.space/llms-full.txtStep 2 is the one that matters. It is not an overview — it is the accumulated list of things that are surprising, each with the measurement that made it worth writing down.
Every fetchable file
Section titled “Every fetchable file”| URL | size | what it is |
|---|---|---|
/llms.txt |
~700 B | the index. Start here if you are deciding what to read |
/agents/skill.md |
~22 kB | the consumer guide. Setup, URL building, uploads, the failure modes and what each symptom actually means |
/agents/sdk.md |
~3 kB | @nitida/sdk in brief — the four things that bite, if you only read one screen |
/agents/asset-client.md |
~1.5 kB | @nitida/asset-client — URL building only. No network, no key |
/agents/index.json |
small | machine-readable index of this table |
/llms-small.txt |
~300 kB | the site with non-essential prose removed |
/llms-full.txt |
~340 kB | the whole site, including the generated API reference |
Any page on this site is also available as raw Markdown by appending .md:
/guides/video-and-hls.md,
/start/quickstart.md. Every page has a Copy page
button that does the same thing to your clipboard.
If you installed the package, you already have these
Section titled “If you installed the package, you already have these”node_modules/@nitida/sdk/AGENTS.mdnode_modules/@nitida/sdk/skills/nitida-sdk/SKILL.mdnode_modules/@nitida/asset-client/AGENTS.mdReading them from disk is better than fetching: it is the version you are actually calling. The URLs above exist for the case where you are deciding whether to install.
The five things that cost people the most time
Section titled “The five things that cost people the most time”Fetch skill.md for the full list with measurements. These are the ones that
produce a confident wrong answer rather than an error:
- The browser PUTs straight to object storage, so the bucket’s CORS
policy answers that preflight — not your app’s, not any tenant setting.
Symptom:
network errorwith every earlier step green. - A video is served from a stored variant, never from
/t/. A transform URL on a stored video never returns video: it transforms the poster frame (200 image/webp), or answers410when that video has no poster. - Video finalizes asynchronously. The call returns
{ assetId, status: "processing" }and a job flips it toready1–2 min later. Filter onstatus === "ready"and budget a real timeout. - Ask for the presets you need at the first ingest. A variant you skip is
not lost — cleanup keeps
raw/for any sha with an asset row, verified on a 2-month-old thumb-only asset — butgetAssetUrl(asset,"md")will 404 while/t/…width=1280serves fine. One API denies what the other delivers. Fix withregenerate({presets}). - Transform widths are a fixed ladder — 21 of them:
96 · 128 · 160 · 180 · 240 · 256 · 320 · 400 · 480 · 600 · 640 · 800 · 960 · 1080 · 1200 · 1280 · 1440 · 1600 · 1920 · 2560 · 3840. Anything off it is
400at the edge, deliberately. Import theTransformWidthtype and it becomes a compile error instead.
Do not trust a green upload
Section titled “Do not trust a green upload”The single most expensive habit when testing this SDK: a retried upload takes the dedup branch. Presign short-circuits on bytes it has already seen, so the second run skips the code you are trying to exercise and reports success.
If you are verifying upload behaviour, generate genuinely unique bytes each run. This is how a bug that made no video ever register stayed invisible for weeks — every retry “worked”.