API Documentation

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.

Authentication

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/projects

Required headers

  • Authorization: Bearer thk_... — your API token
  • User-Agent: AppName (contact) — your app name and contact email or URL
  • Content-Type: application/json — for POST/PUT requests

Rate Limiting

API 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:

Pagination

List 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: 47

Caching

GET 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)

Errors

All errors return a consistent JSON shape:

{
  "error": "Human-readable message",
  "code": "MACHINE_READABLE_CODE",
  "detail": "Optional additional context"
}
StatusCodeDescription
400BAD_REQUESTInvalid request parameters
400MISSING_USER_AGENTMissing User-Agent header
401UNAUTHORIZEDMissing or invalid credentials
401TOKEN_REVOKEDToken has been revoked
401TOKEN_EXPIREDToken has expired
403INSUFFICIENT_PERMISSIONToken lacks required permission
404RESOURCE_NOT_FOUNDResource doesn't exist or is inaccessible
422VALIDATION_ERRORRequest body failed validation
429RATE_LIMITEDToo many requests — check Retry-After header
500INTERNAL_ERRORServer error — retry with exponential backoff

Versioning

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.

Endpoints

Projects

GET/api/v1/projects

List all projects in the organization.

Query parameters

page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: projects:read

POST/api/v1/projects

Create a new project.

Request body

name*
string
Project name
description
string
Project description

Permission 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"
  }'
GET/api/v1/projects/:id

Get a single project by ID.

Permission required: projects:read

PUT/api/v1/projects/:id

Update a project.

Request body

name
string
New project name
description
string
New description

Permission required: projects:write

DELETE/api/v1/projects/:id

Trash a project.

Permission required: projects:write

Tools

Tools are the building blocks within a project — Grove boards, to-do lists, and more.

GET/api/v1/projects/:id/tools

List all tools in a project.

Permission required: tools:read

POST/api/v1/projects/:id/tools

Create a new tool in a project.

Request body

name*
string
Tool name
type*
string
Tool type (e.g., GROVE, TODOLIST)

Permission required: tools:write

GET/api/v1/projects/:id/tools/:toolId

Get a single tool by ID.

Permission required: tools:read

PUT/api/v1/projects/:id/tools/:toolId

Update a tool.

Request body

name
string
New tool name

Permission required: tools:write

DELETE/api/v1/projects/:id/tools/:toolId

Delete a tool from a project.

Permission required: tools:write

PUT/api/v1/projects/:id/tools/:toolId/enable

Enable a tool.

Permission required: tools:write

PUT/api/v1/projects/:id/tools/:toolId/disable

Disable a tool.

Permission required: tools:write

PUT/api/v1/projects/:id/tools/:toolId/position

Update a tool's position in the project.

Request body

position*
integer
New position (0-indexed)

Permission required: tools:write

Grove Cards

Grove cards are items on a project's Grove board. All Grove endpoints are scoped to a project.

GET/api/v1/projects/:id/grove

List Grove tools in a project.

Permission required: kanban:read

GET/api/v1/projects/:id/grove/cards

List cards in a project's Grove board. Returns paginated results grouped by status.

Query parameters

status
string
Filter by status: CONSIDERING, IN_PROGRESS, or DONE
archived
boolean
Include archived cards (default: false)
page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: kanban:read

POST/api/v1/projects/:id/grove/cards

Create a new card in a project's Grove board.

Request body

title*
string
Card title
description
string
Card description (plain text)
status
string
CONSIDERING (default), IN_PROGRESS, or DONE
assigneeId
string (UUID)
User ID to assign the card to
label
string
Card label/tag
dueDate
string (ISO 8601)
Due date
priority
string
NORMAL (default), LOW, HIGH, URGENT

Permission 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"
  }'
GET/api/v1/projects/:id/grove/cards/:cardId

Get a single Grove card by ID.

Permission required: kanban:read

PUT/api/v1/projects/:id/grove/cards/:cardId

