API Endpoints
All paths are prefixed with your BasePath (default: /auth). Endpoints depend on which modules you register.
Every successful response is wrapped in the standard APIResponse envelope:
{
"data": { ... },
"message": "optional message"
}
Error responses use the same envelope with an error field:
{
"data": {
"code": "ERROR_CODE",
"message": "Human-readable message"
}
}
List endpoints return a ListResponse inside data:
{
"data": {
"list": [ ... ],
"sort_field": "created_at",
"sort_dir": "desc",
"total": 42
}
}
Core Module (auto-registered)​
The core module is always present. It handles user registration, profile management, password flows, and verification. Login/logout/refresh are provided by either the Session or Stateless module.
POST /signup — Register a new user
Request:
{
"email": "user@example.com",
"password": "SecurePassword123!",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"phone_number": "+1234567890"
}
Only email (or username) and password are required. The other fields are optional.
Success Response 201 Created:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"user": {
"id": "01961abc-...",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"phone_number": "+1234567890",
"active": true,
"email_verified": false,
"phone_number_verified": false,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": null
},
"message": "User registered successfully"
}
}
If the Two-Factor module is registered and the user has 2FA enabled, the response may include a challenges array instead of tokens (see Two-Factor Module).
Error 400: validation errors (email already exists, password policy violation, etc.)
GET /me — Get current user Auth
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": {
"id": "01961abc-...",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"avatar": "https://example.com/avatar.png",
"phone_number": "+1234567890",
"active": true,
"email_verified": true,
"phone_number_verified": false,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-15T00:00:00Z",
"last_login_at": "2025-01-20T10:30:00Z"
}
}
PUT /profile — Update profile Auth
Headers: Authorization: Bearer <access_token>
Request:
{
"name": "Jane Doe",
"phone": "+9876543210",
"avatar": "https://example.com/new-avatar.png"
}
All fields are optional. phone is validated in E.164 format. avatar must be a valid URL.
Response 200:
{
"data": {
"id": "01961abc-...",
"email": "user@example.com",
"name": "Jane Doe",
"phone_number": "+9876543210",
"avatar": "https://example.com/new-avatar.png",
"active": true,
"email_verified": true,
"phone_number_verified": false,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-20T12:00:00Z"
}
}
PUT /change-password — Change password Auth
Headers: Authorization: Bearer <access_token>
Request:
{
"old_password": "OldPassword123!",
"new_password": "NewPassword456!"
}
Both fields are required. New password must be at least 8 characters and different from the old password.
Response 200:
{
"data": {
"message": "Password changed successfully"
}
}
POST /is-available — Check availability
Check whether an email, username, or phone number is already taken. Provide exactly one of the three fields.
Request (email):
{"email": "newuser@example.com"}
Request (username):
{"username": "johndoe"}
Request (phone):
{"phone": "+1234567890"}
Response 200:
{
"data": {
"available": true,
"field": "email",
"message": "email is available"
}
}
POST /forgot-password — Request password reset
Request:
{"email": "user@example.com"}
Or by phone:
{"phone": "+1234567890"}
Response 200:
{
"data": {
"message": "Password reset email sent"
}
}
POST /reset-password — Reset password with token or code
Request (token-based, from email link):
{
"token": "reset-token-from-email",
"email": "user@example.com",
"new_password": "NewPassword456!"
}
Request (code-based, from SMS):
{
"code": "123456",
"phone": "+1234567890",
"new_password": "NewPassword456!"
}
Either token or code is required, along with the corresponding email or phone.
Response 200:
{
"data": {
"message": "Password reset successfully"
}
}
POST /send-verification-email — Send verification email
Request:
{"email": "user@example.com"}
Response 200:
{
"data": {
"message": "Verification email sent"
}
}
POST /resend-verification-email — Resend verification email
Request:
{"email": "user@example.com"}
Same as /send-verification-email but intended for resend flows.
GET /verify-email?token=...&email=... — Verify email
Called from the email verification link. Redirects to FrontendConfig.VerifyEmailCallbackPath with ?status=success or ?status=error.
Falls back to a JSON response if FrontendConfig is not set.
POST /send-verification-phone — Send phone verification SMS
Request:
{"phone": "+1234567890"}
Requires the Notification module with an SMS sender configured.
POST /resend-verification-phone — Resend phone verification SMS
Request:
{"phone": "+1234567890"}
POST /verify-phone — Verify phone number
Request:
{
"phone": "+1234567890",
"code": "123456"
}
Code must be exactly 6 digits.
Response 200:
{
"data": {
"message": "Phone number verified successfully"
}
}
Session Module​
Requires session.New(...). Mutually exclusive with the Stateless module.
POST /login — Login (create session)
Request:
{
"email": "user@example.com",
"password": "SecurePassword123!"
}
Or login by username:
{
"username": "johndoe",
"password": "SecurePassword123!"
}
Success Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"user": {
"id": "01961abc-...",
"email": "user@example.com",
"name": "John Doe",
"active": true,
"email_verified": true,
"phone_number_verified": false,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-15T00:00:00Z"
},
"message": "Login successful"
}
}
If the Two-Factor module is registered and the user has 2FA enabled, the response will contain a challenges array instead of tokens:
{
"data": {
"user": { ... },
"challenges": [
{
"type": "2fa",
"data": {
"requires_2fa": true,
"temp_token": "eyJhbGciOi...",
"user_id": "01961abc-...",
"message": "Two-factor authentication required. Please provide your 2FA code."
}
}
],
"message": "Login requires additional verification"
}
}
POST /logout — Logout (end session) Auth
Headers: Authorization: Bearer <access_token>
Ends the current session.
Response 200:
{
"data": {
"message": "Logged out successfully"
}
}
POST /refresh — Refresh tokens
Request:
{"refresh_token": "eyJhbGciOi..."}
Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"message": "Token refreshed successfully"
}
}
GET /sessions — List sessions Auth
Headers: Authorization: Bearer <access_token>
Returns all active sessions for the authenticated user.
Response 200:
{
"data": [
{
"id": "sess-01961abc-...",
"user_agent": "Mozilla/5.0...",
"ip_address": "192.168.1.1",
"created_at": "2025-01-01T00:00:00Z",
"expires_at": "2025-01-02T00:00:00Z",
"current": true
},
{
"id": "sess-01961def-...",
"user_agent": "Chrome/120...",
"ip_address": "10.0.0.1",
"created_at": "2025-01-01T12:00:00Z",
"expires_at": "2025-01-02T12:00:00Z",
"current": false
}
]
}
GET /sessions/{session_id} — Get session Auth
Headers: Authorization: Bearer <access_token>
Returns details for a specific session.
Response 200:
{
"data": {
"id": "sess-01961abc-...",
"user_agent": "Mozilla/5.0...",
"ip_address": "192.168.1.1",
"created_at": "2025-01-01T00:00:00Z",
"expires_at": "2025-01-02T00:00:00Z",
"current": false
}
}
DELETE /sessions/{session_id} — Revoke session Auth
Headers: Authorization: Bearer <access_token>
Revokes a specific session by ID.
Response 200:
{
"data": {
"message": "Session revoked successfully"
}
}
DELETE /sessions — Revoke all sessions Auth
Headers: Authorization: Bearer <access_token>
Revokes all sessions except the current one.
Response 200:
{
"data": {
"message": "All other sessions revoked"
}
}
Stateless Module​
Default if no auth module is registered. Or register explicitly with stateless.New(...). Mutually exclusive with Session module.
POST /login — Login (JWT tokens)
Request:
{
"email": "user@example.com",
"password": "SecurePassword123!"
}
Or login by username:
{
"username": "johndoe",
"password": "SecurePassword123!"
}
Success Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"user": {
"id": "01961abc-...",
"email": "user@example.com",
"name": "John Doe",
"active": true,
"email_verified": true,
"phone_number_verified": false,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-15T00:00:00Z"
},
"message": "Login successful"
}
}
If the Two-Factor module is registered and the user has 2FA enabled, the response includes challenges instead (see Session module login for shape).
POST /logout — Blacklist token Auth
Headers: Authorization: Bearer <access_token>
Blacklists the current access token.
Response 200:
{
"data": {
"message": "Logged out successfully"
}
}
POST /refresh — Refresh tokens
Request:
{"refresh_token": "eyJhbGciOi..."}
Returns a new access token. If RefreshTokenRotation: true (the default), a new refresh token is also issued and the old one is invalidated.
Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"message": "Token refreshed successfully"
}
}
Two-Factor Module​
Requires twofactor.New(...).
POST /2fa/setup — Start 2FA setup Auth
Headers: Authorization: Bearer <access_token>
Generates a TOTP secret, QR code URL, and backup codes. The user must verify with a code before 2FA is enabled.
Response 200:
{
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"qr_url": "otpauth://totp/GoAuth:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GoAuth",
"backup_codes": ["A1B2C3D4", "E5F6G7H8", "..."],
"message": "Scan the QR code with your authenticator app, then verify with a code to enable 2FA"
}
}
POST /2fa/verify — Verify and enable 2FA Auth
Headers: Authorization: Bearer <access_token>
Verifies a TOTP code against the pending secret and enables 2FA.
Request:
{"code": "123456"}
Response 200:
{
"data": {
"message": "Two-factor authentication enabled successfully"
}
}
POST /2fa/disable — Disable 2FA Auth
Headers: Authorization: Bearer <access_token>
Requires a current TOTP code for verification before disabling.
Request:
{"code": "123456"}
Response 200:
{
"data": {
"message": "Two-factor authentication disabled successfully"
}
}
GET /2fa/status — Get 2FA status Auth
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": {
"enabled": true,
"method": "totp"
}
}
When 2FA is not enabled, method is an empty string.
POST /2fa/verify-login — Complete login with 2FA
Called after login returns a challenges array with type: "2fa". No auth header required -- uses temp_token from the challenge data.
Request:
{
"temp_token": "eyJhbGciOi...",
"code": "123456"
}
The code can be a TOTP code or a backup code.
Success Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"user": {
"id": "01961abc-...",
"email": "user@example.com"
}
}
}
OAuth Module​
Requires oauth.New(...) with configured providers and APIURL set in config.
GET /oauth/{provider} — Start OAuth flow
Redirects the user to the OAuth provider's consent screen.
Supported providers: google, github, facebook, microsoft, apple, discord
GET /oauth/{provider}/callback — OAuth callback
Handles the provider callback. Creates or links the user account, then:
- Redirects to
DefaultRedirectURLwith tokens in the URL fragment:#access_token=xxx&refresh_token=xxx - Or returns a JSON response if no redirect URL is configured:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"token_type": "Bearer",
"user": {
"id": "01961abc-...",
"email": "user@gmail.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"avatar": "https://lh3.googleusercontent.com/...",
"email_verified": true,
"active": true,
"created_at": "2025-01-01T00:00:00Z"
},
"is_new_user": false,
"provider": "google"
}
}
DELETE /oauth/{provider} — Unlink provider Auth
Headers: Authorization: Bearer <access_token>
Unlinks an OAuth provider from the user's account.
Response 200:
{
"data": {
"message": "Provider unlinked successfully"
}
}
GET /oauth/providers — List available providers
Response 200:
{
"data": {
"providers": [
{"name": "google", "enabled": true},
{"name": "github", "enabled": true}
]
}
}
GET /oauth/linked — List linked providers Auth
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": {
"providers": ["google", "github"]
}
}
Admin Module​
Requires admin.New(...). All routes require auth + admin middleware.
GET /admin/users — List users Admin
Headers: Authorization: Bearer <access_token>
Query Parameters:
| Param | Default | Description |
|---|---|---|
offset | 0 | Number of records to skip |
limit | 20 | Max records to return (max 100) |
sort_field | created_at | Sort by: created_at, email, username, name |
sort_dir | desc | Sort direction: asc or desc |
query | Search by name, email, or username |
Response 200:
{
"data": {
"list": [
{
"id": "01961abc-...",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"avatar": "",
"phone_number": "+1234567890",
"active": true,
"email_verified": true,
"phone_number_verified": false,
"is_super_admin": false,
"token_version": 1,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-15T00:00:00Z",
"last_login_at": "2025-01-20T10:30:00Z"
}
],
"sort_field": "created_at",
"sort_dir": "desc",
"total": 42
}
}
GET /admin/users/{id} — Get user Admin
Headers: Authorization: Bearer <access_token>
Returns full user details including admin-only fields (is_super_admin, token_version).
Response 200:
{
"data": {
"id": "01961abc-...",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"avatar": "",
"phone_number": "+1234567890",
"active": true,
"email_verified": true,
"phone_number_verified": false,
"is_super_admin": false,
"token_version": 1,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-15T00:00:00Z",
"last_login_at": "2025-01-20T10:30:00Z"
}
}
PUT /admin/users/{id} — Update user Admin
Headers: Authorization: Bearer <access_token>
All fields are optional (use JSON null or omit). At least one field must be provided.
Request:
{
"first_name": "Jane",
"last_name": "Smith",
"name": "Jane Smith",
"email": "jane@example.com",
"username": "janesmith",
"avatar": "https://example.com/avatar.png",
"phone_number": "+9876543210",
"active": false,
"email_verified": true,
"phone_number_verified": false,
"is_super_admin": false
}
Response 200:
{
"data": {
"message": "User updated successfully"
}
}
DELETE /admin/users/{id} — Delete user Admin
Headers: Authorization: Bearer <access_token>
Permanently deletes the user.
Response 200:
{
"data": {
"message": "User deleted successfully"
}
}
Audit Module​
Requires audit.New(...).
User self-service routes​
GET /me/audit — My audit logs Auth
Headers: Authorization: Bearer <access_token>
Query Parameters:
| Param | Default | Description |
|---|---|---|
offset | 0 | Number of records to skip |
limit | 20 | Max records to return (max 100) |
sort_field | created_at | Sort by: created_at, action, severity, actor_id |
sort_dir | desc | Sort direction: asc or desc |
Response 200:
{
"data": {
"list": [
{
"id": "01961abc-...",
"action": "auth.login.success",
"actor_id": "01961abc-...",
"actor_type": "user",
"severity": "info",
"details": "Action: auth.login.success",
"metadata": "{...}",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"created_at": "2025-01-20T10:30:00Z"
}
],
"sort_field": "created_at",
"sort_dir": "desc",
"total": 15
}
}
GET /me/audit/logins — My login history Auth
Headers: Authorization: Bearer <access_token>
Returns login-related audit events for the authenticated user. Same query parameters and response shape as /me/audit.
GET /me/audit/changes — My profile changes Auth
Headers: Authorization: Bearer <access_token>
Returns profile update events. Same query parameters and response shape as /me/audit.
GET /me/audit/security — My security events Auth
Headers: Authorization: Bearer <access_token>
Returns security-related events (2FA changes, password changes, etc.). Same query parameters and response shape as /me/audit.
Admin audit routes​
GET /admin/audit — All audit logs Admin
Headers: Authorization: Bearer <access_token>
Returns all audit logs across all users. Same query parameters and response shape as /me/audit.
GET /admin/audit/users/{id} — User audit logs Admin
Headers: Authorization: Bearer <access_token>
Returns audit logs for a specific user. Same query parameters and response shape as /me/audit.
GET /admin/audit/actions/{action} — Logs by action Admin
Headers: Authorization: Bearer <access_token>
Returns audit logs filtered by action type (e.g., auth.login.success, auth.password.changed). Same query parameters and response shape as /me/audit.
POST /admin/audit/cleanup — Cleanup old logs Admin
Headers: Authorization: Bearer <access_token>
Triggers manual cleanup of old audit logs based on retention policy.
Response 200:
{
"data": {
"message": "Audit logs cleaned up successfully"
}
}
Magic Link Module​
Requires magiclink.New(...) and the Notification module.
POST /magic-link/send — Send magic link
Request:
{"email": "user@example.com"}
Sends an email with a magic link. If AutoRegister: true, creates a new user if the email does not exist.
Response 200:
{
"data": {
"message": "Magic link sent"
}
}
GET /magic-link/verify?token=... — Verify magic link
Called from the email link. Verifies the token and either:
- Redirects to
CallbackURLwith tokens in the URL fragment:#access_token=xxx&refresh_token=xxx - Or returns a JSON auth response if no callback URL is configured
POST /magic-link/verify-code — Verify by code
For mobile apps -- verifies using the numeric code from the email.
Request:
{"email": "user@example.com", "code": "123456"}
Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi...",
"expires_in": 900,
"user": {
"id": "01961abc-...",
"email": "user@example.com"
}
}
}
POST /magic-link/resend — Resend magic link
Request:
{"email": "user@example.com"}
Response 200:
{
"data": {
"message": "Magic link sent"
}
}
CSRF Module​
Requires csrf.New(...).
GET /csrf-token — Get CSRF token
Response 200:
{
"data": {
"csrf_token": "hmac-signed-token"
}
}
Also sets a cookie (default name: __goauth_csrf) with HttpOnly: false so client JavaScript can read it.
Include the token in the X-CSRF-Token header for state-changing requests (POST, PUT, DELETE, PATCH). The CSRF middleware validates the header token against the cookie automatically.
Invitation Module​
Standalone platform invitations. For org-scoped invitations, see the Organization Module below.
Authenticated routes​
POST /invitations — Send invitation Auth
Headers: Authorization: Bearer <access_token>
Request:
{
"email": "invitee@example.com",
"purpose": "beta",
"metadata": "{\"referral_code\": \"ABC123\"}"
}
purpose defaults to "platform". metadata is optional.
Response 201:
{
"data": {
"id": "01961abc-...",
"email": "invitee@example.com",
"purpose": "beta",
"inviter_id": "01961def-...",
"status": "pending",
"expires_at": "2025-01-09T00:00:00Z",
"created_at": "2025-01-02T00:00:00Z"
}
}
GET /invitations — List sent invitations Auth
Lists invitations sent by the authenticated user. Supports ?status=pending&purpose=beta&limit=20&offset=0&sort_field=created_at&sort_dir=desc.
GET /invitations/my — My pending invitations Auth
Returns pending invitations for the authenticated user's email.
DELETE /invitations/{invId} — Cancel invitation Auth
Only the inviter can cancel their own invitations.
Public routes (no auth required)​
POST /invitations/accept — Accept invitation Public
No authentication required. The invitation token is the authorization. If the invited email has no account, provide name and password to create one.
Request:
{
"token": "invitation-token-from-email",
"name": "John Doe",
"password": "securepassword123"
}
name and password are only required when the invited email has no existing account.
Response 200:
{
"data": {
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"user": {
"id": "01961abc-...",
"email": "invitee@example.com",
"name": "John Doe",
"email_verified": true
},
"is_new_user": true
}
}
POST /invitations/decline — Decline invitation Public
No authentication required.
Request:
{"token": "invitation-token-from-email"}
Response 200:
{"data": null}
Organization Module​
Requires organization.New(...).
User-level routes (no org context)​
POST /org — Create organization Auth
Headers: Authorization: Bearer <access_token>
Request:
{
"name": "Acme Inc",
"slug": "acme-inc"
}
slug is optional -- auto-generated from name if omitted. Must be lowercase alphanumeric with hyphens, 2-64 characters.
Response 201:
{
"data": {
"id": "01961abc-...",
"name": "Acme Inc",
"slug": "acme-inc",
"owner_id": "01961abc-...",
"active": true,
"created_at": "2025-01-01T00:00:00Z"
}
}
GET /org/my — List my organizations Auth
Headers: Authorization: Bearer <access_token>
Returns all organizations the authenticated user is a member of.
Response 200:
{
"data": [
{
"id": "01961abc-...",
"name": "Acme Inc",
"slug": "acme-inc",
"owner_id": "01961abc-...",
"active": true,
"created_at": "2025-01-01T00:00:00Z"
}
]
}
POST /org/switch — Switch active organization Auth
Headers: Authorization: Bearer <access_token>
Switches the active organization context. Returns new tokens with the organization claims embedded.
Request:
{"org_id": "01961abc-..."}
Response 200:
{
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "eyJhbGciOi..."
}
}
GET /org/my/invitations — My pending invitations Auth
Headers: Authorization: Bearer <access_token>
Returns pending invitations for the authenticated user.
Response 200:
{
"data": [
{
"id": "01961abc-...",
"org_id": "01961def-...",
"email": "user@example.com",
"role": "member",
"inviter_id": "01961ghi-...",
"status": "pending",
"expires_at": "2025-01-08T00:00:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
POST /org/invitations/accept — Accept org invitation Public
No authentication required. The invitation token is the authorization. If the invited email has no account, provide name and password to create one.
Request:
{
"token": "invitation-token-from-email",
"name": "John Doe",
"password": "securepassword123"
}
name and password are only required when the invited email has no existing account.
Response 200:
{
"data": {
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"user": {
"id": "01961abc-...",
"email": "john@example.com",
"name": "John Doe",
"email_verified": true
},
"member": {
"id": "01961def-...",
"org_id": "01961ghi-...",
"user_id": "01961abc-...",
"role": "member",
"joined_at": "2025-01-02T00:00:00Z"
},
"is_new_user": true
}
}
POST /org/invitations/decline — Decline org invitation Public
No authentication required.
Request:
{"token": "invitation-token-from-email"}
Response 200:
{
"data": null
}
Org-scoped routes (require org membership)​
These routes require the org auth middleware, which verifies the user is a member of the specified organization.
GET /org/{orgId} — Get organization Auth Org
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": {
"id": "01961abc-...",
"name": "Acme Inc",
"slug": "acme-inc",
"owner_id": "01961abc-...",
"logo_url": "https://example.com/logo.png",
"metadata": "{\"plan\": \"pro\"}",
"active": true,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-15T00:00:00Z"
}
}
PUT /org/{orgId} — Update organization Auth Org
Headers: Authorization: Bearer <access_token>
At least one field must be provided.
Request:
{
"name": "Acme Corp",
"logo_url": "https://example.com/new-logo.png",
"metadata": "{\"plan\": \"enterprise\"}"
}
Response 200:
{
"data": {
"id": "01961abc-...",
"name": "Acme Corp",
"slug": "acme-inc",
"owner_id": "01961abc-...",
"logo_url": "https://example.com/new-logo.png",
"metadata": "{\"plan\": \"enterprise\"}",
"active": true,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-20T12:00:00Z"
}
}
DELETE /org/{orgId} — Delete organization Auth Org
Headers: Authorization: Bearer <access_token>
Permanently deletes the organization. Requires owner role.
Response 200:
{
"data": {
"message": "Organization deleted"
}
}
GET /org/{orgId}/members — List members Auth Org
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": [
{
"id": "01961abc-...",
"org_id": "01961def-...",
"user_id": "01961ghi-...",
"role": "owner",
"joined_at": "2025-01-01T00:00:00Z",
"user": {
"id": "01961ghi-...",
"name": "John Doe",
"email": "john@example.com",
"username": "johndoe",
"avatar": "",
"active": true,
"email_verified": true,
"created_at": "2025-01-01T00:00:00Z"
}
}
]
}
GET /org/{orgId}/members/{userId} — Get member Auth Org
Headers: Authorization: Bearer <access_token>
Returns a specific member with their user details. Same shape as a single item in the list above.
PUT /org/{orgId}/members/{userId} — Update member role Auth Org
Headers: Authorization: Bearer <access_token>
Request:
{"role": "admin"}
Valid roles: owner, admin, member.
Response 200:
{
"data": {
"message": "Member role updated"
}
}
DELETE /org/{orgId}/members/{userId} — Remove member Auth Org
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": {
"message": "Member removed"
}
}
POST /org/{orgId}/invite — Invite member Auth Org
Headers: Authorization: Bearer <access_token>
Request:
{
"email": "newmember@example.com",
"role": "member"
}
role is optional (defaults to member). Valid values: owner, admin, member.
Response 201:
{
"data": {
"id": "01961abc-...",
"org_id": "01961def-...",
"email": "newmember@example.com",
"role": "member",
"inviter_id": "01961ghi-...",
"status": "pending",
"expires_at": "2025-01-08T00:00:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
}
GET /org/{orgId}/invitations — List invitations Auth Org
Headers: Authorization: Bearer <access_token>
Returns all invitations for the organization.
Response 200:
{
"data": [
{
"id": "01961abc-...",
"org_id": "01961def-...",
"email": "newmember@example.com",
"role": "member",
"inviter_id": "01961ghi-...",
"status": "pending",
"expires_at": "2025-01-08T00:00:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
DELETE /org/{orgId}/invitations/{invId} — Cancel invitation Auth Org
Headers: Authorization: Bearer <access_token>
Response 200:
{
"data": {
"message": "Invitation cancelled"
}
}
Authentication​
Protected endpoints (marked with Auth) require:
Authorization: Bearer <access_token>
Get tokens from the /login endpoint (Session or Stateless module). Refresh expired tokens via /refresh.
Admin endpoints (marked with Admin) additionally require the is_super_admin flag on the user account.
Org endpoints (marked with Org) additionally require the user to be a member of the specified organization.