The card format, version 1
A Caute library on disk: what an export from Caute contains, described so that other tools can read it and rely on it. A card is the original as it was caught, the text read from it, and everything the person added: notes, highlights, tags, links and versions. Anyone can export their whole library from Caute's settings, at any time, on any plan.
The JSON Schemas linked from each section are part of this specification.
Versions
manifest.json names the version in export_format.
- Additive changes keep the number. A new file, a new field in an object, or a new value for a field that lists its known values (a kind, a source, a status) is still version 1. A reader must ignore fields it doesn't know and treat values it doesn't know as "other".
- Anything else is version 2: a field renamed, removed, or given a different type or meaning, or a file moved. When that happens, version 1 can still be asked for.
Layout
An export is one zip of what one person could read in one workspace when it was made.
README.md a short guide for the person
manifest.json the format version, counts, and the spaces included
items/<id>/item.json one saved thing that isn't a note
items/<id>/original.<ext> that thing's original, exactly as it was caught
notes/<slug>.md each note, as Markdown with properties
highlights.md every marked passage, grouped under the card it's in
highlights.json the same, with positions
tags.json each tag, with the cards and notes it is on
links.json connections between things in the export
saved_searches.json the person's saved searches
questions.json questions the person asked Caute, with answers
The folder opens as an Obsidian vault, or in any Markdown editor: links in notes point at files in the export.
Ids and dates
- Ids are UUIDs in lowercase (
0190f3a2-7c1d-7e4b-9a10-3f2e1d0c9b8a). A card's id is permanent: the card's link ishttps://app.getcaute.com/c/<id>. - Dates are a date and time with an offset, with a space between the date and the time:
2026-10-14 03:04:05.123456+00:00. Fractional seconds are left out when they are zero. RFC 3339 allows the space; parse with a reader that accepts it, or replace the space withT. - Text is UTF-8.
manifest.json
Schema. export_format, created_at, the workspace (id, name, kind),
requested_by (the person's email address), spaces (the names of the spaces included) and counts of each kind
of file.
items/<id>/item.json
Schema. One per saved thing that isn't a note: web pages, documents, pictures, recordings, emails, text shared in, agent conversations and archives.
| Field | What it holds |
|---|---|
id |
The card's id. |
kind |
web_page, document, image, audio, video, email, text, agent_conversation or archive. |
title |
Its title, or null. |
source |
How it was caught: ios_share, extension, email, mcp, api, web_upload, folder_watch, import or feed. |
url |
The address it was saved from, after redirects, or null. |
filename |
The file's name as it was caught, or null. |
captured_at |
When it was caught. |
space |
The name of its space. |
mime_type, byte_size |
The original's type and size, or null. |
status |
captured, processing, searchable, failed or quarantined. |
superseded_by |
When a newer version replaced it, the newer one's id; otherwise null. Every version is in the export. |
summary |
The summary Caute wrote, or null. |
text |
The text read from the original, or the person's correction of it, or null. Blocks are separated by a blank line; headings, quotes, list items and fenced code are marked as in Markdown. |
reading_state |
The person's reading queue: later, archived or none; null if it was never in the queue. |
properties |
Its properties, by name (servings, doi, due): text, a number, a date such as 2026-10-15, a web address, or a list of text. Only the ones the person confirmed. Exports made before properties existed have no such field. |
tags |
Its tags, by path (projects/atlas): the ones confirmed that the person who made it can see, as tags.json lists them. Exports made before tags were here have no such field. |
capture |
The record of its catch: sha256 (the original's bytes as caught, in hex), byte_size, via (sent, fetched, uploaded, attachment, archive or copied), source, caught_at (when it was really caught), requested_url, arrived_url and http_status for a page Caute's server fetched, and recorded_later with recorded_at for things caught before records were kept. caute verify checks original.<ext> against it. Absent when there is no original, and from exports made before records existed. |
items/<id>/original.<ext>
The original, byte for byte. A web page is the page as it was archived. The extension comes from the file's name when it had one, or from its type. A thing Caute holds no original for has no such file.
notes/<slug>.md
Each note, named from its title and the start of its id (Reading-list-0190f3a2.md). Highlights with nothing
written about them are in highlights.* instead.
A note starts with its properties (schema) between --- lines, one per
line as key: value. Each value is written as JSON, which YAML reads too. A property with no value is left out.
| Property | What it holds |
|---|---|
id |
The note's id. |
title |
Its title, taken from its first line. |
created, updated |
When it was written, and last changed. |
space |
The name of its space. |
tags |
Its tag paths. |
pinned |
true when it is pinned. |
annotates |
The id of the card it is written on, when that card is in the export. |
The body is the note's Markdown. Links to cards ([words](card:<id>) inside Caute) are rewritten to paths in the
export: to another note's file, to a card's item.json, or for an embedded picture () to the card's
original. A link to something not in the export keeps its words and loses its target.
highlights.json and highlights.md
Schema. Each marked passage: its id, the card it is in (item_id,
item_title), the words it marks (quote), where (anchor: char_start and char_end count code points into the
card's text, and an anchor may hold more, such as a page or a time) and created_at. highlights.md is the same,
readable: each card's passages as quotes under its title.
tags.json
Schema. Each tag the person could see that is confirmed on something in the export:
its path (lowercase, /-separated, so clients/acme/contracts is under clients) and the ids of the items it is
on, notes included. Suggested and dismissed tags are left out.
links.json
Schema. Each connection whose two ends are both in the export: from_item, to_item,
its kind (attachment, inline, thread, forwarded_original, annotates, related, manual, mentions,
embeds or supersedes), its origin (system, user or agent), its label and created_at.
saved_searches.json
Schema. Each saved search: name, query, filters (as POST /v1/search
takes them), pinned and created_at.
questions.json
Schema. Each question asked of Caute: question, asked_at, the answer with only
the sentences whose sources are in the export, cites (the ids of the cards it cites, in the order its numbers refer
to) and the note_id it was saved as, if it was.
What it leaves out, and why
- Embeddings, chunks and other index data. They are derived from the text, tied to one model's version, and rebuilt from the text by whatever reads the export.
- Every text read from a card.
textis one of them: the person's own correction if there is one, else a transcript, else text read by OCR, else the text extracted from the file (or a picture's caption). - Suggested and dismissed tags, and dismissed link suggestions. They were never the person's decision.
- Anything the person couldn't read when the export was made, including cards in spaces they aren't in, and other people's personal tags.
- Credentials, sessions, tokens and email addresses. They open the account and don't belong in a file.