Docs
Quickstart and curls for org keys, device registration, validation, usage, and Stripe-backed billing.
Create an org, register a device, and validate it. You can store an org key above for quick reference; curls below use {{ORG_KEY}} placeholders.
From your backend or CLI, create an org and store the returned key alongside your customer.
The response includes your orgApiKey. Save it; your own agents and tools will send it in the x-org-key header.
Call this from your agent, gateway, or service when a machine first comes online.
A successful response returns status: "ok". If the device already exists you'll see
"exists", and if you hit your cap you'll see "limit_reached".
Your agent should call validate before doing real work (on startup or on a schedule).
Active devices return valid: true. Revoked devices return valid: false and
revoked: true.
You can wire these same calls into your own control plane or admin UI:
POST /api/v1/org/createwhen a customer signs up.POST /api/v1/devices/registerfrom your agent or gateway.GET /api/v1/devices/validatebefore doing work.POST /api/v1/devices/revoketo turn a device off.POST /api/v1/devices/unrevoketo restore it.
The Dashboard uses the same endpoints, so you can sanity-check your flow visually.
A small set of primitives: org keys, devices, plan tiers, and server-side limits.
One key per customer or tenant. All devices for that customer share the same orgApiKey.
Store it in your own user/org record and in your agents. Send it in the x-org-key header
when calling the API.
Anything that phones home: an agent, gateway, service instance, or hardware device. Each uses a
deviceId string you control.
Plans map to device caps: free (3), pro (25), scale (250), max (1000). Limits are enforced server-side, not baked into your binaries.
Plans are backed by Stripe Checkout and portal. Plan changes update limits on the API without requiring new builds. Think: built by people who ship agents, for people who ship agents—keeping pricing logic off the edge and in one place.
A simple lifecycle: create org → register device → validate regularly → revoke or restore if needed.
In your control plane or signup flow, call POST /api/v1/org/create and store the
orgApiKey with your customer record.
On first install or provisioning, call POST /api/v1/devices/register with
deviceId in the body and your org key in the x-org-key header.
Before doing real work, call GET /api/v1/devices/validate. If
valid: true, continue. If valid: false or revoked: true,
stop and optionally show an upgrade or contact-support message.
From your admin tools or automation, call POST /api/v1/devices/revoke to turn off a device.
Revoked devices will fail validation until you restore them.
When a device should be allowed again, call POST /api/v1/devices/unrevoke (or use the dashboard).
If an org hits its plan cap, /devices/register returns status: "limit_reached",
along with planTier, limit, and devicesUsed. You can use this to
prompt for an upgrade in your own UI or logs.
Check how many devices are active for an org, what cap applies, and whether it’s in a grace or frozen state.
From your backend or internal tools, call /api/v1/usage to show the same numbers you see in
the MachineID.io dashboard.
A successful response includes the current plan, how many devices are active, the limit for that plan, and simple flags for grace/frozen state:
{
"status": "ok",
"handler": "usage",
"planTier": "free",
"planState": "active",
"accessUntil": null,
"limit": 3,
"devicesUsed": 1,
"remaining": 2,
"overLimit": false,
"isActive": true,
"isGrace": false,
"isFrozen": false
}
Plans are backed by Stripe. You can query the current plan and open Checkout to upgrade.
Use /billing/summary to display the current plan and a short message, like “Free plan — upgrade available”
or “Managed via Stripe customer portal”.
When it’s time to upgrade, your dashboard or backend can call /billing/checkout with the target plan tier.
The response includes a Stripe url you can redirect the user to.
In production, you would typically call this from your own UI, then redirect the user to the returned
url. If Stripe is not configured for a given environment or plan, the response will return
ok: false with an error message instead of a URL.
Responses are small and predictable. Log status and handler for quick debugging.
Common patterns:
-
Missing or empty org key:
{ "status": "error", "error": "missing_params", "handler": "usage" } -
Org not found:
{ "status": "not_found", "handler": "usage" } -
Device registration hitting the plan cap:
{ "status": "limit_reached", "deviceId": "dev-999", "planTier": "free", "limit": 3, "devicesUsed": 3, "handler": "devices/register" } -
Generic input error for devices:
{ "status": "error", "error": "missing_params", "handler": "devices/register" }
Your agents and services can branch on status and error, and you can use
handler to quickly see which part of the API responded.