# Uploading documents

> How a paystub, W-2 or statement gets into Truenote from an agent or a script without the file passing through the model.

Canonical: https://usetruenote.com/docs/uploads

Documents (paystubs, W-2s, 1098s, last year's return, statements) are kept sealed at rest, their text extracted for agents with sensitive numbers masked, and tied to what they're about: a tax year, an income source, an account.

## From an agent

With `documents:write`, an agent calls `prepare_upload` with what the document is (name, kind, tax year, the income source or account it belongs to). Truenote answers with a one-time link, good for 15 minutes and one file. The agent either sends the file itself (`curl -F file=@paystub.pdf <link>`) or hands the link to the person, who drops the file on its page. The model never carries the bytes.

## From a script

```sh
curl https://app.usetruenote.com/v1/documents \
  -H "Authorization: Bearer tn_pat_…" \
  -F file=@paystub.pdf \
  -F 'metadata={"name":"Paystub Oct 16","kind":"paystub","taxYear":2026}'
```

PDF, PNG, JPEG and WebP, up to 10 MB. The real type is read from the bytes.

## What agents read back

`list_documents` (search by text, kind, year) and `read_document`: a PDF's text, masked, or an image as itself, with a hint about what it's good for. A paystub's year-to-date gross, 401(k) and federal withholding are offered as the tax inputs (`upsert_income_source`) after asking. `get_tax_projection` names the paystubs and forms behind its figures and warns when a newer paystub exists.
