CloudrawAPI v0
Menu

API reference

Enrollments

Enrollment codes that add a device or a connector to the workspace.

List pending enrollments

GET/v0/tenants/{tenant_id}/enrollments

read-only token

Device enrollments that were issued but not used yet and have not expired ("waiting to enroll"). Never returns a token or code. A device that has joined disappears from this list and shows in GET /devices.

Token: read-only or full access · Created by: owner or security admin

Path parameters

  • tenant_idstringrequired

    Your workspace id (Settings → Workspace in the console; it is also in every console URL).

    Example: tq7x2m9k4ab

Query parameters

  • kindstring

    Only device is supported.

    Example: device

  • statestring

    Only issued is supported.

    Example: issued

Responses

200 Pending enrollments (not paginated).

application/json

  • itemsarray of Enrollmentrequired

    Newest first.

    items fields
    • idstringrequired
    • kindstring

      device.

    • statestring

      issued (not used yet).

    • device_namestringrequired
    • created_atstring (date-time)
    • created_by_integratorobject | null

      Set when an integrator (partner) you approved created this record from its own account; null otherwise.

      created_by_integrator fields
      • kindstring

        Always partner.

      • partner_idstring
      • partner_namestring
      • memberstring | null

        Which of the integrator's staff.

      • member_idstring | null
      • atstring (date-time)
    • expires_atstring (date-time)required
    • claim_expires_atstring | null (date-time)

      Expiry of the live short code; null when no code is live (a new one can be issued in the console).

  • next_cursornull

    Always null: the list is bounded by the device quota.

400 invalid-kind invalid-state

invalid-kind: kind is not device.

invalid-state: state is not issued.

401 unauthorized invalid-token token-expired

unauthorized: No Authorization: Bearer crw_… header was sent.

invalid-token: The token is unknown or was revoked.

token-expired: The token is past its expiry date. Create a new one.

403 insufficient-role tenant-assertion-mismatch

insufficient-role: The token's role ceiling does not allow this call.

tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.

404 tenant-not-found

tenant-not-found: No workspace with this id.

curl
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments" \
  -H "Authorization: Bearer $CLOUDRAW_TOKEN"
PowerShell
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments" -Headers $headers
Python
import os, uuid, requests

r = requests.get(
    "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments",
    headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
    timeout=30,
)
r.raise_for_status()
print(r.json())
Node.js
const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
  },
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());
Response 200 · application/json
{
  "items": [
    {
      "id": "en_7k2x9m0s1d",
      "kind": "device",
      "state": "issued",
      "device_name": "omer-laptop",
      "created_at": "2026-10-13T08:00:00.000Z",
      "created_by_integrator": null,
      "expires_at": "2026-10-20T08:00:00.000Z",
      "claim_expires_at": "2026-10-13T09:00:00.000Z"
    }
  ],
  "next_cursor": null
}

Create a device enrollment

POST/v0/tenants/{tenant_id}/enrollments

full-access tokenidempotent

Issues a one-time enrollment for a new device and returns how to join it: a short code (claim_code, valid 1 hour, entered in Cloudraw Connect), a link with the same code (claim_url) and the enrollment token itself (jwt, valid 7 days). Give one of them to the user over a direct channel. Counts toward the device quota. Audited.

Token: full access · Created by: owner

Idempotency: send Idempotency-Key. The answer carries a secret shown once: a retry with the same key answers 409 already-issued instead of the secret.

Secret answer: the token and code are shown only in this answer. Lost them? Cancel the enrollment (DELETE /enrollments/{enrollment_id}) and create a new one.

Path parameters

  • tenant_idstringrequired

    Your workspace id (Settings → Workspace in the console; it is also in every console URL).

    Example: tq7x2m9k4ab

Headers

  • Idempotency-Keystring

    A unique value (e.g. a UUID) per logical operation. Retrying with the same key and body within 24 hours returns the first answer instead of doing the work twice.

    Example: 6f1c2b9e-3d4a-4c1e-9b8f-0a7d5e2c1b3f

