User sign-in

How the people who use your app sign in, over the auth endpoints your client calls with the publishable key.

Overview

Your users sign in to your product, not to ArchAstro. Your client calls the auth endpoints under /api/v1/auth with your app's publishable key, the person completes the method their organization allows, and the response carries the tokens your client uses from then on.

Every request in this guide sends the publishable key in the X-ArchAstro-API-Key header. Publishable keys start with pk_dap_ for Production and pk_dsb_ for the Test environment, and they identify the app without granting it anything on their own. Keep secret keys (sk_) on your server.


Sign-in methods

Each organization chooses which methods it accepts:

  • Magic link. A one-time link sent to the person's email. On by default for new organizations.
  • Password. Email and password.
  • Google and GitHub. Hosted browser flows. Send the person to /auth/federated/google/authorize or /auth/federated/github/authorize; they come back to your redirect_uri with a token to exchange, the same as a magic link.
  • SAML SSO. Okta, Azure AD, or any SAML 2.0 identity provider, configured per organization. See Organizations.
  • Two-factor. An organization can require TOTP for its members when they sign in to the portal. The /api/v1/auth endpoints in this guide take no TOTP code.

When a method is turned off, /auth/login, /auth/register, and /auth/verify/link return HTTP 403, and a Google or GitHub flow redirects back to your redirect_uri with error=method_not_enabled. GET /api/v1/auth/allowed_auth_methods lists the methods an organization accepts. Sign in with Apple and passkeys are not available.


The token response

Every endpoint that signs a person in returns the same object:

Field Meaning
token The access token, a JWT. Send it as Authorization: Bearer <token> on every request the person makes.
refresh_token Exchange it at /auth/refresh for a new pair when the access token expires.
token_type Always Bearer.
expires_in Seconds until the access token expires.
user The signed-in user, with their org, org_kind, and org_role.

One endpoint handles both sign-in and sign-up, so your client needs one email field.

  1. Your client posts the email and the URL to return to:

    curl -X POST https://api.archastro.ai/api/v1/auth/request/link \
      -H "X-ArchAstro-API-Key: pk_dap_..." \
      -H "Content-Type: application/json" \
      -d '{"email": "person@example.com", "redirect_uri": "https://app.example.com/auth/callback"}'
    

    The response is HTTP 204. If an account with that email exists, the person receives a sign-in link; if not, a sign-up link. redirect_uri must be one of the hosts registered on your app, or the request returns HTTP 400.

  2. The person clicks the link and lands on your redirect_uri with a single-use token query parameter.

  3. Your client exchanges it:

    curl -X POST https://api.archastro.ai/api/v1/auth/verify/link \
      -H "X-ArchAstro-API-Key: pk_dap_..." \
      -H "Content-Type: application/json" \
      -d '{"token": "<token from the query string>"}'
    

    The response is the token object above. An expired link returns HTTP 401 with the error code expired_token; an unknown or already used one returns invalid_or_expired_token.

Pass "set_org": true on the request to create or reuse an organization from a new user's work-email domain during confirmation.


Password

Register:

curl -X POST https://api.archastro.ai/api/v1/auth/register \
  -H "X-ArchAstro-API-Key: pk_dap_..." \
  -H "Content-Type: application/json" \
  -d '{"email": "person@example.com", "password": "...", "full_name": "Alex Rivera"}'

Returns HTTP 201 with the token object. Optional fields: alias, timezone (an IANA name), invite_code for invite-gated apps, team_invite to add the new user to a team on registration, and set_org.

Sign in:

curl -X POST https://api.archastro.ai/api/v1/auth/login \
  -H "X-ArchAstro-API-Key: pk_dap_..." \
  -H "Content-Type: application/json" \
  -d '{"email": "person@example.com", "password": "..."}'

Returns the token object, or HTTP 401 for bad credentials.


Refreshing

curl -X POST https://api.archastro.ai/api/v1/auth/refresh \
  -H "X-ArchAstro-API-Key: pk_dap_..." \
  -H "Content-Type: application/json" \
  -d '{"refresh_token": "rt_..."}'

Returns a new access token and a new refresh token. The refresh token rotates on every call: store the new one and discard the old one.


Rate limits

Endpoint Per IP Per email and IP
/auth/request/link 10 per minute 3 per minute
/auth/login 10 per minute 5 per minute
/auth/verify/link, /auth/token 10 per minute

Exceeding a limit returns HTTP 429.


After sign-in

  • GET /api/v1/users/me returns the signed-in person and their organization. See Organizations.
  • Custom objects, key-value entries, files, and OAuth connections can be owned by one user inside the organization. See Custom Objects and Key-Value Storage.
  • Sessions run for one user: pass the user to POST /api/v1/agent_sessions. See Agents.