# Add Task

Source: https://help.zira.us/developers/api-reference/add-task
Summary: Create a task from integration requests.
Updated: 2026-08-06

## `POST /task/`

Use this endpoint to create a task in Zira from an external integration flow.

## Authentication

```http
x-api-key: <your-api-key>
Content-Type: application/json
```

See [API Authentication](/developers/api-reference/api-authentication) for how to create a key.

## Request body

Send the task fields needed to create a task in the integration context.

```json
{
  "name": "Replace inlet filter on Line 1",
  "siteId": "1512",
  "typeId": "1",
  "priorityId": "10",
  "statusId": "5",
  "toChannelId": "45187",
  "description": "Differential pressure above threshold for two shifts."
}
```

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | Task name. |
| `siteId` | string | yes | Site the task belongs to. |
| `typeId` | string | yes | Task type. `"1"` for a manual task, `"3"` for a task about a data source. Send it explicitly — leaving it out makes the request fail asking for `deviceId`. |
| `deviceId` | string | no | Data source the task is about. Required when `typeId` is `"3"`, and not allowed when `typeId` is `"1"`. |
| `priorityId` | string | no | Priority — `5` Low, `10` Medium, `15` High. An unrecognised value is silently ignored. |
| `statusId` | string | no | Status. Defaults to `"5"` (To Do). Omit the key rather than sending `null`. |
| `description` | string | no | Plain-text task description. |
| `dueDate` | string | no | When the task is due. |
| `assigneeId` | string | no | User to assign the task to. |
| `toChannelId` | string | no | Channel the task’s feed post is created in. |
| `fileIds` | string[] | no | Files to attach to the task. |
| `formattedDescription` | object[] | no | Rich-text description as an array of nodes. A plain HTML string is rejected — use `description` for plain text. |
| `timeSpentMandatory` | boolean | no | Require time to be logged before the task can be completed. |
| `noInitialComment` | boolean | no | Set true to skip the automatic opening comment. Omit it rather than sending false. |

## Response

`200 OK`

Returns the new task’s ID as a bare number under `data`. The created task is not echoed back — call `GET /tasks` if you need the full record.

```json
{
  "data": 9901
}
```

| Field | Type | Description |
| --- | --- | --- |
| `data` | number | ID of the newly created task. It comes back as a number, while `GET /tasks` returns task IDs as strings — convert before comparing. |

### Good to know

- Send `typeId` explicitly. Leave it out and the request fails asking for `deviceId`; send `typeId: "1"` and `deviceId` must be omitted; send `typeId: "3"` and `deviceId` is required.
- Creating a task also creates a feed post for it in the target channel and adds an opening comment. Send `noInitialComment: true` to skip the comment.
- Assignees and followers are always notified — there is no way to create a task silently.
- The body is strict: any field not listed above is rejected with `400`. That includes `imageIds`, `mentions`, `hashtags` and `ctas`, which belong to posts rather than tasks.
- All IDs must be quoted strings. `siteId: 15` as a number is a `400`; so are `"0"` and `""`.
- `statusId` defaults to `"5"` (To Do) and `typeId` to `"1"`. Sending an explicit `null` for either is rejected — omit the key instead.
- An ID that does not exist — an unknown priority, status or site — is accepted and then quietly ignored, so the task is created without that field set. Check your IDs.
- Do not add a query string to this request; it interferes with body validation and produces a misleading `400`.

## Errors

Failures return a JSON body with a `message` and an `internalErrorCode`, at the status shown below. Whenever the underlying error carries structured detail — which every schema-validation failure does — the body is replaced with a generic `Internal server error.` / `02-001` pair while the real status code is kept. Branch on the HTTP status and on `internalErrorCode`; never parse the message text.

```json
{
  "message": "Internal server error.",
  "internalErrorCode": "02-001"
}
```

| Status | Meaning |
| --- | --- |
| `400` | The request failed validation — a missing required field, a field the schema does not allow, an unparseable body, a value out of range, or a malformed `lastValue`. |
| `401` | The API key resolved to a user context that is not allowed to read or write the record you asked for. |
| `403` | The `x-api-key` header is missing or is not a recognised key. API Gateway rejects the call before the endpoint runs, so the body is only `{"message":"Forbidden"}`. |
| `409` | The write conflicts with an existing record, or it references a record that does not exist. |
| `429` | The API key exceeded the rate limit or quota on its usage plan. Also returned by API Gateway rather than the endpoint. |
| `500` | Unexpected server error, or the database returned no result where one was required. |