Update a Grove card. Send only the fields you want to change.

Request body (all optional)

title
string
New title
description
string
New description
status
string
CONSIDERING, IN_PROGRESS, or DONE
assigneeId
string (UUID)
Reassign to a user
archived
boolean
Archive or unarchive
label
string
Update label
dueDate
string (ISO 8601)
Update due date
priority
string
Update priority

Permission required: kanban:write

DELETE/api/v1/projects/:id/grove/cards/:cardId

Permanently delete a Grove card.

Permission required: kanban:write

PUT/api/v1/projects/:id/grove/cards/:cardId/move

Move a card to a new column and position.

Request body

status*
string
Target column: CONSIDERING, IN_PROGRESS, or DONE
position*
integer
Position in the column (0-indexed)

Permission required: kanban:write

To-do Lists

To-do lists organize todos within a project. Each list contains ordered todo items.

GET/api/v1/projects/:id/todolists

List all to-do lists in a project.

Permission required: todos:read

POST/api/v1/projects/:id/todolists

Create a new to-do list in a project.

Request body

name*
string
List name
description
string
List description

Permission 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"
  }'
GET/api/v1/projects/:id/todolists/:listId

Get a single to-do list by ID.

Permission required: todos:read

PUT/api/v1/projects/:id/todolists/:listId

Update a to-do list.

Request body

name
string
New list name
description
string
New description

Permission required: todos:write

DELETE/api/v1/projects/:id/todolists/:listId

Delete a to-do list and all its todos.

Permission required: todos:write

To-dos

GET/api/v1/projects/:id/todolists/:listId/todos

List all todos in a to-do list.

Query parameters

page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: todos:read

POST/api/v1/projects/:id/todolists/:listId/todos

Create a new todo in a list.

Request body

content*
string
Todo content
assigneeId
string (UUID)
User ID to assign the todo to
dueDate
string (ISO 8601)
Due date

Permission 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"
  }'
GET/api/v1/projects/:id/todos/:todoId

Get a single todo by ID.

Permission required: todos:read

PUT/api/v1/projects/:id/todos/:todoId

Update a todo.

Request body (all optional)

content
string
New content
assigneeId
string (UUID)
Reassign to a user
dueDate
string (ISO 8601)
Update due date

Permission required: todos:write

DELETE/api/v1/projects/:id/todos/:todoId

Permanently delete a todo.

Permission required: todos:write

PUT/api/v1/projects/:id/todos/:todoId/complete

Mark a todo as complete.

Permission required: todos:write

PUT/api/v1/projects/:id/todos/:todoId/uncomplete

Mark a todo as incomplete.

Permission required: todos:write

PUT/api/v1/projects/:id/todos/:todoId/position

Reorder a todo within its list.

Request body

position*
integer
New position (0-indexed)

Permission required: todos:write

Messages

Messages are posted to a project's message board. Think announcements, updates, and discussions.

GET/api/v1/projects/:id/messages

List messages in a project. Returns paginated results.

Query parameters

page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: messages:read

POST/api/v1/projects/:id/messages

Create a new message.

Request body

title*
string
Message title
content*
string
Message body
category_id
string (UUID)
Message category ID
visible_to_clients
boolean
Whether the message is visible to client users

Permission 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..."
  }'
GET/api/v1/projects/:id/messages/:msgId

Get a single message by ID.

Permission required: messages:read

PUT/api/v1/projects/:id/messages/:msgId

Update a message.

Request body (all optional)

title
string
New title
content
string
New body
category_id
string (UUID)
Update category
visible_to_clients
boolean
Update client visibility
pinned
boolean
Pin or unpin the message

Permission required: messages:write

DELETE/api/v1/projects/:id/messages/:msgId

Trash a message.

Permission required: messages:write

Events

Events are scheduled items on a project's schedule. Meetings, deadlines, milestones.

GET/api/v1/projects/:id/events

List events in a project. Returns paginated results.

Query parameters

page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: events:read

