A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Teamwork API is how an app or AI agent works with a Teamwork account: creating and completing tasks, organizing them into task lists and projects, setting milestones, and logging time. Access is granted through a user's API key or an OAuth token, and there are no per-endpoint permissions, so a call can do whatever the person behind the key is allowed to do in Teamwork. Two generations of the API run together, and it can push events to a webhook when something changes.
How an app or AI agent connects to Teamwork determines what it can reach. There is a route for making calls, a route for receiving events, and a hosted server that exposes Teamwork actions to agents, and each is governed by the key or token behind it.
The REST API answers at a site's own subdomain, https://{yoursite}.teamwork.com. The older v1 paths end in .json, while the newer v3 paths sit under /projects/api/v3/ and use consistent request and response formats. The two run together, and an integration uses v3 where it exists and falls back to v1 for the rest.
Teamwork POSTs an event payload to a registered URL when a chosen event happens, like a task being completed or a project being created. The receiver verifies the X-Projects-Signature header, an HMAC SHA-256 of the body computed with the webhook's token, to confirm the request came from Teamwork. Version 2 of webhooks is the current option.
Teamwork's first-party MCP server lets an AI agent call Teamwork through the Model Context Protocol, with tools for listing, creating, updating, and deleting tasks and projects, plus Teamwork Desk data. It ships as a production HTTP server for cloud and multi-client use, a STDIO server for desktop clients, and a CLI for testing, authenticating with a bearer token or OAuth2. The source is at github.com/Teamwork/mcp.
A user's API token is sent through HTTP Basic auth, as the username with any value as the password, base64-encoded in the Authorization header. The token carries the same account permissions as the user it belongs to, so it can do whatever that person can do. Teamwork advises using it only over HTTPS.
An app registered in the Developer Portal gets a client ID and secret and runs the App Login Flow to obtain a bearer token, sent as Authorization: Bearer. This is the route for an integration that others install, since it acts on behalf of the user who granted access without handling their API token.
The Teamwork API is split into areas an agent can act on, like tasks, task lists, projects, milestones, time, and people. Each call runs as the person behind the key, so an agent sees and changes only what that person is allowed to.
List and read tasks, create them in a task list, update them, mark them complete, and delete them.
List and read task lists, read a list's tasks, and create a new list on a project.
List and read projects, create a project, and update a project's settings.
List and read milestones and create a milestone on a project.
List logged time and log a time entry against a project or a task.
List the people on an account and read a single person's details.
List a task's comments and create a comment on a task, milestone, or other resource.
List the companies on an account and read a single company.
List the tags on an account and apply tags to a resource such as a task or project.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
TasksList and read tasks, create them in a task list, update them, mark them complete, and delete them.6 | ||||||
| GET | /projects/api/v3/tasks.json | List tasks across the account, filtered by project, assignee, status, and more. | read | — | Current | |
Returns only the tasks the person behind the key can see. Teamwork has no per-endpoint API scopes; access follows that person's account permissions. Acts ontask Permission (capability)None required VersionAvailable since the API’s base version Webhook event task-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/api/v3/tasklists/{tasklistId}/tasks.json | List the tasks in a specific task list. | read | — | Current | |
Read access follows the caller's account permissions. Acts ontask Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /projects/api/v3/tasklists/{tasklistId}/tasks.json | Create a new task in the given task list. | write | — | Current | |
The caller must have permission to add tasks to the project the list belongs to. Acts ontask Permission (capability)None required VersionAvailable since the API’s base version Webhook event task-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /projects/api/v3/tasks/{taskId}.json | Update an existing task, such as its title, dates, assignees, or tags. | write | — | Current | |
The caller must have permission to edit the task. Acts ontask Permission (capability)None required VersionAvailable since the API’s base version Webhook event task-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /tasks/{id}/complete.json | Mark a task as complete. | write | — | Current | |
This action is on the older v1 API; there is no v3 equivalent. The caller must be able to edit the task. Acts ontask Permission (capability)None required VersionAvailable since the API’s base version Webhook event task-completedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /tasks/{id}.json | Delete a task. | write | — | Current | |
This action is on the older v1 API; there is no v3 equivalent. The caller must be able to delete the task. Acts ontask Permission (capability)None required VersionAvailable since the API’s base version Webhook event task-deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Task listsList and read task lists, read a list's tasks, and create a new list on a project.3 | ||||||
| GET | /projects/api/v3/tasklists.json | List all task lists across the account. | read | — | Current | |
Read access follows the caller's account permissions. Acts ontasklist Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/api/v3/projects/{projectId}/tasklists.json | List the task lists in a specific project. | read | — | Current | |
Read access follows the caller's account permissions. Acts ontasklist Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /projects/{id}/tasklists.json | Create a task list on a project. | write | — | Current | |
This action is on the older v1 API. The caller must have permission to add lists to the project. Acts ontasklist Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ProjectsList and read projects, create a project, and update a project's settings.4 | ||||||
| GET | /projects/api/v3/projects.json | List projects on the account, with filtering and pagination. | read | — | Current | |
Returns only the projects the caller is a member of or can see. Acts onproject Permission (capability)None required VersionAvailable since the API’s base version Webhook event project-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/api/v3/projects/{projectId}.json | Get a single project's details. | read | — | Current | |
Read access follows the caller's account permissions. Acts onproject Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /projects.json | Create a project. | write | — | Current | |
This action is on the older v1 API. The caller must have permission to create projects on the account. Acts onproject Permission (capability)None required VersionAvailable since the API’s base version Webhook event project-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /projects/{id}.json | Update a project's settings. | write | — | Current | |
This action is on the older v1 API. The caller must have permission to administer the project. Acts onproject Permission (capability)None required VersionAvailable since the API’s base version Webhook event project-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
MilestonesList and read milestones and create a milestone on a project.3 | ||||||
| GET | /projects/api/v3/milestones.json | List milestones across the account. | read | — | Current | |
Read access follows the caller's account permissions. Acts onmilestone Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/api/v3/projects/{projectId}/milestones.json | List the milestones in a specific project. | read | — | Current | |
Read access follows the caller's account permissions. Acts onmilestone Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /projects/{id}/milestones.json | Create a milestone on a project. | write | — | Current | |
This action is on the older v1 API. The caller must have permission to add milestones to the project. Acts onmilestone Permission (capability)None required VersionAvailable since the API’s base version Webhook event milestone-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Time entriesList logged time and log a time entry against a project or a task.3 | ||||||
| GET | /projects/api/v3/time.json | List logged time entries across the account. | read | — | Current | |
Returns only the time entries the caller can access. Acts ontime entry Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /projects/api/v3/projects/{projectId}/time.json | Log a time entry against a project. | write | — | Current | |
The caller must be able to log time on the project. Acts ontime entry Permission (capability)None required VersionAvailable since the API’s base version Webhook event time-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /projects/api/v3/tasks/{taskId}/time.json | Log a time entry against a task. | write | — | Current | |
The caller must be able to log time on the task. Acts ontime entry Permission (capability)None required VersionAvailable since the API’s base version Webhook event time-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
PeopleList the people on an account and read a single person's details.2 | ||||||
| GET | /projects/api/v3/people.json | List the people on the account. | read | — | Current | |
Read access follows the caller's account permissions. Acts onperson Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/api/v3/people/{personId}.json | Get a single person's details. | read | — | Current | |
Read access follows the caller's account permissions. Acts onperson Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CommentsList a task's comments and create a comment on a task, milestone, or other resource.2 | ||||||
| GET | /projects/api/v3/tasks/{taskId}/comments.json | List the comments on a task. | read | — | Current | |
Read access follows the caller's account permissions. Acts oncomment Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /{resource}/{resourceId}/comments.json | Create a comment on a resource such as a task, milestone, or notebook. | write | — | Current | |
This action is on the older v1 API. The resource segment is the type being commented on, such as tasks or milestones. Pass content-type: html for a formatted comment. Acts oncomment Permission (capability)None required VersionAvailable since the API’s base version Webhook event comment-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CompaniesList the companies on an account and read a single company.2 | ||||||
| GET | /projects/api/v3/companies.json | List the companies on the account. | read | — | Current | |
Read access follows the caller's account permissions. Acts oncompany Permission (capability)None required VersionAvailable since the API’s base version Webhook event company-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/api/v3/companies/{companyId}.json | Get a single company's details. | read | — | Current | |
Read access follows the caller's account permissions. Acts oncompany Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TagsList the tags on an account and apply tags to a resource such as a task or project.2 | ||||||
| GET | /projects/api/v3/tags.json | List the tags on the account. | read | — | Current | |
Read access follows the caller's account permissions. Acts ontag Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /{resource}/{resourceId}/tags.json | Set the tags on a resource such as a task, project, or milestone. | write | — | Current | |
This action is on the older v1 API. The resource segment is the type being tagged, such as tasks or projects. Acts ontag Permission (capability)None required VersionAvailable since the API’s base version Webhook event task-taggedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Teamwork can notify an app or AI agent when something happens in an account, like a task being completed or a project being created, instead of the app repeatedly asking. Teamwork posts the event to a webhook URL that has been registered for the chosen events.
| Event | What it signals | Triggered by |
|---|---|---|
TASK.CREATED | Fires when a task is created. | /projects/api/v3/tasklists/{tasklistId}/tasks.json |
TASK.UPDATED | Fires when a task is changed, such as its title, dates, or assignees. | /projects/api/v3/tasks/{taskId}.json |
TASK.COMPLETED | Fires when a task is marked complete. | /tasks/{id}/complete.json |
TASK.DELETED | Fires when a task is deleted. | /tasks/{id}.json |
TASK.TAGGED | Fires when one or more tags are added to a task. | /{resource}/{resourceId}/tags.json |
PROJECT.CREATED | Fires when a project is created. | /projects.json |
PROJECT.UPDATED | Fires when a project is changed. | /projects/{id}.json |
MILESTONE.CREATED | Fires when a milestone is created. | /projects/{id}/milestones.json |
TIME.CREATED | Fires when a time entry is logged. | /projects/api/v3/projects/{projectId}/time.json/projects/api/v3/tasks/{taskId}/time.json |
COMMENT.CREATED | Fires when a comment is created on a task, milestone, or other resource. | /{resource}/{resourceId}/comments.json |
COMPANY.UPDATED | Fires when a company is changed. Company events are at the site level. | In-app only |
Teamwork limits how fast an app or AI agent can call, through a per-account request quota measured per minute that depends on the plan, shared across everyone calling that account.
Teamwork meters requests per account, not per method, and the quota is shared across everyone calling that account. Plans up to and including Grow allow 150 requests per minute, and the Scale plan allows 300 per minute. Going over returns HTTP 429 with a message that the rate limit has been exceeded. Every response carries X-Rate-Limit-Limit, X-Rate-Limit-Remaining, and X-Rate-Limit-Reset, where the reset is a UTC epoch-seconds timestamp for when the window clears. An integration that constantly pulls paged data may have its limit reduced unless it passes an updatedAfterDate parameter, which scopes a sync to recent changes.
v3 list endpoints page through the page and pageSize query parameters and report totals in response headers. The older v1 endpoints page through page and pageSize as well. A large sync should pass updatedAfterDate to fetch only changed records, which Teamwork limits to roughly the last six months when the dataset is large.
Responses are JSON. There is no single documented payload-size ceiling across the API; individual list endpoints cap their page size, and large pulls are expected to page and to filter with updatedAfterDate rather than fetch everything at once.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | Bad Request | The request was malformed or a required field was missing or invalid. | Read the MESSAGE in the response body, correct the request, and resend. |
| 401 | Unauthorized | Authentication failed: the API token is missing, wrong, or the bearer token is invalid or expired. | Send a valid token in the Authorization header, refreshing an OAuth token if it has expired. |
| 403 | Forbidden | The request authenticated, but the person behind the key lacks the account permission for it. Teamwork has no per-endpoint API scopes, so this reflects that person's own permissions. | Grant the person the permission in Teamwork, or call as a user who already has it. |
| 404 | Not Found | The resource does not exist, or the caller cannot see it. | Confirm the id and the path, and that the caller has access to the resource. |
| 422 | Unprocessable Entity | The request was understood but a field failed validation. The body holds a STATUS of Error and a MESSAGE naming the problem. | Read the MESSAGE, fix the named field, and resend. |
| 429 | Too Many Requests | The per-account rate limit was exceeded. The body reads that the rate limit has been exceeded and to try again in a little while. | Wait until the X-Rate-Limit-Reset time, then retry. Pass updatedAfterDate when syncing to avoid a reduced limit. |
Teamwork runs two generations of its API side by side. The older v1 covers the widest set of actions, while the newer v3 is a standards-first redesign with consistent request and response formats, and the two are used together.
v3 is a fresh, standards-first, cross-product API with consistent request and response formats. Its paths sit under /projects/api/v3/ and end in .json, and it is where new read and reporting endpoints land. It runs alongside v1 rather than replacing it, and some areas are still being filled in, so an integration mixes both generations.
v1 is the original Teamwork Projects API, with paths ending in .json. It has the broadest coverage and still holds many actions that v3 does not, including completing a task, deleting a task, creating a project, and creating a milestone. It continues to run alongside v3.
An integration mixes v1 and v3 calls, using v3 where it exists and v1 for the rest.
Teamwork API changelog ↗Bollard AI sits between a team's AI agents and Teamwork. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.