---
title: "Upsert a task"
method: POST
path: "/public/v1/tasks"
tags: ["Task"]
---

# Upsert a task

`POST /public/v1/tasks`

Creates or updates a single task in one call. Omit `id` to create a new task; pass the `id` of
an existing task to update it. Responds 201 on create and 200 on update, with the full saved
task as the body. The task's creator is always the API key's user; it cannot be set.

On create, `name`, `status`, and `due_datetime` are required. On update every field is optional:
this is a sparse update, so only the fields you send are changed and any field you omit keeps its
stored value. Sending a nullable optional field (`description`, `color`, `owner_id`,
`location_id`) as null clears it; sending a required field as null is rejected with a 400.

Linking to another entity: set exactly one of `order_id`, `invoice_id`, `purchase_id`,
`contact_id`, `product_id`, `batch_id`, `assembly_id`, `return_id`, or `company_id`. Sending more
than one is a 400. The linked entity must exist in your company. The link is set-once: once a task
is linked, the link cannot be changed or removed, and sending any relation field for an
already-linked task is a 400. The linked entity is returned as the matching relation field in the
response.

Required permission: `tasks_permissions_create` to create, `tasks_permissions_edit` to update.

## Request body

- object
  - `id` string — ID of the task to update. Omit to create. When present but not matching a task in your company, the request fails.
  - `name` string — The task's name. Required on create. On update, omit to leave unchanged.
  - `description` string — Free-form description. Optional. On update, send null to clear.
  - `status` 'ACTIVE' | 'COMPLETED' — The task's status. Required on create.
  - `due_datetime` string — When the task is due, as a UTC ISO8601 datetime. Required on create.
  - `color` string — A label color for the task. Must be one of the company's allowed default colors. Optional; send null to clear.
  - `owner_id` string — ID of the user the task is assigned to. Optional; send null to unassign. Must be a user you are allowed to assign.
  - `location_id` string — ID of the location the task is at. Optional; send null to clear.
  - `custom_data` object — Custom field values as an object keyed by custom field ID. Replaces the stored custom data when sent; omit to leave unchanged. Use `GET /public/v1/custom-fields` to find Task field IDs and their value formats.
  - `order_id` string — Link this task to an order. Set-once; at most one relation field.
  - `invoice_id` string — Link this task to an invoice. Set-once; at most one relation field.
  - `purchase_id` string — Link this task to a purchase. Set-once; at most one relation field.
  - `contact_id` string — Link this task to a contact. Set-once; at most one relation field.
  - `product_id` string — Link this task to a product. Set-once; at most one relation field.
  - `batch_id` string — Link this task to a batch. Set-once; at most one relation field.
  - `assembly_id` string — Link this task to an assembly. Set-once; at most one relation field.
  - `return_id` string — Link this task to a return. Set-once; at most one relation field.
  - `company_id` string — Link this task to a company relationship, by its ID. Set-once; at most one relation field.

## Response `200`

The updated task

## Other responses

- `201` — The created task
- `400` — Invalid parameters
- `401` — Missing or invalid API token
- `403` — The API token lacks the required permission
- `404` — Not Found

---

[API](https://skmtc.dev/distru/apis/distru-api.md) · [All operations](https://skmtc.dev/distru/apis/distru-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/distru/distru-api/revisions/eb775b7b6ee0/schema)
