API Documentation

v1

Build integrations with the ClipJot REST API.

Overview

The ClipJot API provides programmatic access to your bookmarks. All endpoints use POST method and accept/return JSON.

Base URL

https://clipjot.net/api/v1

Request Format

All requests must include:

  • Content-Type: application/json header
  • Authorization: Bearer <token> header (except public endpoints)
  • JSON request body

Authentication

Most API endpoints require authentication via Bearer token. Tokens can be obtained through OAuth login or by creating an API token in Settings.

Token Types

  • Session tokens - Created during OAuth login, used by web UI and mobile apps
  • API tokens - Created in Settings > API Tokens, for scripts and integrations

Token Scopes

  • read - Can read bookmarks and tags
  • write - Can read, create, update, and delete bookmarks and tags

Example Request

curl -X POST https://your-domain.com/api/v1/bookmarks/list \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
POST/api/v1/user/profile

Get current user profile

Returns the authenticated user's profile information including email, account type, and creation date.

Scope: read

Response

Field Type Description
email string User's email address
is_premium boolean Whether user has premium account
created_at string ISO 8601 timestamp of account creation
curl -X POST https://your-domain.com/api/v1/user/profile \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
POST/api/v1/auth/invite

Authenticate with invite code

Exchange an invite code for a session token. This is a public endpoint that does not require authentication.

Public endpoint

Request Body

Field Type Description
code * string 8-character invite code (uppercase alphanumeric)

Response

Field Type Description
token string Session token for API authentication
user object User object with id and email
curl -X POST https://your-domain.com/api/v1/auth/invite \
  -H "Content-Type: application/json" \
  -d '{"code": "ABC12345"}'
POST/api/v1/logout

Logout and revoke session

Revokes the current session token, logging out the user.

Scope: read

Response

Field Type Description
logged_out boolean Always true on success
message string Confirmation message
curl -X POST https://your-domain.com/api/v1/logout \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Bookmarks

POST/api/v1/bookmarks/add

Create a new bookmark

Add a new bookmark with optional title, comment, and tags. Tags are created automatically if they don't exist.

Scope: write

Request Body

Field Type Description
url * string The URL to bookmark
title string Display title (optional)
comment string Personal note or comment (optional)
tags array List of tag names (optional)

Response

Field Type Description
id integer Unique bookmark ID
url string The bookmarked URL
title string Display title
comment string Personal note
tags array List of tag objects
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp
curl -X POST https://your-domain.com/api/v1/bookmarks/add \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/article",
    "title": "Interesting Article",
    "comment": "Read this later",
    "tags": ["reading", "tech"]
  }'
POST/api/v1/bookmarks/edit

Update an existing bookmark

Update the title, comment, or tags of an existing bookmark. Only provided fields are updated.

Scope: write

Request Body

Field Type Description
id * integer Bookmark ID to update
title string New title (optional)
comment string New comment (optional)
tags array New tag list (replaces existing tags)

Response

Field Type Description
id integer Bookmark ID
url string The bookmarked URL
title string Updated title
comment string Updated comment
tags array Updated tag list
updated_at string ISO 8601 timestamp
curl -X POST https://your-domain.com/api/v1/bookmarks/edit \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 123,
    "title": "Updated Title",
    "tags": ["important", "work"]
  }'
POST/api/v1/bookmarks/delete

Delete a bookmark

Permanently delete a bookmark by ID.

Scope: write

Request Body

Field Type Description
id * integer Bookmark ID to delete

Response

Field Type Description
deleted boolean Always true on success
curl -X POST https://your-domain.com/api/v1/bookmarks/delete \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": 123}'
POST/api/v1/bookmarks/list

List all bookmarks

Get all bookmarks with cursor-based pagination. Use for full sync or bulk operations.

Scope: read

Request Body

Field Type Description
cursor string Pagination cursor from previous response
limit integer Max results (default: 100, max: 500)

Response

Field Type Description
bookmarks array List of bookmark objects
has_more boolean Whether more results exist
next_cursor string Cursor for next page (if has_more is true)
curl -X POST https://your-domain.com/api/v1/bookmarks/list \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"limit": 100}'
POST/api/v1/bookmarks/sync

