Personal link database with hybrid search. Save links, search later.
All endpoints require a Bearer token in the Authorization header.
Authorization: Bearer YOUR_API_TOKEN
Generate a token at links.rip/users/settings
and store it in the LINKS_RIP_TOKEN environment variable.
export LINKS_RIP_TOKEN="your-token-here" curl -H "Authorization: Bearer $LINKS_RIP_TOKEN" https://links.rip/api/entries/search?q=example
List entries, newest first. 25 per batch.
GET /api/entries GET /api/entries?cursor=OPAQUE_CURSOR GET /api/entries?days=7 GET /api/entries?tag_ids[]=1&tag_ids[]=2 GET /api/entries?stack_id=5 GET /api/entries?feed_id=3
The cursor is opaque. Pass the next_cursor value from the
previous response back unchanged to fetch the next batch.
Response (200):
{
"has_more": true,
"next_cursor": "eyJ2IjoxLCJzb3J0IjoiaW5zZXJ0ZWRfYXQiLCJ0cyI6IjIwMjYtMDMtMjhUMTI6MzQ6NTZaIiwiaWQiOjEyM30",
"entries": [ ... ]
}
Hybrid search across your saved entries. Combines full-text search with semantic vector similarity, ranked by reciprocal rank fusion. Falls back to full-text only if the embedding service is unavailable.
GET /api/entries/search?q=elixir+genserver
Response (200):
{
"query": "elixir genserver",
"count": 3,
"entries": [ ... ]
}
Errors:
400 - missing/empty q or query exceeds 1000 bytesGet a single entry by ID.
GET /api/entries/42
Response (200):
{
"id": 42,
"type": "link",
"content": "https://example.com",
"summary": "...",
"tags": ["programming"],
"processing_state": "complete",
"url": {
"url": "https://example.com",
"title": "Example",
"authority": "example.com"
},
"created_at": "2026-03-27T12:00:00Z"
}
Errors:
404 - entry not found or belongs to another userSave a link or note.
POST /api/entries
Content-Type: application/json
{ "url": "https://example.com" }
-- or --
{ "content": "some note text" }
Response (201):
{
"id": 42,
"content": "https://example.com",
"type": "link",
"created_at": "2026-03-27T12:00:00Z"
}
Errors:
422 - missing content, validation error, or duplicate"link" (has a URL) or "note" (plain text).processing_state field tracks progress: new → processing_url → classifying → generating_embedding → complete (or error).url field is null for notes.links.rip