Skip to content

Log in with email and password

POST
/v1/auth/login
curl --request POST \
--url https://api.aetherpush.com/v1/auth/login \
--header 'Content-Type: application/json' \
--data '{ "email": "adrian@aetherpush.com", "password": "correct horse battery staple" }'

Authenticates an account and returns an access key (session bearer token) usable on subsequent requests. The returned accessKey is the raw token — store it securely; the server cannot return it again.

Rate limited to 5 failed attempts per client address per 15 minutes. The address is the exact one on IPv4 and the /64 prefix on IPv6.

Repeated failures against a single account escalate rather than lock it: past a small number of recent failures the next attempt must carry a Turnstile token in challengeToken, and the server signals that with a 403 carrying code: challenge_required. Where that escalation is not enabled, the account instead stops accepting attempts for an hour after ten recent failures.

Media typeapplication/json
object
email
required
string format: email
password
required
string format: password
challengeToken

Cloudflare Turnstile token. Only needed once an account has accumulated enough recent failed logins for the server to ask for one, which it signals with a 403 carrying code: challenge_required. Sending it before then is harmless and ignored.

string
Example
{
"email": "adrian@aetherpush.com",
"password": "correct horse battery staple"
}

Password accepted. For accounts without MFA the response carries the access key. For MFA-enabled accounts it instead carries a short-lived pending login token; complete the login via /v1/auth/mfa/verify (passkey), /v1/auth/mfa/totp (authenticator code), or /v1/auth/mfa/recovery (recovery code). methods lists which of those this account can use. The two shapes are told apart by the mfaRequired field.

Media typeapplication/json
One of:
object
accessKey
required

Raw bearer token. Send as Authorization: Bearer <accessKey> on subsequent requests. Store securely (cookie or secure storage). The server cannot reveal it again.

string
expires
required

Unix timestamp in milliseconds at which this token expires.

integer format: int64
mfaSetupRequired

Present and true when the account has no MFA method yet. Every account is expected to enroll a passkey or an authenticator app. The dashboard nags until mfaSetupDeadline and blocks navigation after it. Clients that cannot enroll (the CLI) may ignore this field.

boolean
mfaSetupDeadline

Unix timestamp in milliseconds. Present alongside mfaSetupRequired; fixed on the account’s first MFA-less login and stable on later logins. Before it, MFA setup is a dismissible prompt; after it, the dashboard requires setup before continuing.

integer format: int64
Examples
{
"accessKey": "abc123-base64url-secret",
"expires": 1719964800000
}

Email or password missing.

Media typeapplication/json
object
error
required

Human-readable error message.

string
requestId

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

string
Example
{
"error": "Email and password are required.",
"requestId": "req_abc123"
}

Invalid email or password.

Media typeapplication/json
object
error
required

Human-readable error message.

string
requestId

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

string
Example
{
"error": "Invalid email or password.",
"requestId": "req_abc123"
}

Either the email address has not been verified, or the account needs a Turnstile token before the attempt is considered. The two are told apart by the code field, which is present only on the second.

Media typeapplication/json
One of:
object
error
required

Human-readable error message.

string
requestId

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

string
Examples
{
"error": "Please verify your email address before logging in.",
"requestId": "req_abc123"
}

Too many login attempts.

Media typeapplication/json

Returned with HTTP 429 when an endpoint-specific rate limit is hit. retryAfterSeconds indicates how long the client should wait before retrying.

object
error
required
string
retryAfterSeconds
integer
>= 1
requestId
string
Example
{
"error": "Too many login attempts. Please try again later.",
"retryAfterSeconds": 900,
"requestId": "req_abc123"
}

Internal server error.

Media typeapplication/json
object
error
required

Human-readable error message.

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.",
"requestId": "req_abc123"
}