1KEY Developers
Reference

API reference

Base URL https://api.1keyplatform.dev/v1. Generated from the OpenAPI contract, which you can download as openapi.yaml.

Sites

The buildings your organization manages. Every hub is at a site.

GET /sites

List sites

Scope sites:read

Your organization's sites, oldest first.

ParameterIn Type Description
limit query integer
starting_after query string ID of the last item on the previous page.
Responses 200 400 401 403 429

200 A page of sites.

{
  "data": [
    {
      "created_at": "2026-09-12T15:20:00Z",
      "hub_count": 2,
      "id": "6f1c2a9e-4b7d-4e0a-9c3f-2d8e5a1b7c40",
      "name": "120 Harbour St"
    }
  ],
  "has_more": false
}

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

429 Too many requests. Retry after the `Retry-After` header.

POST /sites

Create a site

Scope sites:write
Request body
{
  "name": "120 Harbour St"
}
Responses 201 400 401 403

201 The new site.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}
GET /sites/{site_id}

Get a site

Scope sites:read
ParameterIn Type Description
site_id required path string
Responses 200 401 403 404

200 The site.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}
PATCH /sites/{site_id}

Rename a site

Scope sites:write
ParameterIn Type Description
site_id required path string
Request body
{
  "name": "Harbour Tower"
}
Responses 200 400 401 403 404

200 The updated site.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

Hubs

Hubs your organization owns.

GET /hubs

List hubs

Scope hubs:read

Hubs your organization owns, ordered by hub ID.

ParameterIn Type Description
limit query integer
starting_after query string ID of the last item on the previous page.
site_id query string Only hubs at this site.
Responses 200 401 403 429

200 A page of hubs.

{
  "data": [
    {
      "connection": {
        "since": "2026-10-01T09:14:02Z",
        "status": "online"
      },
      "id": "1key-xfy2-nmf4-5xwp",
      "name": "Lobby hub",
      "registered_at": "2026-09-12T15:30:00Z",
      "site_id": "6f1c2a9e-4b7d-4e0a-9c3f-2d8e5a1b7c40"
    }
  ],
  "has_more": false
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

429 Too many requests. Retry after the `Retry-After` header.

POST /hubs

Add a hub to a site

Scope hubs:write

Adds a hub to one of your sites by the Serial on its label. The hub must be installed and online. The first organization to add a hub keeps it. Adding a hub your organization already has moves it to the given site.

Request body
{
  "name": "Lobby hub",
  "serial": "1KEY-XFY2-NMF4-5XWP",
  "site_id": "6f1c2a9e-4b7d-4e0a-9c3f-2d8e5a1b7c40"
}
Responses 200 400 401 403 404 422

200 The hub, now at the site.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

422 The hub can't be added. The Serial is unknown, the hub has not come online, or another organization has it.

{
  "error": {
    "message": "This hub can't be added. Check the Serial, and that the hub is online.",
    "request_id": "req_5LqW2v",
    "type": "hub_not_addable"
  }
}
GET /hubs/{hub_id}

Get a hub

Scope hubs:read
ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Responses 200 401 403 404

200 The hub.

{
  "connection": {
    "since": "2026-10-01T09:14:02Z",
    "status": "online"
  },
  "id": "1key-xfy2-nmf4-5xwp",
  "name": "Lobby hub",
  "registered_at": "2026-09-12T15:30:00Z",
  "site_id": "6f1c2a9e-4b7d-4e0a-9c3f-2d8e5a1b7c40"
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}
PATCH /hubs/{hub_id}

Update a hub

Scope hubs:write

Renames the hub, moves it to another of your sites, or both.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Request body
{
  "name": "Lobby hub"
}
Responses 200 400 401 403 404

200 The updated hub.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

Members

People in your organization, and invitations to join it.

GET /invitations

List pending invitations

Scope members:read

Invitations not yet accepted, revoked or expired, newest first.

Responses 200 401 403

200 All pending invitations.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}
POST /invitations

Invite someone

Scope members:write

Emails the address a link to join your organization, valid for 7 days. Opening it creates their account if they have none.

Request body
{
  "email": "[email protected]",
  "role": "member"
}
Responses 201 400 401 403

201 The invitation.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}
DELETE /invitations/{invitation_id}

Revoke an invitation

Scope members:write
ParameterIn Type Description
invitation_id required path string
Responses 204 401 403 404

204 Revoked; the link no longer works.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}
GET /members

List members

Scope members:read

Everyone in your organization, owners first.

