Authentication

AIUS uses two user credentials:
  1. a short-lived HS256 session token, normally held in the __Host-aius_session cookie; and
  2. a durable aius_… terminal/API credential bound to an organization and a user principal.
The portal does not expose API-key management. The normal terminal path is the browser-approved device flow.
Examples target https://dev.aius.co/api. For dev, use https://dev.aius.co/api and Accept-Encoding: identity.

1. Register

POST /v1/register creates an email/password account and its default organization. The account must verify its email before normal use.
curl -X POST https://dev.aius.co/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "dev@example.com",
    "name": "Dev User",
    "password": "SuperSecret123!"
  }'
Passwords require at least eight characters with a letter, number, and special character.

2. Log in and complete 2FA

POST /v1/login accepts email/password. Without 2FA it returns {user, message, session_token}. With 2FA it returns {requires_2fa: true, challenge_token, email, message}.
curl -X POST https://dev.aius.co/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{"email":"dev@example.com","password":"SuperSecret123!"}'
Complete a 2FA challenge through unauthenticated POST /v1/2fa/login:
curl -X POST https://dev.aius.co/api/v1/2fa/login \
  -H "Content-Type: application/json" \
  -d '{"challenge_token":"eyJ...","code":"123456"}'
A current TOTP or unused recovery code is accepted. The CLI performs the following exchange:
1

Request a code

POST /v1/auth/device/code returns a device code, short user code, verification URL, expiry, and polling interval.
2

Approve in the portal

The user opens /account/device, signs in, and approves the code. If they have multiple live organization memberships, they choose one. The portal calls POST /v1/auth/device/authorize with {user_code, client_id?} and its session cookie.
3

Collect once

The CLI polls POST /v1/auth/device/poll until it receives {status: "complete", token, client_id, email}. The token is returned once and the completed code is consumed.
client_id must be an exact org_… id in the signed-in user’s live memberships. If omitted, AIUS resolves the default organization. Selecting an inaccessible organization returns 403; failure to establish memberships returns 503. Each organization/principal pair has its own active credential. A new device login rotates only that user’s previous credential in that organization, so teammates do not sign each other out.

4. Direct credential mint

POST /v1/tokens is the session-authenticated programmatic mint used by the same credential layer. It is not a portal key-management feature.
curl -X POST https://dev.aius.co/api/v1/tokens \
  -H "Content-Type: application/json" \
  --cookie "__Host-aius_session=eyJ..." \
  -d '{
    "token_name": "automation",
    "client_id": "org_a1b2c3d4e5f6"
  }'
token_name is optional and defaults to API key. client_id is optional; when present it must be an organization the session user currently owns or has membership in. The response returns the plaintext token once:
{
  "id": 42,
  "client_id": "org_a1b2c3d4e5f6",
  "token_name": "automation",
  "token": "aius_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "created_at": 1717123999
}
Store the token securely. Listing and mutation are principal-scoped, so one member cannot enumerate or revoke a teammate’s credential.

5. Use the bearer credential

curl https://dev.aius.co/api/v1/auth/verify \
  -H "Authorization: Bearer aius_xxxxxxxx..."
The run WebSocket sends the same value in its first frame: {"type":"auth","token":"aius_…"}. An unknown, revoked, or removed-member credential is rejected. For a user-associated organization credential, AIUS revalidates live membership before run/chat and protected account operations:
  • 403 means the user no longer belongs to the organization;
  • 503 means the membership authority could not be established, and the request fails closed rather than running unbilled.
Billing and concurrency use the credential’s organization. Teammates therefore share one organization balance and concurrency cap, while signed outcome headers preserve the acting user. Many data routes additionally require an org_id query parameter matching the resource scope, for example:
curl "https://dev.aius.co/api/v1/models?org_id=org_a1b2c3d4e5f6" \
  -H "Authorization: Bearer aius_xxxxxxxx..."

Team membership endpoints

These routes use a browser session or an authorized bearer identity:
EndpointMethodAccess
/v1/clients/{client_id}/membersGETAny live member
/v1/clients/{client_id}/membersPOSTOwner; body {"email":"exact@example.com"}
/v1/clients/{client_id}/members/{user_id}DELETEOwner; cannot remove owner
Only an already registered, live account can be added. Email comparison is trimmed and case-insensitive, but domain membership is never inferred. Removal invalidates access immediately and triggers targeted credential cleanup.

Manage TOTP

Authenticated TOTP endpoints:
EndpointMethodPurpose
/v1/2fa/statusGETRead enabled state
/v1/2fa/setupPOSTReturn secret and otpauth_uri
/v1/2fa/enablePOSTConfirm code and return recovery codes
/v1/2fa/disablePOSTDisable with TOTP or recovery code
Save recovery codes when enabling 2FA; each is one-time use.

Password reset

EndpointMethodPurpose
/v1/password/reset/requestPOSTSend reset email; does not reveal whether an address exists
/v1/password/reset/confirmPOSTSet a new password from the reset token