Assistants and API

API reference

Search, read, and add to your Savepad from your own scripts, Zapier, or anything that can make a web request. Every endpoint, with an example you can copy.

Savepad has a small, boring, reliable API. It’s the same one the assistant connection uses underneath, and it’s on every plan. You don’t pay extra for it, and there’s no separate account.

If you want an assistant like Claude or ChatGPT to use your Savepad, you don’t need any of this. Follow Connect an assistant instead. This page is for when you’re writing your own thing.

Get a token

  1. In Savepad, go to Settings, then API and assistants.
  2. Open For developers and fill in Make a token. Name it after what will use it (“Zapier”, “my Raycast script”).
  3. Tick what it’s allowed to do (see Permissions).
  4. Press Make the token and copy it. You only see it once.

Every request sends it as a header:

Terminal
curl https://my.savepad.app/api/v1/me \
  -H "Authorization: Bearer sp_…"

The base address for everything below is https://my.savepad.app/api/v1. Requests and responses are JSON.

Permissions

PermissionLets a token
items:readSearch and read saves, folders, and tags
items:writeSave new links and notes, and edit titles, notes, and favourites
organiseFile saves into folders and tag them
manageFull control: everything above (the extra Full control actions are in the MCP tools for now)

A request that needs a permission the token doesn’t have gets a 403.

Who am I

GET /me tells you whose token it is and what it can do.

Terminal
curl https://my.savepad.app/api/v1/me -H "Authorization: Bearer sp_…"
JSON
{ "username": "anya", "name": "Anya G.", "scopes": ["items:read", "items:write"] }

Search or list saves

GET /saves lists your newest saves. Add q to search titles, notes, and the full text of saved pages, PDFs, emails, and code, best match first.

ParameterWhat it does
qWords to look for
typeOnly these types, comma-separated: link, image, pdf, email, code, note, video, place, and the rest
folderOnly this folder (and its subfolders), by id
tagOnly saves with this tag, by id
unsortedtrue for saves that aren’t in a folder yet
limitHow many, 1 to 100. Default 30
offsetSkip this many, for the next page
Terminal
curl "https://my.savepad.app/api/v1/saves?q=pricing%20toggle&type=link&limit=5" \
  -H "Authorization: Bearer sp_…"
JSON
{
  "saves": [
    {
      "id": "0192…",
      "type": "link",
      "title": "Pricing that flips between monthly and yearly",
      "url": "https://example.com/pricing",
      "domain": "example.com",
      "note": "The toggle animation is the whole page",
      "folders": [{ "id": "0191…", "path": "Work / Landing pages / Pricing" }],
      "tags": [{ "id": "0190…", "name": "pricing" }],
      "favourite": false,
      "saved_at": "2026-09-30T09:12:44Z",
      "snippet": "monthly or <mark>pricing</mark> yearly <mark>toggle</mark>",
      "app_url": "https://my.savepad.app/saves/0192…"
    }
  ],
  "total": 1,
  "limit": 5,
  "offset": 0
}

Needs items:read.

One save

GET /saves/{id} returns a single save in the same shape.

Terminal
curl https://my.savepad.app/api/v1/saves/0192… -H "Authorization: Bearer sp_…"

Needs items:read. A save that isn’t yours, or is gone, is a 404.

Save something

POST /saves saves a link (send url) or a note (send text). It goes into Unsorted unless you give a folderId.

Terminal
curl https://my.savepad.app/api/v1/saves \
  -H "Authorization: Bearer sp_…" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/launch", "note": "Love the countdown", "folderId": "0191…" }'
FieldWhat it does
urlThe link to save. Or send text instead, for a note
titleOptional. Otherwise Savepad uses the page’s own
noteOptional. Why you saved it
folderIdOptional. Which folder it goes in
tagIdsOptional. Tags to add, by id

You get 201 with the new save. Saving a link you already have gives 200 with the existing save and "duplicate": true, so running the same script twice doesn’t make doubles. Over your plan’s limit is a 402.

Needs items:write.

Edit a save

PATCH /saves/{id} changes a save. Send only what you’re changing.

Terminal
curl -X PATCH https://my.savepad.app/api/v1/saves/0192… \
  -H "Authorization: Bearer sp_…" \
  -H "Content-Type: application/json" \
  -d '{ "favourite": true, "addTagIds": ["0190…"] }'
FieldNeeds
title, note, favouriteitems:write
addFolderIds, removeFolderIds, addTagIds, removeTagIdsorganise

Nothing here deletes anything.

Spaces, folders, and tags

GET /folders lists your spaces and folders, with each folder’s full path. GET /tags lists your tags. Use the ids from these in the calls above.

Terminal
curl https://my.savepad.app/api/v1/folders -H "Authorization: Bearer sp_…"

Both need items:read.

Limits and errors

Each token gets 120 requests a minute. Go over and you get a 429, so wait a minute and carry on.

Errors always look like this, with a sentence a person can read:

JSON
{ "error": "That token can't do this. It needs the organise permission." }
CodeWhat happened
400Something in the request is missing or malformed
401No token, or it was revoked or expired
402Over your plan’s limit
403The token is missing a permission
404Not yours, or gone
429Too many requests, wait a minute

For machines

If you’re plugging Savepad into a tool that reads OpenAPI (Postman, Insomnia, code generators, or an assistant), point it at the machine-readable version of this page: https://my.savepad.app/api/v1/openapi.json. There’s also an Agent skill that teaches assistants how to use Savepad well.