POST/api/v1/projects/:id/events

Create a new event.

Request body

title*
string
Event title
description
string
Event description
location
string
Event location
start_time*
string (ISO 8601)
Start time
end_time
string (ISO 8601)
End time
all_day
boolean
Whether this is an all-day event
video_link
string
Video call link

Permission 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"
  }'
GET/api/v1/projects/:id/events/:eventId

Get a single event by ID.

Permission required: events:read

PUT/api/v1/projects/:id/events/:eventId

Update an event.

Request body (all optional)

title
string
New title
description
string
New description
location
string
New location
start_time
string (ISO 8601)
New start time
end_time
string (ISO 8601)
New end time
all_day
boolean
Toggle all-day
video_link
string
Update video link

Permission required: events:write

DELETE/api/v1/projects/:id/events/:eventId

Trash an event.

Permission required: events:write

Documents

Documents are rich text docs in a project's Docs tool. Supports versioning — every title/content change creates a new version.

GET/api/v1/projects/:id/documents

List documents in a project. Returns paginated results.

Query parameters

status
string
Filter by status: draft, published, or scheduled
folder_id
string (UUID)
Filter by folder
page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: docs:read

POST/api/v1/projects/:id/documents

Create a new document.

Request body

title*
string
Document title
content*
string
Document body
status
string
Status: draft (default), published, or scheduled
folder_id
string (UUID)
Folder to place the document in
color
string
Document color
visible_to_clients
boolean
Whether the document is visible to client users
notify_option
string
Notification option for publishing
scheduled_for
string (ISO 8601)
Scheduled publish date (when status is "scheduled")

Permission 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"
  }'
GET/api/v1/projects/:id/documents/:docId

Get a single document by ID. Includes the latest 5 versions.

Permission required: docs:read

PUT/api/v1/projects/:id/documents/:docId

Update a document. Creates a new version if title or content changed.

Request body (all optional)

title
string
New title
content
string
New body
status
string
Update status
folder_id
string (UUID)
Move to a folder
color
string
Update color
visible_to_clients
boolean
Update client visibility
notify_option
string
Update notification option
scheduled_for
string (ISO 8601)
Update scheduled publish date
position
integer
Reorder within folder

Permission required: docs:write

DELETE/api/v1/projects/:id/documents/:docId

Trash a document.

Permission required: docs:write

Comments

Comments can be added to messages, todos, documents, and events. Polymorphic — one API for all content types.

GET/api/v1/projects/:id/comments

List all comments in a project. Optionally filter by content type.

Query parameters

commentable_type
string
Filter by type: message, task, document, or event
commentable_id
string (UUID)
Filter by specific resource ID
page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: comments:read

POST/api/v1/projects/:id/messages/:msgId/comments

Add a comment to a message.

Request body

content*
string
Comment body

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."
  }'
POST/api/v1/projects/:id/todos/:todoId/comments

Add a comment to a todo.

Request body

content*
string
Comment body

Permission required: comments:write

POST/api/v1/projects/:id/documents/:docId/comments

Add a comment to a document.

Request body

content*
string
Comment body

Permission required: comments:write

POST/api/v1/projects/:id/events/:eventId/comments

Add a comment to an event.

Request body

content*
string
Comment body

Permission required: comments:write

PUT/api/v1/projects/:id/comments/:commentId

Update a comment.

Request body

content*
string
New comment body

Permission required: comments:write

DELETE/api/v1/projects/:id/comments/:commentId

Trash a comment.

Permission required: comments:write

Chat

Project chat rooms (Campfire-style). Post lines, read history. No real-time — poll for new messages.

GET/api/v1/projects/:id/chats

List chat rooms for a project.

Permission required: chat:read

GET/api/v1/projects/:id/chats/:chatId/lines

List lines in a chat room. Returns paginated results, newest first.

Query parameters

page
integer
Page number (default: 1)
per_page
integer
Results per page, 1-100 (default: 25)

Permission required: chat:read