Request body application/json

  • kindstring

    Default device.

    One of: device.

  • deliverystring

    How you will hand the enrollment to the user (recorded on the device as delivery; the answer is the same). Default token. sso and provision are set by Cloudraw only.

    One of: token, code, qr, email.

  • device_namestring

    Name for the device. Lowercased, other characters become -, at most 40 characters. Default device-<n>. Must not be in use by another device.

  • person_idstring | null

    Person the device will belong to. An unknown id is ignored (the device is unassigned).

Responses

201 The enrollment, with its secrets. Shown once: they are never returned again and are not kept for Idempotency-Key replays. Sent with Cache-Control: no-store; do not cache or log it.

application/json

  • idstringrequired

    Enrollment id; also the id of the device once it joins.

  • kindstring

    device.

  • statestring

    issued.

  • jwtstringrequired

    One-time enrollment token (shown once). Valid until expires_at.

  • claim_codestringrequired

    Short code the user types in Cloudraw Connect, CRW-XXXXX-XXXXX (shown once). Valid 1 hour.

  • claim_urlstringrequired

    Link that opens Cloudraw Connect with the code (shown once).

  • claim_expires_atstring (date-time)
  • qr_png_base64null
  • expires_atstring (date-time)required

    When the enrollment token expires (7 days).

400 invalid-delivery

invalid-delivery: delivery is not one of token, code, qr, email.

401 unauthorized invalid-token token-expired

unauthorized: No Authorization: Bearer crw_… header was sent.

invalid-token: The token is unknown or was revoked.

token-expired: The token is past its expiry date. Create a new one.

403 device-quota-reached insufficient-scope insufficient-role tenant-assertion-mismatch

device-quota-reached: The workspace already has as many devices as its plan allows.

insufficient-scope: The token is read-only and this call changes something.

insufficient-role: The token's role ceiling does not allow this call.

tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.

404 tenant-not-found

tenant-not-found: No workspace with this id.

409 idempotency-key-reuse already-issued

idempotency-key-reuse: The same Idempotency-Key was used with a different body within 24 hours.

already-issued: This Idempotency-Key already created a secret; it is shown only once. Retry with a new key.

502 provisioning-failed

provisioning-failed: The device identity could not be created (for example the name is already in use, or a temporary failure). Nothing was issued; retry or choose another name.

503 busy

busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.

curl
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments" \
  -H "Authorization: Bearer $CLOUDRAW_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "device_name": "omer-laptop",
  "person_id": "p4hd8s0qk2l"
}'
PowerShell
$body = @'
{
  "device_name": "omer-laptop",
  "person_id": "p4hd8s0qk2l"
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN"; "Idempotency-Key" = [guid]::NewGuid().ToString() }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments" -Headers $headers -ContentType "application/json" -Body $body
Python
import os, uuid, requests

r = requests.post(
    "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments",
    headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
        "device_name": "omer-laptop",
        "person_id": "p4hd8s0qk2l"
    },
    timeout=30,
)
r.raise_for_status()
print(r.json())
Node.js
const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "device_name": "omer-laptop",
    "person_id": "p4hd8s0qk2l"
  }),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());
Response 201 · application/json
{
  "id": "en_7k2x9m0s1d",
  "kind": "device",
  "state": "issued",
  "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIn0.c2lnbmF0dXJl",
  "claim_code": "CRW-7KQ2M-X9D4P",
  "claim_url": "https://connect.example.com/d/CRW-7KQ2M-X9D4P",
  "claim_expires_at": "2026-10-13T10:24:11.000Z",
  "qr_png_base64": null,
  "expires_at": "2026-10-20T09:24:11.000Z"
}

Get an enrollment

GET/v0/tenants/{tenant_id}/enrollments/{enrollment_id}

read-only token

