Devices.

The devices of the key's project: who each one is, whether it is connected, and the policy ArdaForm holds for it — two switches and the screen's orientation. PATCH sets them; they reach the device at once when it is online, else when it next connects.

Working — v1 at api.ardaform.net

About devices

  • A device is added by the code it shows — typed into the portal, or sent to POST /v1/devices/activate — and removed in the portal. Besides activating one, this API lists the project's devices, reads one, moves one into a space, and sets its policy. The area devices has r and w, and no other verb. A key made before 2026-10-24 has no devices entry in its scopes until it is edited in the portal.
  • Every device is in a space, or in none. Its space decides the branch it runs and — a private space — whose data it reads; null is Unassigned: it runs no app, and its screen says it is waiting for a space. ?space= lists one space's devices: an id or slug, default, or unassigned.
  • The key names the project. A uid on another project answers 404 NO_DEVICE, exactly like a uid that does not exist.
  • presence is the word the portal's screens use: online, offline, or never (never connected). online is the same answer as a boolean.
  • A removed device stays in the list with enrolled: false, so a script that knew it can see what became of it.

The policy

A small JSON object of optional keys — two switches and the screen's orientation — kept per device and re-stated to the device on every check-in. Today an Android device acts on it; a Linux device accepts it and ignores it.

exitAllowedWhether Shut down in the portal — and the app's Arda.system.shutdown() — may close the player. The device's own default is true. false: both are refused on the device, and the portal's Shut down dims.
kioskLock the screen to the player: no status bar, Home or Recents. Needs the player set up as device owner on the box; a box that is not keeps running as an ordinary app and says so in android.deviceOwner. The device's own default is false.
orientationWhich way the screen is drawn: portrait, landscape, or auto — follow the device, its own default. For tablets and anything else that turns.
  • An absent key means no opinion: the device keeps what it holds. PATCH changes only the keys it is sent, and a key cannot be cleared. {} is a policy that says nothing.
  • Two words, shown side by side. policy is what ArdaForm holds; android (on one device) is what the device last reported — kiosk the screen's live lock state, exitAllowed what it applies now. They differ until the device has checked in.
  • Takes effect at once when the device is online, else at its next connection. The answer's applies says which.
  • The app's manifest has a say on the orientation. A top-level "screen": {"orientation": "landscape", "writable": {"portal": true, "api": true}} presets it — what a device follows while nothing is saved for it — and may lock it: "api": false makes a PATCH with orientation a 403 NOT_WRITABLE, "portal": false locks the row in the portal. A locked orientation is the manifest's on every device whatever is saved; policy here is always what is saved. An Android device turns its screen to it from ArdaPlayer v1.3.0; a Linux device keeps the fact.

GET/v1/devicesEvery device of the key's project, or of one space

Every device of the key's project, by name, with the space each is in — or one space's, with ?space=. The device here was made for the examples and has never connected, so presence is never and nobody has set a policy on it yet: {}.

Key scope devices:r — read devices

Query parameters

NameType
spacestring
at most 100 characters
Only the devices of one space: its id or slug, default for the Default, or unassigned for the devices in none. Absent: every device of the project (or of the space Arda-Space names).

Answer 200 The devices

FieldType
devicesarray of object

Errors

StatusWordWhen
403OUT_OF_SCOPEThe key's scopes do not allow this area and verb (or this dataset, for records). A key edited before an area existed has no entry for it and is refused there until it is edited again in the portal.
404NO_SPACENo space with that id or slug in the key's project — in /v1/spaces/{space}, a space field or parameter, or the Arda-Space header. unassigned is no space (the devices in none). Another project's space answers the same, so nothing can be probed for.

And, like every keyed call: NO_KEY BAD_KEY KEY_REVOKED KEY_EXPIRED ACCOUNT_INACTIVE NO_API_ACCESS RATE_LIMITED INTERNAL.

curl "https://api.ardaform.net/v1/devices" \
  -H "Authorization: Bearer $ARDA_KEY"