Incremental sync with long polling

Get new bookmarks since a cursor position. Supports long polling to wait for changes.

Scope: read

Request Body

Field Type Description
cursor integer Last seen bookmark ID (0 for initial sync)
limit integer Max results (default: 50, max: 100)
wait boolean Enable long polling (wait up to 30s for new data)

Response

Field Type Description
bookmarks array New bookmarks since cursor
cursor integer New cursor position
has_more boolean Whether more results exist
waited boolean Whether request waited (long polling)
# Initial sync
curl -X POST https://your-domain.com/api/v1/bookmarks/sync \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cursor": 0}'

# Long polling for changes
curl -X POST https://your-domain.com/api/v1/bookmarks/sync \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cursor": 123, "wait": true}'

Tags

POST/api/v1/tags/list

List all tags

Get all tags for the current user with bookmark counts.

Scope: read

Response

Field Type Description
tags array List of tag objects with id, name, and bookmark_count
curl -X POST https://your-domain.com/api/v1/tags/list \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
POST/api/v1/tags/create

Create a new tag

Create a new tag. Returns error if tag name already exists.

Scope: write

Request Body

Field Type Description
name * string Tag name

Response

Field Type Description
id integer Tag ID
name string Tag name
created_at string ISO 8601 timestamp
curl -X POST https://your-domain.com/api/v1/tags/create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "recipes"}'
POST/api/v1/tags/update

Rename a tag

Update the name of an existing tag.

Scope: write

Request Body

Field Type Description
id * integer Tag ID to update
name * string New tag name

Response

Field Type Description
id integer Tag ID
name string Updated tag name
curl -X POST https://your-domain.com/api/v1/tags/update \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": 5, "name": "cooking"}'
POST/api/v1/tags/delete

Delete a tag

Delete a tag. The tag is removed from all bookmarks but bookmarks are not deleted.

Scope: write

Request Body

Field Type Description
id * integer Tag ID to delete

Response

Field Type Description
deleted boolean Always true on success
curl -X POST https://your-domain.com/api/v1/tags/delete \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": 5}'

Import & Export

POST/api/v1/export

Export all bookmarks

Export all bookmarks as JSON. Includes tags for each bookmark.

Scope: read

Response

Field Type Description
bookmarks array All bookmarks with tags
exported_at string ISO 8601 timestamp
count integer Total bookmark count
curl -X POST https://your-domain.com/api/v1/export \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' > bookmarks.json
POST/api/v1/import

Import bookmarks

Import bookmarks from JSON. Supports merge (skip duplicates) or replace mode.

Scope: write

Request Body

Field Type Description
bookmarks * array Array of bookmark objects to import
mode string 'merge' (default) or 'replace'

Response

Field Type Description
imported integer Number of bookmarks imported
skipped integer Number of duplicates skipped
errors array List of import errors
curl -X POST https://your-domain.com/api/v1/import \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bookmarks": [
      {"url": "https://example.com", "title": "Example", "tags": ["test"]}
    ],
    "mode": "merge"
  }'

Errors

When an error occurs, the API returns a JSON object with error details:

{"error": "Human-readable message", "code": "ERROR_CODE"}
Code HTTP Status Description
INVALID_TOKEN 401 The provided token is invalid, expired, or missing.
PERMISSION_DENIED 403 The token does not have the required scope for this operation.
VALIDATION_ERROR 400 The request body is missing required fields or contains invalid data.
NOT_FOUND 404 The requested resource (bookmark, tag, etc.) was not found.
RATE_LIMITED 429 Too many requests. Check the Retry-After header.
LIMIT_EXCEEDED 403 Account limit reached (e.g., max bookmarks for free tier).

Rate Limits

The API is rate limited to 100 requests per 60 seconds per token.

When rate limited, the API returns a 429 status code. Check the Retry-After header for how long to wait.

Rate Limit Headers

  • X-RateLimit-Limit - Maximum requests per window
  • X-RateLimit-Remaining - Requests remaining in current window
  • X-RateLimit-Reset - Unix timestamp when the window resets
  • Retry-After - Seconds to wait (only on 429 response)