Tasks — List & Detail
Read tasks with rich filtering and pagination, choose how much detail to receive, and expand heavy blocks (events, forms, attachments, pauses, geofences) only when you need them. A single read resource covers both active and finished tasks — you never couple to where a task physically lives.
All endpoints require a valid JWT token, API key, and tenant header. See Authentication.
Holding the read permission does not grant access to the whole tenant. Both list and detail apply the same visibility limits as your technical user (the user tied to your API key): task-level access, procedence isolation, and group visibility. An empty filter means "everything your technical user can see", never "everything in the company". To widen what the API returns, widen the technical user's visibility — not the endpoint permission.
Detail levels
The list resource exposes three levels through query flags — not three different endpoints:
| Level | How to request | What you get |
|---|---|---|
| Standard | GET /apidev/v1/tasks with no flags | Task base fields + dynamic_fields[] (custom fields) |
| Pro | GET /apidev/v1/tasks?include=... | Base + custom fields + opt-in heavy blocks |
| Custom | GET /apidev/v1/tasks?fields=... | Only the requested fields (closed whitelist) + targeted custom fields |
include and fields are mutually exclusive — sending both returns INCLUDE_FIELDS_CONFLICT. The detail endpoint (GET /apidev/v1/tasks/{id}) accepts the same include/fields flags.
List Tasks
Retrieve a paginated list of tasks with extensive filtering. The three identifiers — serid, service_number, assistance_number — are always present on every item, even at the custom level.
/apidev/v1/tasksQuery Parameters — Pagination & time window
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | integer | No | 20 | Page size. Min: 1, Max: 100 (capped lower with heavy include, see below) |
offset | integer | No | 0 | Page number, 0-based (the service applies OFFSET = offset × limit) |
date_type | enum | No | created | Which date column to filter: created | scheduled | finished |
startdate | string | Conditional¹ | — | ISO YYYY-MM-DDTHH:MM:SS (no timezone). Range startdate..enddate must be ≤ 31 days |
enddate | string | Conditional¹ | — | Same format; enddate must be ≥ startdate |
¹ startdate + enddate are required when you don't filter by a specific identifier (task_ids / external_ids / service_number). Without either a date range or an identifier, the request returns 400 DATE_RANGE_REQUIRED (performance protection).
Query Parameters — Catalog filters
All catalog filters are multi-select, sent as a CSV of IDs (e.g. statuses=SA,ASI). IDs are opaque strings. An empty or absent filter means no filter — there is no [All] sentinel.
| Parameter | Type | Description |
|---|---|---|
statuses | CSV | Each value ∈ SA,ASI,ACE,INI,USU,FIN,CAN. Including FIN/CAN reads from the historical store |
procedencias | CSV | Procedence IDs |
productos | CSV | Product IDs (line) |
procedence_product_pairs | CSV | Tuples proid or proid|protipclilin for true parent→child pairing |
provisions | CSV | Provision IDs |
causes | CSV | Cause IDs |
subcauses | CSV | Subcause IDs (line) |
provision_cause_pairs | CSV | Tuples prestaid | prestaid|cauid | prestaid|cauid|causubcaulin |
coverages | CSV | Coverage IDs (line) |
motives | CSV | Motive IDs |
end_reasons | CSV | End-of-service reason IDs |
comm_media | CSV | Communication medium / template IDs |
devices | CSV | Vehicle IDs |
drivers | CSV | Driver / personnel IDs |
providers | CSV | Provider IDs |
shifts | CSV | Shift IDs |
routes | CSV | Fixed-route IDs |
telephonists | CSV | Telephonist IDs |
operators | CSV | Operator IDs |
reserved_drivers | CSV | Reserved driver IDs |
reserved_devices | CSV | Reserved vehicle IDs |
reserved_users | CSV | Reserved user IDs |
country | string | Country ID (single value) |
departments | CSV | Department IDs (line) |
account_id | string | Account ID |
Query Parameters — Identifiers & free text
| Parameter | Type | Description |
|---|---|---|
task_ids | CSV | serid values (opaque strings). Max 200 |
external_ids | CSV | Client external IDs. Max 200 |
service_number | string | Service number. Max length 80 |
assistance_number | string | Assistance number. Max length 80 |
tracking_number | string | Tracking number. Max length 120 |
q | string | Free-text search over contact / account / document. Max length 200 |
Query Parameters — Level flags
| Parameter | Type | Description |
|---|---|---|
include | CSV | Activates Pro level. Each token ∈ forms,events,attachments,invoices,pauses,cercas,dynamic_fields. Unknown token → 400 INVALID_INCLUDE |
fields | CSV | Activates Custom level. Each token from the field whitelist. Unknown token → 400 INVALID_FIELD. dynamic_fields.<label> is always accepted |
include=events, include=forms, or include=attachments require task_ids / external_ids or a short date range, otherwise the request returns 400 INCLUDE_REQUIRES_NARROWER_FILTER. When a heavy block is requested, the effective limit is capped (lower with events/forms, higher with attachments only); the applied cap is reported in meta.capped and meta.limit.
Response Fields — Standard level
The standard field set is fixed and stable. All IDs are opaque strings. All dates are serialized raw from the row (timestamp without timezone) or as an empty string "" — null is never emitted inside the task payload.
| Field | Type | Description |
|---|---|---|
serid | string | Task unique identifier (always present) |
service_number | string | Service number (always present) |
assistance_number | string | Assistance number (always present) |
external_id | string | Client external identifier |
status | string | Status code: SA,ASI,ACE,INI,USU,FIN,CAN |
status_label | string | Human-readable status |
priority | number | Task priority |
detail | string | Free-text detail |
tracking_number | string | Tracking number |
created_at | string | Call/creation timestamp |
scheduled_at | string | Scheduled timestamp |
scheduled_until | string | Scheduled-until timestamp |
computes | boolean | Whether the task counts toward billing/metrics |
contact | object | { name, phone, phone_mobile } |
account | object | { name, external_code, document, policy } |
classification | object | procedence{id,name}, product{id,line,name}, coverage{name}, provision{name}, motive{name}, cause{name}, subcause{name} |
origin | object | country, department, city, zone, street, corner, door_number, apt, special_place, lat, lng |
destination | object | Same shape as origin (mirror) |
vehicle | object | { plate, brand, model, year, color } |
assignment | object | device, device_imei, device_type, driver, driver_external_code, provider, operator, telephonist, communication_medium |
reserve | object | { driver, provider, mobile, user } |
load | object | Cargo data { weightKg?, volumeM3?, packages?, requiresCold?, requiresFragile?, requiresHeavy? }. Only the dimensions the product enables appear; omitted entirely when the product has no cargo profile |
dynamic_fields | array | Custom fields as [{ label, value }] (see Custom fields) |
Code Example
- cURL
- JavaScript
- Python
curl -s "https://$TENANT/apidev/v1/tasks?date_type=created&startdate=2026-06-24T00:00:00&enddate=2026-06-24T23:59:59&statuses=ASI,INI&limit=2" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const params = new URLSearchParams({
date_type: "created",
startdate: "2026-06-24T00:00:00",
enddate: "2026-06-24T23:59:59",
statuses: "ASI,INI",
limit: "2",
});
const response = await fetch(
`https://${TENANT}/apidev/v1/tasks?${params}`,
{
headers: {
"Authorization": `Bearer ${token}`,
"X-API-Key": API_KEY,
"tenant": TENANT,
},
}
);
const { data, meta } = await response.json();
console.log(`Fetched ${data.length} of ${meta.total} tasks`);
response = requests.get(
f"https://{TENANT}/apidev/v1/tasks",
headers=headers,
params={
"date_type": "created",
"startdate": "2026-06-24T00:00:00",
"enddate": "2026-06-24T23:59:59",
"statuses": "ASI,INI",
"limit": 2,
},
)
result = response.json()
for task in result["data"]:
print(f"{task['serid']}: {task['status_label']} ({task['service_number']})")
Example Response
{
"success": true,
"data": [
{
"serid": "920183744012",
"service_number": "103878",
"assistance_number": "44021",
"external_id": "OT-2026-0099",
"status": "INI",
"status_label": "Iniciado",
"priority": 2,
"detail": "Cliente reporta auto sin arranque.",
"tracking_number": "TRK-9981",
"created_at": "2026-06-24T09:12:00",
"scheduled_at": "2026-06-24T11:00:00",
"scheduled_until": "",
"contact": { "name": "Ana Pérez", "phone": "099111222", "phone_mobile": "" },
"account": { "name": "Ana Pérez", "external_code": "CLI-55", "document": "1.234.567-8", "policy": "POL-77" },
"classification": {
"procedence": { "id": "12", "name": "Seguros del Sur" },
"product": { "id": "12", "line": "3", "name": "Auxilio Mecánico" },
"coverage": { "name": "Cobertura Total" },
"provision": { "name": "Remolque" },
"motive": { "name": "" },
"cause": { "name": "No arranca" },
"subcause": { "name": "Batería descargada" }
},
"origin": {
"country": "Uruguay", "department": "Montevideo", "city": "Montevideo", "zone": "Centro",
"street": "18 de Julio", "corner": "Ejido", "door_number": "1234", "apt": "5",
"special_place": "", "lat": "-34.90547800000000", "lng": "-56.18815900000000"
},
"destination": {
"country": "", "department": "", "city": "", "zone": "",
"street": "", "corner": "", "door_number": "", "apt": "",
"special_place": "", "lat": "", "lng": ""
},
"vehicle": { "plate": "SAB1234", "brand": "Ford", "model": "Fiesta", "year": 2018, "color": "Gris" },
"assignment": {
"device": "Móvil 12", "device_imei": "352093081234567", "device_type": "Grúa liviana",
"driver": "Juan Gómez", "driver_external_code": "COND-3",
"provider": "Grúas del Este", "operator": "mesa1", "telephonist": "mesa1",
"communication_medium": "Teléfono"
},
"reserve": { "driver": "", "provider": "", "mobile": "", "user": "" },
"computes": true,
"load": { "weightKg": 320, "volumeM3": 1.5, "packages": 4 },
"dynamic_fields": [
{ "label": "Póliza", "value": "POL-77" },
{ "label": "Kilometraje", "value": "84210" }
]
}
],
"meta": { "total": 47, "limit": 2, "offset": 0, "count": 2 }
}
All timestamps are returned without timezone (e.g. "2026-06-24T09:12:00"). The value represents the company's configured timezone. Do not append Z or apply UTC conversion — display as-is.
Pro level — include blocks
Add include to expand heavy blocks on each item. Each block is composed by its internal service, batched by the page's serid values (no N+1).
| Token | Field | Notes |
|---|---|---|
dynamic_fields | dynamic_fields[] | Already present at standard level; accepted in include for symmetry |
events | events[] | Heavy block — needs a narrow filter |
pauses | pauses[] | Comes from the same source as events |
forms | forms[] | The form PDF is not inline — fetch it via the form-PDF endpoint |
attachments | attachments[] | Metadata + handle only. Never base64 inline |
cercas | cercas{origin[],destination[]} | Origin/destination geofence name lists |
invoices | invoices[] | Deferred — returns [] with meta.deferred: ["invoices"] |
Block sub-shapes
events[] item: id, at (datetime), status, status_label, lat, lng, user, device, driver, driver_external_code, provider, odometer, address, parameters[] ({ name, value }).
pauses[] item: started_at, ended_at, user, driver, device, reason, notes.
forms[] item: form_id, name, driver, device, filled_at, sections[] ({ name, order, fields[] } where each field is { name, order, value }), attachments[].
attachments[] item: name, type, size, date, notes, task_id, form_id ("" if standalone), media_id, provider.
Take attachments[].media_id (or attachments[].name) and pass it to the attachment download endpoint to obtain a signed link. The list and detail endpoints never return base64 — only metadata and a handle.
Code Example
- cURL
- JavaScript
- Python
curl -s "https://$TENANT/apidev/v1/tasks/920183744012?include=events,forms,attachments,pauses,cercas" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`https://${TENANT}/apidev/v1/tasks/920183744012?include=events,forms,attachments,pauses,cercas`,
{ headers }
);
const { data } = await response.json();
console.log(`${data.serid}: ${data.events.length} events, ${data.forms.length} forms`);
response = requests.get(
f"https://{TENANT}/apidev/v1/tasks/920183744012",
headers=headers,
params={"include": "events,forms,attachments,pauses,cercas"},
)
task = response.json()["data"]
print(f"{task['serid']}: {len(task['events'])} events")
Example Response
{
"success": true,
"data": {
"serid": "920183744012",
"service_number": "103878",
"assistance_number": "44021",
"external_id": "OT-2026-0099",
"status": "FIN",
"status_label": "Finalizado",
"dynamic_fields": [ { "label": "Póliza", "value": "POL-77" } ],
"events": [
{ "id": "5512", "at": "2026-06-24T09:30:00", "status": "ASI", "status_label": "Asignado",
"lat": "-34.90500000000000", "lng": "-56.18800000000000", "user": "mesa1",
"device": "Móvil 12", "driver": "Juan Gómez", "driver_external_code": "COND-3",
"provider": "Grúas del Este", "odometer": "84200", "address": "18 de Julio 1234",
"parameters": [ { "name": "Observación", "value": "En camino" } ] },
{ "id": "5518", "at": "2026-06-24T10:25:00", "status": "FIN", "status_label": "Finalizado",
"lat": "-34.90600000000000", "lng": "-56.18900000000000", "user": "mesa1",
"device": "Móvil 12", "driver": "Juan Gómez", "driver_external_code": "COND-3",
"provider": "Grúas del Este", "odometer": "84210", "address": "18 de Julio 1234",
"parameters": [] }
],
"pauses": [
{ "started_at": "2026-06-24T09:45:00", "ended_at": "2026-06-24T09:55:00",
"user": "mesa1", "driver": "Juan Gómez", "device": "Móvil 12",
"reason": "Corte de tránsito", "notes": "" }
],
"forms": [
{ "form_id": "771", "name": "Checklist de Auxilio", "driver": "Juan Gómez", "device": "Móvil 12",
"filled_at": "2026-06-24T10:20:00",
"sections": [
{ "name": "Datos del vehículo", "order": 1,
"fields": [ { "name": "Kilometraje", "order": 1, "value": "84210" } ] }
],
"attachments": [
{ "name": "771_foto_frente.jpg", "type": "image/jpeg", "size": 142233,
"date": "2026-06-24T10:21:00", "notes": "", "task_id": "920183744012",
"form_id": "771", "media_id": "88231", "provider": "azure" }
] }
],
"attachments": [
{ "name": "920183744012_remito.pdf", "type": "application/pdf", "size": 90122,
"date": "2026-06-24T10:25:00", "notes": "Remito firmado", "task_id": "920183744012",
"form_id": "", "media_id": "88240", "provider": "azure" }
],
"cercas": { "origin": ["Zona Sur"], "destination": [] }
},
"meta": { "source": "historic", "includes": ["events","forms","attachments","pauses","cercas"] }
}
Custom level — fields
Use fields to receive only the fields you ask for (plus the three forced identifiers serid, service_number, assistance_number). The alias whitelist is closed — an alias outside it returns 400 INVALID_FIELD.
id (=serid), external_id, service_number, assistance_number,
status, status_label, priority, detail, tracking_number, computes,
created_at, scheduled_at, scheduled_until,
contact.name, contact.phone, contact.phone_mobile,
account.name, account.external_code, account.document, account.policy,
classification.procedence.id, classification.procedence.name,
classification.product.id, classification.product.line, classification.product.name,
classification.coverage.name, classification.provision.name,
classification.motive.name, classification.cause.name, classification.subcause.name,
origin.country, origin.department, origin.city, origin.zone, origin.street,
origin.corner, origin.door_number, origin.apt, origin.special_place, origin.lat, origin.lng,
destination.country, destination.department, destination.city, destination.zone, destination.street,
destination.corner, destination.door_number, destination.apt, destination.special_place,
destination.lat, destination.lng,
vehicle.plate, vehicle.brand, vehicle.model, vehicle.year, vehicle.color,
assignment.device, assignment.device_imei, assignment.device_type,
assignment.driver, assignment.driver_external_code, assignment.provider,
assignment.operator, assignment.telephonist, assignment.communication_medium,
reserve.driver, reserve.provider, reserve.mobile, reserve.user,
load.weightKg, load.volumeM3, load.packages,
load.requiresCold, load.requiresFragile, load.requiresHeavy,
dynamic_fields, (the whole array)
dynamic_fields.<label> (one custom field by label; case-insensitive)
dynamic_fields.<label>(e.g.dynamic_fields.Póliza) resolves the value of the custom field whose label matches (trimmed, case-insensitive). If it doesn't exist → empty string"", not a 400. When you request targeted custom fields, the result is returned as an object{ "Póliza": "POL-77" }.fieldsdoes not enable heavy blocks (events/forms/attachments/invoices) — useincludefor those. Asking for a heavy-block alias infieldsreturns400 INVALID_FIELD.
Example Response
{
"success": true,
"data": [
{ "serid": "920183744012", "service_number": "103878", "assistance_number": "44021",
"external_id": "OT-2026-0099", "status": "FIN", "scheduled_at": "2026-06-24T11:00:00",
"dynamic_fields": { "Póliza": "POL-77" } }
],
"meta": { "total": 1, "limit": 20, "offset": 0, "count": 1,
"fields": ["id","external_id","status","scheduled_at","dynamic_fields.Póliza"] }
}
Custom fields
Custom fields (dynamic_fields) come from a single source in both list and detail, so the same custom field looks identical in either response. Each entry is { label, value }:
- At standard and pro levels,
dynamic_fieldsis an array[{ label, value }]. - With targeted
fields=dynamic_fields.<label>, it's an object{ label: value }. - An unknown
<label>resolves to"", never a 400.
Task Detail
Full profile of a single task. Same item shape as the list, expanded according to include/fields.
/apidev/v1/tasks/{id}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Task identifier (serid). Identity is resolved by serid only |
Query Parameters
Same include and fields flags as the list endpoint.
Code Example
- cURL
- JavaScript
- Python
curl -s "https://$TENANT/apidev/v1/tasks/920183744012" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const response = await fetch(
`https://${TENANT}/apidev/v1/tasks/920183744012`,
{ headers }
);
const { data, meta } = await response.json();
console.log(`${data.serid} — ${data.status_label} (source: ${meta.source})`);
response = requests.get(
f"https://{TENANT}/apidev/v1/tasks/920183744012",
headers=headers,
)
task = response.json()["data"]
print(f"{task['serid']} — {task['status_label']}")
Example Response
{
"success": true,
"data": {
"serid": "920183744012",
"service_number": "103878",
"assistance_number": "44021",
"external_id": "OT-2026-0099",
"status": "INI",
"status_label": "Iniciado",
"priority": 2,
"detail": "Cliente reporta auto sin arranque.",
"tracking_number": "TRK-9981",
"created_at": "2026-06-24T09:12:00",
"scheduled_at": "2026-06-24T11:00:00",
"scheduled_until": "",
"contact": { "name": "Ana Pérez", "phone": "099111222", "phone_mobile": "" },
"account": { "name": "Ana Pérez", "external_code": "CLI-55", "document": "1.234.567-8", "policy": "POL-77" },
"classification": {
"procedence": { "id": "12", "name": "Seguros del Sur" },
"product": { "id": "12", "line": "3", "name": "Auxilio Mecánico" },
"coverage": { "name": "Cobertura Total" },
"provision": { "name": "Remolque" },
"motive": { "name": "" },
"cause": { "name": "No arranca" },
"subcause": { "name": "Batería descargada" }
},
"vehicle": { "plate": "SAB1234", "brand": "Ford", "model": "Fiesta", "year": 2018, "color": "Gris" },
"assignment": {
"device": "Móvil 12", "device_imei": "352093081234567", "device_type": "Grúa liviana",
"driver": "Juan Gómez", "driver_external_code": "COND-3",
"provider": "Grúas del Este", "operator": "mesa1", "telephonist": "mesa1",
"communication_medium": "Teléfono"
},
"reserve": { "driver": "", "provider": "", "mobile": "", "user": "" },
"computes": true,
"load": { "weightKg": 320, "volumeM3": 1.5, "packages": 4 },
"dynamic_fields": [ { "label": "Póliza", "value": "POL-77" } ]
},
"meta": { "source": "active" }
}
meta.sourcedata is a single object (not an array). meta.source reports which store resolved the task (active, historic, or despacho) and is debug-only — don't couple your integration to the physical origin. A task that doesn't exist for your company returns 404 TASK_NOT_FOUND.
meta reference
| Field | Type | When | Meaning |
|---|---|---|---|
total | number | list (always) | Total matches across all pages |
limit | number | list (always) | Page size applied (may be lower than requested due to a cap) |
offset | number | list (always) | Page number applied |
count | number | list (always) | Items in this page |
includes | array | pro level | Blocks actually expanded |
fields | array | custom level | Fields actually projected |
deferred | array | when a deferred block was requested | Blocks not implemented yet (e.g. ["invoices"]) |
source | string | detail (debug) | Store that resolved the task |
capped | object | when a cap was applied | { field, requested, applied } (e.g. limit trimmed by a heavy include) |
Errors
All endpoints on this page may return these errors. See Error Handling for the full reference.
| Code | HTTP | Description |
|---|---|---|
DATE_RANGE_REQUIRED | 400 | Requested tasks without a date range or a specific identifier |
DATE_RANGE_TOO_WIDE | 400 | The range exceeds the 31-day maximum |
DATE_RANGE_INVALID | 400 | enddate before startdate, or an invalid date format |
INVALID_STATUS | 400 | A statuses value is not a valid task status |
INVALID_INCLUDE | 400 | An include token is not in the list |
INVALID_FIELD | 400 | A fields alias is not in the whitelist |
INCLUDE_FIELDS_CONFLICT | 400 | include and fields were sent together |
LIMIT_OUT_OF_RANGE | 400 | limit outside 1..100 |
INCLUDE_REQUIRES_NARROWER_FILTER | 400 | A heavy block was requested without a narrow enough filter |
UNAUTHORIZED | 401 | Missing, invalid, or expired tenant / Authorization / X-API-Key |
FORBIDDEN | 403 | User lacks APICLI_TASKS_READ |
TASK_NOT_FOUND | 404 | The {id} doesn't exist for your company |
RATE_LIMITED | 429 | Exceeded 30 req/min |
INTERNAL_ERROR | 500 | Unexpected server error |
Related
- Authentication
- Pagination — Standard pagination parameters
- Error Handling — Full error reference
- Rate Limits — Per-endpoint limits