Answer · 200 OKran live 2026-10-27 · test project
{
  "devices": [
    {
      "uid": "aa11aa11aa11aa11aa11a9e5",
      "name": "zz-docs-tablet",
      "os": "android",
      "arch": "arm64",
      "model": "Samsung SM-X200",
      "player": "v1.2.4",
      "branch": "main",
      "partition": null,
      "location": "Counter 1",
      "enrolled": false,
      "space": {
        "id": 1,
        "slug": "default",
        "name": "Default"
      },
      "presence": "never",
      "online": false,
      "last_seen_at": null,
      "policy": {}
    }
  ]
}

GET/v1/devices/{uid}One device, with what it last reported

One device, with android beside it on an Android device: what the device last reported about itself. Null on a Linux device. A malformed uid, or one that is not on this project, is 404 NO_DEVICE.

Key scope devices:r — read devices

Path parameters

NameType
uidstring
pattern ^[0-9a-f]{24}$
The device's id — 24 hex characters, shown on its page in the portal. Anything else is 404 NO_DEVICE.

Answer 200 The device

FieldType
deviceobjectOne device of the key's project, as ArdaForm knows it — its identity, whether it is connected, and the policy ArdaForm holds for it. On one device, android is what the device last reported about itself.
device.uidstringThe device's id — 24 hex characters, the one on its page in the portal. How you address it.
device.namestringWhat it was named in the portal.
device.osstring, nullableThe player's operating system as it reports it: linux, android, …
device.archstring, nullableThe processor family: arm64, amd64, …
device.modelstring, nullableThe hardware, as the device reports it.
device.playerstring, nullableThe ArdaPlayer version it last reported.
device.branchstring, nullableThe code branch it runs — its space's. Null when it is Unassigned: it runs no app.
device.partitionstring, nullableIts data partition, or null when it has none.
device.locationstring, nullableWhere it is, as typed in the portal. Null when nothing was typed.
device.enrolledbooleanFalse once it was removed (wiped), or never activated — its record stays.
device.spaceobject, nullableThe space it is in: id, slug, name. Null when it is in none — Unassigned.
device.presencestring — online or offline or never, nullableThe one word every portal screen uses: online, offline, or never (never connected).
device.onlinebooleanConnected to ArdaForm right now.
device.last_seen_atstring (date-time), nullableWhen it was last heard from. Null when never. UTC.
device.policyobjectThe switches — and the screen's orientation — ArdaForm holds for this device and re-states to it on every check-in — only the keys that were ever set, {} when none. A key that is absent means the device keeps what it holds.
device.androidobject, nullableOnly on GET /v1/devices/{uid}, and only on an Android device: what the device last REPORTED about itself (its sysinfo.android) — kiosk is the screen's live lock state, exitAllowed what it applies now, deviceOwner whether kiosk can work at all, with release, model, appVersion and battery. It differs from policy until the device has checked in. Null on a Linux device; absent in the list.

Errors

StatusWordWhen
403OUT_OF_SCOPEThe key's scopes do not allow this area and verb (or this dataset, for records). A key edited before an area existed has no entry for it and is refused there until it is edited again in the portal.
404NO_DEVICENo device with that uid on the key's project. A uid is 24 hex characters; a device on another project answers the same, so nothing can be probed for.
404NO_SPACENo space with that id or slug in the key's project — in /v1/spaces/{space}, a space field or parameter, or the Arda-Space header. unassigned is no space (the devices in none). Another project's space answers the same, so nothing can be probed for.

And, like every keyed call: NO_KEY BAD_KEY KEY_REVOKED KEY_EXPIRED ACCOUNT_INACTIVE NO_API_ACCESS RATE_LIMITED INTERNAL.

curl "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5" \
  -H "Authorization: Bearer $ARDA_KEY"
