Kanban Boards
Browse workspaces, list boards, inspect board configuration, and retrieve tasks associated with a board.
All endpoints on this page require a valid JWT token, API key, and tenant header. See Authentication for details.
List Workspaces
Retrieve a paginated list of kanban workspaces available to the authenticated user.
/apidev/v1/kanban/workspacesRequest 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 |
Query Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
limit | integer | No | 25 | Min 1, Max 100 | Records per page |
offset | integer | No | 0 | ≥ 0 | Records to skip |
Response
| Field | Type | Description |
|---|---|---|
id | string | Workspace unique identifier (BigInt) |
name | string | Workspace display name |
description | string | null | Optional description |
boards_count | integer | Number of boards in this workspace |
role | string | Authenticated user's role in the workspace |
created_at | string | ISO 8601 timestamp |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "$TENANT_URL/apidev/v1/kanban/workspaces?limit=10" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/workspaces?limit=10`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
},
}
);
const { data, meta } = await response.json();
console.log(`Fetched ${data.length} of ${meta.total} workspaces`);
import requests
response = requests.get(
f"{TENANT_URL}/apidev/v1/kanban/workspaces",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
params={"limit": 10},
)
result = response.json()
for ws in result["data"]:
print(f"{ws['id']}: {ws['name']} ({ws['boards_count']} boards)")
Example Response
{
"success": true,
"data": [
{
"id": "7284917284917284",
"name": "Operations",
"description": "Main operations workspace for field teams.",
"boards_count": 4,
"role": "admin",
"created_at": "2025-09-01T10:00:00"
}
],
"meta": {
"total": 3,
"limit": 10,
"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 |
List Boards
Retrieve a paginated list of kanban boards. Optionally filter by workspace or type.
/apidev/v1/kanban/boardsQuery Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
limit | integer | No | 25 | Min 1, Max 100 | Records per page |
offset | integer | No | 0 | ≥ 0 | Records to skip |
workspace_id | string | No | — | Max length 30 | Filter by workspace ID |
type | string | No | — | tasks or custom | Filter by board type |
Response
| Field | Type | Description |
|---|---|---|
id | string | Board unique identifier (BigInt) |
name | string | Board display name |
description | string | null | Optional description |
type | string | Board type: tasks or custom |
workspace_id | string | Parent workspace ID (BigInt) |
workspace_name | string | Parent workspace name |
is_default | boolean | Whether this is the default board |
column_count | integer | Number of columns configured |
status | string | Board status |
created_at | string | ISO 8601 timestamp |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "$TENANT_URL/apidev/v1/kanban/boards?workspace_id=7284917284917284&type=tasks&limit=10" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/boards?workspace_id=7284917284917284&type=tasks&limit=10`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
},
}
);
const { data, meta } = await response.json();
console.log(`Fetched ${data.length} of ${meta.total} boards`);
import requests
response = requests.get(
f"{TENANT_URL}/apidev/v1/kanban/boards",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
params={"workspace_id": "7284917284917284", "type": "tasks", "limit": 10},
)
result = response.json()
for board in result["data"]:
print(f"{board['id']}: {board['name']} ({board['column_count']} columns)")
Example Response
{
"success": true,
"data": [
{
"id": "8391728491728491",
"name": "Field Installations",
"description": "Track field installation tasks from scheduling to completion.",
"type": "tasks",
"workspace_id": "7284917284917284",
"workspace_name": "Operations",
"is_default": false,
"column_count": 5,
"status": "active",
"created_at": "2025-09-05T11:00:00"
}
],
"meta": {
"total": 4,
"limit": 10,
"offset": 0
}
}
Board Detail
Retrieve the full configuration for a single board, including columns and custom fields.
/apidev/v1/kanban/boards/{id}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Board unique identifier (BigInt) |
Response
Returns the same top-level fields as List Boards, plus:
| Field | Type | Description |
|---|---|---|
columns | array | Ordered list of columns (see below) |
custom_fields | array | Custom field definitions (see below) |
columns[]:
| Field | Type | Description |
|---|---|---|
id | string | Column unique identifier (BigInt) |
name | string | Column display name |
color | string | null | Hex color code |
order | integer | Position on the board |
status_codes | string[] | Task status codes mapped to this column |
wip_limit | integer | null | Work-in-progress limit (null = unlimited) |
custom_fields[]:
| Field | Type | Description |
|---|---|---|
id | string | Field unique identifier (BigInt) |
name | string | Field display name |
type | string | Field type (text, number, date, select) |
options | string[] | null | Available options for select type |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "$TENANT_URL/apidev/v1/kanban/boards/8391728491728491" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/boards/8391728491728491`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
},
}
);
const { data } = await response.json();
console.log(`Board "${data.name}" has ${data.columns.length} columns`);
import requests
response = requests.get(
f"{TENANT_URL}/apidev/v1/kanban/boards/8391728491728491",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
)
board = response.json()["data"]
for col in board["columns"]:
print(f" [{col['order']}] {col['name']} — status_codes: {col['status_codes']}")
Example Response
{
"success": true,
"data": {
"id": "8391728491728491",
"name": "Field Installations",
"description": "Track field installation tasks from scheduling to completion.",
"type": "tasks",
"workspace_id": "7284917284917284",
"workspace_name": "Operations",
"is_default": false,
"columns": [
{
"id": "9100000000000001",
"name": "Backlog",
"color": "#6B7280",
"order": 1,
"status_codes": ["SA"],
"wip_limit": null
},
{
"id": "9100000000000002",
"name": "In Progress",
"color": "#3B82F6",
"order": 2,
"status_codes": ["ASI", "ACE", "INI"],
"wip_limit": 10
},
{
"id": "9100000000000003",
"name": "Done",
"color": "#10B981",
"order": 3,
"status_codes": ["FIN"],
"wip_limit": null
}
],
"custom_fields": [
{
"id": "6200000000000001",
"name": "Region",
"type": "select",
"options": ["North", "South", "East", "West"]
}
]
},
"meta": {}
}
Board Tasks
Retrieve tasks grouped by column for a specific board.
/apidev/v1/kanban/boards/{id}/tasksPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Board unique identifier (BigInt) |
Query Parameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
status | string | No | — | Max length 50 | Filter by task status code |
search | string | No | — | Max length 120 | Search task title or number |
driver_id | string | No | — | Max length 30 | Filter by driver ID (BigInt) |
client_id | string | No | — | Max length 30 | Filter by client ID (BigInt) |
priority | string | No | — | Max length 20 | Filter by priority level |
Response
| Field | Type | Description |
|---|---|---|
board_id | string | Board ID (BigInt) |
columns | array | Columns with their tasks (see below) |
total_tasks | integer | Total tasks across all columns |
timestamp | string | ISO 8601 timestamp of the snapshot |
columns[]:
| Field | Type | Description |
|---|---|---|
id | string | Column ID (BigInt) |
name | string | Column display name |
tasks | array | Tasks in this column (see below) |
task_count | integer | Number of tasks in this column |
columns[].tasks[]:
| Field | Type | Description |
|---|---|---|
id | string | Task unique identifier (BigInt) |
number | string | Task display number |
status | string | Current task status code |
title | string | Task title |
client_name | string | null | Client name |
account_name | string | null | Account name |
driver_name | string | null | Assigned driver name |
priority | string | Priority level |
scheduled_at | string | null | Scheduled date (ISO 8601) |
created_at | string | Creation timestamp (ISO 8601) |
delay_minutes | integer | null | Minutes of delay (null if on time) |
Code Examples
- cURL
- JavaScript
- Python
curl -s -X GET "$TENANT_URL/apidev/v1/kanban/boards/8391728491728491/tasks?status=INI" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`${TENANT_URL}/apidev/v1/kanban/boards/8391728491728491/tasks?status=INI`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"X-API-Key": APIKEY,
"tenant": TENANT,
},
}
);
const { data } = await response.json();
console.log(`Board has ${data.total_tasks} tasks across ${data.columns.length} columns`);
import requests
response = requests.get(
f"{TENANT_URL}/apidev/v1/kanban/boards/8391728491728491/tasks",
headers={
"Authorization": f"Bearer {TOKEN}",
"X-API-Key": APIKEY,
"tenant": TENANT,
},
params={"status": "INI"},
)
result = response.json()["data"]
for col in result["columns"]:
print(f"{col['name']}: {col['task_count']} tasks")
for task in col["tasks"]:
print(f" - {task['number']} {task['title']} [{task['status']}]")
Example Response
{
"success": true,
"data": {
"board_id": "8391728491728491",
"columns": [
{
"id": "9100000000000002",
"name": "In Progress",
"tasks": [
{
"id": "5001847291847291",
"number": "T-2026-00142",
"status": "INI",
"title": "Install GPS device at warehouse #7",
"client_name": "Acme Corp",
"account_name": "Warehouse District 7",
"driver_name": "Carlos Mendoza",
"priority": "high",
"scheduled_at": "2026-03-25T18:00:00",
"created_at": "2026-03-10T09:00:00",
"delay_minutes": 45
}
],
"task_count": 1
}
],
"total_tasks": 47,
"timestamp": "2026-03-19T16:45:00"
},
"meta": {}
}
Errors
| Code | HTTP | Description |
|---|---|---|
BAD_REQUEST | 400 | Missing required headers |
VALIDATION_ERROR | 400 | Invalid query 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 |