Files
crumbs-original/docs/API.md
T
Frederic CabassutandClaude Opus 4.6 96e0212d55 fix: include tags in sync pull response and update API spec
- GET /api/sync now attaches tags to notes (matching GET /api/notes
  and GET /api/search behavior)
- Add trashedAt field to Note schema in OpenAPI spec
- Add optional id field to NoteInput schema
- Add 400 error response for POST /api/sync
- Add response schema for GET attachments list
- Regenerate API.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 07:52:36 +01:00

7.3 KiB

Crumbs API

REST API for Crumbs by Bretzel — a self-hostable, offline-first notes app.

Base URL: http://localhost:3000

All endpoints require a session cookie (set by login) except where noted.

Auth

POST /api/auth/setup

First-time password setup

Creates the single user account. Only works once — returns 400 if already set up.

No authentication required.

Request:

{
  "password": "password"
}

Response: 201

{
  "success": true
}

Errors: 400 Setup already completed or invalid password


POST /api/auth/login

Log in

No authentication required.

Request:

{
  "password": "password"
}

Response: 200

{
  "success": true
}

Errors: 401 Invalid password


POST /api/auth/logout

Log out

Response: 200

{
  "success": true
}

Notes

GET /api/notes

List notes

Parameters:

Name In Type Required Description
filter query string no (all, archived, trashed) — default: all

Response: 200

[
  {
    "id": "uuid",
    "title": "title",
    "content": "content",
    "color": "default",
    "pinned": true,
    "archived": true,
    "trashed": true,
    "trashedAt": "2025-01-01T00:00:00.000Z",
    "checklistMode": true,
    "sortOrder": 1,
    "createdAt": "2025-01-01T00:00:00.000Z",
    "updatedAt": "2025-01-01T00:00:00.000Z",
    "version": 1,
    "tags": [
      "item"
    ]
  }
]

POST /api/notes

Create a note

Request:

{
  "id": "uuid",
  "title": "title",
  "content": "content",
  "color": "default",
  "pinned": true,
  "archived": true,
  "trashed": true,
  "checklistMode": true,
  "sortOrder": 1
}

Response: 201

{
  "id": "uuid",
  "title": "title",
  "content": "content",
  "color": "default",
  "pinned": true,
  "archived": true,
  "trashed": true,
  "trashedAt": "2025-01-01T00:00:00.000Z",
  "checklistMode": true,
  "sortOrder": 1,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-01T00:00:00.000Z",
  "version": 1,
  "tags": [
    "item"
  ]
}

GET /api/notes/{id}

Get a note

Parameters:

Name In Type Required Description
id path string yes

Response: 200

{
  "id": "uuid",
  "title": "title",
  "content": "content",
  "color": "default",
  "pinned": true,
  "archived": true,
  "trashed": true,
  "trashedAt": "2025-01-01T00:00:00.000Z",
  "checklistMode": true,
  "sortOrder": 1,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-01T00:00:00.000Z",
  "version": 1,
  "tags": [
    "item"
  ]
}

Errors: 404 Note not found


PATCH /api/notes/{id}

Update a note

Partial update — only include changed fields.

Parameters:

Name In Type Required Description
id path string yes

Request:

{
  "id": "uuid",
  "title": "title",
  "content": "content",
  "color": "default",
  "pinned": true,
  "archived": true,
  "trashed": true,
  "checklistMode": true,
  "sortOrder": 1
}

Response: 200

{
  "id": "uuid",
  "title": "title",
  "content": "content",
  "color": "default",
  "pinned": true,
  "archived": true,
  "trashed": true,
  "trashedAt": "2025-01-01T00:00:00.000Z",
  "checklistMode": true,
  "sortOrder": 1,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-01T00:00:00.000Z",
  "version": 1,
  "tags": [
    "item"
  ]
}

Errors: 404 Note not found


DELETE /api/notes/{id}

Permanently delete a note

Parameters:

Name In Type Required Description
id path string yes

Response: 200

{
  "success": true
}

Errors: 404 Note not found


Attachments

GET /api/notes/{id}/attachments

List or download attachments

Without attachmentId, lists all attachments. With attachmentId, returns the file.

Parameters:

Name In Type Required Description
id path string yes
attachmentId query string no

Response: 200

[
  {
    "id": "id",
    "noteId": "noteId",
    "filename": "filename",
    "mimeType": "mimeType",
    "size": 1,
    "createdAt": "2025-01-01T00:00:00.000Z"
  }
]

POST /api/notes/{id}/attachments

Upload an image attachment

Parameters:

Name In Type Required Description
id path string yes

Request: multipart/form-data with file field.

Response: 201

{
  "id": "id",
  "noteId": "noteId",
  "filename": "filename",
  "mimeType": "mimeType",
  "size": 1,
  "createdAt": "2025-01-01T00:00:00.000Z"
}

Errors: 400 Invalid file


DELETE /api/notes/{id}/attachments

Delete an attachment

Parameters:

Name In Type Required Description
id path string yes
attachmentId query string yes

Response: 200

{
  "success": true
}

GET /api/search

Full-text search

Searches across note titles, content, and tags. Excludes trashed notes.

Parameters:

Name In Type Required Description
q query string yes

Response: 200

[
  {
    "id": "uuid",
    "title": "title",
    "content": "content",
    "color": "default",
    "pinned": true,
    "archived": true,
    "trashed": true,
    "trashedAt": "2025-01-01T00:00:00.000Z",
    "checklistMode": true,
    "sortOrder": 1,
    "createdAt": "2025-01-01T00:00:00.000Z",
    "updatedAt": "2025-01-01T00:00:00.000Z",
    "version": 1,
    "tags": [
      "item"
    ]
  }
]

Tags

GET /api/tags

List all tags

Response: 200

[
  {
    "id": 1,
    "name": "name"
  }
]

Sync

GET /api/sync

Pull changes since timestamp

Parameters:

Name In Type Required Description
since query integer yes Unix timestamp in milliseconds

Response: 200

[
  {
    "id": "uuid",
    "title": "title",
    "content": "content",
    "color": "default",
    "pinned": true,
    "archived": true,
    "trashed": true,
    "trashedAt": "2025-01-01T00:00:00.000Z",
    "checklistMode": true,
    "sortOrder": 1,
    "createdAt": "2025-01-01T00:00:00.000Z",
    "updatedAt": "2025-01-01T00:00:00.000Z",
    "version": 1,
    "tags": [
      "item"
    ]
  }
]

POST /api/sync

Push local changes

Request:

{
  "changes": [
    {
      "noteId": "uuid",
      "operation": "create",
      "timestamp": 1,
      "data": {
        "id": "uuid",
        "title": "title",
        "content": "content",
        "color": "default",
        "pinned": true,
        "archived": true,
        "trashed": true,
        "checklistMode": true,
        "sortOrder": 1
      }
    }
  ]
}

Response: 200

{
  "success": true
}

Errors: 400 Invalid changes payload