Responses 200 401 403

200 All members.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}
DELETE /members/{member_id}

Remove a member

Scope members:write

API keys cannot remove owners.

ParameterIn Type Description
member_id required path string
Responses 204 401 403 404

204 Removed.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 API keys cannot change or remove owners, or make someone an owner.

{
  "error": {
    "message": "API keys can't change or remove owners, or make someone an owner.",
    "request_id": "req_5LqW2v",
    "type": "forbidden"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}
GET /members/{member_id}

Get a member

Scope members:read
ParameterIn Type Description
member_id required path string
Responses 200 401 403 404

200 The member.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}
PATCH /members/{member_id}

Change a member's role

Scope members:write

Between `admin` and `member`. API keys cannot change owners or make owners.

ParameterIn Type Description
member_id required path string
Request body
{
  "role": "admin"
}
Responses 200 400 401 403 404

200 The member.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 API keys cannot change or remove owners, or make someone an owner.

{
  "error": {
    "message": "API keys can't change or remove owners, or make someone an owner.",
    "request_id": "req_5LqW2v",
    "type": "forbidden"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

Devices

Devices connected to a hub and their channels, read live from the hub.

GET /hubs/{hub_id}/devices

List a hub's devices

Scope hubs:read

Asked of the hub live, so it fails with `503 hub_offline` while the hub is disconnected and `504 hub_timeout` if it does not answer within 10 seconds. Channels are listed without their values; get a device for those.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Responses 200 401 403 404 502 503 504

200 The hub's devices.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

502 The hub failed, or the request could not be sent to it.

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}

504 The hub did not answer in time.

DELETE /hubs/{hub_id}/devices/{device_id}

Forget a device the hub can't reach

Scope hubs:write

A device still on the hub's network is refused with `400`; remove it with the removal window.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
device_id required path integer
Responses 204 400 401 403 404 503

204 Forgotten; a `device.forgotten` event follows.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}
GET /hubs/{hub_id}/devices/{device_id}

Get a device and its current state

Scope hubs:read

Each channel with the value the device last reported, asked of the hub live.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
device_id required path integer
Responses 200 401 403 404 502 503 504

200 The device, with each channel's state.

{
  "channels": [
    {
      "available": true,
      "capabilities": {},
      "desired": null,
      "desired_at": null,
      "endpoint": 0,
      "key": "battery",
      "kind": "battery",
      "observed_at": "2026-10-03T13:58:00.000000Z",
      "readable": true,
      "status": "synchronized",
      "unit": "%",
      "value": 82,
      "writable": false
    },
    {
      "available": true,
      "capabilities": {},
      "desired": null,
      "desired_at": null,
      "endpoint": 0,
      "key": "lock",
      "kind": "lock",
      "observed_at": "2026-10-03T14:00:00.000000Z",
      "readable": true,
      "status": "synchronized",
      "unit": null,
      "value": true,
      "writable": true
    }
  ],
  "id": 7,
  "manufacturer": "Yale",
  "model": "YRD256",
  "name": "Front door"
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

502 The hub failed, or the request could not be sent to it.

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}

504 The hub did not answer in time.

PATCH /hubs/{hub_id}/devices/{device_id}

Name a device and set its room

Scope hubs:write

Kept in the cloud. Send `name`, `room` or both; `null` clears one.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
device_id required path integer
Request body
{
  "name": "Main entrance",
  "room": "Entrance"
}
Responses 200 400 401 403 404

200 The device's name and room.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}
DELETE /hubs/{hub_id}/pairing

Close the pairing window

Scope hubs:write
ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Responses 204 401 403 404 503

204 Closed.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}
POST /hubs/{hub_id}/pairing

Open the hub's network for a device to join

Scope hubs:write

The hub listens for one device for two minutes; put the device in pairing mode. It arrives as a `device.added` event.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Responses 202 400 401 403 404 503 504

202 The window is open.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}

504 The hub did not answer in time.

DELETE /hubs/{hub_id}/removal

Close the removal window

Scope hubs:write
ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Responses 204 401 403 404 503

204 Closed.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}
POST /hubs/{hub_id}/removal

Open the hub's network for a device to leave

Scope hubs:write

Press the device's button within two minutes. It leaves as a `device.forgotten` event.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Responses 202 401 403 404 503 504

202 The window is open.

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}

504 The hub did not answer in time.

Commands

Actions sent to a hub's devices.

POST /hubs/{hub_id}/devices/{device_id}/commands

Set a channel

Scope hubs:command

