Developer Docs

REST & Auth API

While the platform's primary interface is GraphQL, several services expose REST endpoints for authentication flows, content feeds, admin metrics, and SCIM provisioning.


Dev Token (Quick Auth)

The fastest way to get an authenticated session for API testing: no OAuth, no browser required.

# Issue a session token for any seeded user
curl -s -X POST http://localhost:3008/auth/dev/token \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}' | jq .
{
	"session_token": "sess_a1b2c3d4...",
	"expires_in": 86400,
	"user": { "id": "...", "email": "user@example.com", "username": "user" }
}

Requires DEV_MODE=true in the auth service. Enabled by default in local development.

Use the token in subsequent requests:

export TOKEN="sess_a1b2c3d4..."

# GraphQL
curl http://localhost:30000/graphql \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ me { id email } }"}'

# REST (auth service)
curl http://localhost:3008/me \
  -H "Cookie: session_token=$TOKEN"

Auth Service (`localhost:3008`)

OAuth Flows

Method Endpoint Description
GET /auth/oauth/:provider Initiate OAuth login (redirects to provider). Providers: google, apple, twitter, facebook
GET /auth/oauth/:provider/callback OAuth callback (provider redirects back here)
POST /auth/logout Destroy session (requires cookie)
POST /auth/refresh Refresh session token (cookie-based)
# Initiate Google OAuth (open in browser)
open "http://localhost:3008/auth/oauth/google"

Email OTP (Passwordless)

Method Endpoint Description
POST /auth/email/login/start Send 6-digit OTP to email
POST /auth/email/login/finish Verify OTP and create session
GET /auth/email/check?email=... Check if email exists
# Start email login
curl -X POST http://localhost:3008/auth/email/login/start \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

# Verify OTP
curl -X POST http://localhost:3008/auth/email/login/finish \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "code": "123456"}'
Method Endpoint Description
POST /auth/magic-link/start Send magic link email
POST /auth/magic-link/verify Verify magic link token

Passkeys (WebAuthn)

Method Endpoint Description Auth
POST /auth/passkey/login/start Get WebAuthn challenge Public
POST /auth/passkey/login/finish Verify WebAuthn response Public
POST /auth/passkey/register/start Start passkey registration ๐Ÿ”’ Session
POST /auth/passkey/register/finish Complete registration ๐Ÿ”’ Session

MFA (Two-Factor)

Method Endpoint Description Auth
POST /auth/mfa/verify Verify MFA challenge (TOTP or SMS) Public
POST /auth/mfa/backup Use backup code Public
GET /auth/mfa/status Check MFA enrollment status ๐Ÿ”’ Session
POST /auth/mfa/totp/enroll Start TOTP enrollment ๐Ÿ”’ Session
POST /auth/mfa/totp/confirm Confirm TOTP enrollment ๐Ÿ”’ Session
POST /auth/mfa/sms/enroll Start SMS enrollment ๐Ÿ”’ Session
POST /auth/mfa/sms/confirm Confirm SMS enrollment ๐Ÿ”’ Session
POST /auth/mfa/disable Disable MFA ๐Ÿ”’ Session
POST /auth/mfa/backup/regenerate Regenerate backup codes ๐Ÿ”’ Session

Mobile Token Exchange

For native mobile apps (React Native / KMP) that handle OAuth client-side:

Method Endpoint Description
POST /auth/mobile/token Exchange provider access_token for session tokens
POST /auth/mobile/refresh Refresh session via JSON body
POST /auth/mobile/logout Logout via Bearer header
# Exchange a Google access token for session tokens
curl -X POST http://localhost:3008/auth/mobile/token \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "google",
    "access_token": "ya29.a0AfH6..."
  }'

Response:

{
	"session_token": "sess_...",
	"refresh_token": "ref_...",
	"expires_in": 900,
	"refresh_expires_in": 2592000,
	"user": { "id": "...", "email": "..." }
}

SAML SSO

Method Endpoint Description
POST /auth/saml/:org_id/acs SAML Assertion Consumer Service (IdP posts here)
GET /auth/saml/:org_id/metadata SAML Service Provider metadata XML

Session Validation

Method Endpoint Description
GET /auth/validate Validate session cookie (used by gateway)
GET /me Get current user profile
GET /auth/phone/check?phone=... Check if phone exists

Gateway (`localhost:30000`)

Content Feeds

