API¶
Everything the dashboard does with devices, commands, packages, scripts and runs can be done from a
script, a CI pipeline or your own tools, with an API token. The API is GraphQL at
https://back.kinuxota.com/graphql. For running commands and scripts from a terminal or CI, the
kx command line does the waiting and the exit codes for you.
API tokens¶
Make one in Team > API tokens > New token: a name, a role and an expiry (7 to 365 days). The
token (kxt_...) is shown once; KinuxOTA keeps only a hash of it. Keep it in your CI's secret
store, never in a repository.
| Kind | Acts as | Made by |
|---|---|---|
| Personal | you, with the token's role or your own role in the organisation, whichever is lower. It stops when you leave the organisation. | any member |
| Organisation | the organisation itself (shown as token <name> in the audit log). It keeps working when the person who made it leaves. |
admins and owners |
The role works as for members (Team): a viewer token reads, an operator token also sends commands and runs scripts, an admin token also adds, edits and deletes devices and scripts and reads the audit log. A token can never have a higher role than the person who makes it.
- Revoke a token in the same list; it stops at once. Admins see and revoke every token of the organisation, others their own.
- Each token shows when and from where it was last used. Every action taken with it is in the audit log with the token's name, and its use is recorded there at most once an hour.
- If the organisation requires two-factor sign-in, personal tokens of members without it are refused.
- A token cannot manage accounts, members, invitations or tokens: sign in to the dashboard for those.
Requests¶
Send the token in the Authorization header and the query as JSON:
export KX_TOKEN=kxt_...
kxapi() { # kxapi '<query>' '<variables as JSON>'
curl -sS https://back.kinuxota.com/graphql \
-H "Authorization: Bearer $KX_TOKEN" -H 'Content-Type: application/json' \
-d "$(jq -n --arg q "$1" --argjson v "${2:-{\}}" '{query: $q, variables: $v}')"
}
A request with a wrong, expired or revoked token gets UNAUTHENTICATED; one the token's role does not
allow gets FORBIDDEN. Requests are limited to 1000 per token in 5 minutes.
List devices¶
kxapi '{ devices(limit: 100) { items { id name status os osVersion firmwareVersion lastSeen } total } }'
devices(search: "edge") filters by name, serial number, model or description; pass cursor:
nextCursor for the next page.
Run a command and wait for the result¶
kxapi 'mutation($d: ID!) { sendCommandToDevice(deviceId: $d, input: { command: "uptime" }) { id } }' \
'{"d": "<device id>"}'
# then ask until status is COMPLETED, FAILED or CANCELLED (the device runs it when it next connects)
kxapi 'query($id: ID!) { deviceCommand(id: $id) { status exitCode message } }' '{"id": "<command id>"}'
# the output, in pages: ask again with afterSeq = lastSeq while done is false
kxapi 'query($id: ID!) { deviceCommandOutput(commandId: $id, afterSeq: 0) { chunks { data } lastSeq done } }' '{"id": "<command id>"}'
sendCommandToDevices(deviceIds: [...], input: ...) sends one command to up to 100 devices.
Run a script on devices¶
kxapi '{ scripts { id name parameters { name type required } } }'
kxapi 'mutation($in: RunScriptInput!) { runScript(input: $in) { id number } }' \
'{"in": {"scriptId": "<script id>", "deviceIds": ["<device id>"], "parameters": [{"name": "SERVICE", "value": "nginx"}]}}'
# until finished is true; each target is one device
kxapi 'query($id: ID!) { scriptRun(id: $id) { finished summary { completed failed } targets { id deviceName status exitCode } } }' '{"id": "<run id>"}'
kxapi 'query($t: ID!) { scriptRunOutput(targetId: $t, afterSeq: 0) { chunks { data } lastSeq done } }' '{"t": "<target id>"}'
Download the audit log¶
With an admin token:
curl -sS -H "Authorization: Bearer $KX_TOKEN" https://back.kinuxota.com/api/audit/export -o audit.csv
What a token can use¶
Queries: organization, devices, device, deviceLogs, deviceCommands,
deviceCommandsForDevice, deviceCommand, deviceCommandOutput, commandBatch,
packagesForDevice, package, scripts, script, scriptTemplates, scriptLimits,
scriptFileUrl, scriptRuns, scriptRun, scriptRunTargets, scriptRunTarget,
scriptRunOutput, auditEvents, clientReleases.
Mutations: createDevice, updateDevice, deleteDevice, newInstallKey, sendCommandToDevice,
sendCommandToDevices, cancelCommand, installPackage, updatePackage, removePackage,
createScript, saveScript, duplicateScript, deleteScript, requestUploads, runScript,
rerunScriptRun, cancelScriptRun, cancelScriptRunTarget, startScriptRun.
The schema can be read by introspection with any token, so GraphQL tools (Insomnia, Postman,
graphql-codegen) complete the fields for you.