Answer · 200 OKran live 2026-10-27 · test project
{
  "device": {
    "uid": "aa11aa11aa11aa11aa11a9e5",
    "name": "zz-docs-tablet",
    "os": "android",
    "arch": "arm64",
    "model": "Samsung SM-X200",
    "player": "v1.2.4",
    "branch": "main",
    "partition": null,
    "location": "Counter 1",
    "enrolled": false,
    "space": {
      "id": 1,
      "slug": "default",
      "name": "Default"
    },
    "presence": "never",
    "online": false,
    "last_seen_at": null,
    "policy": {},
    "android": {
      "sdk": 34,
      "release": "14",
      "model": "Samsung SM-X200",
      "abi": "arm64-v8a",
      "appVersion": "1.2.4",
      "appCode": 1020400,
      "deviceOwner": true,
      "kiosk": false,
      "kioskWanted": false,
      "home": true,
      "exitAllowed": true,
      "screen": {
        "w": 1280,
        "h": 800,
        "dpi": 240
      },
      "battery": {
        "pct": 87,
        "charging": true
      }
    }
  }
}

A uid on another project, or none

curl "https://api.ardaform.net/v1/devices/4acf91e8d59988744ea33baa" \
  -H "Authorization: Bearer $ARDA_KEY"
Answer · 404 Not Foundran live 2026-10-27 · test project
{
  "error": {
    "code": "NO_DEVICE",
    "message": "No device with the uid '4acf91e8d59988744ea33baa' on this project."
  }
}

PATCH/v1/devices/{uid}Move a device into a space

Moves the device into a space: {"space": "<id or slug>"}, "default", or "unassigned" for none. It takes the space's branch at once. Into unassigned it stops running its app and its screen says it is waiting for a space; moved into one again, the app comes back. Into or out of a private space it drops its data, its data partition is cleared, and it walks the new space's data again; between spaces that share the project's data nothing is walked again. A device that is away does it when it next connects — applies says which. A space holding its max_devices is 409 SPACE_FULL; moved: false when it was already there.

Key scope devices:w — write devices

Path parameters

NameType
uidstring
pattern ^[0-9a-f]{24}$
The device's id — 24 hex characters, shown on its page in the portal. Anything else is 404 NO_DEVICE.

Body

FieldType
space requiredstring, nullableThe space: id, slug, default, or unassigned / null for none.

Answer 200 Moved, or already there

FieldType
deviceobjectOne device of the key's project, as ArdaForm knows it — its identity, whether it is connected, and the policy ArdaForm holds for it. On one device, android is what the device last reported about itself.
device.uidstringThe device's id — 24 hex characters, the one on its page in the portal. How you address it.
device.namestringWhat it was named in the portal.
device.osstring, nullableThe player's operating system as it reports it: linux, android, …
device.archstring, nullableThe processor family: arm64, amd64, …
device.modelstring, nullableThe hardware, as the device reports it.
device.playerstring, nullableThe ArdaPlayer version it last reported.
device.branchstring, nullableThe code branch it runs — its space's. Null when it is Unassigned: it runs no app.
device.partitionstring, nullableIts data partition, or null when it has none.
device.locationstring, nullableWhere it is, as typed in the portal. Null when nothing was typed.
device.enrolledbooleanFalse once it was removed (wiped), or never activated — its record stays.
device.spaceobject, nullableThe space it is in: id, slug, name. Null when it is in none — Unassigned.
device.presencestring — online or offline or never, nullableThe one word every portal screen uses: online, offline, or never (never connected).
device.onlinebooleanConnected to ArdaForm right now.
device.last_seen_atstring (date-time), nullableWhen it was last heard from. Null when never. UTC.
device.policyobjectThe switches — and the screen's orientation — ArdaForm holds for this device and re-states to it on every check-in — only the keys that were ever set, {} when none. A key that is absent means the device keeps what it holds.
device.androidobject, nullableOnly on GET /v1/devices/{uid}, and only on an Android device: what the device last REPORTED about itself (its sysinfo.android) — kiosk is the screen's live lock state, exitAllowed what it applies now, deviceOwner whether kiosk can work at all, with release, model, appVersion and battery. It differs from policy until the device has checked in. Null on a Linux device; absent in the list.
movedbooleanFalse when it was already in that space — nothing changed.
appliesstring — now or when the device next connectsWhether the device was connected at the time.

