API reference

The Keep API lets you save items, search them, retrieve structured content plus rendered markdown, manage sources, and inspect account usage. All responses are JSON unless noted otherwise.

Base URL

https://keep.md/api

Authentication

All requests require a Bearer token in the Authorization header. You can create a personal API key from your settings.

curl https://keep.md/api/me \
  -H "Authorization: Bearer $KEEP_API_KEY"

Rate limits

Free accounts have a lifetime cap of 50 saved items. Paid plans reset each billing cycle. When your limit is reached, write requests return 429 with error: "quota_reached". Read requests are never limited.

Errors

Errors return a JSON object with an error field and an appropriate HTTP status code.

// 401 -- missing or invalid token
{ "error": "unauthorized" }

// 429 -- plan limit reached
{ "error": "quota_reached", "plan": "free", "linkLimit": 50, "linkCount": 50 }

// 404 -- item not found
{ "error": "not_found" }

GET /api/me

Returns your plan, limits, and usage counts.

curl https://keep.md/api/me \
  -H "Authorization: Bearer $KEEP_API_KEY"
{
  "plan": "plus",
  "linkLimit": 500,
  "linkCount": 42,
  "linkCountMonth": 12,
  "linkCountPeriod": 12,
  "linkCountLifetime": 87
}

GET /api/stats

Usage statistics for a date range.

since -- start of range (timestamp, ISO date, or relative like 7d, 24h). until -- end of range (optional).

curl "https://keep.md/api/stats?since=7d" \
  -H "Authorization: Bearer $KEEP_API_KEY"
{
  "total": 12,
  "byStatus": { "stashed": 10, "flagged": 2 },
  "range": { "since": "...", "until": "...", "count": 12 }
}

GET /api/items

List your saved items. Archived items are excluded by default.

since / until -- filter by time. status -- comma-separated filter (for example stashed,flagged). tags -- comma-separated tag names or slugs. collection -- collection id, name, or slug. include=content -- include structured content plus rendered markdown. limit -- 1-1000, default 200. offset -- pagination offset.

curl "https://keep.md/api/items?collection=x-articles&tags=agent-tooling&limit=10&include=content" \
  -H "Authorization: Bearer $KEEP_API_KEY"
{
  "items": [
    {
      "id": "a1b2c3",
      "url": "https://example.com/article",
      "title": "Example Article",
      "status": "stashed",
      "collectionName": "X Articles",
      "collectionSlug": "x-articles",
      "tagSlugs": ["agent-tooling"],
      "createdAt": 1709251200,
      "contentAvailable": true,
      "contentMarkdown": "---\ntitle: \"Example Article\"\n---\n\nThe full extracted markdown...",
      "content": {
        "schemaVersion": 2,
        "meta": {
          "frontmatter": {
            "title": "Example Article",
            "source": "https://example.com/article",
            "content_type": "article"
          }
        },
        "items": {
          "content": {
            "format": "markdown",
            "markdown": "The full extracted markdown...\n"
          }
        }
      }
    }
  ],
  "limit": 10,
  "offset": 0,
  "count": 1
}

Search your saved items by title, URL, notes, tags, and semantic similarity.

q is required. Supports the same since, until, status, tags, collection, include=content, limit, and offset params as /api/items.

curl "https://keep.md/api/items/search?q=react%20hooks&collection=x-articles&tags=agent-tooling&limit=10" \
  -H "Authorization: Bearer $KEEP_API_KEY"

GET /api/items/:id

Get a single item by ID. This returns both the structured content object and the rendered markdown when content is available.

curl https://keep.md/api/items/a1b2c3 \
  -H "Authorization: Bearer $KEEP_API_KEY"

POST /api/items/:id

Update item metadata or state.

Supports title, notes, tags, collectionId, collectionIds, archived, and processed. Collection inputs accept ids, names, or slugs.

curl -X POST https://keep.md/api/items/a1b2c3 \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Better title", "tags": ["AI Research"], "collectionIds": ["x-articles"], "processed": true }'
{
  "id": "a1b2c3",
  "title": "Better title",
  "tags": ["AI Research"],
  "tagSlugs": ["ai-research"],
  "collectionName": "X Articles",
  "collectionSlug": "x-articles",
  "processedAt": 1709251200
}

GET /api/tags

List the distinct tags currently used by your non-archived items. Each tag includes its display name and slug.

curl "https://keep.md/api/tags" \
  -H "Authorization: Bearer $KEEP_API_KEY"
{
  "tags": [
    { "name": "X Articles", "slug": "x-articles" },
    { "name": "Agent Tooling", "slug": "agent-tooling" }
  ]
}

GET /api/collections

List your collections. Each collection includes an id, display name, and slug.

curl "https://keep.md/api/collections" \
  -H "Authorization: Bearer $KEEP_API_KEY"

POST /api/collections

Create a collection by name. If it already exists, the existing one is returned.

curl -X POST "https://keep.md/api/collections" \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "X Articles" }'

GET /api/items/:id/content

Returns the rendered markdown as plain text. Response headers include x-content-size and x-content-truncated.

curl https://keep.md/api/items/a1b2c3/content \
  -H "Authorization: Bearer $KEEP_API_KEY"

POST /api/ingest

Save a URL. Keep fetches the page, normalizes it into structured content, and renders markdown from that contract. Duplicate URLs are deduplicated automatically.

curl -X POST https://keep.md/api/ingest \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/article" }'
{
  "ok": true,
  "id": "a1b2c3",
  "url": "https://example.com/article",
  "extracted": true
}

POST /api/items/archive

Archive items by ID. Archived items are hidden from the default list.

curl -X POST https://keep.md/api/items/archive \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ids": ["a1b2c3"] }'
{ "archived": 1 }

POST /api/items/delete

Permanently delete items by ID.

curl -X POST https://keep.md/api/items/delete \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ids": ["a1b2c3"] }'
{ "deleted": 1 }

GET /api/feed

Returns unprocessed items with structured content plus rendered markdown. Designed for AI agents that consume your saved items as context. Supports the same since, until, q, tags, collection, limit, and offset params as /api/items/search.

curl "https://keep.md/api/feed?limit=5" \
  -H "Authorization: Bearer $KEEP_API_KEY"

POST /api/items/mark-processed

Mark items as processed so they no longer appear in the feed.

curl -X POST https://keep.md/api/items/mark-processed \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ids": ["a1b2c3", "d4e5f6"] }'
{ "processed": 2 }

GET /api/sources

List your sources and subscriptions.

curl https://keep.md/api/sources \
  -H "Authorization: Bearer $KEEP_API_KEY"

POST /api/sources

Create an RSS, YouTube, X articles, or email inbox source.

curl -X POST https://keep.md/api/sources \
  -H "Authorization: Bearer $KEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "rss", "feedUrl": "https://example.com/feed.xml" }'

POST /api/sources/:id/delete

Remove a source.

curl -X POST https://keep.md/api/sources/src_123/delete \
  -H "Authorization: Bearer $KEEP_API_KEY"

openapi.json