API reference
Batata exposes a small REST API for everything the web app does. There are also Pinboard-compatible endpoints so existing Pinboard clients work out-of-the-box.
Authentication
The API supports two auth modes:
1. Personal Access Tokens (PATs)
Generate a PAT in Settings → API Tokens. Then pass it as a query parameter — same convention Pinboard uses:
curl 'https://batata.page/api/v1/posts/recent?auth_token=YOUR_TOKEN'
2. Session cookie (for browser-based scripts)
If you're signed in to batata.page, your session cookie works automatically. This is what the web app, Chrome extension, and bookmarklet use.
Base URL
https://batata.page/api
Bookmarks
POST /bookmarks
Create a bookmark. Triggers inline archive + embed + enrich.
POST /bookmarks
content-type: application/json
{
"url": "https://example.com",
"title": "Optional title",
"description": "Optional notes",
"tags": ["tag1", "tag2"],
"is_private": true
}Returns 201 with the created bookmark. 409 if you've already saved this URL. 403if you're a free user at the 100-bookmark cap.
GET /bookmarks
List the current user's bookmarks. Newest first.
GET /bookmarks?limit=50&offset=0&tag=startups&q=negotiation
limit(1-200, default 50) — page sizeoffset— pagination offsettag(optional) — filter to a specific tagq(optional) — full-text search on title + description + URL
GET /bookmarks/{id}/archive
Get the archived text + signed URL to the full HTML snapshot (if R2 is configured).
DELETE /bookmarks/{id}
Delete a bookmark. Returns 204.
Search
GET /search
Hybrid search: combines BM25 keyword scoring with pgvector cosine similarity using Reciprocal Rank Fusion.
GET /search?q=negotiation&mode=hybrid
mode—hybrid(default),keyword, orsemantic
Ask
POST /ask
RAG: embeds the question, retrieves top chunks, synthesizes a grounded answer with citations.
POST /ask
content-type: application/json
{ "question": "What have I saved about productivity?" }Returns the answer text and an array of cited sources (only sources actually referenced).
Tags
GET /tags
List all tags with usage counts, sorted by frequency.
Import
POST /import/pinboard
Upload a Pinboard JSON export as multipart form data with field name file. Free-tier accounts cap at 100 bookmarks; over-cap imports return limit_reached: true in the response.
Pinboard compatibility
Existing Pinboard clients (Pinner, Pushpin, etc.) work by pointing them at https://batata.page/api with a Batata PAT in place of the Pinboard token.
GET /v1/posts/all— all bookmarks, Pinboard JSON formatGET /v1/posts/recent— most recent bookmarks (default count=15)
Both support ?tag= filtering and the standard ?auth_token= query auth.
Rate limits
Errors
401— not authenticated403— free tier limit reached (on save)404— resource not found409— duplicate URL429— rate limited