Errors

StatusWordWhen
400BAD_REQUESTThe body is missing a required field, has one of the wrong type or length, or (on PUT /v1/content/…) arrived shorter or longer than its Content-Length. The message says which.
400NOTHING_TO_DOA PATCH sent no field it can change (a dataset with none of its fields; a device policy with no key).
403OUT_OF_SCOPEThe key's scopes do not allow this area and verb (or this dataset, for records). A key edited before an area existed has no entry for it and is refused there until it is edited again in the portal.
404NO_DEVICENo device with that uid on the key's project. A uid is 24 hex characters; a device on another project answers the same, so nothing can be probed for.
404NO_SPACENo space with that id or slug in the key's project — in /v1/spaces/{space}, a space field or parameter, or the Arda-Space header. unassigned is no space (the devices in none). Another project's space answers the same, so nothing can be probed for.
409SPACE_FULLThe space already holds its max_devices.

And, like every keyed call: NO_KEY BAD_KEY KEY_REVOKED KEY_EXPIRED ACCOUNT_INACTIVE NO_API_ACCESS RATE_LIMITED INTERNAL BAD_JSON TOO_LARGE.

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"space":"zz-docs-cake-co"}'
Answer · 200 OKran live 2026-10-27 · test project
{
  "device": {
    "uid": "aa11aa11aa11aa11aa11a9e5",
    "name": "zz-docs-tablet",
    "os": "android",
    "arch": "arm64",
    "model": "Samsung SM-X200",
    "player": "v1.2.4",
    "branch": "main",
    "partition": null,
    "location": "Counter 1",
    "enrolled": false,
    "space": {
      "id": 850,
      "slug": "zz-docs-cake-co",
      "name": "Cake & Co, Soho Road"
    },
    "presence": "never",
    "online": false,
    "last_seen_at": null,
    "policy": {
      "exitAllowed": false,
      "kiosk": true,
      "orientation": "landscape"
    }
  },
  "moved": true,
  "applies": "when the device next connects"
}

Back to the Default

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"space":"default"}'
Answer · 200 OKran live 2026-10-27 · test project
{
  "device": {
    "uid": "aa11aa11aa11aa11aa11a9e5",
    "name": "zz-docs-tablet",
    "os": "android",
    "arch": "arm64",
    "model": "Samsung SM-X200",
    "player": "v1.2.4",
    "branch": "main",
    "partition": null,
    "location": "Counter 1",
    "enrolled": false,
    "space": {
      "id": 1,
      "slug": "default",
      "name": "Default"
    },
    "presence": "never",
    "online": false,
    "last_seen_at": null,
    "policy": {
      "exitAllowed": false,
      "kiosk": true,
      "orientation": "landscape"
    }
  },
  "moved": true,
  "applies": "when the device next connects"
}

PATCH/v1/devices/{uid}/policySet a device's switches and screen

Sets the policy ArdaForm holds for the device: the body is any of {"exitAllowed": true|false}, {"kiosk": true|false} and {"orientation": "portrait"|"landscape"|"auto"}. The answer is the whole saved policy after the merge.

  • Checked in this order: the key's devices:w, the device exists, the body is an object with only policy keys — each switch a JSON boolean, the orientation one of the three words — and, for orientation, the app's manifest does not say "screen": {"writable": {"api": false}} (403 NOT_WRITABLE; the switches beside it still write).
  • A policy that already says so writes nothing: changed: false.
  • applies is now when the device was connected — it is told straight away — or when the device next connects. Either way the next check-in re-states it, so nothing is lost.
  • Read it back on the device itself (GET /v1/devices/{uid}); there is no GET on /policy.

Key scope devices:w — write devices

Path parameters

NameType
uidstring
pattern ^[0-9a-f]{24}$
The device's id — 24 hex characters, shown on its page in the portal. Anything else is 404 NO_DEVICE.

Body

