Skip to content

API Reference

Complete API reference for GrydAuth endpoints.

Base URL

https://your-api.com/api

Authentication

Most endpoints require authentication via Bearer token:

http
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Auth Endpoints

Login

Authenticate a user and obtain tokens.

http
POST /api/auth/login

Headers:

HeaderRequiredDescription
X-App-IdNoApplication ID for app-specific access validation

Request Body:

FieldTypeRequiredDescription
emailstringYesUser email
passwordstringYesUser password
isPasswordEncryptedbooleanNoIf true, password is already encrypted (default: true)
preferredTenantIdguidNoPreferred tenant for multi-tenant login
requestedAppIdstringNoSet automatically from X-App-Id header

Example:

json
{
  "email": "user@example.com",
  "password": "Password123!",
  "isPasswordEncrypted": false,
  "preferredTenantId": "550e8400-e29b-41d4-a716-446655440001"
}

Response (200):

json
{
  "isSuccess": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2g...",
    "expiresAt": "2026-01-29T13:00:00Z",
    "permissions": ["read:products", "update:products"],
    "isFirstLogin": false,
    "mustChangePassword": false,
    "daysUntilPasswordExpiration": null,
    "isGlobal": false,
    "requiresTenantSelection": false,
    "tokenType": "Tenant",
    "currentTenant": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Acme Corp",
      "isDefault": true,
      "permissions": ["read:products"]
    },
    "smartAutoSwitched": true
  }
}

Multi-Tenant Login Flow

When isGlobal: true and requiresTenantSelection: true:

  1. User has access to multiple tenants
  2. Token is a Global Token (2 minutes TTL, restricted access)
  3. Use POST /api/auth/switch-tenant to select a tenant
  4. Receive a full Tenant Token (60 minutes TTL)

Error Responses:

StatusCodeDescription
401INVALID_CREDENTIALSInvalid email or password
401ACCOUNT_LOCKEDAccount locked
401ACCOUNT_DISABLEDAccount disabled
401EMAIL_NOT_CONFIRMEDEmail not confirmed

Social Login

Authenticate using a social provider (Auth0, Google, etc.).

http
POST /api/auth/social-login

Headers:

HeaderRequiredDescription
X-App-IdNoApplication ID for app-specific access validation

Request Body:

json
{
  "provider": "google",
  "accessToken": "ya29.a0AfH6SM...",
  "preferredTenantId": "550e8400-e29b-41d4-a716-446655440001"
}

Register

Create a new user account.

http
POST /api/auth/register

Request Body:

FieldTypeRequiredDescription
emailstringYesUser email
passwordstringYesPassword (min 8 chars)
fullNamestringYesFull name
phoneNumberstringNoPhone number

Response (201):

json
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "email": "newuser@example.com",
    "fullName": "Jane Doe",
    "createdAt": "2026-01-29T12:00:00Z"
  }
}

Refresh Token

Exchange refresh token for new tokens.

http
POST /api/auth/refresh

Request Body:

FieldTypeRequiredDescription
refreshTokenstringYesThe refresh token from login
tenantIdguidNoTarget tenant ID (for tenant switching during refresh)
json
{
  "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2g..."
}

Response (200):

json
{
  "isSuccess": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "bmV3IHJlZnJlc2ggdG9rZW4...",
    "expiresAt": "2026-01-29T14:00:00Z",
    "permissions": ["read:products"],
    "isGlobal": false,
    "tokenType": "Tenant"
  }
}

Logout

Invalidate current session and all user tokens.

http
POST /api/auth/logout
Authorization: Bearer {token}

Simplified OAuth 2.0 Logout

GrydAuth follows OAuth 2.0 RFC 7009 best practices:

  • No request body required - All info extracted from Authorization header
  • Global logout only - Invalidates ALL user sessions using timestamp-based blacklist
  • Secure by design - Doesn't expose refresh token in requests

Response (200):

json
{
  "isSuccess": true,
  "message": "Logged out successfully"
}

Switch Tenant

Switch to a different tenant context. Works with both Global Tokens (first-time selection) and Tenant Tokens (switching between tenants).

http
POST /api/auth/switch-tenant
Authorization: Bearer {token}

Request Body:

json
{
  "tenantId": "550e8400-e29b-41d4-a716-446655440002"
}

Response (200):

json
{
  "isSuccess": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "bmV3IHJlZnJlc2ggdG9rZW4...",
    "expiresAt": "2026-01-29T14:00:00Z",
    "isGlobal": false,
    "tokenType": "Tenant",
    "currentTenant": {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "New Tenant",
      "isDefault": false
    }
  }
}

Get Current User

Get authenticated user information.

http
GET /api/auth/me
Authorization: Bearer {token}

Query Parameters:

ParameterTypeDescription
includestringUse profile for complete user data from database

Response (200) - Basic (from JWT token, no DB access):

json
{
  "isSuccess": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "John Doe",
    "email": "user@example.com",
    "roles": ["User", "Manager"],
    "permissions": ["read:products", "update:products"]
  }
}

Response (200) - With ?include=profile (from database, cached 30min):

json
{
  "isSuccess": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "fullName": "John Doe",
    "phoneNumber": "+1234567890",
    "profilePictureUrl": "https://...",
    "emailConfirmed": true,
    "roles": ["User", "Manager"],
    "permissions": ["read:products", "update:products"],
    "tenants": [
      {
        "id": "tenant-1",
        "name": "Acme Corp",
        "isDefault": true
      }
    ],
    "createdAt": "2026-01-01T00:00:00Z",
    "lastLoginAt": "2026-01-29T10:00:00Z"
  }
}

Get Complete User Profile

Alias for GET /api/auth/me?include=profile. Returns complete user data.

