Kanban Cards
Manage custom cards on Kanban boards. List, retrieve, create, update, and move cards between columns.
All endpoints on this page require a valid JWT token, API key, and tenant header. See Authentication for details.
List Cards
Retrieve a paginated list of cards for a specific board.
/apidev/v1/kanban/boards/{id}/cardsRequest Headers
Every request to a protected endpoint requires these headers:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token obtained from the Login endpoint. Format: Bearer <token> |
X-API-Key | Yes | Company integration key provided during onboarding. Format: gtk_xxx... |
tenant | Yes | Your company hostname (e.g., yourcompany.geotareas.com) |
Content-Type | Conditional | application/json — required for POST and PUT requests |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Board unique identifier (BigInt) |
Query Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
limit | integer | No | 100 | Min 1, Max 100 | Records per page |
offset | integer | No | 0 | ≥ 0 | Records to skip |
column_id | string | No | — | Max length 30 | Filter by column ID (BigInt) |
priority | string | No | — | NONE, LOW, MEDIUM, HIGH, URGENT | Filter by priority |
assignee_id | string | No | — | Max length 30 | Filter by assignee ID (BigInt) |
search | string | No | — | Max length 120 | Search card title |
archived | boolean | No | false | — | Include archived cards |
Response
| Field | Type | Description |
|---|---|---|
id | string | Card unique identifier (BigInt) |
board_id | string | Parent board ID (BigInt) |
column_id | string | Current column ID (BigInt) |
column_name | string | Current column name |
title | string | Card title |
description | string | null | Card description |
priority | string | Priority level |
color | string | null | Card color hex code |
due_date | string | null | Due date (ISO 8601) |
labels | array | Label objects with name and color |
checklist_total | integer | Total checklist items |
checklist_completed | integer | Completed checklist items |
assignee | object | null | {id, name} of the assignee |
comments_count | integer | Number of comments |
order | integer | Position within the column |
archived | boolean | Whether the card is archived |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "$TENANT_URL/apidev/v1/kanban/boards/8391728491728491/cards?limit=20&priority=HIGH" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/boards/8391728491728491/cards?limit=20&priority=HIGH`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
},
}
);
const { data, meta } = await response.json();
console.log(`Fetched ${data.length} of ${meta.total} cards`);
import requests
response = requests.get(
f"{TENANT_URL}/apidev/v1/kanban/boards/8391728491728491/cards",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
params={"limit": 20, "priority": "HIGH"},
)
result = response.json()
for card in result["data"]:
print(f"{card['id']}: {card['title']} [{card['column_name']}]")
Example Response
{
"success": true,
"data": [
{
"id": "4200000000000001",
"board_id": "8391728491728491",
"column_id": "9100000000000002",
"column_name": "In Progress",
"title": "Review Q1 fleet maintenance schedule",
"description": "Verify all units have scheduled maintenance before April.",
"priority": "HIGH",
"color": "#EF4444",
"due_date": "2026-03-25T18:00:00",
"labels": [{"name": "maintenance", "color": "#F59E0B"}],
"checklist_total": 5,
"checklist_completed": 3,
"assignee": {"id": "1100000000000001", "name": "Carlos Mendoza"},
"comments_count": 3,
"order": 1,
"archived": false,
"created_at": "2026-03-10T09:00:00",
"updated_at": "2026-03-18T14:30:00"
}
],
"meta": {
"total": 8,
"limit": 20,
"offset": 0
}
}
Rate Limit Headers
Every response includes rate limit information in the headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed in the current window |
X-RateLimit-Remaining | Number of requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp (seconds) when the current window resets |
Retry-After | Seconds to wait before retrying (only present on 429 responses) |
X-Request-Id | Unique request identifier for debugging and support tickets |
Card Detail
Retrieve the full details for a single card, including checklist items and custom fields.
/apidev/v1/kanban/cards/{id}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Card unique identifier (BigInt) |
Response
Returns all fields from the List endpoint, plus:
| Field | Type | Description |
|---|---|---|
checklist | array | [{text, checked}] checklist items |
custom_fields | array | [{field_id, name, type, value}] custom field values |
created_by | object | {id, name} of the creator |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "$TENANT_URL/apidev/v1/kanban/cards/4200000000000001" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/cards/4200000000000001`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
},
}
);
const { data } = await response.json();
console.log(`Card "${data.title}" — ${data.comments_count} comments`);
import requests
response = requests.get(
f"{TENANT_URL}/apidev/v1/kanban/cards/4200000000000001",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
)
card = response.json()["data"]
print(f"{card['title']} — priority: {card['priority']}, comments: {card['comments_count']}")
Example Response
{
"success": true,
"data": {
"id": "4200000000000001",
"board_id": "8391728491728491",
"column_id": "9100000000000002",
"column_name": "In Progress",
"title": "Review Q1 fleet maintenance schedule",
"description": "Verify all units have scheduled maintenance before April.",
"priority": "HIGH",
"color": "#EF4444",
"due_date": "2026-03-25T18:00:00",
"labels": [{"name": "maintenance", "color": "#F59E0B"}],
"checklist": [
{"text": "Check unit 01 schedule", "checked": true},
{"text": "Check unit 02 schedule", "checked": true},
{"text": "Check unit 03 schedule", "checked": true},
{"text": "Order replacement parts", "checked": false},
{"text": "Confirm technician availability", "checked": false}
],
"assignee": {"id": "1100000000000001", "name": "Carlos Mendoza"},
"custom_fields": [
{"field_id": "6200000000000001", "name": "Region", "type": "select", "value": "North"}
],
"comments_count": 3,
"created_by": {"id": "1100000000000002", "name": "Admin User"},
"created_at": "2026-03-10T09:00:00",
"updated_at": "2026-03-18T14:30:00",
"archived": false
},
"meta": {}
}
Create Card
Create a new card on a board. Returns HTTP 201.
/apidev/v1/kanban/cardsRequest Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
board_id | string | Yes | Max length 30 | Target board ID (BigInt) |
column_id | string | Yes | Max length 30 | Target column ID (BigInt) |
title | string | Yes | Max length 500 | Card title |
description | string | No | Max length 5000 | Card description |
priority | string | No | Max length 10 | NONE, LOW, MEDIUM, HIGH, URGENT |
color | string | No | Max length 10 | Hex color code |
due_date | string | No | Max length 30 | ISO 8601 date |
labels | array | No | — | [{name (required, max 50), color (max 10)}] |
checklist | array | No | — | [{text (required, max 500), checked (boolean)}] |
assignee_id | string | No | Max length 30 | Assignee user ID (BigInt) |
custom_fields | array | No | — | [{field_id (required, max 30), value (max 500)}] |
Response
| Field | Type | Description |
|---|---|---|
id | string | Created card ID (BigInt) |
board_id | string | Board ID (BigInt) |
column_id | string | Column ID (BigInt) |
title | string | Card title |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X POST "$TENANT_URL/apidev/v1/kanban/cards" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"board_id": "8391728491728491",
"column_id": "9100000000000001",
"title": "Schedule maintenance for unit #12",
"priority": "MEDIUM",
"labels": [{"name": "maintenance", "color": "#F59E0B"}],
"checklist": [{"text": "Confirm schedule", "checked": false}],
"due_date": "2026-04-01T12:00:00"
}'
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/cards`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
"Content-Type": "application/json",
},
body: JSON.stringify({
board_id: "8391728491728491",
column_id: "9100000000000001",
title: "Schedule maintenance for unit #12",
priority: "MEDIUM",
labels: [{ name: "maintenance", color: "#F59E0B" }],
checklist: [{ text: "Confirm schedule", checked: false }],
due_date: "2026-04-01T12:00:00",
}),
}
);
const { data } = await response.json();
console.log(`Created card ${data.id}: ${data.title}`);
import requests
response = requests.post(
f"{TENANT_URL}/apidev/v1/kanban/cards",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
json={
"board_id": "8391728491728491",
"column_id": "9100000000000001",
"title": "Schedule maintenance for unit #12",
"priority": "MEDIUM",
"labels": [{"name": "maintenance", "color": "#F59E0B"}],
"checklist": [{"text": "Confirm schedule", "checked": False}],
"due_date": "2026-04-01T12:00:00",
},
)
card = response.json()["data"]
print(f"Created card {card['id']}: {card['title']}")
Example Response
{
"success": true,
"data": {
"id": "4200000000000002",
"board_id": "8391728491728491",
"column_id": "9100000000000001",
"title": "Schedule maintenance for unit #12"
},
"meta": {}
}
Update Card
Update an existing card. Only provided fields are modified (partial update).
/apidev/v1/kanban/cards/{id}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Card unique identifier (BigInt) |
Request Body
Same fields as Create Card. All fields are optional.
Response
| Field | Type | Description |
|---|---|---|
id | string | Card ID (BigInt) |
updated_fields | string[] | List of fields that were modified |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X PUT "$TENANT_URL/apidev/v1/kanban/cards/4200000000000001" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"priority": "URGENT",
"assignee_id": "1100000000000003"
}'
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/cards/4200000000000001`,
{
method: "PUT",
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
"Content-Type": "application/json",
},
body: JSON.stringify({
priority: "URGENT",
assignee_id: "1100000000000003",
}),
}
);
const { data } = await response.json();
console.log(`Updated card ${data.id}: ${data.updated_fields.join(", ")}`);
import requests
response = requests.put(
f"{TENANT_URL}/apidev/v1/kanban/cards/4200000000000001",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
json={
"priority": "URGENT",
"assignee_id": "1100000000000003",
},
)
card = response.json()["data"]
print(f"Updated card {card['id']}: {card['updated_fields']}")
Example Response
{
"success": true,
"data": {
"id": "4200000000000001",
"updated_fields": ["priority", "assignee_id"]
},
"meta": {}
}
Move Card
Move a card to a different column and/or change its position.
/apidev/v1/kanban/cards/{id}/movePath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Card unique identifier (BigInt) |
Request Body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
target_column_id | string | Yes | Max length 30 | Destination column ID (BigInt) |
position | integer | No | ≥ 0 | Target position within the column. Default: appended at end |
Response
| Field | Type | Description |
|---|---|---|
id | string | Card ID (BigInt) |
previous_column_id | string | Previous column ID (BigInt) |
new_column_id | string | New column ID (BigInt) |
position | integer | New position within the column |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X PUT "$TENANT_URL/apidev/v1/kanban/cards/4200000000000001/move" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"target_column_id": "9100000000000003",
"position": 0
}'
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/cards/4200000000000001/move`,
{
method: "PUT",
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
"Content-Type": "application/json",
},
body: JSON.stringify({
target_column_id: "9100000000000003",
position: 0,
}),
}
);
const { data } = await response.json();
console.log(`Card moved from column ${data.previous_column_id} to ${data.new_column_id}`);
import requests
response = requests.put(
f"{TENANT_URL}/apidev/v1/kanban/cards/4200000000000001/move",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
json={
"target_column_id": "9100000000000003",
"position": 0,
},
)
result = response.json()["data"]
print(f"Moved from {result['previous_column_id']} to {result['new_column_id']}")
Example Response
{
"success": true,
"data": {
"id": "4200000000000001",
"previous_column_id": "9100000000000002",
"new_column_id": "9100000000000003",
"position": 0
},
"meta": {}
}
Errors
| Code | HTTP | Description |
|---|---|---|
BAD_REQUEST | 400 | Missing required headers |
VALIDATION_ERROR | 400 | Invalid parameters |
UNAUTHORIZED | 401 | Invalid or expired JWT / API Key |
FORBIDDEN | 403 | User lacks required permission |
NOT_FOUND | 404 | Resource not found |
RATE_LIMITED | 429 | Exceeded rate limit |
INTERNAL_ERROR | 500 | Unexpected server error |