# APIs This reference is the entrypoint for working with Super Productivity's APIs. The app exposes **two API systems**: the **Sync Server REST API** (for data synchronization) and the **Plugin API** (for extending the app). This reference summarizes both; full request/response schemas and examples live in the repository (Sync Server: `packages/super-sync-server/`; Plugin API: `packages/plugin-api/` and `docs/plugin-development.md`). ## 1. Sync Server REST API The Sync Server is a custom, operation-based synchronization service (event-sourcing style). It is **not** WebDAV. It is intended for use with the built-in SuperSync sync provider. SuperSync is very new and is still in beta. See [[2.08-Choose-Sync-Backend]] and [[2.09-Configure-Sync-Backend]] for user-facing sync options. ### Authentication and Authorization All sync endpoints require **JWT Bearer** authentication: `Authorization: Bearer `. - **Token expiry:** 7 days. - **Environment:** Server requires `JWT_SECRET` (minimum 32 characters). - **Token contents:** `userId`, `email`, `tokenVersion` (for invalidation). - Invalid or missing token returns 401. ### Authentication Endpoints **Traditional:** - `POST /api/register` — User registration (email verification required). - `POST /api/login` — Password login. - `POST /api/verify-email` — Email verification. - `POST /api/replace-token` — Replace compromised JWT (requires current auth). **Passkey (WebAuthn):** - `POST /api/register/passkey/options` — Registration options. - `POST /api/register/passkey/verify` — Verify registration. - `POST /api/login/passkey/options` — Authentication options. - `POST /api/login/passkey/verify` — Verify authentication. - `POST /api/recover/passkey` — Request passkey recovery (e.g. magic link). - `POST /api/recover/passkey/options` — Recovery registration options. - `POST /api/recover/passkey/complete` — Complete recovery. **Magic link:** - `POST /api/login/magic-link` — Request magic link email. - `POST /api/login/magic-link/verify` — Verify magic link token. **Account:** - `DELETE /api/account` — Delete user and all data (requires auth). ### Synchronization Endpoints All require authentication. **Operations:** - `POST /api/sync/ops` — Upload operations (incremental). Request: `ops[]`, `clientId`, optional `lastKnownServerSeq`, optional `requestId` (deduplication). - `GET /api/sync/ops?sinceSeq={seq}&limit={limit}&excludeClient={clientId}` — Download operations. Query: `sinceSeq` (required), `limit` (default 500, max 1000), `excludeClient` (optional). **Snapshots:** - `GET /api/sync/snapshot` — Get full state snapshot. - `POST /api/sync/snapshot` — Upload full state (backup/repair/migration). Body limit 30 MB (compressed). **Status and maintenance:** - `GET /api/sync/status` — Sync status and storage info. - `DELETE /api/sync/data` — Delete all sync data for the user (e.g. encryption password change). - `GET /api/sync/restore-points?limit={limit}` — List restore points (limit 1–100). - `GET /api/sync/restore/{serverSeq}` — Get state snapshot at a specific sequence. **Health:** - `GET /health` — Database connectivity check (no auth). Returns 200 with `{ status: 'ok', db: 'connected' }` or 503 on failure. ### Request/Response Overview - **Upload ops:** Body is an array of operations; each has `id`, `clientId`, `actionType`, `opType`, `entityType`, `entityId`/`entityIds`, `payload`, `vectorClock`, `timestamp`, `schemaVersion`, optional `isPayloadEncrypted`. Response: `results[]` (per-op accepted/rejected + `serverSeq`), optional `newOps`, `latestSeq`, optional `hasMorePiggyback`, optional `deduplicated`. - **Download ops:** Response: `ops`, `hasMore`, `latestSeq`, optional `gapDetected`, optional `latestSnapshotSeq`, optional `snapshotVectorClock`, `serverTime`. - **Snapshot:** Response: `state`, `serverSeq`, `generatedAt`. Upload snapshot body: `state`, `clientId`, `reason`, `vectorClock`, `schemaVersion`, optional `isPayloadEncrypted`. - **Status:** Response: `latestSeq`, `devicesOnline`, optional `snapshotAge`, `storageUsedBytes`, `storageQuotaBytes`. Exact schemas (Zod on server, TypeScript types in repo) are in `packages/super-sync-server/src/sync/sync.types.ts` and `sync.routes.ts`. ### Error Codes Structured error codes (for client handling) include: `VALIDATION_FAILED`, `INVALID_OP_ID`, `INVALID_OP_TYPE`, `INVALID_ENTITY_TYPE`, `INVALID_ENTITY_ID`, `INVALID_PAYLOAD`, `PAYLOAD_TOO_LARGE`, `INVALID_VECTOR_CLOCK`, `INVALID_CLIENT_ID`, `CONFLICT_CONCURRENT`, `CONFLICT_SUPERSEDED`, `DUPLICATE_OPERATION`, `RATE_LIMITED`, `STORAGE_QUOTA_EXCEEDED`, `ENCRYPTED_OPS_NOT_SUPPORTED`, `SYNC_IMPORT_EXISTS`, `INTERNAL_ERROR`. Defined in `sync.types.ts` (`SYNC_ERROR_CODES`). ### Rate Limits (per endpoint) - Email verification: 20 / 15 min. - Token replacement: 5 / 15 min. - Account deletion: 3 / 15 min. - Passkey registration: 10 / 15 min. - Passkey login: 20 / 15 min. - Passkey recovery (request/options/complete): 5–10 / 15 min. - Magic link request: 5 / 15 min; verify: 10 / 15 min. - Upload ops: 100 / 1 min. - Download ops: 200 / 1 min. - Snapshot (GET): 10 / 5 min. ### Storage Quotas (Sync Server) - **Per user:** Default 100 MB. Enforced before accepting uploads; automatic cleanup (restore points and old operations) when over quota. - **Upload limits:** Max payload 20 MB; max operations per upload 100. Compressed ops body: 10 MB; compressed snapshot: 30 MB; decompressed cap (zip-bomb protection): 100 MB. ### Compression - **Request:** Gzip via `Content-Encoding: gzip`. Android can send base64-encoded gzip with `Content-Transfer-Encoding: base64`. - **Response:** Server may send compressed responses where configured. ### CORS Configurable via environment/config. Typical allowed headers include `Authorization`, `Content-Type`, `Content-Encoding`, `X-Expected-Rev`, `X-Force-Overwrite`, `X-Requested-With`. Credentials supported. ### Data Retention Operations, devices, and related validation data are retained for **45 days**. Older data is purged. ### Request Deduplication Upload ops accepts optional `requestId`. Repeated requests with the same `requestId` receive cached results (and fresh piggybacked ops if applicable), so clients can retry safely without duplicating operations. ### End-to-End Encryption Payloads can be encrypted client-side; server stores them as opaque blobs. Restore-at-sequence is not supported when operations are encrypted (`ENCRYPTED_OPS_NOT_SUPPORTED`). --- ## 2. Plugin API The Plugin API is exposed to plugins via a global `PluginAPI` object. Plugins run in a sandboxed environment (VM or iframe). See [[3.05-Web-App-vs-Desktop]] for web limitations (e.g. Node-only plugins disabled, iframe API restrictions). Full types and the development guide: `packages/plugin-api/src/types.ts`, `docs/plugin-development.md`. ### Plugin API Categories **Data — Tasks:** - `getTasks()`, `getArchivedTasks()`, `getCurrentContextTasks()` — Read tasks. - `addTask(taskData)`, `updateTask(taskId, updates)`, `deleteTask(taskId)` — Create/update/delete. - `batchUpdateForProject(request)` — Batch create/update/delete/reorder for a project. - `reorderTasks(taskIds, contextId, contextType)` — Reorder tasks. **Data — Projects:** - `getAllProjects()`, `addProject(projectData)`, `updateProject(projectId, updates)`. **Data — Tags:** - `getAllTags()`, `addTag(tagData)`, `updateTag(tagId, updates)`. **Data — Simple counters:** - `setCounter(id, value)`, `getCounter(id)`, `incrementCounter(id, incrementBy)`, `decrementCounter(id, decrementBy)`, `deleteCounter(id)`, `getAllCounters()`. **UI:** - `showSnack(snackCfg)`, `notify(notifyCfg)` — Notifications. - `openDialog(dialogCfg)`, `showIndexHtmlAsView()` — Dialogs and plugin UI. **Registration (main plugin context only; not in iframe):** - `registerHeaderButton(config)`, `registerMenuEntry(config)`, `registerShortcut(config)`, `registerSidePanelButton(config)`, `registerHook(hook, handler)`. **Persistence:** - `persistDataSynced(dataStr)`, `loadSyncedData()`, `getConfig()` — Plugin-specific storage and config. **Advanced:** - `executeNodeScript(request)` — Run Node.js scripts (Electron only, `nodeExecution` permission and user consent). - `dispatchAction(action)` — Dispatch NgRx actions (allowed subset). - `downloadFile(filename, data)`, `isWindowFocused()`, `onWindowFocusChange(handler)`. ### Hooks (Events) Plugins can register handlers for: `taskCreated`, `taskComplete`, `taskUpdate`, `taskDelete`, `currentTaskChange`, `finishDay`, `languageChange`, `persistedDataUpdate`, `action`, `anyTaskUpdate`, `projectListUpdate`. Payload types are defined in `plugin-api` types (`HookPayloadMap`). ### Plugin Data Types Core types (Task, Project, Tag, ProjectFolder, etc.) and batch types (`BatchUpdateRequest`, `BatchUpdateResult`, `BatchOperation`, etc.) are in `packages/plugin-api/src/types.ts`. ### Plugin Manifest Plugins require `manifest.json`: `name`, `id`, `manifestVersion`, `version`, `minSupVersion`, optional `description`, `hooks`, `permissions`, optional `iFrame`, `isSkipMenuEntry`, `type`, `assets`, `icon`, `nodeScriptConfig`, `sidePanel`, `jsonSchemaCfg`. See `PluginManifest` in the repo. ### Plugin Permissions - **nodeExecution:** Required for `executeNodeScript()` (Electron only; user consent). See [[3.05-Web-App-vs-Desktop]] and [[3.06-User-Data]] for file-system and desktop-only behavior. - Other permissions may gate specific API methods; see the plugin development guide. ### Iframe Restrictions When a plugin uses an iframe UI, the following are **not** available: `registerHeaderButton`, `registerMenuEntry`, `registerSidePanelButton`, `registerShortcut`, `registerHook`, `execNodeScript`. Iframe content is subject to CSP (e.g. no external scripts; same-origin or inlined only). --- ## 3. Versioning and Compatibility ### Schema Versioning (Sync) - **Current schema version:** 1 (shared schema in `packages/shared-schema`). - **Minimum supported:** 1. - **Max version skip:** 3 (if remote data is more than 3 versions ahead, client should update). - Operations and snapshots carry `schemaVersion`; server validates and may reject unsupported versions. ### Vector Clocks Sync uses vector clocks for conflict resolution. Server validates/sanitizes clocks: max 50 entries; keys max 255 chars; values 0–10,000,000. Invalid entries are stripped. ### API Validation (Sync Server) - Operation IDs: 1–255 characters. Client IDs: alphanumeric, underscore, hyphen; max 255. - Entity types: 1–255 characters. Schema version: 1–100. - Payload validation by op type (CRT, UPD, DEL, MOV, BATCH, SYNC_IMPORT, etc.); see `validatePayload` in `sync.types.ts`. --- ## Notes - **Sync Server:** Production-oriented (JWT, rate limiting, CORS, Helmet). Multi-instance deployment has limitations (e.g. passkey challenge storage in memory; snapshot generation locks); single-instance is the typical deployment. - **Plugin API:** Sandboxed; iframe and Electron have different capabilities. See [[3.05-Web-App-vs-Desktop]] and the repo plugin guide. - **Further documentation:** Sync Server README and auth docs in `packages/super-sync-server/`; Plugin API and examples in `packages/plugin-api/`, `docs/plugin-development.md`, and example plugins under `packages/plugin-dev/`.