Platform API Reference
The Platform Backend provides the foundational SaaS services: authentication, user management, organization management, billing, and configuration.
Base URL: https://gateway.trueportai.com/platform/api
Authentication
The Platform API uses JWT Bearer tokens issued via the auth endpoints. There are two token types:
Token Type |
Scope |
Claims |
|---|---|---|
Global JWT |
Cross-tenant actions (list orgs, register) |
|
Scoped JWT |
Tenant-specific actions |
|
Global Auth Endpoints
Base path: /platform/api/global/auth
POST /register
Create a new user account.
Request Body:
{
"email": "dev@acme.com",
"password": "SecurePassword123!",
"first_name": "Jane",
"last_name": "Doe"
}
Response 201 Created:
{
"id": "usr_a1b2c3d4",
"email": "dev@acme.com",
"first_name": "Jane",
"last_name": "Doe",
"created_at": "2024-01-15T10:30:00Z"
}
Errors: 400 Email already registered | 422 Validation error
POST /login
Authenticate with email and password. Returns a global JWT.
Request Body:
{
"email": "dev@acme.com",
"password": "SecurePassword123!"
}
Response 200 OK:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 1800
}
Errors: 401 Invalid credentials
POST /otp/request
Request a one-time password sent to email (passwordless login).
Request Body:
{
"email": "dev@acme.com"
}
Response 200 OK:
{
"message": "OTP sent to your email"
}
POST /otp/verify
Verify OTP code and receive a JWT.
Request Body:
{
"email": "dev@acme.com",
"code": "847291"
}
Response 200 OK:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
POST /select-tenant
Exchange a global JWT for a scoped JWT tied to a specific tenant. Required before calling service APIs.
Headers: Authorization: Bearer {global_jwt}
Request Body:
{
"tenant_id": "ten_x1y2z3w4"
}
Response 200 OK:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"tenant_id": "ten_x1y2z3w4",
"role": "admin",
"environment": "prod"
}
POST /forgot-password
Initiate password reset. Sends a reset link via email.
Request Body:
{
"email": "dev@acme.com"
}
Response 200 OK (always — prevents email enumeration):
{
"message": "If that email exists, a reset link has been sent"
}
POST /reset-password
Complete password reset using the token from the email link.
Request Body:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"new_password": "NewSecurePassword456!"
}
Response 200 OK:
{
"message": "Password updated successfully"
}
PUT /password
Update password for the currently authenticated user.
Headers: Authorization: Bearer {jwt}
Request Body:
{
"current_password": "OldPassword123!",
"new_password": "NewPassword456!"
}
Response 200 OK
Organization Management
Base path: /platform/api/global
POST /tenants
Create a new organization (tenant). The caller becomes the owner.
Headers: Authorization: Bearer {global_jwt}
Request Body:
{
"name": "Acme Corp",
"slug": "acme-corp",
"billing_email": "billing@acme.com"
}
Response 201 Created:
{
"id": "ten_x1y2z3w4",
"name": "Acme Corp",
"slug": "acme-corp",
"status": "active",
"billing_email": "billing@acme.com",
"created_at": "2024-01-15T10:30:00Z"
}
Errors: 409 Slug already taken
GET /tenants
List all organizations the authenticated user belongs to.
Headers: Authorization: Bearer {global_jwt}
Response 200 OK:
[
{
"id": "ten_x1y2z3w4",
"name": "Acme Corp",
"slug": "acme-corp",
"role": "owner",
"status": "active"
}
]
GET /tenants/check-availability
Check if a tenant slug is available before creating.
Query Parameters: ?slug=acme-corp
Response 200 OK:
{
"slug": "acme-corp",
"available": false
}
Service APIs (Tenant-Scoped)
Base path: /platform/api/service
All service endpoints require a scoped JWT (
Authorization: Bearer {scoped_jwt}). The tenant context is derived from the token’stidclaim — notenant_idin URL paths.
GET /info
Get current tenant information.
Response 200 OK:
{
"id": "ten_x1y2z3w4",
"name": "Acme Corp",
"slug": "acme-corp",
"status": "active",
"billing_email": "billing@acme.com",
"subscription": {
"plan": "Pro",
"status": "ACTIVE",
"end_date": "2025-01-15T00:00:00Z"
}
}
POST /auth/switch-environment
Switch the active environment for the current session.
Request Body:
{
"environment": "staging"
}
Value |
Description |
|---|---|
|
Production data |
|
Staging/QA data |
|
Development data |
Response 200 OK:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"environment": "staging"
}
Member Management
GET /members
List all members of the current tenant.
Response 200 OK:
[
{
"id": "mem_001",
"user_id": "usr_a1b2c3d4",
"email": "dev@acme.com",
"first_name": "Jane",
"last_name": "Doe",
"role": "admin",
"status": "active",
"joined_at": "2024-01-15T10:30:00Z"
}
]
POST /invites
Invite a new user to the organization by email.
Request Body:
{
"email": "newuser@acme.com",
"role": "member"
}
Role |
Description |
|---|---|
|
Can manage members, keys, policies |
|
Can use keys, view analytics |
|
Read-only analytics access |
Response 201 Created:
{
"id": "inv_001",
"email": "newuser@acme.com",
"role": "member",
"expires_at": "2024-01-22T10:30:00Z"
}
DELETE /members/{user_id}
Remove a member from the organization.
Response 200 OK
Errors: 403 Cannot remove the owner | 404 Member not found
Billing & Subscriptions
GET /catalog/plans
List available subscription plans.
Response 200 OK:
[
{
"id": "plan_dev",
"name": "Developer",
"price": 0,
"billing_cycle": "MONTHLY",
"features": ["10,000 req/month", "1 API key", "7-day log retention"]
},
{
"id": "plan_pro",
"name": "Pro",
"price": 299,
"billing_cycle": "MONTHLY",
"features": ["500,000 req/month", "10 API keys", "90-day log retention", "ML violation detection"]
},
{
"id": "plan_enterprise",
"name": "Enterprise",
"price": 0,
"billing_cycle": "MONTHLY",
"features": ["Unlimited requests", "Unlimited keys", "365-day retention", "Custom ML models", "On-premise option"]
}
]
POST /subscriptions
Activate or change the subscription plan for the current tenant.
Headers: Must be owner or admin role
Request Body:
{
"plan_id": "plan_pro"
}
Response 201 Created:
{
"id": "sub_001",
"plan_id": "plan_pro",
"plan_name": "Pro",
"status": "ACTIVE",
"start_date": "2024-01-15T10:30:00Z",
"end_date": "2024-02-15T10:30:00Z"
}
Configuration Management
GET /configs
Retrieve the merged configuration for the current tenant and environment.
Response 200 OK:
{
"resources": [
{
"resrc_name": "Security",
"config_groups": [
{
"grp_title": "Authentication",
"type": "TENANT",
"sections": [
{
"header_title": "MFA Settings",
"configs": [
{
"key": "auth.mfa_enforced",
"lbl": "Enforce MFA for all users",
"val": false,
"gen_type": "boolean",
"mod": true,
"is_locked": false
}
]
}
]
}
]
}
]
}
PUT /configs/{key}
Update a configuration value for the current tenant.
Request Body:
{
"value": true
}
Errors: 403 Config is locked by platform admin | 404 Config key not found
Storage Configuration
GET /storage
Get the current storage provider configuration for the tenant.
Response 200 OK:
{
"provider": "S3",
"bucket": "acme-corp-audit-logs",
"region": "us-east-1",
"credentials_set": true
}
PUT /storage
Update the storage provider configuration.
Request Body (S3):
{
"provider": "S3",
"bucket": "acme-corp-audit-logs",
"region": "us-east-1",
"aws_access_key_id": "AKIAIOSFODNN7EXAMPLE",
"aws_secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
Request Body (Azure):
{
"provider": "AZURE",
"azure_connection_string": "DefaultEndpointsProtocol=https;AccountName=...",
"container_name": "acme-audit-logs"
}
Admin APIs
Base path: /platform/api/admin
Requires
is_platform_admin = trueon the authenticated user.
Tenant Management
GET /tenants
List all tenants in the platform.
Query Parameters: ?status=active&limit=50&offset=0
Response 200 OK:
{
"items": [
{
"id": "ten_x1y2z3w4",
"name": "Acme Corp",
"slug": "acme-corp",
"status": "active",
"subscription_plan": "Pro",
"member_count": 12
}
],
"total": 847
}
PUT /tenants/{tenant_id}/status
Update a tenant’s status (suspend, activate, archive).
Request Body:
{
"status": "suspended",
"reason": "Payment overdue"
}
GET /users
List all users across the platform.
Query Parameters: ?limit=50&offset=0&email=acme.com
GET /stats
Platform-wide statistics.
Response 200 OK:
{
"total_tenants": 847,
"active_tenants": 812,
"total_users": 5240,
"total_api_requests_24h": 1847200,
"total_violations_24h": 143
}
Admin Configuration
GET /configs
Retrieve all global platform configurations.
PUT /configs/{key}
Update a global configuration value.
Request Body:
{
"value": "smtp.sendgrid.com",
"scope": "GLOBAL",
"is_locked": false
}
Response Status Codes
Status |
Meaning |
|---|---|
|
OK — successful read/update |
|
Created — resource successfully created |
|
No Content — successful delete |
|
Bad Request — validation error |
|
Unauthorized — missing or invalid JWT |
|
Forbidden — insufficient role/permissions |
|
Not Found — resource does not exist |
|
Conflict — duplicate resource (e.g. slug taken) |
|
Unprocessable Entity — schema validation failed |
|
Internal Server Error |