Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ephraimduncan/minimal.so/llms.txt

Use this file to discover all available pages before exploring further.

The main extension endpoint for saving bookmarks from the Chrome extension. Handles deduplication, source tracking, auto-grouping, and metadata fetching.

Endpoint

POST /api/extension/bookmark
Source: app/api/extension/bookmark/route.ts:135

Authentication

Requires a valid user session. The extension authenticates by including session cookies in the request.

CORS

This endpoint validates the request origin against configured extension IDs:
  • chrome-extension://<CHROME_EXTENSION_ID> (from env)
  • http://localhost:3000 (for development)
Requests from unauthorized origins will receive a 403 Forbidden response.

Request body

url
string
required
The URL to bookmark (must be a valid URL)
title
string
Optional title to use instead of auto-fetched title
source
enum
The source of the bookmark. One of:
  • manual_popup - Saved via extension popup
  • manual_context_menu - Saved via right-click menu
  • manual_shortcut - Saved via keyboard shortcut
  • x_bookmark - Auto-captured from X/Twitter
  • browser_bookmark - Auto-captured from browser bookmarks
destinationGroup
string
Optional group name override. If not provided, uses group based on source:
  • x_bookmark → “Imported - X”
  • browser_bookmark → “Imported - Browser”
  • All others → User’s default group (oldest group)
capturedAt
string
ISO 8601 timestamp of when the bookmark was captured (defaults to current time)

Response

success
boolean
Always true on successful save
action
enum
The action performed:
  • created - New bookmark created
  • updated - Existing bookmark updated (metadata refreshed)
  • reclassified - Existing bookmark moved to new group due to source priority
bookmark
object

Deduplication & reclassification

The endpoint uses normalized URLs for deduplication. If a bookmark with the same normalized URL already exists:
  1. Metadata is always updated (title and favicon refreshed)
  2. Reclassification occurs if:
    • New capture timestamp is more recent, OR
    • Same timestamp but higher source priority

Source priority (lowest to highest)

0: manual_popup
1: manual_context_menu  
2: manual_shortcut
3: x_bookmark
4: browser_bookmark
Manual saves have higher priority than auto-captures. This means manually saving a link will move it out of auto-import groups.

Source history

The endpoint tracks all sources that have captured a bookmark in the sourceHistory field. This allows you to see if a bookmark was both manually saved and auto-imported from X, for example.

Auto-grouping

If no destinationGroup is provided:
  • x_bookmark → Creates/uses “Imported - X” group
  • browser_bookmark → Creates/uses “Imported - Browser” group
  • All other sources → Uses user’s oldest (default) group
Import groups are created automatically with a gray color (#6b7280).

Example requests

Save from extension popup

curl -X POST https://minimal.so/api/extension/bookmark \
  -H "Content-Type: application/json" \
  -H "Origin: chrome-extension://your-extension-id" \
  --cookie "session=your-session-cookie" \
  -d '{
    "url": "https://github.com/ephraimduncan/minimal.so",
    "source": "manual_popup"
  }'

Save from context menu with custom title

curl -X POST https://minimal.so/api/extension/bookmark \
  -H "Content-Type: application/json" \
  -H "Origin: chrome-extension://your-extension-id" \
  --cookie "session=your-session-cookie" \
  -d '{
    "url": "https://example.com/article",
    "title": "My Custom Title",
    "source": "manual_context_menu"
  }'

Auto-capture from X

curl -X POST https://minimal.so/api/extension/bookmark \
  -H "Content-Type: application/json" \
  -H "Origin: chrome-extension://your-extension-id" \
  --cookie "session=your-session-cookie" \
  -d '{
    "url": "https://x.com/user/status/123456",
    "source": "x_bookmark",
    "capturedAt": "2024-01-15T10:30:00Z"
  }'

Example responses

Created new bookmark

{
  "success": true,
  "action": "created",
  "bookmark": {
    "id": "cm3x1y2z3...",
    "title": "Minimal - Simple Bookmarking",
    "url": "https://github.com/ephraimduncan/minimal.so",
    "groupName": "Bookmarks"
  }
}

Updated existing bookmark

{
  "success": true,
  "action": "updated",
  "bookmark": {
    "id": "cm3x1y2z3...",
    "title": "Updated Title from Metadata",
    "url": "https://github.com/ephraimduncan/minimal.so",
    "groupName": "Bookmarks"
  }
}

Reclassified to new group

{
  "success": true,
  "action": "reclassified",
  "bookmark": {
    "id": "cm3x1y2z3...",
    "title": "Minimal - Simple Bookmarking",
    "url": "https://github.com/ephraimduncan/minimal.so",
    "groupName": "Imported - X"
  }
}

Error responses

Unauthorized (401)

{
  "error": "Please log in to save bookmarks",
  "code": "Unauthorized"
}

Invalid URL (400)

{
  "error": "Invalid URL provided",
  "code": "Bad Request"
}

No group exists (400)

{
  "error": "No bookmark group found. Please create one first.",
  "code": "No Group"
}

Origin not allowed (403)

{
  "error": "Origin not allowed",
  "code": "Forbidden"
}

Build docs developers (and LLMs) love