Local API
Reference for the HTTP API the agent opens on the device (port 8600)
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.tokenis 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 theX-Edge-Api-Tokenheader; a wrong one gets401 invalid api token. GET /healthis 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
| Method | Path | What it does |
|---|---|---|
GET | /health | Liveness. No token needed. {"status":"ok","version":"0.2.0"} |
GET | /api/v1/status | Device, link, backlog, sync, models, collectors, resources and attention all at once |
GET | /api/v1/resources | cpu / gpu / mem / disk utilization (%) |
GET | /api/v1/queue | Queued items. state (pending, uploading, failed), kind, limit (1–500, default 50), offset |
DELETE | /api/v1/queue/{id} | Drop one item |
POST | /api/v1/records | Push a record without a declaration. Body {"kind", "payload", "priority"} |
POST | /api/v1/blobs | Push 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/sync | Uploader state |
POST | /api/v1/sync:run | Send now |
POST | /api/v1/sync:retry-failed | Put items folded into failed back into the queue |
GET | /api/v1/models | Cached models and the active model |
POST | /api/v1/models/{name}:pull | Body {"version", "activate"} — pull (activates by default) |
POST | /api/v1/models/{name}:activate | Body {"version"} — switch to this version |
DELETE | /api/v1/models/{name}?version= | Delete one version from the cache |
POST | /api/v1/inference | Run the active model on an image — Models and inference |
GET | /api/v1/settings | Settings in effect (tokens left out, only whether they are configured) |
GET | /api/v1/events | Server-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.