Metadata of one device enrollment: name, token expiry and whether a short code is live (claim_expires_at). Never returns a code or token (claim_code and claim_url are always null). Sent with Cache-Control: no-store.

Token: read-only or full access · Created by: owner or security admin

Path parameters

  • tenant_idstringrequired

    Your workspace id (Settings → Workspace in the console; it is also in every console URL).

    Example: tq7x2m9k4ab

  • enrollment_idstringrequired

    Enrollment id (from POST /enrollments or GET /enrollments).

    Example: en_7k2x9m0s1d

Responses

200 The enrollment.

application/json

  • idstringrequired
  • device_namestring
  • claim_codenull

    Never returned here.

  • claim_urlnull
  • claim_expires_atstring | null (date-time)
  • expires_atstring (date-time)required
  • reveal_withobject

    The call that issues a fresh short code (and invalidates the previous one).

    reveal_with fields
    • methodstring
    • pathstring
401 unauthorized invalid-token token-expired

unauthorized: No Authorization: Bearer crw_… header was sent.

invalid-token: The token is unknown or was revoked.

token-expired: The token is past its expiry date. Create a new one.

403 insufficient-role tenant-assertion-mismatch

insufficient-role: The token's role ceiling does not allow this call.

tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.

404 enrollment-not-found tenant-not-found

enrollment-not-found: No device enrollment with this id.

tenant-not-found: No workspace with this id.

curl
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d" \
  -H "Authorization: Bearer $CLOUDRAW_TOKEN"
PowerShell
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d" -Headers $headers
Python
import os, uuid, requests

r = requests.get(
    "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d",
    headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
    timeout=30,
)
r.raise_for_status()
print(r.json())
Node.js
const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
  },
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());
Response 200 · application/json
{
  "id": "en_7k2x9m0s1d",
  "device_name": "omer-laptop",
  "claim_code": null,
  "claim_url": null,
  "claim_expires_at": "2026-10-13T09:00:00.000Z",
  "expires_at": "2026-10-20T08:00:00.000Z",
  "reveal_with": {
    "method": "POST",
    "path": "/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d"
  }
}

Cancel a pending enrollment

DELETE/v0/tenants/{tenant_id}/enrollments/{enrollment_id}

full-access token

Cancels an enrollment that has not been used: its token can no longer be exchanged and every short code for it stops working. Audited. An enrollment that was already used is a device: remove it with DELETE /devices/{device_id}.

Token: full access · Created by: owner

Path parameters

  • tenant_idstringrequired

    Your workspace id (Settings → Workspace in the console; it is also in every console URL).

    Example: tq7x2m9k4ab

  • enrollment_idstringrequired

    Enrollment id (from POST /enrollments or GET /enrollments).

    Example: en_7k2x9m0s1d

Responses

204 Cancelled.
401 unauthorized invalid-token token-expired

unauthorized: No Authorization: Bearer crw_… header was sent.

invalid-token: The token is unknown or was revoked.

token-expired: The token is past its expiry date. Create a new one.

403 insufficient-scope insufficient-role tenant-assertion-mismatch

insufficient-scope: The token is read-only and this call changes something.

insufficient-role: The token's role ceiling does not allow this call.

tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.

404 enrollment-not-found enrollment-consumed tenant-not-found

enrollment-not-found: No pending device enrollment with this id.

enrollment-consumed: The enrollment was already used; remove the device instead.

tenant-not-found: No workspace with this id.

502 cancel-failed

cancel-failed: The enrollment could not be cancelled right now; nothing was changed. Retry.

503 busy

busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.

curl
curl -sS -X DELETE "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d" \
  -H "Authorization: Bearer $CLOUDRAW_TOKEN"
PowerShell
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Delete -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d" -Headers $headers
Python
import os, uuid, requests

r = requests.delete(
    "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d",
    headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
    timeout=30,
)
r.raise_for_status()
print(r.status_code)
Node.js
const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/enrollments/en_7k2x9m0s1d", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
  },
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(res.status);