Skip to main content

Tracking Commands

Every command you send the vehicle is assigned a command id — a UUID the vehicle generates when it accepts the command. The id comes back in the response, and you use it to follow that command through the queue and to look up how it finished.

This guide walks through submitting a command, reading the queue, and reading the history.

Prerequisites

Set POLYMATH_ACCESS_TOKEN and POLYMATH_VEHICLE_ID as shown in Authentication and First Steps.

Command ids

Every endpoint that submits commands returns data.command_ids, aligned one-to-one with the commands you sent and in the same order:

Keep these ids. They are the only way to correlate a command you submitted with the record you later read back, and the same id is used as the navigation goal id on the vehicle.

curl --request POST \
"https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/gps-waypoints" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN" \
--header "content-type: application/json" \
--data '{
"goals": [
{"lat": 40.6342, "lon": -96.1626},
{"lat": 40.6351, "lon": -96.1618}
],
"navigation_options": {"mode": "ADD"}
}'

Both waypoints go to the vehicle as a single navigation command, so one id comes back:

{
"status": "success",
"message": "Gps waypoints successfully sent to the robot",
"data": {
"sent": {},
"received": "GPS Waypoints transmitted",
"command_ids": ["2cd16280-c0ed-414e-b658-c67098b868ae"]
}
}

command_ids is empty when the vehicle handled your request without queueing a command — a RESUME motion command is the case you will hit in practice, since it resumes what is already queued rather than adding to it. A request that fails validation returns an error and queues nothing.

Read the queue

GET /v2/command-queue returns the commands waiting to run, in the order they will be dispatched, plus the id of the one currently executing:

curl "https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/command-queue" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"
{
"status": "success",
"message": "Resource fetched successfully",
"data": {
"queued": [
{
"id": "2cd16280-c0ed-414e-b658-c67098b868ae",
"summary": "NAVIGATION: geo path with 2 waypoints",
"state": 1,
"state_text": "ACTIVE",
"outcome": 0,
"outcome_text": "OUTCOME_UNKNOWN",
"detail": "",
"queued_time": {"sec": 1786949841, "nanosec": 893512222},
"started_time": {"sec": 1786949842, "nanosec": 100000000},
"completed_time": {"sec": 0, "nanosec": 0}
}
],
"active_command_id": "2cd16280-c0ed-414e-b658-c67098b868ae",
"number_commands_remaining": 1
}
}

active_command_id is the nil UUID (00000000-0000-0000-0000-000000000000) when nothing is running. The active command is the front entry and is reported with state_text: ACTIVE; everything behind it is QUEUED.

The same id is also published in the vehicle's feedback as data.polymath_feedback.current_command_id, so you can watch the active command without polling the queue.

Read the history

GET /v2/command-history returns commands that have finished, newest first:

curl "https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/command-history?max_count=10" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"

Each record carries how the command ended:

{
"status": "success",
"message": "Resource fetched successfully",
"data": {
"records": [
{
"id": "a012d668-31cf-4957-9f5a-b959d13a34fb",
"summary": "VEHICLE: not_a_real_command",
"state": 2,
"state_text": "TERMINAL",
"outcome": 5,
"outcome_text": "REJECTED",
"detail": "command had an invalid vehicle command name: not_a_real_command",
"queued_time": {"sec": 0, "nanosec": 0},
"started_time": {"sec": 0, "nanosec": 0},
"completed_time": {"sec": 1786985028, "nanosec": 661649839}
}
]
}
}

A command moves through three states. It is QUEUED when accepted, becomes ACTIVE when the vehicle starts it — which stamps started_time — and becomes TERMINAL when it finishes, which stamps completed_time and sets the outcome. started_time stays zero for a command that never ran, so a terminal record with a zero started_time was discarded or rejected while still waiting.

outcome_text tells you what happened:

outcomeoutcome_textMeaning
1SUCCEEDEDThe vehicle ran the command to completion. For a navigation command that means it drove the whole path, not just that it accepted the goal
2FAILEDThe command could not be started, or aborted while running
3CANCELEDDiscarded by a stop
4PREEMPTEDDiscarded by a preempting command
5REJECTEDNever accepted, because it failed validation. detail carries the reason

detail is the place to look when a command did not do what you expected — for a rejection it holds the validation message verbatim.

A FAILED command stops the vehicle, and the stop discards everything still queued behind it as CANCELED. So one failure normally produces one FAILED record followed by a run of CANCELED ones; that is the single original fault, not several. The FAILED record is the one to read.

History is a bounded, in-memory ring: it holds the most recent commands and is empty after a vehicle restart. Poll it or record ids as you go rather than treating it as a permanent log.

Filter the history

The filters are optional query parameters and combine:

ParameterEffect
max_countReturn at most this many records. Omit or pass 0 for no limit
command_idReturn only the record with this command id
since_sec, since_nanosecReturn only records completed at or after this time

Looking up one of your own commands is the most common case — pass the id you kept from the submit response:

curl "https://polyglot.polymathrobotics.dev/api/synapse/$POLYMATH_VEHICLE_ID/v2/command-history?command_id=2cd16280-c0ed-414e-b658-c67098b868ae" \
--header "Authorization: Bearer $POLYMATH_ACCESS_TOKEN"

An empty records array means that command has not finished yet — check GET /v2/command-queue to see whether it is still queued or active.