Start a device authorization - Spacefast Docs
Start a device authorization
Creates a device code and a user code, and returns the approval page a person opens to authorize the device. Poll POST /v1/auth/device/poll with deviceCode no faster than interval seconds, until expiresAt. The response also carries a requiresAction envelope whose continuation token drives the same wait through POST /v1/actions/resume. Send claim to attach an unclaimed Space, which the approver then assigns to one of their teams.
POST /v1/auth/device
Request body
- required
application/json
Parameters
clientIdstring
Client starting the flow, shown to the person on the approval page. Onlyspacefast-cliis accepted, and it is the default.- min length 1 · max length 255 · default: "spacefast-cli"
accessstring
How much access the device asks for:readfor reading teams, Spaces, and domains, oragentfor everything an interactive login can grant. The approver can narrow the resulting scopes but never widen them.- default: "agent"
- Allowed:
readagent
claimobject
Attaches an unclaimed Space to this login. Omit for an ordinary sign-in. When present, the approver must pick a team to receive the Space.spaceIdstring required
Unclaimed Space to claim when this login is approved.- min length 1
claimTokenstring required
Space key proving control ofspaceId. Only its hash is stored.- min length 1 · max length 512
Responses
200 Response for status 200
$schemastring
Canonical JSON Schema URL for this response body. The server also sends it in theLink: rel="describedby"response header.dataobject requireddeviceCodestring required
Secret the device polls with. Send it in the request body only, and never log or display it.- min length 1
userCodestring required
Short code the person enters on the approval page. Uppercase alphanumerics, at most eight characters, with a dash after the fourth.- min length 1
verificationUrlstringrequired
Approval page to open in a browser. It carriesuserCodealready filled in when one is available, otherwise the person types the code.intervalinteger required
Seconds to wait between polls. Polling faster answers 429slow_down.- max 9007199254740991
expiresAtstringrequired
ISO 8601 timestamp after which both codes stop working.- matches ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:.\d+)?)?(?:Z))$
requiresActionobjectactionTypestring required
Which step is blocking:device_authorizationwaits for a browser sign-in,confirmationwaits for a person to approve one action,elevationwaits for a person to grant temporary access.- Allowed:
device_authorizationconfirmationelevation
- Allowed:
instructionstring required
One sentence an agent can show a person, naming what they have to do.urlstring| any
Page to send the person to. Absent on adevice_authorizationpoll, where the agent already holds the verification URL from the response that started the flow.pollUrlstring
Endpoint that takescontinuationTokenand drives this flow:POST /v1/actions/resume.continuationTokenstring required
Signed capability naming this one flow and the principal that started it. It is the only credentialPOST /v1/actions/resumeneeds for a device sign-in; a confirmation or elevation also has to be resumed with the same agent credential that requested it. Treat it as a secret and never log it.- min length 1
pollAfterSecondsinteger required
How long to wait before calling resume again, in seconds.- max 9007199254740991
expiresAtstringrequired
ISO 8601 deadline for the human step. Resuming after it answersexpired. The token itself outlives the deadline by a short grace so resume can report that rather than rejecting the token.- matches ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:.\d+)?)?(?:Z))$
Try it
cURL Example
curl -X POST "https://api.spacefast.com/v1/auth/device" \
-H "Content-Type: application/json" \
-d '{
"clientId": "spacefast-cli",
"access": "read",
"claim": {
"spaceId": "string",
"claimToken": "string"
}
}'
JavaScript Example
const response = await fetch("https://api.spacefast.com/v1/auth/device", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: "{\n \"clientId\": \"spacefast-cli\",\n \"access\": \"read\",\n \"claim\": {\n \"spaceId\": \"string\",\n \"claimToken\": \"string\"\n }\n}"
});
Python Example
import requests
response = requests.post(
"https://api.spacefast.com/v1/auth/device",
headers={
"Content-Type": "application/json"
},
data="{\n \"clientId\": \"spacefast-cli\",\n \"access\": \"read\",\n \"claim\": {\n \"spaceId\": \"string\",\n \"claimToken\": \"string\"\n }\n}",
)
Response Example
{
"$schema": "http://example.com",
"data": {
"deviceCode": "string",
"userCode": "string",
"verificationUrl": "http://example.com",
"interval": 9007199254740991,
"expiresAt": "2019-08-24T14:15:22Z"
},
"requiresAction": {
"actionType": "device_authorization",
"instruction": "string",
"url": "http://example.com",
"pollUrl": "http://example.com",
"continuationToken": "string",
"pollAfterSeconds": 9007199254740991,
"expiresAt": "2019-08-24T14:15:22Z"
}
}
Error Example
{
"$schema": "http://example.com",
"type": "string",
"title": "string",
"status": -9007199254740991,
"detail": "string",
"code": "string",
"pointer": "string",
"details": {
"property1": null,
"property2": null
},
"suggestions": [
"string"
],
"next": [
"string"
],
"requestId": "string"
}