POST/api/v1/projects/:id/chats/:chatId/lines

Post a new line to a chat room.

Request body

content*
string
Line content
reply_to_id
string (UUID)
ID of the line to reply to

Permission 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!"
  }'
GET/api/v1/projects/:id/chats/:chatId/lines/:lineId

Get a single chat line by ID.

Permission required: chat:read

DELETE/api/v1/projects/:id/chats/:chatId/lines/:lineId

Trash a chat line.

Permission required: chat:write

People

People in your organization and project members.

GET/api/v1/people

List all people in your organization.

Permission required: people:read

GET/api/v1/people/:personId

Get a single person by ID.

Permission required: people:read

GET/api/v1/projects/:id/people

List people in a project.

Permission required: people:read

GET/api/v1/my/profile

Get 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

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 created
  • task.updated — a task's fields were changed
  • task.completed — a task was marked as complete
  • task.deleted — a task was permanently deleted

Card events

  • card.created — a new card was added to a Grove board
  • card.updated — a card's fields were changed (title, description, assignee, etc.)
  • card.moved — a card was moved to a different column
  • card.deleted — a card was permanently deleted

Delivery behavior

  • Deliveries timeout after 10 seconds
  • Failed deliveries retry up to 3 times with exponential backoff (0s, 10s, 60s)
  • 4xx responses are not retried (considered permanent failures)
  • Maximum 10 active webhooks per organization
GET/api/v1/webhooks?organizationId=...

List active webhooks for an organization.

Requires: admin or owner role (session auth)

POST/api/v1/webhooks

Create a new webhook. Returns the signing secret once — store it securely.

Request body

organizationId*
string (UUID)
Organization ID
url*
string
HTTPS endpoint URL to receive events
events
string[]
Event types to subscribe to. Default: all events

Requires: 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"
  }
}
GET/api/v1/webhooks/:webhookId

Get webhook details and recent delivery history (last 25 deliveries).

Requires: admin or owner role (session auth)

PUT/api/v1/webhooks/:webhookId

Update a webhook's URL, events, or active status.

Request body (all optional)

url
string
New HTTPS endpoint URL
events
string[]
New event subscriptions
active
boolean
Enable or disable the webhook

Requires: admin or owner role (session auth)

DELETE/api/v1/webhooks/:webhookId

Permanently delete a webhook and its delivery history.

Requires: admin or owner role (session auth)

Token Management

These endpoints require session authentication (browser) and admin or owner role in the organization.

GET/api/v1/tokens?organizationId=...

List active API tokens for an organization.

Requires: admin or owner role (session auth)

POST/api/v1/tokens

Create a new API token. Returns the token value once — store it securely.

Request body

organizationId*
string (UUID)
Organization ID
name*
string
Token name (1-100 characters)
permissions
string[]
Array of permissions. Default: all permissions
expiresAt
string (ISO 8601)
Optional expiration date

Requires: admin or owner role (session auth). Max 25 active tokens per org.

DELETE/api/v1/tokens/:tokenId

Revoke a token. Takes effect immediately.

Requires: admin or owner role (session auth)

Permissions

API tokens are scoped with permissions selected at creation time:

PermissionAccess
projects:readRead projects
projects:writeCreate, update, and delete projects
tools:readRead tools within projects
tools:writeCreate, update, enable/disable, reorder, and delete tools
kanban:readRead Grove cards and board data
kanban:writeCreate, update, move, and delete Grove cards
todos:readRead to-do lists and todos
todos:writeCreate, update, complete, reorder, and delete todos and lists
messages:readRead messages and categories
messages:writeCreate, update, pin, and delete messages
events:readRead scheduled events
events:writeCreate, update, and delete events
docs:readRead documents and folders
docs:writeCreate, update, and delete documents
comments:readRead comments on any content type
comments:writeCreate, update, and delete comments
chat:readRead chat rooms and lines
chat:writePost and delete chat lines
people:readRead organization members and project people

Questions about the API? Get in touch.