Create a new access key
const url = 'https://api.aetherpush.com/v1/access-keys';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"friendlyName":"ci-deploy-key","ttl":5184000000}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.aetherpush.com/v1/access-keys \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "friendlyName": "ci-deploy-key", "ttl": 5184000000 }'Creates a new access key on the current account. The response
contains the raw key string in the name field. This is the
only time the raw key is returned; store it securely.
If friendlyName collides with an existing key on the account,
the request returns 409.
Creating an access key requires a dashboard login session. API keys
and named access keys are refused earlier by the login-session
requirement, with 403 and code session_required. A valid CLI session or a
session that predates credential attribution is refused with 403 and
code dashboard_session_required, so a stolen session cannot mint a
sibling that survives its own revocation. The raw key value is always
server-generated; a body carrying name is refused with 400.
An account that passed its two-factor setup deadline with MFA still off
is refused here with 403 and code mfa_setup_required.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”Body shape for creating or updating an access key. On create,
a non-empty friendlyName or a non-empty legacy description
is required; whitespace is trimmed first. A body that sends both
keeps friendlyName. On update, all fields are optional; only
provided fields are modified.
The raw key value is always generated by the server. A create
request carrying a name field is refused with 400. createdBy is
not part of the request: the server records it from the request IP,
so a body still carrying it is not schema-valid, and the server
ignores the value rather than refusing the request.
object
Human-friendly identifier for the key.
Legacy input name for friendlyName. Used when friendlyName
is omitted. Empty or whitespace-only values do not satisfy
create. A body that sends both keeps friendlyName and
discards this value. The stored key’s description always
equals the resulting friendlyName.
Time-to-live in milliseconds. If omitted, the key expires in 60 days.
Example
{ "friendlyName": "ci-deploy-key", "ttl": 5184000000}Responses
Section titled “Responses”Access key created. Raw key returned in name.
object
object
The raw key string. Only returned in full on POST /v1/access-keys
(creation). On GET /v1/access-keys it is masked as (hidden).
On GET /v1/access-keys/{name} it is omitted entirely.
Human-friendly identifier for the key.
Mirrors friendlyName. Kept for legacy clients.
IP address that created the key.
Unix timestamp in milliseconds.
Unix timestamp in milliseconds.
True if the key was created by a login flow (vs. CLI/manual creation).
How the credential was created. Absent on credentials that predate
CLI browser login. cli_browser and cli_device credentials are
the ones listed and revoked through /v1/cli/devices.
Stable identifier the CLI generates once per machine.
Human-facing device label shown on the approval screen.
Client that requested the credential.
Client version at the time of authorization.
Operating system and architecture reported by the client.
Example
{ "accessKey": { "name": "abc123-base64url-secret", "friendlyName": "ci-deploy-key", "description": "ci-deploy-key", "createdBy": "203.0.113.42", "createdTime": 1714867200000, "expires": 1720051200000 }}Headers
Section titled “Headers”Resource location of the newly created key.
Missing or invalid fields.
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
Human-readable error message.
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.
Unique identifier for the request, also exposed as the X-Request-Id response header.
object
object
Stable machine code for this field error.
Example
{ "error": "The requested resource was not found.", "code": "not_found", "requestId": "req_abc123"}Unauthenticated.
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
Human-readable error message.
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.
Unique identifier for the request, also exposed as the X-Request-Id response header.
Example
{ "error": "The requested resource was not found.", "code": "not_found", "requestId": "req_abc123"}API keys and named access keys receive a plain 403. A valid login
session that is not a dashboard login session receives
dashboard_session_required; an account past its two-factor setup
deadline receives mfa_setup_required.
Returned after login-session validation when a valid session that is
not a dashboard login session tries to issue or widen an API key,
create an access key or change its lifetime, enrol a passkey or
authenticator app, start a passkey step-up challenge, run the CLI
device ceremony, change the password, or request or cancel the
account’s deletion. Endpoints that enforce both guards reject API keys and
named access keys earlier with a plain 403 carrying
code: session_required. API-key creation applies only the
dashboard-session guard, so any non-dashboard credential receives
this response there. Listing,
renaming and revoking stay open to any login session. Sessions created
before the credential_origin column existed cannot be attributed to
the dashboard and are also refused; signing out and back in fixes that.
object
Returned when the account passed its two-factor setup deadline and asks
for a new credential. Same shape as the reauth response so clients can
branch on code rather than on message text.
object
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
Human-readable error message.
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.
Unique identifier for the request, also exposed as the X-Request-Id response header.
Example
{ "error": "This operation requires a login session. API keys and named access keys cannot access it.", "code": "session_required", "requestId": "req_abc123"}A key with that friendlyName already exists.
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
Human-readable error message.
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.
Unique identifier for the request, also exposed as the X-Request-Id response header.
Example
{ "error": "The requested resource was not found.", "code": "not_found", "requestId": "req_abc123"}The tenant’s per-minute management API budget is spent.
Retry-After and X-RateLimit-* say when to retry. This is
not a plan quota: quota 429s use the Error envelope and do
not set Retry-After.
Returned with HTTP 429 when an endpoint-specific rate limit is hit,
including the per-tenant management API budget. Not the process-wide
address limiter (see GlobalAddressRateLimitErrorResponse).
retryAfterSeconds
indicates how long the client should wait before retrying, and matches
the Retry-After header when that header is set. code names the
limit that fired so clients can translate without matching on error.
object
Example
{ "error": "Rate limit exceeded", "code": "tenant_rate_limit_exceeded", "retryAfterSeconds": 60}Headers
Section titled “Headers”Seconds until the tenant window resets.