# Conventions

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

> For the complete documentation index, see [llms.txt](https://helpdesk.orangescrum.com/llms.txt).

Source: https://helpdesk.orangescrum.com/guide/api/conventions

---
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": []
}
```

- `success` *boolean* (required) — Whether the operation completed. Check this rather than inferring from the presence of `data`.

- `message` *string* (required) — A human-readable summary. Useful in logs; do not branch on its wording.

- `data` *object | 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" }
```

| Field | Refers to |
| --- | --- |
| `project_id` | A project's `uniq_id` |
| `task_id` | A task's UUID |
| `assigned_to` | A **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

| Kind | Format | Example |
| --- | --- | --- |
| Date | `YYYY-MM-DD` | `2024-01-15` |
| Timestamp | `YYYY-MM-DD HH:MM:SS` | `2024-01-10 10:30:00` |
| Signing timestamp | Unix seconds | `1704806400` |

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`.

| Field | Accepted values |
| --- | --- |
| Task `priority` | `low`, `medium`, `high`, `urgent` |
| Task `status` | `Open`, `Closed` |
| Project `status` | `Started`, `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](https://helpdesk.orangescrum.com/guide/api/errors): Status codes, validation failures and what to retry.
