API

Create and update tasks from your own tools, from an AI agent reading a Slack thread, or while moving off another tracker. Plain REST over HTTPS - no SDK, nothing to install.

curl -s https://app.taskbite.rocks/api/v1/me \
  -H "Authorization: Bearer $TASKBITE_TOKEN" \
  -H "Accept: application/json"

Authentication

A bearer token, created in Settings → API tokens inside your workspace. It is shown once; only a hash is stored, so a leaked token can be revoked but never recovered.

Authorization: Bearer 7|xxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

What a token can do

A token belongs to a person, not to the workspace, and carries exactly that person's permissions. There is no master key with rights of its own:

To give an integration narrower access, add a Member, put them on just the projects it should touch, and make the token as them.

Endpoints

Base URL: https://app.taskbite.rocks/api/v1

EndpointWhat it does
GET /meThe token's user, workspace, and the exact status and priority strings this workspace uses
GET /clientsq, with_projects, per_page
POST /clientsOwner only
GET /projectsclient_id, status, q
POST /projects
GET /tasksproject_id, status, assignee_id, q, updated_since
POST /tasks
GET /tasks/{id}
PATCH /tasks/{id}Send only the fields that changed
POST /tasks/{id}/commentsInternal by default - see below

Lists are paginated (per_page, max 100) and return data, links, meta.

Statuses and priorities

Read these from /me rather than hard-coding them. Statuses are todo, doing, qa, review, bug, done - note that "in progress" is spelled doing and "completed" is done. Priorities are low, normal, high, urgent.

Creating a task

curl -s -X POST https://app.taskbite.rocks/api/v1/tasks \
  -H "Authorization: Bearer $TASKBITE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "project_id": 31,
    "title": "Fix the double-charge on annual upgrade",
    "description": "<p>From #support, 12 Mar.</p>",
    "status": "todo",
    "priority": "high",
    "assignee_email": "sam@studio.com",
    "due_date": "2026-03-20",
    "estimate_minutes": 120
  }'

Only project_id and title are required. An assignee_email matching nobody leaves the task unassigned rather than failing - an import shouldn't stop because one person left the company.

Two field names differ from the app on purpose. estimate_minutes is minutes, because the form takes hours and a field called "estimate" would get sent 2 when it meant 120. And visible_to_client defaults to false - a task filed by a machine is yours until you say otherwise.

Comments are internal by default

The opposite of the app's composer, and deliberate: an agent summarising a thread must not email your client because nobody thought about the default. Pass "internal": false to deliver it normally.

curl -s -X POST https://app.taskbite.rocks/api/v1/tasks/99/comments \
  -H "Authorization: Bearer $TASKBITE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"body": "<p>Agreed to ship behind a flag first.</p>"}'

Moving off another tracker

For a one-off migration you do not need this API at all - there is a visual importer in Settings → Import. Upload a CSV export, point each column at a field, preview exactly what it would create, then run it. It reads ClickUp, ActiveCollab, Trello and Asana exports without being told which is which.

Through the API, send external_source and that system's own id as external_ref. TaskBite matches on the pair, so running the same import twice updates instead of duplicating - a half-finished migration is safe to simply run again.

# The client, then its project, then the tasks - each referring
# to the one above by the OTHER system's id, so you never have to
# hold a map of TaskBite ids while importing.

POST /clients   {"name":"Northwind","external_source":"clickup",
                 "external_ref":"space_9001"}

POST /projects  {"name":"Rebuild","client_external_ref":"space_9001",
                 "external_source":"clickup","external_ref":"list_4410"}

POST /tasks     {"title":"Migrate the blog","project_external_ref":"list_4410",
                 "external_source":"clickup","external_ref":"task_77123"}

Every write returns meta.created: true for a new record, false when an existing one was matched and updated.

Errors

Always JSON.

CodeMeaning
401Token missing, malformed, or revoked
403The token's owner lacks the role - a Member creating a client, say
404Not in this workspace, or in a project this person can't see
422Validation. The body names the field

404 not distinguishing "doesn't exist" from "not yours" is deliberate - telling them apart would confirm that some other workspace holds that id.

{
  "message": "No project of yours matches that.",
  "errors": { "project_id": ["No project of yours matches that."] }
}

Get a token

Start free, then open Settings → API tokens. Free workspaces get the API too.