# Poll a device authorization

Returns the status of the device authorization behind `deviceCode`, and on the one poll that answers `approved`, the minted API key with its one-time `secret`. Wait at least `interval` seconds between polls: a faster poll answers 429 `slow_down`, and five consecutive fast polls invalidate the device code. Every later poll answers `consumed` and never returns the secret again.

## POST `/v1/auth/device/poll`

### Request body

required `application/json`

`deviceCode` string required

`deviceCode` from the start response. Send it in the body only, never in a URL.

min length 1 · max length 512

### Responses

#### 200 Response for status 200

`$schema` string <uri>

Canonical JSON Schema URL for this response body. The server also sends it in the `Link: rel="describedby"` response header.

`data` object required

Show properties Hide properties

##### `access` object

Scopes and team access the approver granted. Present alongside `apiKey`.

Show properties Hide properties

- `profile` string | any required

Access profile whose scope set exactly matches what was granted. Null once the approver changed the set.
- `scopes` string[] required

Scopes the approver granted. These, not `profile`, say what the key can do.

min items 1
- `teams` object required

Teams the key may act in: `all` for every team the approver belongs to, including teams joined later, `teams` for the listed ones, `none` for sign-in only.

Show properties Hide properties

- `teamIds` string[] required

Teams the credential may act in. Each team appears once.

min items 1 · max items 100

##### `apiKey` object

Minted API key, carrying its one-time `secret`. Present only on the poll that answers `approved`.

Show properties Hide properties

- `collection` string required

`team` for a key acting on the owning team's own resources, `partner` for a key acting on customer resources that team manages.

Allowed: `team` `partner`
- `createdAt` string <date-time> required

ISO 8601 timestamp when the key was created.

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))$
- `createdByUserId` string required

User account that created the key.
- `enabled` boolean required

False once the key is revoked, which stops it authenticating.
- `expiresAt` string <date-time> | any required

ISO 8601 timestamp from which requests presenting the key are rejected. Null when it does not expire.
- `id` string required

API key ID (`key_` prefix).
- `ipAllowlist` string[] | any required

Exact IP addresses and IPv4 CIDR ranges the key may be used from. Null when any address is allowed.
- `lastRequestAt` string <date-time> | any required

ISO 8601 timestamp of the most recent request made with the key. Null until it is used.
- `metadata` object required

Metadata stored with the key when it was created or last updated.
- `name` string | any required

Name given to the key. Null when it was created without one.
- `notBefore` string <date-time> | any required

ISO 8601 timestamp before which requests presenting the key are rejected. Null when it works from creation.
- `ownerPrincipal` object | any required

Principal that owns the key. Ownership only: what the key may do comes from `policy`. Null on platform-owned keys.
  - `type` string required

`team` when a team owns the key, `external` when an external customer does.

Allowed: `team` `external`
  - `id` string required

Identifier of the owning team or external customer.

min length 1
- `policy` object | any required

Policy the key authorizes by. Null on a device login key, whose authority is recompiled from the holder's live team roles on every request.
- `statements` object[] required

Statements evaluated on every request. A matching `deny` refuses it, otherwise a matching `allow` permits it, otherwise it is refused.

min items 1

- `actions` string[] required

Actions this statement applies to.

min items 1
  - `conditions` object

Attributes that must all hold for the statement to match. An attribute the server cannot resolve fails closed: it blocks an `allow` and triggers a `deny`.
    - `request.client` string

Narrows the statement to requests the server resolves to this client. Omit to apply it to every client.

Allowed: `dashboard` `cli` `api` `worker`
  - `effect` string required

`allow` permits the listed actions, `deny` refuses them. A matching `deny` beats every `allow`.

Allowed: `allow` `deny`
  - `resources` string[] required

Resources this statement applies to.

min items 1
- `version` string required

Policy format version. Any other value is rejected.
- `preset` string | any required

Named permission bundle the key is labeled with. Null when it was created from an explicit policy or permission list.
- `revokedAt` string <date-time> | any required

ISO 8601 timestamp when the key was revoked. Null while it is still usable.
- `secret` string

The key's secret in full, `sfa_` followed by 56 characters. Present only in the response that created the key.
- `secretPreview` string required

Masked form of the secret: its first eight characters and its last four, joined by three dots.
- `subject` object | any required

What the key acts as in audit records.
  - `type` string required

