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/authorizeor/auth/federated/github/authorize; they come back to yourredirect_uriwith 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/authendpoints 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. |
Magic link
One endpoint handles both sign-in and sign-up, so your client needs one email field.
-
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_urimust be one of the hosts registered on your app, or the request returns HTTP 400. -
The person clicks the link and lands on your
redirect_uriwith a single-usetokenquery parameter. -
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 returnsinvalid_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/mereturns 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
usertoPOST /api/v1/agent_sessions. See Agents.
Need something clearer?
Tell us where this page still falls short.
If a step is confusing, a diagram is misleading, or a workflow needs a better example, send feedback directly and we will tighten it.