Devices
Person-owned devices and machine device-code authorization.
Generated from the contract, version 2.0.0-draft.2 (OpenAPI). Base URL https://usekabu.com/api. Errors are problem details, each code with its own page.
Devices list
GET/v2/devices- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
self.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
limit |
query | integer, from 1 to 100 | Optional | |
after |
query | string | Optional | Opaque cursor from next_cursor. |
| Status | Means | Body |
|---|---|---|
200 |
OK | DeviceList |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl "https://usekabu.com/api/v2/devices" \
-H "Authorization: Bearer $KABU_USER_TOKEN"Devices register
PUT/v2/devicesAtomic compare-and-rebind on the hashed installation with expected_binding_version; first registration requires 0. Possession proof is additionally required for a cross-user rebind. Every success increments binding_version. Lost success replays with the same Idempotency-Key; stale_device_binding is non-retryable, do not fetch/overwrite a newer binding.
- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
self.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string, at most 255 characters | Optional | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |
Request body: DeviceRegister.
| Status | Means | Body |
|---|---|---|
200 |
OK | Device |
409 |
Installation proof conflict or non-retryable stale binding revision | DeviceBindingConflict |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl -X PUT "https://usekabu.com/api/v2/devices" \
-H "Authorization: Bearer $KABU_USER_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"installation_id":"…","expected_binding_version":0,"token":"…","platform":"ios","bundle_id":"…","environment":"sandbox","supported_ask_types":[]}'Devices remove
DELETE/v2/devices/{device_id}- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
self.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
device_id |
path | string | Required | A device owned by this user. |
curl -X DELETE "https://usekabu.com/api/v2/devices/$DEVICE_ID" \
-H "Authorization: Bearer $KABU_USER_TOKEN"Devices liveactivities register
PUT/v2/devices/{device_id}/live-activities/{session_id}Register/rotate a per-activity token for a visible session; user must own the device and be in the session audience.
- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
self.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
device_id |
path | string | Required | A device owned by this user. |
session_id |
path | string | Required | A ses_… id. |
Request body: LiveActivityRegister.
curl -X PUT "https://usekabu.com/api/v2/devices/$DEVICE_ID/live-activities/$SESSION_ID" \
-H "Authorization: Bearer $KABU_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"token":"…"}'Devices liveactivities remove
DELETE/v2/devices/{device_id}/live-activities/{session_id}- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
self.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
device_id |
path | string | Required | A device owned by this user. |
session_id |
path | string | Required | A ses_… id. |
curl -X DELETE "https://usekabu.com/api/v2/devices/$DEVICE_ID/live-activities/$SESSION_ID" \
-H "Authorization: Bearer $KABU_USER_TOKEN"Start machine device-code login
POST/v2/device_authorizations- Auth: no credentials.
Request body: DeviceAuthorizationCreate.
| Status | Means | Body |
|---|---|---|
201 |
OK | DeviceAuthorization |
429 |
A rate, concurrency or quota limit was reached | Problem |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl -X POST "https://usekabu.com/api/v2/device_authorizations" \
-H "Content-Type: application/json" \
-d '{"name":"…"}'Poll machine login result
POST/v2/device_authorizations/pollRFC 8628 token endpoint: form-encoded device_code and grant_type. Before approval: 400 authorization_pending; too-fast polling: 400 slow_down (+5 s interval permanently); denial: 400 access_denied; expiry: 400 expired_token. Approval yields 200 access_token/token_type/scope. Terminal denial/expiry never yields a token.
- Auth: no credentials.
Request body: application/x-www-form-urlencoded: DeviceAuthorizationPoll.
| Status | Means | Body |
|---|---|---|
200 |
OK | DeviceAuthorizationToken |
400 |
RFC 8628 polling error (pending, slow down, denial or expiry) | DeviceAuthorizationError |
429 |
A rate, concurrency or quota limit was reached | Problem |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl -X POST "https://usekabu.com/api/v2/device_authorizations/poll"Deviceauthorizations approve
POST/v2/device_authorizations/approveOwner/admin only; atomically move pending to approved and mint an agent key for the machine in the selected org. Denied/expired codes cannot be approved (409 device_authorization_settled); never expose its secret to the human.
- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string, at most 255 characters | Optional | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |
Kabu-Org |
header | string | Optional | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |
Request body: DeviceAuthorizationApprove.
| Status | Means | Body |
|---|---|---|
200 |
OK | DeviceAuthorizationConsent |
429 |
A rate, concurrency or quota limit was reached | Problem |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl -X POST "https://usekabu.com/api/v2/device_authorizations/approve" \
-H "Authorization: Bearer $KABU_USER_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"user_code":"…"}'Deviceauthorizations lookup
GET/v2/device_authorizations/lookupOwner/admin lookup before consent. Returns only computer name, requested access, expiry and state; never the machine polling capability. Unknown code is 404.
- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user_code |
query | string | Required | |
Kabu-Org |
header | string | Optional | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |
| Status | Means | Body |
|---|---|---|
200 |
OK | DeviceAuthorizationConsent |
429 |
A rate, concurrency or quota limit was reached | Problem |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl "https://usekabu.com/api/v2/device_authorizations/lookup?user_code=%E2%80%A6" \
-H "Authorization: Bearer $KABU_USER_TOKEN"Deviceauthorizations deny
POST/v2/device_authorizations/denyOwner/admin only. Atomically transition pending to denied. Approved/expired codes cannot be denied (409 device_authorization_settled). A denied code polls as access_denied, never a token.
- Kabu apps only: a signed-in human’s token. Integrations use API keys.
- Signed-in humans:
admin.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string, at most 255 characters | Optional | Retry-safe key. For messages, sessions and responses it binds to the created object for its life; elsewhere for 24 h. |
Kabu-Org |
header | string | Optional | Select a live membership (default personal org); non-member is 404. Human tokens are live-only. Caller user id is distinct from billing owner. |
Request body: DeviceAuthorizationDeny.
| Status | Means | Body |
|---|---|---|
200 |
OK | DeviceAuthorizationConsent |
429 |
A rate, concurrency or quota limit was reached | Problem |
4XX |
Error | Problem |
5XX |
Error | Problem |
curl -X POST "https://usekabu.com/api/v2/device_authorizations/deny" \
-H "Authorization: Bearer $KABU_USER_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"user_code":"…"}'Schemas
DeviceList
| Property | Type | Required | Description |
|---|---|---|---|
object |
"list" |
Required | |
data |
array of Device | Required | |
has_more |
boolean | Required | |
next_cursor |
string or null | Required |
Device
| Property | Type | Required | Description |
|---|---|---|---|
object |
"device" |
Required | |
id |
string | Required | |
platform |
string | Required | |
bundle_id |
string | Required | |
environment |
string | Required | |
supported_ask_types |
array of string | Required | |
live_activities |
boolean | Required | |
created_at |
Timestamp | Required | |
binding_version |
integer, ≥ 1 | Required | Server-issued installation binding revision, strictly increases on every successful conditional registration, rotation or rebind. |
DeviceRegister
User comes only from the token. Installation id is stored hashed. Moving a token between users needs the same installation proof (else 409). Bundle/environment allowlisted. Retire v1 only by authenticated legacy device id or same user + token + Kabu bundle, never token alone.
| Property | Type | Required | Description |
|---|---|---|---|
installation_id |
string, 32 to 256 characters | Required | |
expected_binding_version |
integer, ≥ 0 | Required | 0 only for a new installation; otherwise the last server-issued binding_version. A stale version is 409 stale_device_binding, retryable=false. Never refresh/retry a stale request automatically. |
token |
string, 1 to 4096 characters | Required | |
platform |
string, one of "ios" |
Required | |
bundle_id |
string | Required | |
environment |
string, one of "sandbox", "production" |
Required | |
supported_ask_types |
array of string, at most 32 items | Required | The ask types and push capabilities this build reads (open list; unknown values are ignored). Push capabilities: hitl_choice_v1 (KABU_ASK_CHOICE with option labels), hitl_choice_numbered_v1 (a 2- or 3-option choice as KABU_ASK_CHOICE_2/_3 with an “Option N: label” legend in the body; x-push-categories), hitl_sound_v1 (aps.sound), hitl_person_v1 (agent_key, agent_avatar, agent_color), hitl_brand_v1 (project, agent, icon, brand_logo_url, brand_accent), presence_la_v1 (a session’s own Live Activity start and update carry content-state presence and aps stale-date, the lease’s expires_at; x-push-payload-schemas). |
live_activity_start_token |
string or null | Optional | |
legacy_device_id |
string | Optional |
Unknown properties are refused.
DeviceBindingConflict
A binding conflict; stale_device_binding is terminal and cannot be retried automatically.
Type: Problem.
LiveActivityRegister
| Property | Type | Required | Description |
|---|---|---|---|
token |
string, 1 to 4096 characters | Required |
Unknown properties are refused.
DeviceAuthorizationCreate
| Property | Type | Required | Description |
|---|---|---|---|
name |
string, 1 to 80 characters | Required |
Unknown properties are refused.
DeviceAuthorization
| Property | Type | Required | Description |
|---|---|---|---|
object |
"device_authorization" |
Required | |
device_code |
string | Required | |
user_code |
string | Required | |
verification_uri |
string | Required | |
verification_uri_complete |
string | Required | |
expires_in |
integer | Required | |
interval |
integer | Required |
DeviceAuthorizationPoll
| Property | Type | Required | Description |
|---|---|---|---|
device_code |
string, 1 to 256 characters | Required | |
grant_type |
"urn:ietf:params:oauth:grant-type:device_code" |
Required |
Unknown properties are refused.
DeviceAuthorizationToken
RFC 8628 token response. Bearer agent key, machine-only; no human response returns this object. Sealed durable replay survives restart.
| Property | Type | Required | Description |
|---|---|---|---|
access_token |
string | Required | |
token_type |
string | Required | |
scope |
string | Required | |
org_name |
string | Optional | Workspace display name for Connected to |
project |
string | Optional | Connected project slug for installer confirmation. Optional for compatibility with older sealed token replays. |
DeviceAuthorizationError
HTTP 400 application/json OAuth token error, not a Problem. Poll no faster than interval; slow_down permanently adds 5 seconds to the interval. access_denied and expired_token are terminal.
| Property | Type | Required | Description |
|---|---|---|---|
error |
string | Required | RFC 8628: authorization_pending, slow_down, access_denied, expired_token; other OAuth errors may be added. |
error_description |
string | Optional |
DeviceAuthorizationApprove
| Property | Type | Required | Description |
|---|---|---|---|
user_code |
string, 1 to 64 characters | Required | |
project |
ProjectRef | Optional | A project slug (auto-created on first use) or prj_… id. Omit for default. A slug that normalises (lowercase, letters and digits only) to an existing project’s key names that project, so My App, my-app and my_app are one project. Automatic creation stops at 1,000 live projects per org and mode with 429 quota_exceeded; existing projects stay usable. Nothing remembers a deleted project (projects.delete): the next message that names its slug creates a fresh one. |
Unknown properties are refused.
DeviceAuthorizationConsent
Secret-free human consent descriptor. Never contains device_code, an access token or a key secret. Requested access is the server’s agent preset; the human selects the org/project on approval.
| Property | Type | Required | Description |
|---|---|---|---|
object |
"device_authorization_consent" |
Required | |
user_code |
string | Required | |
computer_name |
string | Required | |
requested_access |
array of string | Required | |
requested_at |
Timestamp | Required | |
expires_at |
Timestamp | Required | |
status |
string | Required | pending, approved, denied or expired (open). |
DeviceAuthorizationDeny
| Property | Type | Required | Description |
|---|---|---|---|
user_code |
string, 1 to 64 characters | Required |
Unknown properties are refused.