FieldType
exitAllowedbooleanWhether Shut down, and the app's Arda.system.shutdown(), may close the player on this device.
kioskbooleanLock the screen to the player. Needs the player set up as device owner on the box.
orientationstring — portrait or landscape or autoWhich way the screen is drawn; auto follows the device. Refused while the app's manifest says screen.writable.api: false.

Answer 200 Saved, or already so

FieldType
uidstringThe device.
changedbooleanFalse when the policy already said so — nothing was written.
policyobjectThe switches — and the screen's orientation — ArdaForm holds for this device and re-states to it on every check-in — only the keys that were ever set, {} when none. A key that is absent means the device keeps what it holds.
policy.exitAllowedbooleanAndroid: whether Shut down — and the app's Arda.system.shutdown() — may close the player. The device's own default is true. False: both are refused on the device, and the portal's Shut down dims.
policy.kioskbooleanAndroid: lock the screen to the player — no status bar, Home or Recents. Needs the player set up as device owner on the box; a box that is not keeps running as an ordinary app. The device's own default is false.
policy.orientationstring — portrait or landscape or autoWhich way the screen is drawn: portrait, landscape, or auto — follow the device (its own default). The app's manifest may preset it (screen.orientation) and lock it (screen.writable); a locked orientation is the manifest's whatever is saved here. Android devices act on it today.
appliesstring — now or when the device next connectsWhether the device was connected at the time — told now — or is told when it next connects.

Errors

StatusWordWhen
400BAD_REQUESTThe body is missing a required field, has one of the wrong type or length, or (on PUT /v1/content/…) arrived shorter or longer than its Content-Length. The message says which.
400NOTHING_TO_DOA PATCH sent no field it can change (a dataset with none of its fields; a device policy with no key).
403NOT_WRITABLEThe app's manifest says "writable": {"api": false} for this setting — or the setting is a select whose choices are each device's own ("options": {"device": …}), chosen on each device — or, on PATCH /v1/devices/{uid}/policy, the manifest's screen.writable.api is false and orientation was sent. Read it; change it in the portal.
403OUT_OF_SCOPEThe key's scopes do not allow this area and verb (or this dataset, for records). A key edited before an area existed has no entry for it and is refused there until it is edited again in the portal.
404NO_DEVICENo device with that uid on the key's project. A uid is 24 hex characters; a device on another project answers the same, so nothing can be probed for.
404NO_SPACENo space with that id or slug in the key's project — in /v1/spaces/{space}, a space field or parameter, or the Arda-Space header. unassigned is no space (the devices in none). Another project's space answers the same, so nothing can be probed for.

And, like every keyed call: NO_KEY BAD_KEY KEY_REVOKED KEY_EXPIRED ACCOUNT_INACTIVE NO_API_ACCESS RATE_LIMITED INTERNAL BAD_JSON TOO_LARGE.

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"exitAllowed":false}'
Answer · 200 OKran live 2026-10-27 · test project
{
  "uid": "aa11aa11aa11aa11aa11a9e5",
  "changed": true,
  "policy": {
    "exitAllowed": false
  },
  "applies": "when the device next connects"
}

The other key — the first is kept

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kiosk":true}'
Answer · 200 OKran live 2026-10-27 · test project
{
  "uid": "aa11aa11aa11aa11aa11a9e5",
  "changed": true,
  "policy": {
    "exitAllowed": false,
    "kiosk": true
  },
  "applies": "when the device next connects"
}

The same again

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kiosk":true}'
Answer · 200 OKran live 2026-10-27 · test project
{
  "uid": "aa11aa11aa11aa11aa11a9e5",
  "changed": false,
  "policy": {
    "exitAllowed": false,
    "kiosk": true
  },
  "applies": "when the device next connects"
}

Which way the screen is drawn

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orientation":"landscape"}'
Answer · 200 OKran live 2026-10-27 · test project
{
  "uid": "aa11aa11aa11aa11aa11a9e5",
  "changed": true,
  "policy": {
    "exitAllowed": false,
    "kiosk": true,
    "orientation": "landscape"
  },
  "applies": "when the device next connects"
}

