Tarjetas Kanban
Gestioná tarjetas personalizadas en los tableros Kanban. Listá, recuperá, creá, actualizá y mové tarjetas entre columnas.
Todos los endpoints de esta página requieren un token JWT válido, una clave de API y el encabezado tenant. Consultá Autenticación para más detalles.
Listar tarjetas
Recuperá una lista paginada de tarjetas para un tablero específico.
/apidev/v1/kanban/boards/{id}/cardsEncabezados de la solicitud
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 assigned tenant domain (default: geotareas.com) — always send your assigned tenant |
Content-Type | Conditional | application/json — required for POST and PUT requests |
Parámetros de ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | Identificador único del tablero (BigInt) |
Parámetros de consulta
| Parámetro | Tipo | Obligatorio | Por defecto | Restricciones | Descripción |
|---|---|---|---|---|---|
limit | integer | No | 100 | Mín 1, Máx 100 | Registros por página |
offset | integer | No | 0 | ≥ 0 | Registros a omitir |
column_id | string | No | — | Longitud máxima 30 | Filtrar por ID de columna (BigInt) |
priority | string | No | — | NONE, LOW, MEDIUM, HIGH, URGENT | Filtrar por prioridad |
assignee_id | string | No | — | Longitud máxima 30 | Filtrar por ID del responsable (BigInt) |
search | string | No | — | Longitud máxima 120 | Buscar por título de tarjeta |
archived | boolean | No | false | — | true devuelve solo las tarjetas archivadas. Omitido o false devuelve solo las activas |
archived cambia el listado, no lo amplíaNo hay forma de traer archivadas y activas en una sola llamada: archived=true devuelve el archivo, cualquier otro valor devuelve el tablero activo. Si necesitás las dos cosas, hacé dos llamadas.
Las tarjetas eliminadas nunca se devuelven, mandes el valor que mandes.
Hasta el 2026-08-16 este parámetro se aceptaba pero se ignoraba — toda llamada volvía con las tarjetas activas. Si tu integración mandaba archived=true y leía el resultado como el archivo, en realidad estaba leyendo tarjetas activas.
Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Identificador único de la tarjeta (BigInt) |
board_id | string | ID del tablero padre (BigInt) |
column_id | string | ID de la columna actual (BigInt) |
column_name | string | Nombre de la columna actual |
title | string | Título de la tarjeta |
description | string | null | Descripción de la tarjeta |
priority | string | Nivel de prioridad |
color | string | null | Código de color hexadecimal de la tarjeta |
due_date | string | null | Fecha de vencimiento (ISO 8601) |
labels | array | Objetos de etiqueta con name y color |
checklist_total | integer | Total de ítems de la lista de control |
checklist_completed | integer | Ítems completados de la lista de control |
assignee | object | null | {id, name} del responsable |
comments_count | integer | Cantidad de comentarios |
order | integer | Posición dentro de la columna |
archived | boolean | Si la tarjeta está archivada |
created_at | string | Marca de tiempo ISO 8601 |
updated_at | string | Marca de tiempo ISO 8601 |
Ejemplos de código
- 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']}]")
Ejemplo de respuesta
{
"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
}
}
Encabezados del límite de solicitudes
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 |
Detalle de la tarjeta
Recuperá los detalles completos de una única tarjeta, incluyendo los ítems de la lista de control y los campos personalizados.
/apidev/v1/kanban/cards/{id}Parámetros de ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | Identificador único de la tarjeta (BigInt) |
Respuesta
Devuelve todos los campos del endpoint de listado, más:
| Campo | Tipo | Descripción |
|---|---|---|
checklist | array | Ítems de la lista de control [{text, checked}] |
custom_fields | array | Valores de campos personalizados [{field_id, name, type, value}] |
created_by | object | {id, name} del creador |
comments_count y created_by.name traen valores realesLos dos se resuelven contra la base en cada lectura: comments_count es la cantidad real de comentarios activos de la tarjeta, y created_by.name es el nombre de usuario de quien la creó.
Hasta el 2026-08-16 este endpoint devolvía comments_count: 0 y created_by.name: null en todas las tarjetas, sin importar el dato real. Si armaste algún rodeo por eso — por ejemplo llamar al endpoint de comentarios solo para contarlos — ya podés sacar esa llamada extra.
Ejemplos de código
- 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']}")
Ejemplo de respuesta
{
"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": {}
}
Crear tarjeta
Creá una nueva tarjeta en un tablero. Devuelve HTTP 201.
/apidev/v1/kanban/cardsCuerpo de la solicitud
| Campo | Tipo | Obligatorio | Restricciones | Descripción |
|---|---|---|---|---|
board_id | string | Sí | Longitud máxima 30 | ID del tablero destino (BigInt) |
column_id | string | Sí | Longitud máxima 30 | ID de la columna destino (BigInt) |
title | string | Sí | Longitud máxima 500 | Título de la tarjeta |
description | string | No | Longitud máxima 5000 | Descripción de la tarjeta |
priority | string | No | Longitud máxima 10 | NONE, LOW, MEDIUM, HIGH, URGENT |
color | string | No | Longitud máxima 10 | Código de color hexadecimal |
due_date | string | No | Longitud máxima 30 | Fecha ISO 8601 |
labels | array | No | — | [{name (obligatorio, máx 50), color (máx 10)}] |
checklist | array | No | — | [{text (obligatorio, máx 500), checked (boolean)}] |
assignee_id | string | No | Longitud máxima 30 | ID del usuario responsable (BigInt) |
custom_fields | array | No | — | [{field_id (obligatorio, máx 30), value (máx 500)}] |
Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la tarjeta creada (BigInt) |
board_id | string | ID del tablero (BigInt) |
column_id | string | ID de la columna (BigInt) |
title | string | Título de la tarjeta |
Ejemplos de código
- 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']}")
Ejemplo de respuesta
{
"success": true,
"data": {
"id": "4200000000000002",
"board_id": "8391728491728491",
"column_id": "9100000000000001",
"title": "Schedule maintenance for unit #12"
},
"meta": {}
}
Actualizar tarjeta
Actualizá una tarjeta existente. Solo se modifican los campos proporcionados (actualización parcial).
/apidev/v1/kanban/cards/{id}Parámetros de ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | Identificador único de la tarjeta (BigInt) |
Cuerpo de la solicitud
Los mismos campos que en Crear tarjeta. Todos los campos son opcionales.
Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la tarjeta (BigInt) |
updated_fields | string[] | Lista de los campos que se modificaron |
Ejemplos de código
- 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']}")
Ejemplo de respuesta
{
"success": true,
"data": {
"id": "4200000000000001",
"updated_fields": ["priority", "assignee_id"]
},
"meta": {}
}
Mover tarjeta
Mové una tarjeta a una columna diferente o cambiá su posición.
/apidev/v1/kanban/cards/{id}/moveParámetros de ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | Identificador único de la tarjeta (BigInt) |
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Restricciones | Descripción |
|---|---|---|---|---|
target_column_id | string | Sí | Longitud máxima 30 | ID de la columna destino (BigInt) |
position | integer | No | ≥ 0 | Posición destino dentro de la columna. Por defecto: agregada al final |
Respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID de la tarjeta (BigInt) |
previous_column_id | string | ID de la columna anterior (BigInt) |
new_column_id | string | ID de la nueva columna (BigInt) |
position | integer | Nueva posición dentro de la columna |
Ejemplos de código
- 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']}")
Ejemplo de respuesta
{
"success": true,
"data": {
"id": "4200000000000001",
"previous_column_id": "9100000000000002",
"new_column_id": "9100000000000003",
"position": 0
},
"meta": {}
}
Errores
| Código | HTTP | Descripción |
|---|---|---|
VALIDATION_ERROR | 400 | Parámetros inválidos |
UNAUTHORIZED | 401 | tenant / Authorization / X-API-Key ausente, inválido o expirado |
FORBIDDEN | 403 | El usuario no tiene el permiso requerido |
NOT_FOUND | 404 | Recurso no encontrado |
RATE_LIMITED | 429 | Se superó el límite de solicitudes |
INTERNAL_ERROR | 500 | Error inesperado del servidor |