The agent opens an HTTP API on api.host:api.port (default 0.0.0.0:8600). A tablet screen on site, other programs on the same LAN, and CLI commands such as geo-mlops-edge status all use this API. Edge PCs usually have no screen, so this is your window into the device.

Authentication

  • When api.token is empty, there is no authentication (the default). The LAN is the boundary. This default avoids a situation where nobody can even see whether the line is collecting until a secret has been handed out to every tablet on site.
  • When you set api.token, every request needs the X-Edge-Api-Token header; a wrong one gets 401 invalid api token.
  • GET /health is always open regardless of the token (for load balancer and container health checks).
# Set the token (environment variable recommended)
GEO_EDGE_API__TOKEN=<your-secret>

curl -H 'X-Edge-Api-Token: <your-secret>' http://edge-pc:8600/api/v1/status

Request bodies over api.max_body_bytes (default 2 GiB) are rejected with 413. The limit keeps one misdirected upload to an unauthenticated API from bringing the device down.

Endpoints

MethodPathWhat it does
GET/healthLiveness. No token needed. {"status":"ok","version":"0.2.0"}
GET/api/v1/statusDevice, link, backlog, sync, models, collectors, resources and attention all at once
GET/api/v1/resourcescpu / gpu / mem / disk utilization (%)
GET/api/v1/queueQueued items. state (pending, uploading, failed), kind, limit (1–500, default 50), offset
DELETE/api/v1/queue/{id}Drop one item
POST/api/v1/recordsPush a record without a declaration. Body {"kind", "payload", "priority"}
POST/api/v1/blobsPush a file without a declaration. The body is the file itself. Query kind, filename, priority, dataset_id
PUT/api/v1/collectors/{name}/records/{id}Push into a declared push entry point. Body {"payload", "ts"}. 201 newly stored / 200 duplicate
GET/api/v1/syncUploader state
POST/api/v1/sync:runSend now
POST/api/v1/sync:retry-failedPut items folded into failed back into the queue
GET/api/v1/modelsCached models and the active model
POST/api/v1/models/{name}:pullBody {"version", "activate"} — pull (activates by default)
POST/api/v1/models/{name}:activateBody {"version"} — switch to this version
DELETE/api/v1/models/{name}?version=Delete one version from the cache
POST/api/v1/inferenceRun the active model on an image — Models and inference
GET/api/v1/settingsSettings in effect (tokens left out, only whether they are configured)
GET/api/v1/eventsServer-sent events (SSE): link · sync · queue · model · command …

A file sent with dataset_id is registered as a file of that dataset once Central finishes assembling it, and goes through the same validation as a web upload. A dataset in another tenant gives 404.

Examples

See failed items in the queue

curl -s 'http://127.0.0.1:8600/api/v1/queue?state=failed&limit=5'
{
  "items": [],
  "backlog": { "count": 0, "bytes": 0, "oldest_ts": null, "evicted_24h": 0, "by_kind": {} }
}

When there are items, attempts (number of tries) and last_error (the last error) come with them.

Subscribe to events

curl -N http://127.0.0.1:8600/api/v1/events?history=20
event: <kind>
data: {"kind": "<kind>", "name": "<event name>", "ts": "<ISO time>", "data": {...}}

Right after connecting it first sends the last history events (default 20, maximum 200), so a freshly opened screen does not sit empty.

Check the settings

curl -s http://127.0.0.1:8600/api/v1/settings
{
  "device": {
    "id": "edge-bench-01",
    "location": "bench",
    "hostname": "edge-pc",
    "os": "Ubuntu 24.04.5 LTS x86_64",
    "agent_version": "0.2.0"
  },
  "central": { "base_url": "https://mlops.example.com", "configured": true },
  "policy": { "revision": 0, "heartbeat_interval_s": 5.0, "commands_poll_s": 10.0 }
}

(Some fields are trimmed.) The OpenAPI docs are at the agent's /docs.

Written for the platform as of 2026-09-21.

© Geo-MLOps