📜
SPEC-STV-03 · Spec header. Spec ID: SPEC-STV-03 · Title: API Endpoints Reference · Version: 1.0.0 · Status: Planned · Authority: Specification · Priority: P0 · Owner role: Backend architect · Reviewers: Frontend lead, Security lead · Last reviewed: 2026-05-11 · Sync targets: routes/api.php, app/Http/Controllers/Api/**, docs/API_ENDPOINTS.md · Depends on: SPEC-STV-HUB, SPEC-STV-01, SPEC-STV-02, SPEC-STV-11 · Consumed by: SPEC-STV-04 … SPEC-STV-12, future SwiftUI client · Conflict rule: Hub wins. · Change policy: Backend architect + Frontend lead; Registry bump on any breaking change.
1 · Conventions Base path: /api/v1. Major version increments are breaking changes. Auth: Laravel Sanctum personal access tokens. Each token carries an abilities set (§3). Content-type: application/json request and response. SSE responses use text/event-stream. Pagination: cursor-based on hot lists (?cursor=…&per_page=≤100); page-based on admin lists. Errors: RFC 7807-ish JSON { "error": { "code": "...", "message": "...", "details": {...} } }. HTTP status carries semantics (400|401|403|404|409|422|429|5xx). Timestamps: ISO 8601 UTC. IDs in public URLs use uuid; internal id is never exposed.
2 · Auth
POST /auth/login— Returns Sanctum token. Rate-limited 5 / min / IP.
POST /auth/logoutany Revokes current token.
GET /auth/meany Returns user profile + workspace memberships.
POST /auth/tokenstokens:createIssue a scoped token.
DELETE /auth/tokens/{id}tokens:revokeRevoke a token.
3 · Sanctum ability set workspaces:read, workspaces:write, pages:read, pages:write, blocks:write, databases:read, databases:write, comments:write, files:write, sharing:write, ai:transform, ai:generate, rag:query, rag:reindex (admin), settings:write, tokens:create, tokens:revoke. The web session is treated as carrying the full set scoped by the user's workspace role.
4 · Workspaces
GET /workspacesworkspaces:readList user's workspaces.
POST /workspacesworkspaces:writeBody { name, slug?, icon?, default_language? }.
GET /workspaces/{uuid}workspaces:readDetails + role.
PATCH /workspaces/{uuid}workspaces:write, owner/adminPartial update.
DELETE /workspaces/{uuid}workspaces:write, owner onlySoft-delete, scheduled hard delete in 30 days.
GET /workspaces/{uuid}/membersworkspaces:readList.
POST /workspaces/{uuid}/membersworkspaces:writeInvite by email, role required.
PATCH /workspaces/{uuid}/members/{user_uuid}workspaces:write, admin+Change role.
DELETE /workspaces/{uuid}/members/{user_uuid}workspaces:write, admin+Remove.
5 · Pages
GET /workspaces/{ws}/pages?parent={uuid|null}&cursor=…Sidebar tree, cursor-paginated children only.
POST /workspaces/{ws}/pagesBody { title, parent_page_uuid?, icon?, template_id? }.
GET /pages/{uuid}Returns page + first N blocks (configurable, default 100).
PATCH /pages/{uuid}Partial update: title, icon, cover_url, visibility, seo.
POST /pages/{uuid}/archiveSoft archive; cascade to subpages = config flag.
POST /pages/{uuid}/restoreReverse archive.
POST /pages/{uuid}/moveBody { new_parent_uuid?: "…|null", new_sort_position?: number }.
POST /pages/{uuid}/favoriteToggle favorite for current user.
GET /pages/{uuid}/versionsList event-based versions.
POST /pages/{uuid}/versions/{n}/restoreRestore a prior version.
6 · Blocks
GET /pages/{uuid}/blocks?after={position}&limit=200Cursor-based by position.
POST /pages/{uuid}/blocksSingle or batch { blocks: [...] }. Returns assigned IDs and positions.
PATCH /blocks/{id}Partial update of content / metadata.
POST /blocks/{id}/moveBody { new_parent_block_id?, new_position }.
POST /blocks/batchBulk patch (used by autosave).
DELETE /blocks/{id}Soft delete; emits page_version op.
7 · Databases
POST /databasesCreate. Body { page_id?, name, properties: [...] }.
GET /databases/{id}Returns schema + view list.
POST /databases/{id}/propertiesAdd property.
PATCH /properties/{id}Rename / change config.
GET /databases/{id}/rows?view={id}&cursor=…Filtered/sorted server-side per view.
POST /databases/{id}/rowsCreate row with optional initial cell values.
PATCH /rows/{id}/cellsBulk cell update { values: { property_id: value, ... } }.
POST /databases/{id}/viewsCreate view.
PATCH /views/{id}Edit config.
8 · Templates / Search / Comments / Files
GET /templates?category=…&scope=workspace|global—
POST /templates/{id}/instantiateBody { parent_page_uuid?, workspace_uuid }.
POST /pages/{uuid}/save_as_template—
GET /search?q=…&workspace={uuid}&types=page,block,file,database&limit=20Meilisearch.
GET /pages/{uuid}/comments—
POST /commentsBody { page_uuid, block_id?, parent_comment_id?, body }.
POST /comments/{id}/resolve—
POST /files/presignReturns S3 PUT URL + signed fields.
POST /files/commitBody { key, mime, size, original_name } → creates files row.
GET /files/{uuid}/signed-urlTime-limited download URL.
9 · Sharing
POST /pages/{uuid}/share-linkBody { mode: "view|comment", password?, expires_at? }. Returns { url, token }.
DELETE /share-links/{token}—
POST /pages/{uuid}/sharesBody { user_uuid, role }.
DELETE /pages/{uuid}/shares/{user_uuid}—
GET /public/{token}Public read. No auth. Rate-limited 60 / min / IP. Strips comments unless mode = comment.
10 · AI + RAG
POST /ai/transformBody { action, selection: { page_uuid, block_id?, text }, options? }. Returns transformed text. SSE-friendly via /ai/transform/stream.
POST /ai/transform/streamSSE. Events delta, final, error.
POST /ai/generateBody { prompt, context: { page_uuid?, scope } }. Generates a draft page outline / API doc / spec.
POST /rag/queryBody { workspace_uuid, query, top_k? }. Returns hits with citations { page_uuid, block_id?, score, excerpt }.
POST /rag/reindexAdmin. Body { scope?: "workspace|page", id? }. Queued.
GET /rag/status?workspace={uuid}Returns { chunks, stale, last_indexed_at, queue_depth }.
11 · Activity & Settings
GET /workspaces/{uuid}/activity?entity=page&entity_id={uuid}&cursor=…Read-only audit feed.
GET /workspaces/{uuid}/settings—
PATCH /workspaces/{uuid}/settings/{key}Admin. Body { value }.
12 · Rate limits (defaults) AI transform: 30 / min / user, 500 / day / workspace. AI generate: 10 / min / user. Public share read: 60 / min / IP, 5 / sec burst. RAG reindex: 1 in-flight / workspace. File presign: 60 / min / user.
13 · Error catalogue (selected) workspace.member_required, workspace.role_insufficient, page.archived, page.parent_loop, block.invalid_type, block.content_too_large, database.property_type_mismatch, share.password_required, share.expired, ai.rate_limited, ai.input_too_long, rag.disabled_for_workspace, file.mime_blocked, file.size_exceeded, idor.cross_workspace.