Tenant Resolution & Routing
Every request to the ValidonX API must be resolved to a specific tenant. This document explains how tenant resolution works and what headers are required.
Resolution Paths
Path 1: API Key Resolution (Integration API)
Used for: /v1/integration/* endpoints (license validation, activation, entitlements, usage)
Client → X-API-Key header → HMAC-SHA256 hash → api_keys table lookup → tenantRequired header: X-API-Key: VX-xxxxx...
The middleware:
- Extracts
X-API-Keyfrom the request header - Hashes it with HMAC-SHA256 using the application key
- Looks up the hash in the
api_keystable - Validates the key is active and the tenant is active
- Switches the database connection to the tenant's database
- Binds the tenant to the request
Error responses:
401 AUTH.INVALID_API_KEY— missing, invalid, or revoked key403 TENANT.STATUS.SUSPENDED— tenant is suspended
Path 2: User-Based Resolution (Tenant API)
Used for: /v1/tenant/*, /v1/billing/* endpoints
Client → Bearer token → Sanctum auth → user's tenants → X-Tenant-ID (if multiple)Required header: Authorization: Bearer <token>Optional header: X-Tenant-ID: <uuid> (required if user belongs to multiple tenants)
The middleware:
- Authenticates via Sanctum (
auth:sanctum) - Loads the user's active tenants via the
tenant_userpivot - If single tenant: auto-selects it
- If multiple tenants: requires
X-Tenant-IDheader - Validates the selected tenant is active
- Switches the database connection
Common Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Integration API | Tenant API key |
Authorization | Tenant/Admin API | Bearer <token> |
X-Tenant-ID | Multi-tenant users | UUID of target tenant |
X-Request-ID | Optional | Request correlation ID (auto-generated if absent) |
Rate Limit Headers (Response)
All Integration API responses include:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests in current window |
X-RateLimit-Remaining | Requests remaining |
X-RateLimit-Reset | Unix timestamp when window resets |
Retry-After | Seconds to wait (429 responses only) |