Skip to main content

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​

info

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​

info

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​

info

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​

info

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 DefaultRedirectURL with 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​

info

Requires admin.New(...). All routes require auth + admin middleware.

GET /admin/users — List users Admin

Headers: Authorization: Bearer <access_token>

Query Parameters:

ParamDefaultDescription
offset0Number of records to skip
limit20Max records to return (max 100)
sort_fieldcreated_atSort by: created_at, email, username, name
sort_dirdescSort direction: asc or desc
querySearch 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​

info

Requires audit.New(...).

User self-service routes​

GET /me/audit — My audit logs Auth

Headers: Authorization: Bearer <access_token>

Query Parameters:

ParamDefaultDescription
offset0Number of records to skip
limit20Max records to return (max 100)
sort_fieldcreated_atSort by: created_at, action, severity, actor_id
sort_dirdescSort 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"
}
}

info

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 CallbackURL with 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​

info

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​

info

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.