Read and change your teams’ boards from your own code: a script, a form, Zapier, Make or n8n. The API lives at https://trawpie.org/api/v1 and speaks JSON.
1. Get a token
- Make oneYour account ▸ AI agents and API ▸ New token. Choose the teams it can reach, and Read and write if your code will change things.
- Copy itIt’s shown once and starts
trw_. Keep it out of code you share: put it in an environment variable or your tool’s secret store. - Send it with every requestAs a header:
Authorization: Bearer trw_…
2. Your first request
curl https://trawpie.org/api/v1/teams \
-H "Authorization: Bearer $TRAWPIE_TOKEN"{
"teams": [
{ "id": "t_7c1e9a", "name": "Robotics", "your_role": "Owner",
"you_can_change": "everyone’s tasks", "weeks": 12, "this_week": "WEEK 4" }
],
"token": { "name": "Sheets sync", "access": "read and write" },
"today": "2026-11-11"
}Take a team’s id from there for the other endpoints.
Endpoints
| Method and path | What it does |
|---|---|
GET /teams | Your teams, your role in each, and this week. |
POST /teams | Create a team you own, with weeks and categories. |
GET /teams/{team_id}/board | Weeks, people, categories and one week’s tasks. ?week=current|next|all|2026-11-20|WEEK 4, ?person=me|name|email. |
GET /teams/{team_id}/tasks | Search across all weeks: query, person, status (any, open, completed, pending, backlog, none), overdue=true, due_before, limit, offset. |
POST /teams/{team_id}/tasks | Add a task, or up to 50 as {"tasks": […]}: all or none. |
GET /teams/{team_id}/tasks/{task} | One task, by id or TT- reference, with sub-tasks, history and comments. |
PATCH /teams/{team_id}/tasks/{task} | Change its title, priority, due date, status text, flag or week. |
POST …/tasks/{task}/subtasks | Add sub-tasks. |
PATCH …/tasks/{task}/subtasks/{subtask} | Tick or untick one: {"done": true}. Name it by id, number (1 = first) or title. |
POST …/tasks/{task}/comments | Comment: {"text": "…"}. |
POST /teams/{team_id}/weeks | Add weeks at the end or the start. |
POST /teams/{team_id}/categories | Add a category (a row) for someone. |
GET|POST /teams/{team_id}/webhooks | List or add webhooks; also GET|PATCH|DELETE …/webhooks/{id}, POST …/test and POST …/rotate-secret. Webhooks. |
https://trawpie.org/api/v1/openapi.json (OpenAPI 3.1, no token needed). Import it into Postman or Insomnia, or generate a client for your language.Examples
curl -X POST https://trawpie.org/api/v1/teams/t_7c1e9a/tasks \
-H "Authorization: Bearer $TRAWPIE_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: form-entry-1042" \
-d '{"title": "Order motor drivers", "category": "Hardware",
"week": "next", "due_date": "2026-11-20", "priority": "Major",
"subtasks": ["Get two quotes", "Raise the purchase order"]}'curl -X PATCH https://trawpie.org/api/v1/teams/t_7c1e9a/tasks/TT-LNWZM6 \
-H "Authorization: Bearer $TRAWPIE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"flag": "completed"}'curl "https://trawpie.org/api/v1/teams/t_7c1e9a/tasks?overdue=true&person=me" \
-H "Authorization: Bearer $TRAWPIE_TOKEN"const res = await fetch('https://trawpie.org/api/v1/teams/t_7c1e9a/tasks?status=open&limit=100', {
headers: { Authorization: 'Bearer ' + process.env.TRAWPIE_TOKEN },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { tasks, count } = await res.json();
console.log(count + ' open tasks; first: ' + tasks[0].title);import os, requests
r = requests.post(
"https://trawpie.org/api/v1/teams/t_7c1e9a/tasks/TT-LNWZM6/comments",
headers={"Authorization": f"Bearer {os.environ['TRAWPIE_TOKEN']}"},
json={"text": "Quote from Farnell attached to the purchase order."},
)
r.raise_for_status()Errors
Anything that can’t be done answers with an HTTP status and a message that says why, in plain words:
{ "error": { "code": "conflict", "message": "“Chassis review” needs the “Review” sign-off before it can be completed. …" } }| Status | code | Means |
|---|---|---|
| 400 | invalid | Something in the request isn’t right: the message says what. |
| 401 | unauthorized | No token, or it was revoked. |
| 403 | forbidden | A read-only token, a team the token can’t reach, or your role doesn’t allow it. |
| 404 | not_found | No such team, task or route. |
| 409 | conflict | It clashes with the board: a sign-off is needed, a name is taken, or an Idempotency-Key was reused for another request. |
| 413 · 415 | payload_too_large · unsupported_media_type | Bodies are JSON, up to 256 KB. |
| 429 | rate_limited | Over 60 requests this minute or 500 changes today. Wait for Retry-After seconds. |
Limits and paging
- 60 requests a minute and 500 changes a day per token (the day starts at midnight UK time). Agents and the API share a token’s allowance.
- Searches return up to 200 tasks at a time (
limit, default 50). The answer hascount(all matches) andmore(how many are left): ask again withoffsetto get the next page. - A board shows one week by default;
?week=allgives every week, up to 500 tasks.
Retrying safely
Networks fail. Send an Idempotency-Key header (any unique text, up to 200 characters) with a POST, and send the same key if you retry: Trawpie does it once and answers the retry with the first answer (and Idempotent-Replayed: true). Keys are remembered for a day. Changes with PATCH are safe to repeat as they are: a change that’s already made writes nothing.