Method Endpoint Description
GET /sitemap.xml Sitemap index
GET /sitemap-malets.xml Malets sitemap
GET /sitemap-blogs.xml All blogs sitemap
GET /sitemap/m/:handle/blogs.xml Per-Malet blog sitemap
GET /rss/m/:handle/blogs.xml Per-Malet RSS 2.0+Atom feed
# Get RSS feed for a Malet
curl http://localhost:30000/rss/m/my-coffee-shop/blogs.xml

Admin Metrics

Method Endpoint Description Auth
GET /admin/metrics JSON metrics (operations, cache, errors) None (admin port)
GET /admin/metrics/prometheus Prometheus text format None (admin port)
# JSON metrics
curl http://localhost:30000/admin/metrics | jq .

# Prometheus format
curl http://localhost:30000/admin/metrics/prometheus

GraphQL

Method Endpoint Description
POST /graphql Federated GraphQL endpoint

See the GraphQL API guide for full details.


SCIM Service (`localhost:3019`)

SCIM 2.0 (RFC 7644) for enterprise user provisioning. Requires a SCIM bearer token generated via the Organizations GraphQL API.

Discovery

Method Endpoint Description
GET /scim/v2/ServiceProviderConfig SCIM capabilities
GET /scim/v2/Schemas Supported schemas
GET /scim/v2/ResourceTypes Resource type definitions

Users

Method Endpoint Description
GET /scim/v2/Users List provisioned users (supports filter)
GET /scim/v2/Users/:id Get user by ID
POST /scim/v2/Users Create (provision) user
PUT /scim/v2/Users/:id Replace user
PATCH /scim/v2/Users/:id Partial update (status, name)
DELETE /scim/v2/Users/:id Deprovision user
# List SCIM users (requires SCIM token)
curl http://localhost:3019/scim/v2/Users \
  -H "Authorization: Bearer scim_token_here"

# Filter by username
curl "http://localhost:3019/scim/v2/Users?filter=userName%20eq%20%22john%22" \
  -H "Authorization: Bearer scim_token_here"

Groups (Stub)

Method Endpoint Description
GET /scim/v2/Groups List groups (delegated to organizations service)

Auth Flow Summary

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Browser    โ”‚        โ”‚ Auth Service โ”‚       โ”‚   Gateway    โ”‚
โ”‚  (Frontend)  โ”‚        โ”‚  (:3008)     โ”‚       โ”‚  (:30000)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                       โ”‚                      โ”‚
       โ”‚  GET /auth/oauth/     โ”‚                      โ”‚
       โ”‚  google โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚                      โ”‚
       โ”‚                       โ”‚                      โ”‚
       โ”‚  <โ”€โ”€ redirect to โ”€โ”€โ”€โ”€โ”€โ”‚                      โ”‚
       โ”‚      Google           โ”‚                      โ”‚
       โ”‚                       โ”‚                      โ”‚
       โ”‚  callback + cookie โ”€โ”€>โ”‚                      โ”‚
       โ”‚  <โ”€โ”€ session_token โ”€โ”€โ”€โ”‚                      โ”‚
       โ”‚      (Set-Cookie)     โ”‚                      โ”‚
       โ”‚                       โ”‚                      โ”‚
       โ”‚  POST /graphql โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
       โ”‚  (Cookie: session_t)  โ”‚  GET /auth/validate  โ”‚
       โ”‚                       โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
       โ”‚                       โ”‚  {user_id, email}     โ”‚
       โ”‚                       โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
       โ”‚                       โ”‚                      โ”‚
       โ”‚  <โ”€โ”€ GraphQL responseโ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
       โ”‚                       โ”‚                      โ”‚

โ”€โ”€ API / CLI Flow โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  curl /  โ”‚            โ”‚ Auth Service โ”‚       โ”‚   Gateway    โ”‚
โ”‚ Postman  โ”‚            โ”‚  (:3008)     โ”‚       โ”‚  (:30000)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ”‚                         โ”‚                      โ”‚
     โ”‚ POST /auth/dev/token โ”€โ”€>โ”‚                      โ”‚
     โ”‚ {"email": "..."}        โ”‚                      โ”‚
     โ”‚ <โ”€โ”€ session_token โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                      โ”‚
     โ”‚                         โ”‚                      โ”‚
     โ”‚ POST /graphql โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
     โ”‚ (Bearer: session_t)     โ”‚  POST /validate-tokenโ”‚
     โ”‚                         โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
     โ”‚                         โ”‚  {user_id, email}     โ”‚
     โ”‚                         โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
     โ”‚                         โ”‚                      โ”‚
     โ”‚ <โ”€โ”€ GraphQL response โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