Errors
HTTP status codes
| Status | Meaning |
|---|---|
200 | All rows succeeded (POST/GET), or the task was deleted (DELETE) |
207 Multi-Status | Partial success on POST — at least one row failed; inspect results[].status and results[].error |
400 Bad Request | Invalid request body or query parameter — malformed JSON, empty tasks array, more than 1,000 items, or a bad done/type/limit/updatedSince |
401 Unauthorized | Missing, malformed, or revoked API key |
403 Forbidden | API key lacks the required scope (read:tasks or write:tasks) |
404 Not Found | DELETE only — {id} matched no task in this workspace |
429 Too Many Requests | Rate limit exceeded |
Request-level errors
When the whole request is rejected (before any rows are processed), the response body is:
{ "error": "<message>" }Examples:
{ "error": "tasks must not be empty." }{ "error": "Max 1000 tasks per request." }These are returned with a 400 status.
Per-row validation errors (207)
A row that fails validation does not abort the batch. The failed row is skipped and reported in results with "status": "error" and a human-readable error string:
{
"created": 2,
"updated": 0,
"errors": 1,
"results": [
{ "index": 0, "status": "created", "id": "cmq7task0alk34567890" },
{ "index": 1, "status": "updated", "id": "cmq8task1alk34567891" },
{
"index": 2,
"status": "error",
"error": "contactExternalId: no contact found for \"NOPE\"."
}
]
}The error string format is field: message for each failing validation, joined by ; . Field names match the Task object reference.
When the response status is 207, the rows that succeeded were still written to the database. Only rows listed with "status": "error" were skipped.
DELETE errors
DELETE /api/v1/tasks/{id} returns a 404 when {id} — checked as both a record ID and an externalId — matches nothing in the workspace:
{ "error": "Task not found." }A successful delete is permanent and not reversible. There is no undo endpoint.
Limits
- Max 1,000 tasks per request on
POST— enforced at the request level (400if exceeded). - Each API key is limited to 120 requests/minute (platform-enforced). Exceeding it returns
429 Too Many Requestswith aRetry-Afterheader (seconds until the window resets). - Keep request payloads reasonable in size; a body-size cap is also on the roadmap.