Skip to content

Exchange a CLI authorization for a session credential

POST
/v1/auth/cli/token
curl --request POST \
--url https://api.aetherpush.com/v1/auth/cli/token \
--header 'Content-Type: application/json' \
--data '{ "grantType": "authorization_code", "code": "example", "codeVerifier": "example", "redirectUri": "example", "deviceCode": "example" }'

The only endpoint that returns the CLI’s bearer token. Both grants are single use: a replay, a mismatched verifier, or a mismatched redirect URI terminates the request rather than merely failing.

For device_code, the pending states authorization_pending and slow_down are returned with HTTP 400 per RFC 8628 and are expected during normal polling. The RFC 8628 error codes appear on 400 only; 429 and 500 carry the standard { error, requestId } envelope with a human-readable message, so branch on the status code first.

Either grant answers 400 with account_pending_deletion when the account has a deletion scheduled; the CLI can sign in again once the owner cancels the deletion from the dashboard.

Media typeapplication/json

Either an authorization-code exchange (loopback flow) or a device-code poll. The grant type selects which other fields are required.

object
grantType
required
string
Allowed values: authorization_code device_code
code

Authorization code from the loopback redirect. Required for authorization_code.

string
codeVerifier

The original PKCE verifier. Required for authorization_code.

string
redirectUri

Must byte-match the URI registered when the request was created.

string
deviceCode

Required for device_code.

string

Credential issued.

Media typeapplication/json
object
accessKey
required

The session bearer. Returned only here, only once, and never to the browser. Non-prefixed, so it resolves through the access-key path.

string
expires
required
integer format: int64
credentialId
required

Identifies this device for DELETE /v1/cli/devices/{credentialId}.

string format: uuid
account
object
email
string

Example

{
"expires": 1792049845916,
"account": {
"email": "user@example.com"
}
}

Pending, throttled, denied, expired, or invalid.

Media typeapplication/json

RFC 8628 error codes. authorization_pending and slow_down are normal polling states, not failures.

object
error
required
string
Allowed values: authorization_pending slow_down access_denied expired_token invalid_grant invalid_request unsupported_grant_type mfa_setup_required account_pending_deletion
error_description
string
requestId

Also returned in the X-Request-Id header.

string

Example

{
"error": "authorization_pending"
}

Too many token requests from this address.

Media typeapplication/json
Error

Standard error envelope. code is the stable machine identifier for client branching and i18n. The wording of error is a human-readable fallback and is not part of the contract. Specialized responses keep narrower code enums where clients already branch on them.

object
error
required

Human-readable error message.

string
code
required

Stable machine code. Prefer this over matching on error. The values this API can answer with are listed in the ApiErrorCode schema of the raw document at https://api.aetherpush.com/openapi.yaml. The field stays an open string here so that a release adding a value does not invalidate this response.

string
requestId

Unique identifier for the request, also exposed as the X-Request-Id response header.

string

Example

{
"error": "The requested resource was not found.",
"code": "not_found",
"requestId": "req_abc123"
}

Internal server error.

Media typeapplication/json
Error

Standard error envelope. code is the stable machine identifier for client branching and i18n. The wording of error is a human-readable fallback and is not part of the contract. Specialized responses keep narrower code enums where clients already branch on them.

object
error
required

Human-readable error message.

string
code
required

Stable machine code. Prefer this over matching on error. The values this API can answer with are listed in the ApiErrorCode schema of the raw document at https://api.aetherpush.com/openapi.yaml. The field stays an open string here so that a release adding a value does not invalidate this response.

string
requestId

Unique identifier for the request, also exposed as the X-Request-Id response header.

string

Example

{
"error": "The requested resource was not found.",
"code": "not_found",
"requestId": "req_abc123"
}