API reference
Tasks
Tasks on the task board: create them, link them to a customer or deal, move, complete and reopen them.
Endpoints
-
GET
/tasksList tasks -
GET
/tasks/{task}Retrieve a task -
POST
/tasksCreate a task -
PATCH
/tasks/{task}Update a task -
POST
/tasks/{task}/moveMove a task -
POST
/tasks/{task}/completeComplete a task -
POST
/tasks/{task}/reopenReopen a task -
POST
/tasks/{task}/cancelCancel a task -
DELETE
/tasks/{task}Delete a task
List tasks
/api/v1/tasks
A list of tasks, newest first. Filter by status, priority, user, board, column, customer or modification date.
- Scope
-
tasks.read— Read tasks, boards and comments - Required feature
tasks
Query parameters
| Name | Type | Description |
|---|---|---|
limit
|
integer | Number of results per page. from 1 to 100 · default: 50 |
cursor
|
string | The next_cursor or prev_cursor from meta of the previous response. |
sort
|
string | Sort by created_at or updated_at; a leading minus sign sorts descending. one of: -created_at, created_at, -updated_at, updated_at · default: -created_at |
filter[status]
|
string | Only tasks with this status: open, in_progress, completed or cancelled. one of: open, in_progress, completed, cancelled |
filter[priority]
|
string | Only tasks with this priority. one of: low, normal, high, urgent |
filter[assigned_user_id]
|
string | Only what is assigned to this user (the id from List users). |
filter[board_id]
|
string (uuid) | Only tasks on this board. |
filter[status_id]
|
string (uuid) | Only tasks in this column. |
filter[customer_id]
|
string (uuid) | Only what belongs to this customer. |
filter[updated_since]
|
string (date-time) | Only what changed since this moment: ISO 8601 with a time zone, for example 2026-09-14T10:15:00Z. Useful for synchronising. |
Example request
curl "https://app.klantly.com/api/v1/tasks?filter[status]=open" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'tasks', [
'query' => [
'filter[status]' => 'open',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks?filter[status]=open', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/tasks",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "open"
},
)
data = response.json()["data"]Response 200
The response is a list with cursor pagination: data contains the objects, meta the pagination.
{
"data": [
{
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
422
validation_failed— The input is invalid.
Retrieve a task
/api/v1/tasks/{task}
One task by id, with its links and whether there are open actions.
- Scope
-
tasks.read— Read tasks, boards and comments - Required feature
tasks
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Example request
curl "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
404
not_found— Not found.
Create a task
/api/v1/tasks
Creates a task. Without status_id it lands in the open column of the default board. Use links to link it to a customer, deal, appointment, work order, quote or invoice. The assigned user gets a notification, just like on screen.
- Scope
-
tasks.write— Create, update, move and complete tasks, and post comments - Required feature
tasks
Send an Idempotency-Key and a retry after a timeout will never create a duplicate record.
Body (JSON)
| Field | Type | Description |
|---|---|---|
title
required
|
string | Title of the task. at most 500 characters |
description
optional
|
string | Description. can be empty (null) · at most 10000 characters |
priority
optional
|
string | low, normal (default), high or urgent. one of: low, normal, high, urgent |
due_date
optional
|
string (date) | Deadline as YYYY-MM-DD, or null. can be empty (null) |
assigned_user_id
optional
|
string | The user doing the task, or null. can be empty (null) |
status_id
optional
|
string (uuid) | The column on the board. Optional when creating; without a column: the open column of the default board. can be empty (null) |
links
optional
|
array | The records the task belongs to (up to 20). |
Example request
curl -X POST "https://app.klantly.com/api/v1/tasks" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"title": "Offerte nabellen",
"due_date": "2026-10-01",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
]
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'tasks', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'title' => 'Offerte nabellen',
'due_date' => '2026-10-01',
'assigned_user_id' => 'usr_0k3j9x21m4zq8p',
'links' => [
0 => [
'object' => 'customer',
'id' => '9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70',
],
],
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"title": "Offerte nabellen",
"due_date": "2026-10-01",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
]
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/tasks",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"title": "Offerte nabellen",
"due_date": "2026-10-01",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
]
},
)
data = response.json()["data"]Response 201
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
422
validation_failed— The input is invalid. -
422
unknown_field— The input contains an unknown field. -
415
unsupported_media_type— This format is not supported. -
413
payload_too_large— The request body is too large. -
422
idempotency_key_reused— This Idempotency-Key was already used for a different request. -
409
idempotency_in_progress— A request with this Idempotency-Key is still in progress.
Update a task
/api/v1/tasks/{task}
Changes only the fields you send. links replaces the links as a whole; links the API does not show (such as to a conversation) stay, and sending the same links again changes nothing. A change shows up in the task's history, just like on screen. To change the column or status, use move, complete, reopen or cancel.
- Scope
-
tasks.write— Create, update, move and complete tasks, and post comments - Required feature
tasks
Send the ETag in If-Match and you will never accidentally overwrite a newer version.
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Body (JSON)
| Field | Type | Description |
|---|---|---|
title
optional
|
string | Title of the task. at most 500 characters |
description
optional
|
string | Description. can be empty (null) · at most 10000 characters |
priority
optional
|
string | low, normal (default), high or urgent. one of: low, normal, high, urgent |
due_date
optional
|
string (date) | Deadline as YYYY-MM-DD, or null. can be empty (null) |
assigned_user_id
optional
|
string | The user doing the task, or null. can be empty (null) |
links
optional
|
array | The records the task belongs to (up to 20). |
Example request
curl -X PATCH "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"priority": "high"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('PATCH', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
'json' => [
'priority' => 'high',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"priority": "high"
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
json={
"priority": "high"
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
422
validation_failed— The input is invalid. -
422
unknown_field— The input contains an unknown field. -
415
unsupported_media_type— This format is not supported. -
413
payload_too_large— The request body is too large. -
404
not_found— Not found. -
412
precondition_failed— The record has been changed in the meantime.
Move a task
/api/v1/tasks/{task}/move
Moves the task to another column, just like dragging it on the board. The column determines the status. It cannot move to a completed column while there are open actions.
- Scope
-
tasks.write— Create, update, move and complete tasks, and post comments - Required feature
tasks
Send an Idempotency-Key and a retry after a timeout will never create a duplicate record.
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Body (JSON)
| Field | Type | Description |
|---|---|---|
status_id
required
|
string (uuid) | The id of the column the task moves to (from List task boards). |
Example request
curl -X POST "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'status_id' => '9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8"
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
422
validation_failed— The input is invalid. -
422
unknown_field— The input contains an unknown field. -
415
unsupported_media_type— This format is not supported. -
413
payload_too_large— The request body is too large. -
404
not_found— Not found. -
409
invalid_state_transition— This action is not possible in the current status. -
422
idempotency_key_reused— This Idempotency-Key was already used for a different request. -
409
idempotency_in_progress— A request with this Idempotency-Key is still in progress.
Complete a task
/api/v1/tasks/{task}/complete
Completes the task. If it still has open actions, you get 409: complete or skip them in Klantly first.
- Scope
-
tasks.write— Create, update, move and complete tasks, and post comments - Required feature
tasks
Send an Idempotency-Key and a retry after a timeout will never create a duplicate record.
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Example request
curl -X POST "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
404
not_found— Not found. -
409
invalid_state_transition— This action is not possible in the current status. -
422
idempotency_key_reused— This Idempotency-Key was already used for a different request. -
409
idempotency_in_progress— A request with this Idempotency-Key is still in progress.
Reopen a task
/api/v1/tasks/{task}/reopen
Puts a completed or cancelled task back to open.
- Scope
-
tasks.write— Create, update, move and complete tasks, and post comments - Required feature
tasks
Send an Idempotency-Key and a retry after a timeout will never create a duplicate record.
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Example request
curl -X POST "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reopen" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reopen', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reopen', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/reopen",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
404
not_found— Not found. -
422
idempotency_key_reused— This Idempotency-Key was already used for a different request. -
409
idempotency_in_progress— A request with this Idempotency-Key is still in progress.
Cancel a task
/api/v1/tasks/{task}/cancel
Cancels the task.
- Scope
-
tasks.write— Create, update, move and complete tasks, and post comments - Required feature
tasks
Send an Idempotency-Key and a retry after a timeout will never create a duplicate record.
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Example request
curl -X POST "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "task",
"id": "9d3f7fc5-6bad-4c2a-9f7e-8d9bacbdced6",
"title": "Offerte nabellen",
"description": null,
"status": "open",
"priority": "normal",
"due_date": "2026-10-01",
"board_id": "9d3f80e6-7cbe-4d3b-8a8f-9eacbdcedfe7",
"status_id": "9d3f8207-8dcf-4e4c-9b9a-afbdcedfe0f8",
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"links": [
{
"object": "customer",
"id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70"
}
],
"has_open_actions": false,
"completed_at": null,
"cancelled_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
404
not_found— Not found. -
422
idempotency_key_reused— This Idempotency-Key was already used for a different request. -
409
idempotency_in_progress— A request with this Idempotency-Key is still in progress.
Delete a task
/api/v1/tasks/{task}
Deletes the task permanently, with its comments and actions.
- Scope
-
tasks.delete— Delete tasks - Required feature
tasks
Path parameters
| Name | Type | Description |
|---|---|---|
task required |
string (uuid) | The id (UUID) of the task. |
Example request
curl -X DELETE "https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('DELETE', 'tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.delete(
"https://app.klantly.com/api/v1/tasks/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Response 200
{
"data": {
"object": "note",
"id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
"deleted": true
}
}Possible errors
-
403
insufficient_scope— This API key has no access to this action. -
404
not_found— Not found.
The object
All fields are always present; a field without a value is null.
| Field | Type | Description |
|---|---|---|
object |
string | Always "task". |
id |
string (uuid) | Unique id (UUID). |
title |
string | Title of the task. |
description |
string | Description. can be empty (null) |
status |
string | open, in_progress, completed or cancelled; follows from the column. one of: open, in_progress, completed, cancelled |
priority |
string | low, normal (default), high or urgent. one of: low, normal, high, urgent |
due_date |
string (date) | Deadline as YYYY-MM-DD, or null. can be empty (null) |
board_id |
string (uuid) | The board the task is on. can be empty (null) |
status_id |
string (uuid) | The column on the board. Optional when creating; without a column: the open column of the default board. can be empty (null) |
assigned_user_id |
string | The user doing the task, or null. can be empty (null) |
links |
array<object> | The records the task belongs to (up to 20). |
links.object |
string | Kind of record: customer, deal, appointment, work_order, quote or invoice. one of: customer, deal, appointment, work_order, quote, invoice |
links.id |
string (uuid) | Id (UUID) of the record. |
has_open_actions |
boolean | Are there open actions on the task? Then it cannot be completed. |
completed_at |
string (date-time) | When the task was completed. can be empty (null) |
cancelled_at |
string (date-time) | When the task was cancelled. can be empty (null) |
created_at |
string (date-time) | Created at (UTC). |
updated_at |
string (date-time) | Last updated at (UTC). |