Bookie REST API
Bookie exposes a REST API for programmatic access to your bookmarks and tags.
Base URL: https://bookie.edwardes.xyz
Authentication
All endpoints require authentication via an API key.
Header: x-api-key: <your-api-key>
API keys are managed under Settings → API Keys in the Bookie web app. You can create multiple keys, give them names, and revoke them at any time.
- Rate limit: 10,000 requests per 24-hour window (per key)
- Unauthorized responses return
401 Unauthorizedwith no body
Bookmarks
GET /api/bookmarks
List and search bookmarks.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
q | string | "" | Full-text search term. Empty returns all. |
page | number | 1 | Page number (positive integer). |
limit | number | 50 | Results per page (positive integer, max 500). |
Response 200 OK
{
"bookmarks": [
{
"id": 1,
"url": "https://example.com",
"title": "Example",
"description": "An example bookmark",
"alias": "example",
"isFavorite": false,
"isArchived": false,
"clickCount": 3,
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 142,
"totalPages": 3
}
} Example
curl "https://bookie.edwardes.xyz/api/bookmarks?q=svelte&page=1&limit=10"
-H "x-api-key: YOUR_API_KEY" POST /api/bookmarks
Create a new bookmark.
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The URL to bookmark. |
title | string | No | Display title. Defaults to the URL with the protocol stripped. |
description | string | No | Optional description or notes. |
isFavorite | boolean | No | Mark as favourite. Defaults to false. |
tagIds | number|string[] | No | Array of existing tag IDs to associate. |
alias | string | No | Short URL alias. Lowercase letters, numbers, /, and - only. |
Response 200 OK — the created bookmark object.
{
"id": 42,
"url": "https://svelte.dev",
"title": "Svelte",
"description": null,
"alias": "svelte",
"isFavorite": false,
"isArchived": false,
"clickCount": 0,
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z"
} Error 400 Bad Request — returned when validation fails (e.g. alias contains invalid characters).
Example
curl -X POST "https://bookie.edwardes.xyz/api/bookmarks"
-H "x-api-key: YOUR_API_KEY"
-H "Content-Type: application/json"
-d '{
"url": "https://svelte.dev",
"title": "Svelte",
"alias": "svelte",
"isFavorite": true
}' GET /api/bookmarks/:id
Retrieve a single bookmark by its numeric ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Bookmark ID. |
Response 200 OK — the bookmark object.
{
"id": 42,
"url": "https://svelte.dev",
"title": "Svelte",
"description": null,
"alias": "svelte",
"isFavorite": true,
"isArchived": false,
"clickCount": 7,
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-20T08:30:00.000Z"
} Example
curl "https://bookie.edwardes.xyz/api/bookmarks/42"
-H "x-api-key: YOUR_API_KEY" PUT /api/bookmarks/:id
Partially update a bookmark. Only the fields included in the request body are modified; omitted fields are left unchanged. All fields are optional except the id in the path.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Bookmark ID. |
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
url | string | No | The URL. Updated only when present. |
title | string | No | Display title. An empty string falls back to the URL with the protocol stripped. |
description | string | null | No | Description. Pass null (or an empty string) to clear. |
isFavorite | boolean | No | Favourite status. Updated only when present. |
tagIds | number|string[] | No | Tag IDs to associate. When present, replaces all existing associations; send [] to remove all tags. Omit to leave tags unchanged. |
alias | string | null | No | Short alias. Lowercase letters, numbers, /, and - only. |
Response 200 OK — the updated bookmark object.
Error 400 Bad Request — returned when validation fails.
Example
# Update just the favourite status; all other fields are left unchanged.
curl -X PUT "https://bookie.edwardes.xyz/api/bookmarks/42"
-H "x-api-key: YOUR_API_KEY"
-H "Content-Type: application/json"
-d '{ "isFavorite": true }' DELETE /api/bookmarks/:id
Permanently delete a bookmark.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Bookmark ID. |
Response 200 OK
{
"success": true,
"message": "Bookmark deleted successfully"
} Error 400 Bad Request — returned when the ID is not a valid positive integer.
Example
curl -X DELETE "https://bookie.edwardes.xyz/api/bookmarks/42"
-H "x-api-key: YOUR_API_KEY" Tags
GET /api/tags
List all tags belonging to the authenticated user, sorted alphabetically by name.
Response 200 OK
[
{
"id": 1,
"name": "devtools",
"color": null,
"userId": "user_abc123",
"createdAt": "2024-01-10T09:00:00.000Z"
}
] Example
curl "https://bookie.edwardes.xyz/api/tags"
-H "x-api-key: YOUR_API_KEY" POST /api/tags
Create a new tag. The name is automatically trimmed and lowercased.
Request Body application/json
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Tag name. 1–50 characters. |
Response 201 Created
{
"id": 5,
"name": "devtools",
"userId": "user_abc123",
"createdAt": "2024-01-15T10:00:00.000Z"
} Error 400 Bad Request — returned when name is empty or exceeds 50 characters.
Example
curl -X POST "https://bookie.edwardes.xyz/api/tags"
-H "x-api-key: YOUR_API_KEY"
-H "Content-Type: application/json"
-d '{"name": "devtools"}'