DhokoAuthaz
DocumentationAPI Reference
  • Get Started

    • Authaz
    • Core Concepts
    • Set up your app
    • Quickstart — cURL
  • Authentication

    • Authentication Settings
    • Signup
    • Invitations
    • Password Authentication
    • Multi-Factor Auth
    • Magic Link
    • OAuth / Social Login
    • Passkey (WebAuthn)
    • SAML SSO
    • Machine-to-Machine (M2M)
    • API Keys
  • Authorization

    • Authorization
    • Resources
    • Policies
    • Roles
    • Access Explorer
  • Tenancy

    • Multi-tenancy
    • Tenancy Customization
  • Brand & Host

    • Branding
    • Custom Domains
    • Communications & Email Templates
  • Operate

    • Users
    • Analytics
    • Audit Logs
    • Application Settings
  • SDK Quickstarts

    • Quickstart — Next.js
    • Quickstart — React SPA
    • Quickstart — Hono
    • Quickstart — .NET (Authaz.Sdk)
  • Recipes

    • Recipes & Cookbook
    • Next.js — first integration
    • Next.js — B2B SaaS (multi-tenant)
    • Hono — first integration
    • Hono — B2B SaaS (multi-tenant)
    • React SPA — first integration
    • React SPA — B2B SaaS (multi-tenant)
    • .NET — first integration
    • .NET — B2B SaaS (multi-tenant)
  • Reference

    • Tokens
    • API Reference
    • Errors & Troubleshooting
  • Documentation

    • How Authaz is Built
  1. Authaz
  2. Docs
  3. Get Started
  4. Quickstart — cURL

Get Started

Quickstart — cURL

3 min read·Updated May 7, 2026

cURL · Next.js · React · Hono · .NET

This is the bare-metal walkthrough — no SDK, just HTTP. If your stack isn't covered by an SDK quickstart, or if you just want to see how Authaz works before reaching for one, start here.

You'll authenticate a real user against Authaz Sign-In, exchange the resulting code for tokens, and call a protected endpoint. About 5 minutes.

Prerequisites#

New to Authaz? Take 60 seconds to set up your app, then come back. You'll need an Application ID, your Domain (your-app.authaz.io), and http://localhost:3000/callback registered as a redirect URI. The Password provider is enabled by default, which is enough for this walkthrough.

Step 1 — Generate a PKCE pair#

PKCE (Proof Key for Code Exchange) prevents anyone who intercepts the authorization code from using it. Generate one before kicking off the flow:

Previous
Set up your app
Next
Authentication Settings
# Code verifier — a random string between 43 and 128 chars
CODE_VERIFIER=$(openssl rand -base64 96 | tr -d '=+/' | cut -c1-128)
 
# Code challenge — base64url(SHA256(verifier))
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | openssl base64 | tr -d '=' | tr '/+' '_-')
 
echo "verifier:  $CODE_VERIFIER"
echo "challenge: $CODE_CHALLENGE"

Hold onto $CODE_VERIFIER. You'll need it again in Step 3.

Step 2 — Send the user to Authaz Sign-In#

Open this URL in a browser, replacing YOUR_APP_ID, the domain, and the challenge:

https://your-app.authaz.io/oauth2/authorize
  ?client_id=YOUR_APP_ID
  &redirect_uri=http://localhost:3000/callback
  &response_type=code
  &code_challenge_method=S256
  &code_challenge=YOUR_CHALLENGE
  &scope=openid%20profile%20email
  &state=$(openssl rand -hex 16)

The Authaz Sign-In page loads. Sign up with an email + password (since this is a fresh app). After signup you'll be redirected to:

http://localhost:3000/callback?code=AUTH_CODE&state=...

Copy AUTH_CODE from the URL.

The redirect URI doesn't have to actually serve anything. The browser only needs to land on it so you can grab the code from the URL bar. For production, register a real callback URL in your application's settings.

Step 3 — Exchange the code for tokens#

curl -X POST "https://your-app.authaz.io/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "client_id=YOUR_APP_ID" \
  -d "redirect_uri=http://localhost:3000/callback" \
  -d "code_verifier=$CODE_VERIFIER"

Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "rt_01h...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email"
}

The codes are single-use — try the same code twice and you'll get a 400 invalid_grant.

Step 4 — Call a protected endpoint#

The access token is what you send to your own backend (or to Authaz) for authenticated calls:

curl https://your-app.authaz.io/oauth2/userinfo \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."
{
  "sub": "user_01h...",
  "email": "you@example.com",
  "email_verified": true,
  "name": "Your Name",
  "organizations": [{"organizationId": "0199...", "accessLevel": "owner"}]
}

That same access token also works against any tenant-scoped Management API endpoint where the user has permission.

Step 5 — Refresh when the token expires#

Access tokens expire (default: 15 minutes). Use the refresh token to get a new pair without sending the user back through Authaz Sign-In:

curl -X POST "https://your-app.authaz.io/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=rt_01h..." \
  -d "client_id=YOUR_APP_ID"

You get a fresh access token and (typically) a new refresh token. Always store the new refresh token — Authaz rotates them by default.

If something's wrong#

SymptomLikely causeFix
invalid_request after sign-inThe redirect_uri in Step 2 doesn't match what's registered.Compare exactly — trailing slash, port, scheme. Add http://localhost:3000/callback to Settings → Redirect URIs.
400 invalid_grant on token exchangeAuthorization code already used, or expired (codes are single-use and short-lived).Restart from Step 2 to get a fresh code.
400 invalid_grant with code unusedcode_verifier doesn't match the original code_challenge.Re-run Step 1 and Step 2 in the same shell so $CODE_VERIFIER survives.
401 invalid_clientWrong client_id, or you sent a client secret you shouldn't have for PKCE.PKCE flows don't send a secret. Check the Application ID.
401 on /oauth2/userinfoAccess token expired (default: 15 minutes).Use the refresh token (Step 5) or sign in again.

For everything else, the errors catalog covers every code Authaz returns.

What's next#

  • Verify tokens server-side. Don't trust an access token's claims without checking the signature. Authaz publishes its keys at https://your-app.authaz.io/.well-known/jwks.json (JWKS — the standard set of public keys for verifying RSA-signed JWTs).
  • Add roles and permissions. Use the dashboard or POST /api/v1/roles to define them, then POST /api/v1/role-assignments to assign. Check at runtime via POST /api/v1/authorization/check.
  • Pick an SDK if you want to skip the boilerplate: Next.js, React, Hono, .NET.
  • See a full app in the Recipes & Cookbook — single-tenant and multi-tenant walkthroughs for every supported stack.

Next steps#

  • Core Concepts — the mental model behind what you just did.
  • Multi-tenancy — adding tenant scoping to the flow.
  • API Reference — every Management API endpoint.