Not a JSON boolean

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"exitAllowed":"false"}'
Answer · 400 Bad Requestran live 2026-10-27 · test project
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "'exitAllowed' must be true or false — a JSON boolean, not \"false\". A key cannot be cleared."
  }
}

Not one of the three words

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orientation":"sideways"}'
Answer · 400 Bad Requestran live 2026-10-27 · test project
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "'orientation' is one of \"portrait\", \"landscape\" or \"auto\" — not \"sideways\". A key cannot be cleared."
  }
}

Locked by the manifest

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orientation":"auto"}'
Answer · 403 Forbiddenran live 2026-10-27 · test project
{
  "error": {
    "code": "NOT_WRITABLE",
    "message": "'orientation' is read-only through the API: the app's manifest.json sets the screen to portrait and says \"writable\": {\"api\": false}.",
    "key": "orientation"
  }
}

A key the policy does not have

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"screen":"off"}'
Answer · 400 Bad Requestran live 2026-10-27 · test project
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "'screen' is not a policy key. The keys are `exitAllowed`, `kiosk`, `orientation`."
  }
}

No key at all

curl -X PATCH "https://api.ardaform.net/v1/devices/aa11aa11aa11aa11aa11a9e5/policy" \
  -H "Authorization: Bearer $ARDA_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Answer · 400 Bad Requestran live 2026-10-27 · test project
{
  "error": {
    "code": "NOTHING_TO_DO",
    "message": "The body names no policy key. Send {\"exitAllowed\": true|false}, {\"kiosk\": true|false} and/or {\"orientation\": \"portrait\"|\"landscape\"|\"auto\"}."
  }
}

The Device shape

Device

One device of the key's project, as ArdaForm knows it — its identity, whether it is connected, and the policy ArdaForm holds for it. On one device, android is what the device last reported about itself.

FieldType
uidstringThe device's id — 24 hex characters, the one on its page in the portal. How you address it.
namestringWhat it was named in the portal.
osstring, nullableThe player's operating system as it reports it: linux, android, …
archstring, nullableThe processor family: arm64, amd64, …
modelstring, nullableThe hardware, as the device reports it.
playerstring, nullableThe ArdaPlayer version it last reported.
branchstring, nullableThe code branch it runs — its space's. Null when it is Unassigned: it runs no app.
partitionstring, nullableIts data partition, or null when it has none.
locationstring, nullableWhere it is, as typed in the portal. Null when nothing was typed.
enrolledbooleanFalse once it was removed (wiped), or never activated — its record stays.
spaceobject, nullableThe space it is in: id, slug, name. Null when it is in none — Unassigned.
presencestring — online or offline or never, nullableThe one word every portal screen uses: online, offline, or never (never connected).
onlinebooleanConnected to ArdaForm right now.
last_seen_atstring (date-time), nullableWhen it was last heard from. Null when never. UTC.
policyobjectThe switches — and the screen's orientation — ArdaForm holds for this device and re-states to it on every check-in — only the keys that were ever set, {} when none. A key that is absent means the device keeps what it holds.
policy.exitAllowedbooleanAndroid: whether Shut down — and the app's Arda.system.shutdown() — may close the player. The device's own default is true. False: both are refused on the device, and the portal's Shut down dims.
policy.kioskbooleanAndroid: lock the screen to the player — no status bar, Home or Recents. Needs the player set up as device owner on the box; a box that is not keeps running as an ordinary app. The device's own default is false.
policy.orientationstring — portrait or landscape or autoWhich way the screen is drawn: portrait, landscape, or auto — follow the device (its own default). The app's manifest may preset it (screen.orientation) and lock it (screen.writable); a locked orientation is the manifest's whatever is saved here. Android devices act on it today.
androidobject, nullableOnly on GET /v1/devices/{uid}, and only on an Android device: what the device last REPORTED about itself (its sysinfo.android) — kiosk is the screen's live lock state, exitAllowed what it applies now, deviceOwner whether kiosk can work at all, with release, model, appVersion and battery. It differs from policy until the device has checked in. Null on a Linux device; absent in the list.