Asks the hub to set one of the device's writable channels: lock or unlock, set a setpoint, turn a switch on. `202` means the hub accepted it and handed it to the device: the channel's `desired` is set and its `status` is `pending`. The outcome is the channel's next reading: `synchronized` once the device reports the value, `failed` or `diverged` otherwise. Follow `channel.observed` events, or get the device.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
device_id required path integer
Idempotency-Key header string Any unique string, up to 255 characters. A retry with the same key within 24 hours returns the first response instead of sending the command again.
Request body
{
  "key": "lock",
  "value": false
}
Responses 202 400 401 403 404 409 422 502 503 504

202 Accepted by the hub.

{
  "channel": {
    "available": true,
    "desired": false,
    "desired_at": "2026-10-03T14:03:10.000000Z",
    "endpoint": 0,
    "key": "lock",
    "kind": "lock",
    "observed_at": "2026-10-03T14:00:00.000000Z",
    "status": "pending",
    "unit": null,
    "value": true
  },
  "device_id": 7,
  "hub_id": "1key-xfy2-nmf4-5xwp"
}

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

409 The Idempotency-Key was used with a different request body.

422 The hub refused the command, for example a lock that did not join securely enough to be driven.

{
  "error": {
    "message": "this lock did not join securely enough to be driven",
    "request_id": "req_5LqW2v",
    "type": "command_refused"
  }
}

502 The hub failed, or the request could not be sent to it.

503 `hub_offline`: the hub is not connected. `hub_unavailable`: it is connected but cannot do it now, for example its radio is down or it does not know the time yet.

{
  "error": {
    "message": "Hub 1key-xfy2-nmf4-5xwp is offline.",
    "request_id": "req_5LqW2v",
    "type": "hub_offline"
  }
}

504 The hub did not answer in time.

Events

Events from a hub, kept for 24 hours and read with a per-hub cursor.

GET /hubs/{hub_id}/events

Read a hub's events

Scope events:read

Events after `after`, oldest first. Without `after`, from the oldest kept (events are kept for 24 hours). Pass `next_cursor` as `after` next time.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
after query string A cursor from a previous page or event.
limit query integer
wait query integer Seconds to hold the request open when there are no events yet.
Responses 200 400 401 403 404 410

200 A page of events.

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

410 The cursor is older than the 24-hour retention, or from before the hub was reset.

{
  "error": {
    "message": "Cursor is older than 24 hours. Read current state",
    "request_id": "req_5LqW2v",
    "then continue from the newest event.": null,
    "type": "cursor_expired"
  }
}
GET /hubs/{hub_id}/events/stream

Stream a hub's events

Scope events:read

Server-Sent Events. Each message's `id` is the event's cursor and its `event` the event type. Starts after `Last-Event-ID`, or with the next new event without it. A `: keepalive` comment arrives every 30 seconds. The server ends the stream after 15 minutes; reconnect with `Last-Event-ID`.

ParameterIn Type Description
hub_id required path string The hub ID printed on the hub (lowercase).
Last-Event-ID header string
Responses 200 400 401 403 404 410

200 An event stream.

id: 1043
event: channel.observed
data: {"cursor":"1043","type":"channel.observed","hub_id":"1key-xfy2-nmf4-5xwp","device_id":7,"time":"2026-10-03T14:03:11.143000Z","clock_trusted":true,"data":{"key":"lock","endpoint":0,"value":false}}

400 The request is malformed or a field is invalid.

{
  "error": {
    "message": "action: unknown for device type lock",
    "request_id": "req_5LqW2v",
    "type": "invalid_request"
  }
}

401 Missing, malformed, revoked or unknown API key.

{
  "error": {
    "message": "Invalid API key.",
    "request_id": "req_5LqW2v",
    "type": "unauthenticated"
  }
}

403 The key lacks the scope this operation needs.

{
  "error": {
    "message": "This key needs hubs:command.",
    "request_id": "req_5LqW2v",
    "type": "insufficient_scope"
  }
}

404 No such resource, or it is not your organization's.

{
  "error": {
    "message": "No hub 1key-aaaa-bbbb-cccc in your organization.",
    "request_id": "req_5LqW2v",
    "type": "not_found"
  }
}

410 The cursor is older than the 24-hour retention, or from before the hub was reset.

{
  "error": {
    "message": "Cursor is older than 24 hours. Read current state",
    "request_id": "req_5LqW2v",
    "then continue from the newest event.": null,
    "type": "cursor_expired"
  }
}