# For agents

> Exactly which files to fetch to use this SDK, in what order, and what each one costs you in context.

{/*
  The width ladder below is IMPORTED, not typed. `TRANSFORM_WIDTHS` is the only
  place it exists; a page that repeats it by hand is a page that goes stale in
  silence — which is exactly what happened on 2026-08-30, for four hours, with
  its guard green. See `docs/PLAN_DERIVAR_NO_TRANSCRIBIR.md`.
*/}
import { TRANSFORM_WIDTHS } from "@nitida/asset-client";

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

```bash
# 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.txt
```

Step 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

| URL | size | what it is |
|---|---|---|
| [`/llms.txt`](/llms.txt) | ~700 B | the index. Start here if you are deciding what to read |
| [`/agents/skill.md`](/agents/skill.md) | ~22 kB | **the consumer guide.** Setup, URL building, uploads, the failure modes and what each symptom actually means |
| [`/agents/sdk.md`](/agents/sdk.md) | ~3 kB | `@nitida/sdk` in brief — the four things that bite, if you only read one screen |
| [`/agents/asset-client.md`](/agents/asset-client.md) | ~1.5 kB | `@nitida/asset-client` — URL building only. No network, no key |
| [`/agents/index.json`](/agents/index.json) | small | machine-readable index of this table |
| [`/llms-small.txt`](/llms-small.txt) | ~300 kB | the site with non-essential prose removed |
| [`/llms-full.txt`](/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`](/guides/video-and-hls.md),
[`/start/quickstart.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

```
node_modules/@nitida/sdk/AGENTS.md
node_modules/@nitida/sdk/skills/nitida-sdk/SKILL.md
node_modules/@nitida/asset-client/AGENTS.md
```

Reading 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

Fetch `skill.md` for the full list with measurements. These are the ones that
produce a confident wrong answer rather than an error:

1. **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 error` with every earlier step green.
2. **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 answers `410` when that video has no poster.
3. **Video finalizes asynchronously.** The call returns
   `{ assetId, status: "processing" }` and a job flips it to `ready` 1–2 min
   later. Filter on `status === "ready"` and budget a real timeout.
4. **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 — but
   `getAssetUrl(asset,"md")` will **404** while `/t/…width=1280` serves fine.
   One API denies what the other delivers. Fix with `regenerate({presets})`.
5. **Transform widths are a fixed ladder** — {TRANSFORM_WIDTHS.length} of them:
   {TRANSFORM_WIDTHS.join(" · ")}. Anything off it is `400` at the edge,
   deliberately. Import the `TransformWidth` type and it becomes a compile
   error instead.

## 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".