Quickstart
This walks through the full loop: sign up → authenticate → call an endpoint. Examples
use curl against a Zynth Auth instance at $BASE (e.g. your self-hosted URL).
Bringing an AI agent? An agent can run this entire loop on your behalf — opening the organization with you as its owner (you verify, set a passkey, and approve; the agent gets its own governed credential) and configuring roles, invites, and SSO as code with exactly one review. See Agent-driven onboarding & IAM-as-code.
BASE="https://your-zynth-auth-host"
On a self-hosted instance with a self-signed certificate (IP-only, no domain yet), add
-ktocurlfor local testing. Use a real certificate in production.
1. Join the private beta (creates your organization)
While the beta is private,
POST /api/v1/auth/signupanswers403with a reason naming the early-access page — the door is closed by default (PUBLIC_SIGNUP_ENABLED=false). Invited testers get in one of two ways: their agent opens the organization at the bootstrap door with the invite code (POST /api/v1/onboard/bootstrapwithinvite_code, see Joining the private beta), or the organization was provisioned for them and they set a password from the invite email and sign in at step 3. A self-hosted install that keeps sign-up open (PUBLIC_SIGNUP_ENABLED=true) uses the call below as written.
Signing up creates a user, an organization (tenant), and an owner membership
linking them. The organization slug is derived from the name (e.g. "Acme Inc" → acme-inc).
curl -X POST "$BASE/api/v1/auth/signup" \
-H "Content-Type: application/json" \
-d '{
"email": "you@example.com",
"password": "a-strong-passphrase-min-12-chars",
"organization_name": "Acme Inc"
}'
Response 201 (or 403 while sign-up is closed — see the note above):
{
"access_token": "eyJhbGci...",
"refresh_token": "eyJhbGci...",
"token_type": "bearer"
}
2. Call an authenticated endpoint
Use the access token as a Bearer credential. GET /api/v1/me returns your identity and
tenant context:
curl "$BASE/api/v1/me" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response 200:
{
"user_id": "…",
"tenant_id": "…",
"role": "owner",
"is_owner": true,
"tenant_isolation": "pooled",
"population": "workforce",
"email_verified": false
}
3. Log back in later
Logging in requires the organization slug (a user may belong to more than one org):
curl -X POST "$BASE/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "password": "…", "tenant_slug": "acme-inc"}'
4. Refresh an expired access token
Access tokens are short-lived (15 minutes by default). Exchange a refresh token for a new pair — no re-entry of credentials:
curl -X POST "$BASE/api/v1/auth/refresh" \
-H "Content-Type: application/json" \
-d '{"refresh_token": "'"$REFRESH_TOKEN"'"}'
Next
- API reference — endpoints, fields, and errors for the core surfaces (hand-maintained; some families are documented in their guides instead).
- Verifying tokens — validate tokens in your own services.
- Troubleshooting — if something didn't work.