For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at /guide/api/conventions.md.

APIIntroduction

Conventions

The response envelope, identifiers, filters, dates and other patterns shared by every endpoint.

Every endpoint in the Developer API follows the same handful of rules. Learn them once and the other 58 endpoints behave the way you expect.

#Everything is a POST

Including the reads. projects/list and tasks/search are POST calls just like tasks/create.

That is a consequence of the encrypted payload: filters and identifiers travel inside the encrypted body rather than the query string, so there is no meaningful GET form. Two practical effects:

  • Never cache responses on the assumption that POST means "changes data".
  • URLs are stable and carry no parameters, which keeps them out of proxy logs.

#The response envelope

Every response — success or failure — has the same three top-level fields:

json
{
  "success": true,
  "message": "Projects retrieved successfully",
  "data": []
}
successbooleanrequired

Whether the operation completed. Check this rather than inferring from the presence of data.

messagestringrequired

A human-readable summary. Useful in logs; do not branch on its wording.

dataobject | array

The payload. Collection endpoints return an array, single-record endpoints return an object. Absent on some error responses.

Tip

Branch on the HTTP status code first, then on success. A 200 with "success": false is possible for soft failures such as an empty filter match on some endpoints.

#Identifiers

Records are addressed by UUID, not by the numeric primary key:

json
{ "project_id": "550e8400-e29b-41d4-a716-446655440000" }
FieldRefers to
project_idA project's uniq_id
task_idA task's UUID
assigned_toA numeric user id, not a UUID

Users are the exception

Assignment fields such as assigned_to take the integer user id returned by users/list. Passing a UUID there fails validation.

#Filters

List endpoints take an optional filters object. Unknown keys are ignored, so a typo silently returns unfiltered results — check your filter names when a response looks too large.

json
{
  "filters": {
    "status": "Started",
    "start_date": "2024-01-01",
    "end_date": "2024-12-31"
  }
}

Date filters are inclusive: start_date matches records on or after the date, end_date matches records on or before it.

#Dates and times

KindFormatExample
DateYYYY-MM-DD2024-01-15
TimestampYYYY-MM-DD HH:MM:SS2024-01-10 10:30:00
Signing timestampUnix seconds1704806400

Timestamps in responses are in the workspace's configured timezone, not UTC. The X-TIMESTAMP header used for signing is always Unix epoch seconds.

#Statuses and priorities

These are validated against fixed sets. Sending anything else returns 422.

FieldAccepted values
Task prioritylow, medium, high, urgent
Task statusOpen, Closed
Project statusStarted, Hold, Stack, Completed

Note

Workspaces that use custom task statuses still accept Open and Closed over the API; the custom status is reported in the task detail response.

#Creating versus updating

create endpoints return the new record's UUID in data. update endpoints take that UUID plus only the fields you want to change — omitted fields are left alone, they are not blanked.

To clear a field, send an explicit empty value rather than omitting it.

#Deletes are usually archives

Endpoints named delete in the test-management area archive the record rather than destroying it, so links from defects and runs stay intact. Check each endpoint's description for the exact behaviour.

#Pagination

Collection endpoints return the full filtered set. Where an endpoint supports paging it is documented on that endpoint's own page — do not assume page and limit are accepted everywhere.

⚠️Errors

Status codes, validation failures and what to retry.