Skip to main content
The library is the account’s private store: saved items, the standalone notes and highlights attached to them, reading history, and the original file bytes behind an upload. Three ideas carry the whole surface:

Items

A saved page, file, or supplied text. Addressed by a UUID.

Objects

Items, notes, and highlights under one search. Addressed by a stable ref.

Assets

The original bytes of an uploaded file, streamed back on demand.

Save something

POST /v1/library/items takes either a url for smry to fetch, or title plus content you supply yourself.
The response carries item, an extraction report, and alreadySaved. Saving the same url again returns the existing item with alreadySaved: true rather than creating a duplicate, which is what makes a retry after a timeout safe. externalId lets you carry your own identifier through — see Retries and idempotency.

Uploading a file

Two steps, in this order:
1

Admit the file

POST /v1/library/items with title and fileName — no bytes. Both are required; mimeType and format are optional. You get back an item id.
2

Send the bytes

PUT /v1/library/items/{id}/asset with the binary body, its Content-Type, and an X-Smry-File-Name header. The global ceiling is 100 MB, and audio gets all of it — but anything smry parses for text, a PDF or an EPUB included, is capped at 25 MB, so a 40 MB PDF is a 413. smry reads the extension from X-Smry-File-Name to pick the cap. Concurrent replacements of the same item are serialized, so a second write while one is in flight returns 409.
Read them back with GET /v1/library/items/{id}/asset, which streams the original with its stored MIME type and supports a single HTTP byte range — use it for audio, video, and large documents.

Find things

Two operations, two jobs.
Search everything
Each result carries a stable ref. Pass it to GET /v1/library/objects/{ref} to read the full object, whatever type it turned out to be. GET /v1/library/items filters on query, tag, status, starred, contentKind, captureMethod, format, externalId, savedAfter, and updatedAfter.
Reading history lives behind view=history. It is the only way to get it. GET /v1/library/items?view=history returns what the account has read, in reading order, rather than what it has saved.
savedAfter and updatedAfter are not interchangeable: savedAfter filters on when the item entered the library, updatedAfter on when it last changed. Use updatedAfter for polling, savedAfter for backfill.

Read one item

For anything long, don’t pull the whole body:
  • GET /v1/library/items/{id}/content returns a bounded window plus nextCursor, the same way article reading works.
  • POST /v1/library/items/{id}/search returns only the passages inside that one item that match a query, each with an anchor.
The second is almost always the right call inside an agent loop.

Change things

PATCH /v1/library/items/{id} moves, tags, stars, reclassifies, or marks an item read:
tags is a complete replacement, not a merge. Read the item’s current tags first if you mean to add one. PATCH /v1/library/items (no id) applies one set of changes to up to 100 ids at once, and reports back updated and missing. DELETE /v1/library/items/{id} removes the item. Uploaded file bytes are permanently deleted from synced storage; notes and highlights are kept.

Sync into your own store

GET /v1/library/changes is the incremental feed of every mutation and deletion. The first call is the part people get wrong:
1

Take a checkpoint first

GET /v1/library/changes?cursor=latest. Keep the nextCursor it returns.
2

Then list the current library

Page GET /v1/library/items to load the state as it is now.
3

Then poll from the checkpoint

Continue from the stored nextCursor. Anything that changed during step 2 arrives as a change event, so nothing is lost and nothing is duplicated.
Doing it in the other order — list first, then checkpoint — drops every write that lands in between.
Python
GET /v1/library/counts gives the totals by status and content kind without paging anything — useful for a progress bar or a sanity check after a sync.
Saved article text is still source material written by someone else. Treat it as data, not instructions — see Content safety.

Next

Cursors and paging

Library cursors are nextCursor; feed cursors are next_cursor. Don’t mix them.

Follow sources

Get new material into the library without asking for it.
Last modified on September 13, 2026