The Thicket API lets you manage projects, tools, Grove cards, and to-dos programmatically. Use it to build integrations, automate workflows, or sync data with other tools.
All API requests require a bearer token. Create one in your organization's Settings → API Tokens page (admin or owner role required).
curl -H "Authorization: Bearer thk_your_token_here" \
-H "User-Agent: MyApp ([email protected])" \
https://www.thickethq.com/api/v1/projectsRequired headers
Authorization: Bearer thk_... — your API tokenUser-Agent: AppName (contact) — your app name and contact email or URLContent-Type: application/json — for POST/PUT requestsAPI requests are limited to 50 requests per 10 seconds per token. When you exceed the limit, you'll receive a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.
Every response includes rate limit headers:
X-RateLimit-Limit — requests allowed per windowX-RateLimit-Remaining — requests remaining in current windowX-RateLimit-Reset — Unix timestamp when the window resetsList endpoints return paginated results. Use page and per_page query parameters to navigate. Default: 25 results per page, maximum: 100.
The Link header follows RFC 5988 and provides URLs for next, prev, first, and last pages. The X-Total-Count header contains the total number of resources.
# Response headers
Link: <https://...?page=2&per_page=25>; rel="next", <https://...?page=1&per_page=25>; rel="first"
X-Total-Count: 47GET responses include an ETag header. On subsequent requests, pass it as If-None-Match to receive a 304 Not Modified response when content hasn't changed, saving bandwidth.
# First request — save the ETag
curl -i -H "Authorization: Bearer thk_..." \
https://www.thickethq.com/api/v1/projects
# ETag: W/"a1b2c3d4e5f6g7h8"
# Subsequent request — send it back
curl -H "Authorization: Bearer thk_..." \
-H 'If-None-Match: W/"a1b2c3d4e5f6g7h8"' \
https://www.thickethq.com/api/v1/projects
# 304 Not Modified (no body)All errors return a consistent JSON shape:
{
"error": "Human-readable message",
"code": "MACHINE_READABLE_CODE",
"detail": "Optional additional context"
}| Status | Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid request parameters |
| 400 | MISSING_USER_AGENT | Missing User-Agent header |
| 401 | UNAUTHORIZED | Missing or invalid credentials |
| 401 | TOKEN_REVOKED | Token has been revoked |
| 401 | TOKEN_EXPIRED | Token has expired |
| 403 | INSUFFICIENT_PERMISSION | Token lacks required permission |
| 404 | RESOURCE_NOT_FOUND | Resource doesn't exist or is inaccessible |
| 422 | VALIDATION_ERROR | Request body failed validation |
| 429 | RATE_LIMITED | Too many requests — check Retry-After header |
| 500 | INTERNAL_ERROR | Server error — retry with exponential backoff |
All endpoints are under /api/v1/. Every response includes an X-Api-Version header. We commit to no breaking changes within a version. New fields may be added to responses — your client should ignore unknown fields. If we deprecate an endpoint, we'll announce it with a Sunset header well in advance.
/api/v1/projectsList all projects in the organization.
Query parameters
pageper_pagePermission required: projects:read
/api/v1/projectsCreate a new project.
Request body
name*descriptionPermission required: projects:write
curl -X POST https://www.thickethq.com/api/v1/projects \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"name": "Marketing Website",
"description": "Q2 website redesign"
}'/api/v1/projects/:idGet a single project by ID.
Permission required: projects:read
/api/v1/projects/:idUpdate a project.
Request body
namedescriptionPermission required: projects:write
/api/v1/projects/:idTrash a project.
Permission required: projects:write
Tools are the building blocks within a project — Grove boards, to-do lists, and more.
/api/v1/projects/:id/toolsList all tools in a project.
Permission required: tools:read
/api/v1/projects/:id/toolsCreate a new tool in a project.
Request body
name*type*Permission required: tools:write
/api/v1/projects/:id/tools/:toolIdGet a single tool by ID.
Permission required: tools:read
/api/v1/projects/:id/tools/:toolIdUpdate a tool.
Request body
namePermission required: tools:write
/api/v1/projects/:id/tools/:toolIdDelete a tool from a project.
Permission required: tools:write
/api/v1/projects/:id/tools/:toolId/enableEnable a tool.
Permission required: tools:write
/api/v1/projects/:id/tools/:toolId/disableDisable a tool.
Permission required: tools:write
/api/v1/projects/:id/tools/:toolId/positionUpdate a tool's position in the project.
Request body
position*Permission required: tools:write
Grove cards are items on a project's Grove board. All Grove endpoints are scoped to a project.
/api/v1/projects/:id/groveList Grove tools in a project.
Permission required: kanban:read
/api/v1/projects/:id/grove/cardsList cards in a project's Grove board. Returns paginated results grouped by status.
Query parameters
statusarchivedpageper_pagePermission required: kanban:read
/api/v1/projects/:id/grove/cardsCreate a new card in a project's Grove board.
Request body
title*descriptionstatusassigneeIdlabeldueDatepriorityPermission required: kanban:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/grove/cards \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"title": "Implement feature X",
"status": "IN_PROGRESS"
}'/api/v1/projects/:id/grove/cards/:cardIdGet a single Grove card by ID.
Permission required: kanban:read
/api/v1/projects/:id/grove/cards/:cardIdUpdate a Grove card. Send only the fields you want to change.
Request body (all optional)
titledescriptionstatusassigneeIdarchivedlabeldueDatepriorityPermission required: kanban:write
/api/v1/projects/:id/grove/cards/:cardIdPermanently delete a Grove card.
Permission required: kanban:write
/api/v1/projects/:id/grove/cards/:cardId/moveMove a card to a new column and position.
Request body
status*position*Permission required: kanban:write
To-do lists organize todos within a project. Each list contains ordered todo items.
/api/v1/projects/:id/todolistsList all to-do lists in a project.
Permission required: todos:read
/api/v1/projects/:id/todolistsCreate a new to-do list in a project.
Request body
name*descriptionPermission required: todos:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/todolists \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"name": "Launch Checklist"
}'/api/v1/projects/:id/todolists/:listIdGet a single to-do list by ID.
Permission required: todos:read
/api/v1/projects/:id/todolists/:listIdUpdate a to-do list.
Request body
namedescriptionPermission required: todos:write
/api/v1/projects/:id/todolists/:listIdDelete a to-do list and all its todos.
Permission required: todos:write
/api/v1/projects/:id/todolists/:listId/todosList all todos in a to-do list.
Query parameters
pageper_pagePermission required: todos:read
/api/v1/projects/:id/todolists/:listId/todosCreate a new todo in a list.
Request body
content*assigneeIddueDatePermission required: todos:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/todolists/LIST_ID/todos \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"content": "Review pull request"
}'/api/v1/projects/:id/todos/:todoIdGet a single todo by ID.
Permission required: todos:read
/api/v1/projects/:id/todos/:todoIdUpdate a todo.
Request body (all optional)
contentassigneeIddueDatePermission required: todos:write
/api/v1/projects/:id/todos/:todoIdPermanently delete a todo.
Permission required: todos:write
/api/v1/projects/:id/todos/:todoId/completeMark a todo as complete.
Permission required: todos:write
/api/v1/projects/:id/todos/:todoId/uncompleteMark a todo as incomplete.
Permission required: todos:write
/api/v1/projects/:id/todos/:todoId/positionReorder a todo within its list.
Request body
position*Permission required: todos:write
Messages are posted to a project's message board. Think announcements, updates, and discussions.
/api/v1/projects/:id/messagesList messages in a project. Returns paginated results.
Query parameters
pageper_pagePermission required: messages:read
/api/v1/projects/:id/messagesCreate a new message.
Request body
title*content*category_idvisible_to_clientsPermission required: messages:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/messages \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"title": "Weekly Update",
"content": "Here is what we shipped this week..."
}'/api/v1/projects/:id/messages/:msgIdGet a single message by ID.
Permission required: messages:read
/api/v1/projects/:id/messages/:msgIdUpdate a message.
Request body (all optional)
titlecontentcategory_idvisible_to_clientspinnedPermission required: messages:write
/api/v1/projects/:id/messages/:msgIdTrash a message.
Permission required: messages:write
Events are scheduled items on a project's schedule. Meetings, deadlines, milestones.
/api/v1/projects/:id/eventsList events in a project. Returns paginated results.
Query parameters
pageper_pagePermission required: events:read
/api/v1/projects/:id/eventsCreate a new event.
Request body
title*descriptionlocationstart_time*end_timeall_dayvideo_linkPermission required: events:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/events \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"title": "Sprint Planning",
"start_time": "2026-03-10T10:00:00Z",
"end_time": "2026-03-10T11:00:00Z",
"location": "Conference Room B"
}'/api/v1/projects/:id/events/:eventIdGet a single event by ID.
Permission required: events:read
/api/v1/projects/:id/events/:eventIdUpdate an event.
Request body (all optional)
titledescriptionlocationstart_timeend_timeall_dayvideo_linkPermission required: events:write
/api/v1/projects/:id/events/:eventIdTrash an event.
Permission required: events:write
Documents are rich text docs in a project's Docs tool. Supports versioning — every title/content change creates a new version.
/api/v1/projects/:id/documentsList documents in a project. Returns paginated results.
Query parameters
statusfolder_idpageper_pagePermission required: docs:read
/api/v1/projects/:id/documentsCreate a new document.
Request body
title*content*statusfolder_idcolorvisible_to_clientsnotify_optionscheduled_forPermission required: docs:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/documents \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"title": "Engineering Onboarding Guide",
"content": "Welcome to the team! Here is everything you need...",
"status": "published"
}'/api/v1/projects/:id/documents/:docIdGet a single document by ID. Includes the latest 5 versions.
Permission required: docs:read
/api/v1/projects/:id/documents/:docIdUpdate a document. Creates a new version if title or content changed.
Request body (all optional)
titlecontentstatusfolder_idcolorvisible_to_clientsnotify_optionscheduled_forpositionPermission required: docs:write
/api/v1/projects/:id/documents/:docIdTrash a document.
Permission required: docs:write
Comments can be added to messages, todos, documents, and events. Polymorphic — one API for all content types.
/api/v1/projects/:id/commentsList all comments in a project. Optionally filter by content type.
Query parameters
commentable_typecommentable_idpageper_pagePermission required: comments:read
/api/v1/projects/:id/messages/:msgId/commentsAdd a comment to a message.
Request body
content*Permission required: comments:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/messages/MSG_ID/comments \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"content": "Great update! Looks like we are on track."
}'/api/v1/projects/:id/todos/:todoId/commentsAdd a comment to a todo.
Request body
content*Permission required: comments:write
/api/v1/projects/:id/documents/:docId/commentsAdd a comment to a document.
Request body
content*Permission required: comments:write
/api/v1/projects/:id/events/:eventId/commentsAdd a comment to an event.
Request body
content*Permission required: comments:write
/api/v1/projects/:id/comments/:commentIdUpdate a comment.
Request body
content*Permission required: comments:write
/api/v1/projects/:id/comments/:commentIdTrash a comment.
Permission required: comments:write
Project chat rooms (Campfire-style). Post lines, read history. No real-time — poll for new messages.
/api/v1/projects/:id/chatsList chat rooms for a project.
Permission required: chat:read
/api/v1/projects/:id/chats/:chatId/linesList lines in a chat room. Returns paginated results, newest first.
Query parameters
pageper_pagePermission required: chat:read
/api/v1/projects/:id/chats/:chatId/linesPost a new line to a chat room.
Request body
content*reply_to_idPermission required: chat:write
curl -X POST https://www.thickethq.com/api/v1/projects/PROJECT_ID/chats/CHAT_ID/lines \
-H "Authorization: Bearer thk_..." \
-H "Content-Type: application/json" \
-H "User-Agent: MyApp ([email protected])" \
-d '{
"content": "Deploy looks good, shipping it!"
}'/api/v1/projects/:id/chats/:chatId/lines/:lineIdGet a single chat line by ID.
Permission required: chat:read
/api/v1/projects/:id/chats/:chatId/lines/:lineIdTrash a chat line.
Permission required: chat:write
People in your organization and project members.
/api/v1/peopleList all people in your organization.
Permission required: people:read
/api/v1/people/:personIdGet a single person by ID.
Permission required: people:read
/api/v1/projects/:id/peopleList people in a project.
Permission required: people:read
/api/v1/my/profileGet your own profile. No special permission required — any valid token works.
curl https://www.thickethq.com/api/v1/my/profile \
-H "Authorization: Bearer thk_..." \
-H "User-Agent: MyApp ([email protected])"Webhooks notify your application in real-time when events happen in Thicket. Configure an HTTPS endpoint and we'll POST event payloads to it with an HMAC-SHA256 signature for verification.
Verifying webhook signatures
Each delivery includes an X-Webhook-Signature header with format sha256=HMAC_HEX. Compute HMAC-SHA256 of the raw request body using your webhook secret and compare with a timing-safe equality check.
Available events
Task events
task.created — a new task was createdtask.updated — a task's fields were changedtask.completed — a task was marked as completetask.deleted — a task was permanently deletedCard events
card.created — a new card was added to a Grove boardcard.updated — a card's fields were changed (title, description, assignee, etc.)card.moved — a card was moved to a different columncard.deleted — a card was permanently deletedDelivery behavior
/api/v1/webhooks?organizationId=...List active webhooks for an organization.
Requires: admin or owner role (session auth)
/api/v1/webhooksCreate a new webhook. Returns the signing secret once — store it securely.
Request body
organizationId*url*eventsRequires: admin or owner role (session auth). Max 10 active webhooks per org.
# Example card event payload POSTed to your URL
{
"event": "card.created",
"created_at": "2026-02-27T18:30:00.000Z",
"data": {
"card": {
"id": "...",
"title": "Implement feature X",
"status": "IN_PROGRESS",
...
},
"project_id": "project-uuid",
"tool_id": "grove-board-uuid"
}
}/api/v1/webhooks/:webhookIdGet webhook details and recent delivery history (last 25 deliveries).
Requires: admin or owner role (session auth)
/api/v1/webhooks/:webhookIdUpdate a webhook's URL, events, or active status.
Request body (all optional)
urleventsactiveRequires: admin or owner role (session auth)
/api/v1/webhooks/:webhookIdPermanently delete a webhook and its delivery history.
Requires: admin or owner role (session auth)
These endpoints require session authentication (browser) and admin or owner role in the organization.
/api/v1/tokens?organizationId=...List active API tokens for an organization.
Requires: admin or owner role (session auth)
/api/v1/tokensCreate a new API token. Returns the token value once — store it securely.
Request body
organizationId*name*permissionsexpiresAtRequires: admin or owner role (session auth). Max 25 active tokens per org.
/api/v1/tokens/:tokenIdRevoke a token. Takes effect immediately.
Requires: admin or owner role (session auth)
API tokens are scoped with permissions selected at creation time:
| Permission | Access |
|---|---|
projects:read | Read projects |
projects:write | Create, update, and delete projects |
tools:read | Read tools within projects |
tools:write | Create, update, enable/disable, reorder, and delete tools |
kanban:read | Read Grove cards and board data |
kanban:write | Create, update, move, and delete Grove cards |
todos:read | Read to-do lists and todos |
todos:write | Create, update, complete, reorder, and delete todos and lists |
messages:read | Read messages and categories |
messages:write | Create, update, pin, and delete messages |
events:read | Read scheduled events |
events:write | Create, update, and delete events |
docs:read | Read documents and folders |
docs:write | Create, update, and delete documents |
comments:read | Read comments on any content type |
comments:write | Create, update, and delete comments |
chat:read | Read chat rooms and lines |
chat:write | Post and delete chat lines |
people:read | Read organization members and project people |
Questions about the API? Get in touch.