This page covers the standard behaviours that apply across all API endpoints — how lists are paginated, how dates are formatted, how to send partial updates, and what to expect when something goes wrong.
All list results are paginated. You can control what gets returned using these parameters:
| Parameter | Type | Default | Notes |
|---|---|---|---|
| page | int | 1 | Values below 1 are clamped to 1 |
| pageSize | int | 20 | Clamped between 1 and 50 |
| search | string | none | Optional free-text filter; matched field varies per resource (see below) |
If you request a page beyond the last one, you'll get an empty list — not an error.
All date/time fields are DateTimeOffset, serialized with an explicit offset rather than a trailing Z, e.g. 2026-08-10T09:30:00+00:00. Parse these as offset-aware timestamps, not as UTC-with-Z.
PATCH bodies are partial: only include the fields you want to change. Fields omitted (or null) are left untouched, so you cannot use this API to clear a field back to null. Sending a field with an empty string ("") will overwrite the existing value with an empty string. Omit the field entirely to leave it alone.
Response bodies are not consistent in shape across the API. This is a known inconsistency, not something you should try to pattern-match strictly on. You'll see one of four shapes, depending on where the error originates:
Plain text: for validation-style rejections the controller raises directly. Content-Type is text/plain, and the body is the raw message, not a quoted JSON string:
workflowId is required.
A structured JSON object: for errors raised internally by shared services (project/activity access and existence checks):
{ "status": 0, "message": "Project not found" }
(note: these messages don't end in a period)
A generic problem-details object: for plain 404/401 results the framework generates automatically, with no message specific to what you requested:
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5", "title": "Not Found", "status": 404, "traceId": "..." }
A validation problem-details object with an errors map: when a query parameter or body field can't even be parsed into the expected type (e.g. a non-numeric page, or a status value that isn't a number):
{ "title": "One or more validation errors occurred.", "status": 400, "errors": { "$.status": ["The JSON value could not be converted to System.Int64."] } }
In all cases, the HTTP status code is the reliable signal. Check that first, and treat the body as a human-readable message rather than a machine-parsed contract.
| Code | Meaning |
|---|---|
| 200 OK | Successful GET |
| 204 No Content | Successful PATCH / DELETE (see per-endpoint notes; a 204 doesn't always mean something actually changed) |
| 400 Bad Request | Missing/invalid required parameter or field, or a query/body value that can't be parsed into the expected type |
| 401 Unauthorized | Missing, malformed, or invalid/inactive API key |
| 403 Forbidden | Key lacks write permission, or the underlying user cannot read/write this resource in its current state |
| 404 Not Found | Resource does not exist (or, for some resources, is not visible to the caller; see per-endpoint notes) |
| 409 Conflict | The write would leave the record in an invalid state (activities only; see Activities) |
| 422 Unprocessable Entity | Rare. Only reachable from a small set of internal validation exceptions that normal API usage isn't expected to hit |
| 500 Internal Server Error | Unexpected server-side failure. The response body is not guaranteed to contain a useful message |