http
GET /api/auth/me/complete
Authorization: Bearer {token}

Request Password Reset

Request a password reset email.

http
POST /api/auth/request-password-reset

Request Body:

json
{
  "email": "user@example.com"
}

Reset Password

Complete password reset with token from email.

http
POST /api/auth/reset-password

Request Body:

json
{
  "email": "user@example.com",
  "token": "reset-token-from-email",
  "newPassword": "NewPassword789!"
}

Users Endpoints

Note on User Endpoints

The current user info is now available via GET /api/auth/me. The /api/users endpoints are for administrative user management.

List Users (Admin)

http
GET /api/users
Authorization: Bearer {admin-token}

Required Permission: read:users

Query Parameters:

ParameterTypeDescription
pageintPage number (default: 1)
pageSizeintItems per page (default: 20, max: 100)
searchstringSearch by name or email
rolestringFilter by role
isActiveboolFilter by status
sortBystringSort field
sortDirectionstringasc or desc

Response (200):

json
{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "user@example.com",
      "fullName": "John Doe",
      "roles": ["User"],
      "isActive": true,
      "createdAt": "2026-01-01T00:00:00Z"
    }
  ],
  "totalCount": 150,
  "page": 1,
  "pageSize": 20,
  "totalPages": 8
}

Get User by ID (Admin)

http
GET /api/users/{id}
Authorization: Bearer {admin-token}

Required Permission: read:users


Create User (Admin)

http
POST /api/users
Authorization: Bearer {admin-token}

Required Permission: create:users

Request Body:

json
{
  "email": "newuser@example.com",
  "password": "TempPassword123!",
  "fullName": "New User",
  "roles": ["User"],
  "sendWelcomeEmail": true
}

Update User (Admin)

http
PUT /api/users/{id}
Authorization: Bearer {admin-token}

Required Permission: update:users


Delete User (Admin)

http
DELETE /api/users/{id}
Authorization: Bearer {admin-token}

Required Permission: delete:users


Roles Endpoints

List Roles

http
GET /api/roles
Authorization: Bearer {admin-token}

Required Permission: read:roles

Response (200):

json
{
  "items": [
    {
      "id": "role-1",
      "name": "Admin",
      "description": "Administrator role",
      "permissions": ["*"],
      "userCount": 5
    },
    {
      "id": "role-2",
      "name": "User",
      "description": "Standard user",
      "permissions": ["read:products"],
      "userCount": 150
    }
  ]
}

Create Role

http
POST /api/roles
Authorization: Bearer {admin-token}

Required Permission: create:roles

Request Body:

json
{
  "name": "Manager",
  "description": "Department manager",
  "permissions": [
    "read:products",
    "create:products",
    "update:products",
    "read:reports"
  ]
}

Update Role

http
PUT /api/roles/{id}
Authorization: Bearer {admin-token}

Required Permission: update:roles


Delete Role

http
DELETE /api/roles/{id}
Authorization: Bearer {admin-token}

Required Permission: delete:roles


Assign Role to User

http
POST /api/users/{userId}/roles
Authorization: Bearer {admin-token}

Required Permission: update:users

Request Body:

json
{
  "roleNames": ["Manager", "User"]
}

Permissions Endpoints

List Permissions

http
GET /api/permissions
Authorization: Bearer {admin-token}

Required Permission: read:permissions

Response (200):

json
{
  "items": [
    {
      "id": "perm-1",
      "name": "create:products",
      "description": "Create new products",
      "category": "Products"
    },
    {
      "id": "perm-2",
      "name": "read:products",
      "description": "View products",
      "category": "Products"
    }
  ]
}

Create Permission

http
POST /api/permissions
Authorization: Bearer {admin-token}

Required Permission: create:permissions

Request Body:

json
{
  "name": "export:reports",
  "description": "Export reports to PDF/Excel",
  "category": "Reports"
}

Tenants Endpoints

List Tenants (Super Admin)

http
GET /api/tenants
Authorization: Bearer {super-admin-token}

Required Permission: read:tenants


Create Tenant (Super Admin)

http
POST /api/tenants
Authorization: Bearer {super-admin-token}

Required Permission: create:tenants

Request Body:

json
{
  "name": "New Company",
  "identifier": "newcompany",
  "domain": "newcompany.yourapp.com",
  "settings": {
    "timezone": "America/New_York",
    "language": "en-US"
  }
}

Get Current Tenant

http
GET /api/tenants/current
Authorization: Bearer {token}

Tenant Switching

Tenant switching is done via POST /api/auth/switch-tenant - see Auth Endpoints.


Error Response Format

All error responses follow this format:

json
{
  "isSuccess": false,
  "errorCode": "ERROR_CODE",
  "errorMessage": "Human-readable error message",
  "errors": [
    {
      "field": "email",
      "message": "Invalid email format"
    }
  ]
}

Common Error Codes

CodeHTTP StatusDescription
VALIDATION_ERROR400Request validation failed
INVALID_CREDENTIALS401Invalid email or password
TOKEN_EXPIRED401Access token has expired
TOKEN_INVALID401Token is invalid
UNAUTHORIZED401Authentication required
FORBIDDEN403Permission denied
NOT_FOUND404Resource not found
CONFLICT409Resource already exists
ACCOUNT_LOCKED423Account is locked
RATE_LIMITED429Too many requests
INTERNAL_ERROR500Internal server error

Rate Limits

EndpointLimit
/api/auth/login10 requests/minute
/api/auth/register5 requests/minute
/api/auth/request-password-reset3 requests/minute
Other endpoints100 requests/minute

Pagination

Paginated endpoints support these query parameters:

ParameterTypeDefaultMax
pageint1-
pageSizeint20100
sortBystringvaries-
sortDirectionstringasc-

Released under the MIT License.