Appearance
Trails service
/trails implements the heart of Pantahub: each device's trail — the append-only sequence of steps that drives asynchronous configuration management. The model (revisions, the +1 rule, status lifecycle, retries) is explained in Trails & steps; the practical workflow in Deploying updates.
The API has two views: devices create their trail and report progress; owners append steps and read state.
Create a trail (device, first boot)
A device creates its own trail exactly once, POSTing its factory state — this becomes revision 0:
sh
curl -s -X POST https://api.pantahub.com/trails/ \
-H "Authorization: Bearer $DTOKEN" -H 'Content-Type: application/json' \
-d '{
"kernel": {"object": "prn:pantahub.com:objects:/<kernel-object-id>"},
"app": {"object": "prn:pantahub.com:objects:/<app-object-id>"}
}'The trail's id equals the device id; the response tracks tail/tip (oldest/newest revision).
Read steps
sh
curl -s https://api.pantahub.com/trails/<trail-id>/steps \
-H "Authorization: Bearer $TOKEN"Defaults differ by identity: users get all non-completed steps, devices only steps in state NEW. Query other sets with ?q=<STATE> or ?q=ALL. A single step is addressed by its revision: GET /trails/<trail-id>/steps/<rev>.
Append a step (owner)
A new step must carry rev = current tip + 1 — the "first come, first served" rule that rejects concurrent conflicting updates:
sh
curl -s -X POST https://api.pantahub.com/trails/<trail-id>/steps \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{
"rev": 1,
"commit-msg": "update app to new release",
"state": {
"kernel": {"object": "prn:pantahub.com:objects:/<kernel-object-id>"},
"app": {"object": "prn:pantahub.com:objects:/<new-app-object-id>"}
}
}'The step starts in status NEW; the device picks it up on its next walk. (You rarely craft these by hand — pvr post and the UI's device tabs do it for you.)
Report progress (device)
The device PUTs to the progress node of the step it is working on as it moves through the lifecycle (QUEUED → INPROGRESS → DONE, or ERROR / WONTGO):
sh
curl -s -X PUT \
https://api.pantahub.com/trails/<trail-id>/steps/<rev>/progress \
-H "Authorization: Bearer $DTOKEN" -H 'Content-Type: application/json' \
-d '{"status":"INPROGRESS","progress":40,"status-msg":"downloading","log":""}'Step meta
Every step also has a free-form meta map for tooling to keep its own bookkeeping, readable and writable by the owner:
sh
curl -s -X PUT https://api.pantahub.com/trails/<trail-id>/steps/<rev>/meta \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"ci-run":"1842","approved-by":"release-bot"}'GET on the same path reads it back. Meta lives beside the step — it never affects what the device applies.
Endpoint reference
Try any of these live in the API Reference:
| Endpoint | Reference |
|---|---|
POST /trails | Create trail |
GET /trails | List trails |
GET /trails/{id} | Get trail |
GET /trails/{id}/steps | List steps |
POST /trails/{id}/steps | Append step |
GET /trails/{id}/steps/{rev} | Get step |
GET /trails/{id}/steps/{rev}/state | Step state |
PUT /trails/{id}/steps/{rev}/progress | Report progress |
PUT /trails/{id}/steps/{rev}/meta | Set step meta |
GET /trails/{id}/steps/{rev}/meta | Get step meta |
PUT /trails/{id}/steps/{rev}/cancel | Abort step |
GET /trails/{id}/summary | Trail summary |
GET /trails/summary | All-trails summary |