What the key acts as: a `user`, a `team`, an `external` customer, or Spacefast itself as `system`.

Allowed: `user` `team` `external` `system`
  - `id` string required

Identifier of the subject the key acts as.

min length 1
- `teamScope` object | any required

Teams a device login key follows the holder's membership in. Null on a key that authorizes by a fixed `policy`.
- `teamIds` string[] required

Teams the credential may act in. Each team appears once.

min items 1 · max items 100
- `updatedAt` string <date-time> required

ISO 8601 timestamp of the last change to the key.

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))$ 
- `claimedSpaceId` string | any

Space claimed during approval. Null when the flow carried no claim.
- `status` string required

One of `pending` (nobody has approved or denied it yet), `approved` (returned on the one poll that hands over the API key), `consumed` (the key was already handed over), `denied` (the person refused), `expired` (the codes lapsed or the device polled too fast).

Allowed: `pending` `approved` `denied` `expired` `consumed`

### defaultError.

Every 4xx and 5xx response is one RFC 9457 problem document served as `application/problem+json`.

#### `$schema` string <uri>

Canonical JSON Schema URL for this response body. The server also sends it in the `Link: rel="describedby"` response header.

- `type` string required

URL of the documentation page for this error. Derived from `code`.
- `title` string required

Human-readable name of the error type. Derived from `code`.
- `status` integer required

HTTP status of the response, repeated in the body.

min -9007199254740991 · max 9007199254740991
- `detail` string required

What went wrong in this request.
- `code` string required

Stable snake_case error code. Match on this, not on `detail`.
- `pointer` string

RFC 6901 JSON Pointer to the request field or batch entry that failed, for example `/files/37/path`. Present on validation failures.
- `details` object

Machine-readable context keyed by the error code.
- `suggestions` string[]

Recovery steps safe to show to a person.
- `next` string[]

Commands or API requests to run next, usable as written.
- `requestId` string required

ID of this request, from the `X-Request-Id` header or generated. Quote it when contacting support.

### Try it

#### Server

**Base URL** https://api.spacefast.com

**Custom base URL**  Overrides the selected server when set.

#### Body application/json

`deviceCode` string* `deviceCode` from the start response. Send it in the body only, never in a URL.

### Send

### Request

#### cURL

```bash
curl -X POST "https://api.spacefast.com/v1/auth/device/poll" \
  -H "Content-Type: application/json" \
  -d '{\n  "deviceCode": "string"\n}'
```

#### JavaScript

```javascript
const response = await fetch("https://api.spacefast.com/v1/auth/device/poll", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: "{\n  \"deviceCode\": \"string\"\n}"
});
```

#### Python

```python
import requests

response = requests.post(
    "https://api.spacefast.com/v1/auth/device/poll",
    headers={
        "Content-Type": "application/json"
    },
    data="{\n  \"deviceCode\": \"string\"\n}",
)
```

### Response

#### 200 default

```json
{
  "$schema": "http://example.com",
  "data": {
    "access": {
      "profile": "read",
      "scopes": [
        "teams:read"
      ],
      "teams": {}
    },
    "apiKey": {
      "collection": "team",
      "createdAt": "2019-08-24T14:15:22Z",
      "createdByUserId": "string",
      "enabled": true,
      "expiresAt": "2019-08-24T14:15:22Z",
      "id": "string",
      "ipAllowlist": [
        "string"
      ],
      "lastRequestAt": "2019-08-24T14:15:22Z",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "name": "string",
      "notBefore": "2019-08-24T14:15:22Z",
      "ownerPrincipal": {
        "type": "team",
        "id": "string"
      },
      "policy": {
        "statements": [
          {
            "actions": [
              "spaces:read"
            ],
            "conditions": {
              "request.client": "dashboard"
            },
            "effect": "allow",
            "resources": [
              "string"
            ]
          }
        ],
        "version": "2026-06-09"
      },
      "preset": "ci_deploy",
      "revokedAt": "2019-08-24T14:15:22Z",
      "secret": "string",
      "secretPreview": "string",
      "subject": {
        "type": "user",
        "id": "string"
      },
      "teamScope": {},
      "updatedAt": "2019-08-24T14:15:22Z"
    },
    "claimedSpaceId": "string",
    "status": "pending"
  }
}
```

#### Error Response

```json
{
  "$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"
}
```
