Thicket API
Thicket exposes a versioned REST API at /api/v1. The web app is built on the same service layer, so behavior is identical through either surface. Everything you can do in the product has a corresponding route. Clean REST, predictable snake_case JSON, and structured content make it a comfortable surface for scripts and AI agents. If you're here to put an agent to work, start with Thicket for AI agents.
- Base path:
/api/v1. Org-scoped routes embed the organization slug:/api/v1/{org-slug}/… - JSON uses
snake_casekeys, with no response envelope. Resources are returned directly. - Errors come back as a consistent error object with conventional status codes:
400malformed JSON,401not authenticated,402plan limit reached (limit_reached),403forbidden,404missing or not yours (cross-tenant probes are indistinguishable from missing),422validation,429rate limited (token traffic; honorRetry-After). - Rich text:
contentfields accept plain text (stored as safe paragraph HTML);content_htmlfields accept rich HTML that is sanitized server-side: formatting, links, lists, @-mention spans, tables, headingsh1–h4, code blocks, and inline images/audio restricted to Thicket's own attachment routes. Responses return the stored HTML. - @-mentions: a mention span can name a person or a group; group mentions expand server-side into the group's current members. Mentions subscribe and notify only people with access to the project.
- Roles:
owner,admin,member,client. Clients only see projects they were explicitly added to and, inside them, only recordings shared with clients (visible_to_clients: true). - Tenancy. Every org-scoped request runs in a database transaction with row-level security set after membership verification. A valid session in one organization returns zero rows or 404 for anything in another.
HTTP/1.1 402 Payment Required
{
"error": {
"code": "limit_reached",
"message": "Your plan's project limit has been reached."
}
}Personal access tokens. Create one in the app under My settings, then API tokens (or let the CLI mint one for you: thicket auth login), and send it as a Bearer header. The token works as you: same workspaces, same project access, same permissions as your sign-in. Pick read-and-write or read-only scope at creation; revocation takes effect immediately. The web app's own session cookie (from the auth endpoints below) works on every route too.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/authorization | Who am I: {identity: {id}, organizations: [{id, name, slug, href, membership_id, role}], scope, expires_at}. Make this your integration's first call; membership_id is who you are inside each organization (assignees speak membership ids) |
| GET | /api/v1/me/tokens | Your tokens: name, prefix, scope, created, last used (never the secret). Session-only |
| POST | /api/v1/me/tokens | {name, scope? (read|full, default read), expires_at?} → 201. The response's token field is shown exactly once. Session-only: tokens can't mint tokens |
| DELETE | /api/v1/me/tokens/{id} | Revoke: 204, effective immediately. Session-only |
| POST | /api/v1/cli/authorizations | The CLI sign-in's approve half: {challenge (base64url SHA-256 of the CLI's code_verifier), scope?, device_name} → 201 {code, expires_at}. Single-use code, 10-minute expiry. Session-only; the /cli/authorize page in the app fronts it |
| POST | /api/v1/cli/token | The exchange half, anonymous by design: {code, code_verifier} → 201 with the minted token (shown exactly once). Any exchange attempt burns the code; failures are indistinguishable (401 invalid_grant) |
| POST | /api/auth/sign-in/email | {email, password} sets the session cookie (the web app's own flow) |
| POST | /api/auth/sign-up/email | {name, email, password} sets the session cookie and sends the confirmation email |
| POST | /api/auth/sign-out | Clears the session |
| GET | /api/auth/get-session | Current session, or null |
| GET | /api/auth/sign-in/social?provider=google | Google SSO (browser flow) |
Quick start
Create a token in My settings, then every /api/v1 call is one header. Include a User-Agent naming your app and a way to reach you; token calls without one get a 400.
export THICKET_TOKEN=thicket_pat_... # from My settings, then API tokens
# 1. Who am I, and which workspaces can I reach?
curl -H "Authorization: Bearer $THICKET_TOKEN" \
-A "AcmeSync (dev@acme.com)" \
https://www.thickethq.com/api/v1/authorization
# 2. Create a project (the slug comes from step 1)
curl -H "Authorization: Bearer $THICKET_TOKEN" \
-A "AcmeSync (dev@acme.com)" \
-X POST https://www.thickethq.com/api/v1/acme/projects \
-H "Content-Type: application/json" \
-d '{"name": "Website redesign"}'Thicket's remote MCP endpoint gives ChatGPT, Claude Code, and compatible AI apps a curated set of project tools with the same permissions as your account. Connect with OAuth 2.1, or use a personal access token from clients that support custom headers.
- Endpoint:
https://www.thickethq.com/api/mcp(Streamable HTTP; protocol revisions 2026-07-28 and 2025-11-25 are served statelessly, with no sticky sessions). - OAuth 2.1: Authorization Code with PKCE. Discovery at
/.well-known/oauth-protected-resourceand/.well-known/oauth-authorization-server; clients identify with a Client ID Metadata Document or dynamic registration (POST /api/oauth/register). Short-lived access tokens, rotating refresh tokens, and a consent screen that names the client and what it may do. - Scopes:
thicket.readandthicket.write. A read-only connection never sees the write tools at all. - Tools: a curated set of 21 covering organizations, projects, search and fetch, to-dos, messages and comments, docs, schedule, boards, chat, and people. Writes require an idempotency key and updates carry a freshness precondition, so a retried or stale agent call cannot double-post or overwrite newer work. No billing, people-management, deletion, or file transfer tools, deliberately.
- Identity & audit: the connection is you: your organizations, project access, and role, enforced by the same row-level security as every other surface. Changes are attributed to your account, and each connection appears in My settings under Connected apps with its scope and last use. After you disconnect it, the next request is refused.
- PAT path: send
Authorization: Bearer thicket_pat_...(with a User-Agent) to the same endpoint from clients that support custom headers, the MCP Inspector, or scripts. The token's read/full scope maps to the same tool visibility. - Setup guide: Connect AI apps with MCP in the help center covers consent, permissions, data flow, troubleshooting, and revocation.
Building a product or internal tool on this API needs no approval and no registration: every customer account can mint tokens and integrate, on any plan. Each of your users authorizes your integration with their own token, which carries exactly their access. When your integration is live and you'd like it listed for other Thicket customers to find, email support@thickethq.com with what it does and a link; we review listings by hand and publish an integrations directory as they land.
- OpenAPI spec: thickethq.com/openapi.json (OpenAPI 3.1, date-versioned) covers every route on this page, for code generation in any language.
- TypeScript SDK: github.com/thicket-hq/thicket-sdk (
npm install thicket-sdk): bearer auth, retries with Retry-After, pagination, and types generated from the spec. - Command line: github.com/thicket-hq/thicket-cli (
npm install -g thicket-cli): thethicketcommand for terminals and agents.thicket auth loginsigns in through your browser and mints a personal access token; every command takes--json, andthicket commands --jsonis the machine-readable catalog. - AI agents: the skill file at thickethq.com/thicket-SKILL.md teaches an agent the API's patterns up front. No SDK required; see Thicket for AI agents.
- MCP connector: compatible remote MCP clients connect at
https://www.thickethq.com/api/mcpwith OAuth or a personal access token; see the MCP connector section above.
- Page-numbered lists: timeline and report-style listings (project events, the account activity feed, search) take
?page=and?per_page=(capped at 100; search defaults to 50). - Cursor paging. Chat history pages backwards with a created-before cursor:
?before=<ISO timestamp>&limit=on the children listing. - Sorting: children listings accept
?sort=created_at|updated_atwith?direction=asc|desc, plus filters?type=,?status=,?completed=. Default order is position, then creation. - Positions. Ordered surfaces (to-do lists, board columns, project tools) persist fractional
positionvalues; drop an item between two neighbors by sending the midpoint.
- Plan limits. Exceeding your plan returns
402 { code: "limit_reached" }. Free: 1 project, 20 people (clients included), 1 GB storage, 30-day chat history. Starter ($25/mo or $240/yr): 3 active projects, 20 people, 10 GB. Pro ($49/mo or $468/yr): unlimited projects and people, 50 GB. Pricing is per organization, never per seat. - Uploads: files up to 50 MB per upload (multipart).
- Batch operations run through the bulk recordings endpoint, which accepts 1–100 ids per call.
- List sizes:
per_pagecaps at 100 on paged listings. - Rate limit: token traffic allows 50 requests per 10 seconds per token. Over the line you get
429 { code: "rate_limited" }with aRetry-Afterheader in seconds. Build graceful 429 and 5xx retries into your integration from the start.
Discover the organizations your account belongs to; their slugs key every other route.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/orgs | Your organizations: id, name, slug, role |
Projects contain the six tools (message board, to-dos, docs & files, schedule, Boards, chat) and the people working in them. Each enabled tool appears in the project's tools with the container recording that content is created under.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/projects | Active projects you can access, starred first; ?status=archived|trashed; ?scope=all is an owner-only list of every project |
| POST | /api/v1/{org}/projects | {name, description?, all_access?} → 201 (auto-starred for the creator) |
| GET | /api/v1/{org}/projects/{id} | Project plus its tools (enabled tools with container ids) |
| PATCH | /api/v1/{org}/projects/{id} | {name?, description?, all_access?, folder_id?, color?, starts_on?, ends_on?, clients_enabled?, client_company_name?, …} |
| PUT | /api/v1/{org}/projects/{id}/status/{status} | Lifecycle: active, archived, or trashed |
| PUT / DELETE | /api/v1/{org}/projects/{id}/star | Star or unstar (personal; starred projects pin to the top of home) |
| POST | /api/v1/{org}/projects/{id}/join | Owner-only "add yourself" to any project |
| GET | /api/v1/{org}/projects/{id}/tools | The tools |
| PUT | /api/v1/{org}/projects/{id}/tools/{tool} | {enabled?, title?, position?}: toggle a tool, rename it on this project, or reorder the tools |
| GET / POST | /api/v1/{org}/projects/{id}/links | External links shown alongside the tools; POST {url, title, description?, visible_to_clients?} |
| PATCH / DELETE | /api/v1/{org}/projects/{id}/links/{link_id} | Update (any field incl. position) or remove a link |
| GET | /api/v1/{org}/projects/{id}/people | People on the project with role, title, company |
| PUT | /api/v1/{org}/projects/{id}/people | {membership_ids: []} replaces access, or deltas {grant?, revoke?, create?}; create invites someone new straight into the project |
| GET / PUT | /api/v1/{org}/projects/{id}/notification-pref | The project bell: {scope: "everything" | "mentions" | null} (null = account default) |
| GET | /api/v1/{org}/projects/{id}/events | The project timeline; ?page/?per_page, ?since=ISO, ?q= keyword |
| GET / POST | /api/v1/{org}/folders | Account-wide home-screen folders; POST {name, color?} |
| PATCH / DELETE | /api/v1/{org}/folders/{id} | Rename/recolor/reorder; DELETE drops its projects back to the top level |
Access model: nobody, including owners and admins, has implicit access to a non-all-access project's content; membership or all_access is required. Owners alone may list everything and self-add. Tool keys: message_board, todos, folder (docs & files), schedule, board (Boards), chat. Move a project in or out of a folder via PATCH /projects/{id} with folder_id.
Every piece of content is a recording: messages, comments, to-do lists, to-dos, documents, uploads, folders, schedule entries, board columns, cards, and chat lines all share one lifecycle, one comment system, and one subscription system. Content is created under its parent container with a typed child request.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/recordings?type=todo | Cross-project query; &project_id=, &status= |
| GET | /api/v1/{org}/recordings/{id} | Any recording by id, with author byline and structured metadata for files embedded in its rich text (content_attachments) |
| PATCH | /api/v1/{org}/recordings/{id} | {title?, content?, content_html?, due_on?, starts_on?, starts_at?, ends_at?, all_day?, category_id?, recurrence?, …}: everything editable after creation |
| PUT | /api/v1/{org}/recordings/{id}/status/{status} | active | archived | trashed. Works on any type; trash is recoverable |
| GET / POST | /api/v1/{org}/recordings/{id}/children | List or create content under a container. POST {type, title?, content_html?, due_on?, assignee_ids?, visible_to_clients?, notify?, status? (drafted), scheduled_at?, …} → 201 |
| GET / POST | /api/v1/{org}/recordings/{id}/comments | Comments on any commentable recording; edits are author-only, removal goes through the trash (recoverable) |
| PUT / DELETE | /api/v1/{org}/recordings/{id}/completion | Complete or reopen to-dos, cards, and card steps, independent of status; completion notifies subscribers |
| PUT | /api/v1/{org}/recordings/{id}/position | {parent_id?, position?}: kanban moves, drag reorders, and moving items between lists, groups, and projects; fractional positions |
| POST | /api/v1/{org}/recordings/{id}/copy | {parent_id, include_comments?}: deep copy under a new parent, any project → 201 |
| POST | /api/v1/{org}/recordings/batch | One bulk verb over up to 100 ids: assign, due, shift_dates, move, copy, status, color, or group → {count, ids} |
| GET / PUT | /api/v1/{org}/recordings/{id}/assignees | {membership_ids: []}; new assignees are notified and subscribed |
| GET / PUT / DELETE | /api/v1/{org}/recordings/{id}/subscription | Your notification subscription; doubles as the "watch this column" and chat-room bell |
| GET / PUT / DELETE | /api/v1/{org}/recordings/{id}/watch | Personal "notify me when new to-dos are added" on a list or the whole to-do set |
| GET / PUT | /api/v1/{org}/recordings/{id}/subscribers | Who gets notified; PUT {add?, remove?, notify?: "now" | "next"} |
| PUT | /api/v1/{org}/recordings/{id}/visibility | {visible_to_clients} toggles the flag for the recording and its subtree |
| PUT / DELETE | /api/v1/{org}/recordings/{id}/pin | Pin or unpin a message on its board (max 10 pinned) |
| POST | /api/v1/{org}/recordings/{id}/publish | Publish one of your drafts now |
| PUT | /api/v1/{org}/recordings/{id}/comments-closed | {closed}; closed threads reject new comments and cheers |
| GET / POST | /api/v1/{org}/recordings/{id}/cheers | Short emoji/text reactions; cheering notifies the author (bundled) |
| GET | /api/v1/{org}/recordings/{id}/events | The per-recording change log (created, completed, moved, version added, visibility toggles), oldest first |
| GET | /api/v1/{org}/recordings/{id}/references | Recordings whose content links here, filtered to what you can access |
Parent rules are validated server-side: messages post to the message board, to-do lists to the to-do set (one nesting level makes a group), to-dos to a list or group (or under another to-do as a subtask, one level deep), documents/uploads/folders to the folder, schedule entries to the schedule, columns to the board, cards to a column, chat lines to a room, comments to any content recording.
Drafts & scheduled posts: create with status: "drafted" (no events or notifications until published); add scheduled_at to publish automatically once the time passes. GET /api/v1/{org}/my/drafts lists yours. Every draft write is author-only.
Recurring to-dos. A dated to-do created or patched with recurrence (daily, weekly, monthly, yearly, or custom) becomes a series: occurrences spawn on cadence and when the current one is completed. Editing the primary re-projects future occurrences; editing an instance changes only itself; recurrence: null stops the series.
Client visibility: children inherit the parent's flag at creation; client-created content is always visible; comments always follow their thread.
# The project's tools gives you each tool's container id
curl -b cookies.txt https://www.thickethq.com/api/v1/acme/projects/$PROJECT_ID/tools
# Create a to-do list under the to-do set container
curl -b cookies.txt -X POST \
https://www.thickethq.com/api/v1/acme/recordings/$TODOSET_ID/children \
-H "Content-Type: application/json" \
-d '{"type": "todolist", "title": "Launch checklist"}'
# Add a to-do with a due date, then check it off
curl -b cookies.txt -X POST \
https://www.thickethq.com/api/v1/acme/recordings/$LIST_ID/children \
-H "Content-Type: application/json" \
-d '{"type": "todo", "title": "Draft homepage copy", "due_on": "2026-08-14"}'
curl -b cookies.txt -X PUT \
https://www.thickethq.com/api/v1/acme/recordings/$TODO_ID/completionRecurring questions to the team, asked daily, weekly, every other week, or monthly, with answers collected per occurrence.
| Method | Path | Notes |
|---|---|---|
| GET / POST | /api/v1/{org}/recordings/{check_ins_id}/questions | POST {title, schedule, membership_ids, visible_to_clients?}: schedule sets frequency, days, and hour; askees are notified per occurrence |
| PATCH | /api/v1/{org}/recordings/{question_id} | Edit the title, schedule, or who's asked |
| GET / POST | /api/v1/{org}/recordings/{question_id}/answers | POST {content | content_html, occurs_on?}; answers are commentable and cheerable. GET filters ?date=, ?creator_id= |
| GET | /api/v1/{org}/recordings/{question_id}/answers/by | Everyone who has answered, with counts and latest date |
| PUT | /api/v1/{org}/recordings/{question_id}/pause | {paused}: stop or resume asking |
| PUT | /api/v1/{org}/recordings/{question_id}/opt-out | {opted_out}: per-person "stop asking me" |
Ask a client to sign off on something, with a one-shot decision, plus email-style correspondence threads.
| Method | Path | Notes |
|---|---|---|
| POST | /api/v1/{org}/recordings/{clients_id}/approvals | {title, content_html?, due_on?, approver_id}: ask one client to sign off → 201 |
| PUT | /api/v1/{org}/recordings/{approval_id}/approval | {decision: approved | rejected}. Assigned approver only, one shot; subscribers are notified |
Correspondence threads are plain children: POST …/recordings/{clients_id}/children with type: client_correspondence.
Track each to-do list's position on the project's progress chart, save narrated updates, and run the per-project health gauge.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/recordings/{todos_id}/progress | The chart: dots per tracked list, saved updates, history |
| PUT | /api/v1/{org}/recordings/{todolist_id}/progress | {position: 0–1 | null, note?}; null stops tracking the list |
| POST | /api/v1/{org}/recordings/{todos_id}/progress/updates | Save a progress update: {positions, note?, notify?, visible_to_clients?}; commentable and cheerable |
| GET / PUT | /api/v1/{org}/projects/{id}/health | The gauge: current status/position and update history; PUT {enabled} toggles it (admins) |
| POST | /api/v1/{org}/projects/{id}/health/updates | {position: 0–100, status?: on_track | some_risk | concerned, note?, notify?} |
| GET | /api/v1/{org}/reports/health | Org-wide gauges, most recently updated first (team only) |
Every project has a group chat room; direct messages live outside projects, visible only to their participants.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/chats | Your direct chats with participants and the last line; ?status=archived |
| POST | /api/v1/{org}/chats | {membership_ids: []} finds or starts the conversation → 201 |
| POST | /api/v1/{org}/recordings/{chat_id}/uploads | Multipart file posted straight into a direct conversation |
| GET | /api/v1/{org}/recordings/{chat_id}/uploads | Every file posted in the room or conversation, newest first |
Lines are children of the room: POST …/recordings/{chat_id}/children with type: chat_message; history pages back with the ?before= cursor. Only the author may edit a line (admins may delete, never rewrite); lines hard-delete and never enter the trash. Posting a public URL attaches a fetched link preview. Room subscribers are notified once per burst when a quiet room becomes active; @-mentions always notify.
A combined calendar across every accessible project's schedule plus an org-level account calendar. Recurring events (daily, weekly, monthly, yearly, or custom) expand at read time; iCal feeds let external calendar apps subscribe.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/calendar?from=&to= | Items in the window; &just=me, &tasks=true (due to-dos/cards), &projects=, &starred=true |
| POST | /api/v1/{org}/calendar | {project_id (null → account calendar), title, starts_at, ends_at?, all_day?, content_html?, link?, recurrence?, participant_ids?} → 201; invitees are notified |
| PATCH | /api/v1/{org}/calendar/{event_id} | Edit the event or series; invitees are notified of the change |
| DELETE | /api/v1/{org}/calendar/{event_id}/occurrences/{date} | Recurring events: drop one occurrence, or ?mode=future to end the series |
| GET | /api/v1/{org}/calendar/{event_id}/ics | One event as an .ics download ("Add to my calendar…") |
| GET | /api/v1/{org}/calendar/parse?q= | Natural-language prefill: "Team call Friday at 10am" → {title, starts_at, ends_at} |
| GET | /api/v1/{org}/my/events | Your events for the next 7 days |
| GET | /api/v1/{org}/my/do-today | {events, tasks} for today |
| GET / POST | /api/v1/{org}/calendar/feeds | iCal feeds; POST {project_id?, include_tasks?, just?} → {url} |
| DELETE | /api/v1/{org}/calendar/feeds/{id} | Revoke a feed (its token URL stops working) |
Datetimes: starts_at/ends_at accept ISO 8601 with an explicit offset (meaning exactly that instant) or a zoneless wall clock interpreted in your time zone. Recurrence supports intervals, weekday sets, day-of-month or nth-weekday monthly modes, end dates, and an anchoring time zone so "every week at 10 PM" survives DST.
Uploads live in a project's Docs & Files tool; downloads redirect to short-lived signed URLs, and every past version of a file is kept.
| Method | Path | Notes |
|---|---|---|
| POST | /api/v1/{org}/recordings/{folder_id}/uploads | multipart/form-data with file (≤ 50 MB) → 201; optional rich-text notes and notify picker |
| PATCH | /api/v1/{org}/recordings/{id} | Rename via base_name (the extension is kept); edit the notes |
| GET | /api/v1/{org}/uploads/{id}/versions | Current file plus every kept past version, newest first |
| POST | /api/v1/{org}/uploads/{id}/versions | Replace with a new version: same URL, comments, and subscribers; the old file joins the kept list |
| GET | /api/v1/{org}/uploads/{id}/versions/{version_id}/download | 302 presigned download of a past version |
| GET | /api/v1/{org}/uploads/{id}/download | 302 to a short-lived presigned URL |
| GET | /api/v1/{org}/uploads/{id}/file | Stable inline route that rich-text images/audio point at; access is re-checked per request |
| POST | /api/v1/{org}/embeds | {url} → {html}: sanctioned embed markup for the allowlist (YouTube, Vimeo, Loom, Spotify, X, and more) |
Org membership, invitations, and the directory structures around them.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/people | Org members with role, title, company, out-of-office, and avatar |
| GET | /api/v1/{org}/people/{membership_id} | One person's org profile |
| POST | /api/v1/{org}/people | {email, role, company_id?, name?, title?, note?, project_ids?}: invite; projects are granted on accept; plan limits apply → 201 |
| PATCH | /api/v1/{org}/people/{membership_id} | {role?, company_id?, title?}; last-owner protections apply |
| DELETE | /api/v1/{org}/people/{membership_id} | Remove from the org (self = leave); the removal is soft and contributions keep their name |
| GET / POST / DELETE | /api/v1/{org}/people/{membership_id}/out_of_office | Read, set/replace, or clear out-of-office dates (self, or any admin) |
| GET / POST | /api/v1/{org}/companies | POST {name, is_client?} |
| PATCH / DELETE | /api/v1/{org}/companies/{id} | Rename, toggle client status, restrict private chats, or delete (people keep their membership) |
| GET / POST | /api/v1/{org}/groups | Groups bundle non-client people; PATCH {membership_ids: []} replaces members |
| POST | /api/v1/{org}/people/invitations/{id}/resend | Nudge a pending invitee: fresh email, same token |
| GET / PUT | /api/v1/{org}/people/invitations/{id}/projects | Read or replace a pending invitee's grants-on-accept |
| GET / POST / DELETE | /api/v1/{org}/people/invite-link | The org's shareable auto-join link; POST mints or rotates the token, DELETE turns it off |
| POST | /api/v1/{org}/merge-people | {winner_id, loser_id}: irreversible dedupe; winner inherits assignments, subscriptions, access, authorship |
Board categories for organizing posts (defaults are seeded per org).
| Method | Path | Notes |
|---|---|---|
| GET / POST | /api/v1/{org}/categories | POST {name, icon?} (admins) |
| PATCH / DELETE | /api/v1/{org}/categories/{id} | Admins; deleting clears the category from posts |
Snapshot a project's structure (tools, lists, docs, columns, questions) and stamp out new projects from it.
| Method | Path | Notes |
|---|---|---|
| GET / POST | /api/v1/{org}/templates | POST {project_id?, name?, include_assignments?, include_comments?}: from a project, or empty to build up → 201 |
| GET / PATCH / DELETE | /api/v1/{org}/templates/{id} | Template + its tools; PATCH name/description/client setting; DELETE moves it to the trash |
| POST | /api/v1/{org}/templates/{id}/use | {name, description?, all_access?} → a real project; dates shift relative to today, assigned people join → 201 |
Templates never appear in project listings and don't count against the plan's project limit, but instantiating one enforces it.
Your in-app notification tray, snoozes, drafts, bookmarks, and private notes.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/my/notifications | {unread_count, notifications}; ?unread=true |
| PUT | /api/v1/{org}/my/notifications | Mark all read |
| PATCH | /api/v1/{org}/my/notifications/{id} | {read: bool}; false returns it to "New for you" |
| GET | /api/v1/{org}/my/snoozes | Remind-me list: what's due back and what's still waiting |
| POST / DELETE | /api/v1/{org}/my/snoozes/{recording_id} | POST {resurface_at, note?} snoozes the recording; DELETE dismisses |
| GET | /api/v1/{org}/my/drafts | Your unpublished drafts |
| GET / POST | /api/v1/{org}/my/bookmarks | POST {recording_id}; DELETE …/bookmarks/{recording_id} removes one |
| GET / PUT | /api/v1/{org}/my/ui-state | Personal cross-device UI memory (e.g. collapsed board columns) |
| GET / POST | /api/v1/{org}/my/notes | My Notes: private rich-text notes, creator-only; PATCH/DELETE …/my/notes/{id} |
"Stop notifications" for one thread is DELETE /recordings/{id}/subscription. Notification emails carry per-thread unsubscribe links, and quiet hours hold email (and mobile push) outside your working windows.
Personal cross-project work views, an ordered Up Next list, and full-text search over everything you can access.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/my/assignments | Open work assigned to you across projects, priorities (Up Next) first |
| GET | /api/v1/{org}/my/assignments/completed | Your completed assignments, newest first |
| GET | /api/v1/{org}/my/assignments/due?scope= | overdue (default), due_today, due_tomorrow, due_later_this_week, due_next_week, due_later |
| GET / POST | /api/v1/{org}/my/assignments/priorities | Your Up Next list in order; POST {recording_id} adds one of your assignments |
| PATCH / DELETE | /api/v1/{org}/my/assignments/priorities/{recording_id} | PATCH {move: "up" | "down"}; DELETE drops it out of Up Next |
| GET | /api/v1/{org}/search?q=… | Full-text search, relevance-ranked with a recency boost; filters: &project_id=, &type=, &creator_id=, &after=/&before=, &file_type=, &sort=, &page=/&per_page= |
| GET | /api/v1/{org}/search/metadata | Valid type and file_type filter options; fetch these rather than hardcoding |
curl -b cookies.txt \
"https://www.thickethq.com/api/v1/acme/search?q=homepage&type=todo"The account-wide timeline plus cross-project work reports (team only).
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/activity | The account timeline; ?page/?per_page (≤ 100), ?project_id=, ?person_id=, ?starred=1, ?since=ISO, ?q= |
| GET | /api/v1/{org}/people/{membership_id}/events | One person's activity trail (team only) |
| GET | /api/v1/{org}/reports/todos/assigned | Everyone who can have work assigned |
| GET | /api/v1/{org}/reports/todos/assigned/{membership_id} | That person's open assignments; ?group_by=bucket (by project) or date |
| GET | /api/v1/{org}/reports/todos/overdue | All overdue to-dos in lateness buckets, with days late and assignees |
| GET | /api/v1/{org}/reports/calendar/upcoming | Events and dated work in a required date window |
| GET / POST | /api/v1/{org}/roadmap/markers | Org-wide roadmap markers in date order; POST {name, date} (admins). PUT/DELETE …/markers/{id} to move or remove |
Share a single message, document, or file read-only at a revocable public URL: sanitized content only, no comments, noindex.
| Method | Path | Notes |
|---|---|---|
| GET / PUT / DELETE | /api/v1/{org}/recordings/{id}/public-link | PUT publishes (idempotent) → {published, url}; DELETE unpublishes |
| GET / DELETE | /api/v1/{org}/public-items | Owner-only: list every active link, or unpublish everything; DELETE …/public-items/{recording_id} revokes one |
Account-wide behavior: tool display names, chat history retention, required 2FA, and the governance flags that restrict who can edit projects, people, and content.
| Method | Path | Notes |
|---|---|---|
| GET / PATCH | /api/v1/{org}/settings | {tool_names, history_retention_days, require_two_factor, restrict_project_edits, restrict_people_edits, restrict_content_actions, restrict_public_links, limit_comment_editing, …}. Admin+; require_two_factor is owner-only |
Owner-only bulk tools: move a person's open to-dos to someone else, and the account-wide trash.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/reassign/preview?from=&to=&mode= | Count what a reassign/remove/add would touch, per project |
| POST | /api/v1/{org}/reassign | {mode?, from_id, to_id?, project_id?}: reassign (default), remove, or add alongside; completed history is untouched |
| GET | /api/v1/{org}/trash | Everything deleted across all projects; items purge permanently after 30 days |
| POST | /api/v1/{org}/trash/{recording_id}/restore | Restore the item and the subtree trashed with it |
| DELETE | /api/v1/{org}/trash/{recording_id} | Permanent delete, including stored files. Irreversible |
The organization itself: plan, limits, logo, data export, and Stripe billing.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/{org}/account | Name, slug, logo, owners, plan (tier, status, trial, limits), and settings |
| PATCH | /api/v1/{org}/account | {name} renames the account (owner) |
| PUT / DELETE | /api/v1/{org}/account/logo | Upload/replace or remove the account logo (admin+) |
| GET | /api/v1/{org}/account/export | Full JSON export download (owner); ?projects=id,id limits content. Private chats and personal notes are never included |
| GET | /api/v1/{org}/account/storage | Usage vs plan limit, plus largest files |
| DELETE | /api/v1/{org}/account | Cancel the account: access ends immediately and any subscription is cancelled. Data is kept for 30 days, during which any owner can restore from the account picker; after that it is permanently deleted (owner) |
| GET | /api/v1/{org}/billing | Tier, status, trial, and usage vs limits |
| POST | /api/v1/{org}/billing/create-checkout | {price_id, billing_interval} → Stripe Checkout URL (owner) |
| POST | /api/v1/{org}/billing/create-portal | Stripe customer portal URL (owner) |
| GET | /api/billing/prices | Public price catalog (monthly/yearly Pro prices) |
Plans: Free ($0; 1 project, 20 people (clients included), 1 GB), Pro ($49/mo or $468/yr; unlimited projects and people, 50 GB). Per-organization pricing; no per-seat fees. Every new organization starts with a 30-day Pro trial, no card required.
Personal preferences that apply across all of your organizations.
| Method | Path | Notes |
|---|---|---|
| GET / PATCH | /api/v1/me/preferences | Timezone, time format, week start, theme, notification scope and channels, quiet hours, out-of-office, and per-surface view preferences |
| GET / POST | /api/v1/me/tokens | Personal access tokens: list (name, prefix, scope, last used; never the secret) / mint. Session-only; see Authentication |
| DELETE | /api/v1/me/tokens/{id} | Revoke a token, effective immediately (session-only) |
Password, two-factor (TOTP + backup codes), and session management go through the auth endpoints (/api/auth/two-factor/*, /api/auth/change-password).
Stable under /api/v1. This reference tracks the shipped surface and grows with the product. The web app runs on the same routes, so what you read here is what actually runs.
Questions, or need an endpoint detailed? support@thickethq.com