A valid request URL is required to generate request examples{
"userCode": "<string>",
"clientName": "<string>",
"clientVersion": "<string>",
"requestedFromIp": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"status": "pending",
"orgId": "<string>",
"scopes": [
"devices:read"
],
"ttlMs": 7819200000,
"keyName": "<string>"
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "unauthorized",
"reason": "missing_credentials",
"hint": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "not_found",
"message": "<string>"
}
}{
"error": {
"code": "wrong_state",
"message": "<string>",
"status": "pending"
}
}{
"error": {
"code": "payload_too_large",
"message": "<string>"
}
}{
"error": {
"code": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}Approve a CLI sign-in
Approving a sign-in mints an API key for it, so it asks exactly what POST /v1/api-keys asks: a signed-in person of either role, and no scope your own session does not hold. No recent identity check. The key acts for the organisation you have active, is created by you, and appears on the Keys page like any other.
Without scopes the key gets the CLI default (devices:read, devices:act, devices:lease, runs:start, orders:place) narrowed to what your session holds. Without ttlMs it lasts 180 days from when the CLI collects it. The key is minted on the CLI’s next poll, not by this call, and that collection does not re-check your membership. An approval near the code’s deadline extends it to at least 60 seconds out so the CLI can still collect. Omitting scopes when your session holds none of the defaults is refused 403.
Hosted deployments only. A local checkout does not mount this route, so calling it there is a 404.
A valid request URL is required to generate request examples{
"userCode": "<string>",
"clientName": "<string>",
"clientVersion": "<string>",
"requestedFromIp": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"status": "pending",
"orgId": "<string>",
"scopes": [
"devices:read"
],
"ttlMs": 7819200000,
"keyName": "<string>"
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "unauthorized",
"reason": "missing_credentials",
"hint": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}{
"error": {
"code": "not_found",
"message": "<string>"
}
}{
"error": {
"code": "wrong_state",
"message": "<string>",
"status": "pending"
}
}{
"error": {
"code": "payload_too_large",
"message": "<string>"
}
}{
"error": {
"code": "rate_limited",
"message": "<string>"
}
}{
"error": {
"code": "backend_resolution_failed",
"message": "<string>",
"retryable": true
}
}Authorizations
The control surface credential. Send Authorization: Bearer <token>.
Two kinds of token are accepted and they are told apart by shape, not by a separate header. A token beginning pbk_ is an org scoped API key, whose public half and secret half are generated together and of which only a hash of the secret is ever stored; anything else is treated as an OAuth 2.1 access token and verified against the authorization server's keys.
Both resolve to the same context: an org, a principal and a set of scopes. Nothing downstream branches on which channel you used, with one deliberate exception, key management, which requires a signed-in person so that a key can never mint another key.
Scopes are enforced when MCP tools are REGISTERED rather than when they are called, so a tool your credential cannot use is absent from tools/list rather than refused mid gesture.
Path Parameters
The code from the terminal. Case, spaces and the hyphen are forgiven.
Body
Optional. Everything has a default.
A non empty subset of the scope vocabulary, within your own session's scopes.
1A scope to grant.
devices:read, devices:act, devices:lease, runs:start, orders:place, apps:read, apps:write, apps:delete The key's lifetime in milliseconds, whole days only, counted from collection. Defaults to 15552000000 (180 days). The same name and unit as on POST /v1/api-keys.
86400000 <= x <= 15552000000Must be a multiple of 86400000The key's name. Defaults to CLI · <clientName>.
1 - 120Response
Approved. The CLI collects the key on its next poll.
The sign-in after approval. The key is minted when the CLI next polls, not now.
What the CLI called itself, usually the computer's name. Unverified.
The CLI's version, as it reported it. Unverified.
The address the sign-in was opened from, as this service saw it. Compare it with where you are: a code someone sent you from elsewhere is the phishing case. Null when it could not be determined.
Where this sign-in is. expired is judged on the service's clock.
pending, approved, denied, expired, consumed The organisation the key will act for: the approver's active one.
A scope the key will carry.
devices:read, devices:act, devices:lease, runs:start, orders:place, apps:read, apps:write, apps:delete The key's lifetime in milliseconds, whole days, counted from when the CLI collects it.
86400000 <= x <= 15552000000