Playbook: ATRAX Vehicle Tags API

Discovered 2026-06-30 via browser DevTools inspection. Applies to: et-operational-platform GPS feature, n8n fleet sync workflows.


Overview

ATRAX has no dedicated tags endpoint. Tags are a string[] field on the vehicle object, managed via the standard vehicle update (PUT /api/vehicles/{id}). The same mechanism works for cars and trailers.

Tags in ATRAX serve two purposes:

  1. Free-form labels — user-defined strings (e.g. "DDD", "test")
  2. Sublicences — structured strings ATRAX uses for tachograph/driver sublicence assignment (e.g. "tacho-berlin", "tacho-charter")

Endpoints

Read vehicle (includes tags)

GET /api/external/vehicles/          # list — may or may not include tags (verify per env)
GET /api/vehicles/{atrax_id}         # single vehicle — tags confirmed present

Both use Bearer token auth via atraxHeaders() from _gpsApiAuth.ts.

Update vehicle tags

PUT /api/vehicles/{atrax_id}
Authorization: Bearer <token>
Content-Type: application/json

{ ...fullVehicleObject, tags: ["existing-tag", "new-tag"] }

Critical: the body must include the full vehicle object (not just tags). ATRAX will overwrite the entire vehicle with whatever is sent. Always GET first, then PUT with the modified tags array.


Reading tags in n8n

The fleet-update-v2-batch workflow uses GET /api/external/vehicles/ to populate p24_l_cars_atrax.

Check first: log one raw vehicle item in the build_batch node and inspect whether tags is present.

  • If tags is in the response: add to the mapping:
    atrax_tags: i.json.tags ?? [],
  • If tags is absent from /api/external/vehicles/: a separate HTTP node calling GET /api/vehicles/{id} per vehicle is required (expensive — 262 calls per 3-min cycle). Prefer batching or caching.

Writing tags from et-op API routes

Pattern for a new PATCH /api/gps/vehicle-tags route:

// 1. GET current vehicle state
const vehicle = await atraxGet(`/api/vehicles/${atraxId}`);
 
// 2. Modify tags
const updatedTags = [...new Set([...vehicle.tags, newTag])]; // add
// or: const updatedTags = vehicle.tags.filter(t => t !== removedTag); // remove
 
// 3. PUT full vehicle with modified tags
await atraxPut(`/api/vehicles/${atraxId}`, { ...vehicle, tags: updatedTags });

Use atraxHeaders() and atraxBaseUrl() from src/pages/api/gps/_gpsApiAuth.ts.

Never send a partial body — ATRAX replaces the entire vehicle record.


Creating new global tags

Include a new string in the tags array on any PUT. ATRAX registers the string globally — it becomes selectable in the UI for all future vehicles.

There is no separate tag-creation step.


in_fleet derivation

The vehicle object includes a temporary boolean field:

{ "temporary": false }

Likely derivation: in_fleet = !temporary

  • temporary: false → vehicle is a permanent fleet member → in_fleet = true
  • temporary: true → rental or temporary vehicle → in_fleet = false

Verify by checking atrax_status distinct values in p24_gps_current_state as backup — if an inactive status exists, cross-reference with temporary to confirm.


Known ATRAX vehicle object fields (from PUT response)

FieldTypeNotes
idstringATRAX object ID (MongoDB ObjectId format)
namestringRegistration plate / display name
registrationNostringLicense plate
classificationstring"TRUCK", "TRAILER", etc.
tagsstring[]Labels + sublicences
temporarybooleanfalse = permanent fleet member
make, model, yearstringVehicle specs
engineKindstring"DIESEL", etc.
fuelTankCapacitynumberLitres
hasTachograph, hasDDDbooleanTachograph capability
hasCanbooleanCAN bus connected
etollEnabledbooleane-toll transponder active
linesobject[]Digital input line definitions
foreignIdsobject[]External system ID mappings
vehicleDisplayDefinitionobjectIcon + display number
costPerKmobject{ amount, currency, decimalPlacesVersion }

IssueTopicStatus
#893Sync atrax_tags, current_zone_id, in_fleet to p24_l_cars_atrax via n8nWaiting infra
#896Sublicence assignment UI in VehicleModal — uses tags write patternBlocked on #893
#890Full ATRAX integration epicDesign

Auth notes

  • n8n: uses cookie-based browser session auth (ATRAX_AUTH_STRING credential) — do not change auth nodes
  • et-op API routes: uses Bearer token from /oauth/token via atraxHeaders() from _gpsApiAuth.ts
  • Both auth mechanisms work with the same endpoints; they are independent sessions

  • ATRAX known endpoints: p24-infra/docs/playbooks/ — see atrax-vehicle-tags-api.md (this file)
  • n8n workflow: fleet-update-v2-batch on n8n.vps-h1.infra.zintegrowana.online
  • et-op GPS auth: src/pages/api/gps/_gpsApiAuth.ts