API reference

REST API

A predictable, workspace-scoped JSON API for your fleet. Base URL is your self-hosted backend, e.g. https://convex.your-domain.com/api.

Authentication

Authenticate with a workspace-scoped API key in the x-api-key header. Mint keys under Settings → API keys. Each key resolves to exactly one workspace; all reads and writes are scoped to it.

curl https://convex.your-domain.com/api/v1/devices \
  -H "x-api-key: sk_live_2b1c…"

Errors & pagination

Errors return a non-2xx status with a JSON body. List endpoints are cursor-paginated: pass cursor and read next_cursor from the response (null when exhausted).

{ "error": "forbidden", "status": 403 }

Endpoints

GET /v1/devices

List devices in the workspace.

{
  "items": [
    { "id": "295758162", "name": "qz-win-105",
      "os": "Windows", "online": true,
      "last_seen": "2026-06-28T07:32:35Z" }
  ],
  "next_cursor": null
}
GET /v1/devices/:id

Retrieve a single device.

POST /v1/devices/:id/unbind

Unbind a device from its user. Workspace-scoped.

POST /v1/devices/:id/secret:rotate

Rotate a device's secret; it must re-authenticate.

GET /v1/sessions

List connection history and live sessions.

{
  "items": [
    { "device_id": "295758162", "status": "success",
      "duration_sec": 120, "at": "2026-06-28T07:40:00Z" }
  ]
}
GET /v1/usage

Read metered usage for the workspace.

{
  "session_minutes": 1240,
  "active_devices": 8,
  "devices": 23
}
GET /v1/members

List workspace members and roles.

POST /v1/members:invite

Invite a member by email with a role.

// request
{ "email": "dev@acme.com", "role": "member" }

Webhooks

Your signaling server can push live fleet events to a webhook on your control plane. Events are verified with a shared secret in the x-webhook-secret header and include device and connection deltas.

POST /backend/webhook
{
  "type": "device.online.changed",
  "qdDeviceId": "295758162",
  "online": true
}
Need a key?

Create a workspace-scoped API key in the dashboard.

Open dashboard →