Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.shipfastai.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Enterprise tier adds a full multi-tenancy layer to Shipfastai. Each tenant gets a dedicated PostgreSQL schema containing its own documents, chat_sessions, chat_messages, and fine_tune_jobs tables. Tenant metadata — names, plans, member lists, and API keys — lives in the shared public schema. A FastAPI middleware layer resolves the current tenant on every request before any handler code runs, and an RBAC system controls what each member of a tenant can do.
Multi-tenancy is an Enterprise tier feature. It is not available in the Basic or Pro tiers. Attempting to enable tenant middleware without an Enterprise license will not provide the schema provisioning, RBAC, or audit logging features described on this page.

How tenant isolation works

When a tenant is created, Shipfastai automatically provisions a new PostgreSQL schema named {prefix}{slug} (for example, tenant_acme). All per-tenant application data is written into that schema, not the public schema. This means two tenants can never read each other’s documents or chat sessions, even through direct database queries. The TenantMiddleware identifies the current tenant on every inbound request using one of three strategies, checked in priority order:
  1. HeaderX-Tenant-ID (UUID) or X-Tenant-Slug (slug string).
  2. Subdomainacme.api.example.com resolves to slug acme.
  3. Path prefix/api/v1/acme/... resolves to slug acme.
After resolving a candidate tenant, the middleware validates it against the database and stores the result in request.state.tenant. If the tenant is suspended, the request is rejected with 403 Forbidden. Public paths such as /health, /docs, and /api/v1/auth are excluded from tenant resolution.

Tenant API endpoints

All tenant management endpoints live under /api/tenants. Every endpoint requires an authenticated user; the RBAC layer then enforces what that user is allowed to do within the tenant.
MethodPathDescription
POST/api/tenants/Create a new tenant. The caller becomes the owner.
GET/api/tenants/List tenants the current user is a member of.
GET/api/tenants/{tenant_id}Get details for a single tenant.
PATCH/api/tenants/{tenant_id}Update tenant name, plan, or settings. Requires tenants:write.
DELETE/api/tenants/{tenant_id}Suspend a tenant (soft delete). Requires tenants:delete.
POST/api/tenants/{tenant_id}/transferTransfer ownership to another active member.
Creating a tenant
Request
POST /api/tenants/
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "name": "Acme Corp",
  "slug": "acme",
  "plan": "enterprise",
  "settings": {}
}
Response — 201 Created
{
  "id": "b1c2d3e4-0000-0000-0000-000000000002",
  "name": "Acme Corp",
  "slug": "acme",
  "schema_name": "tenant_acme",
  "plan": "enterprise",
  "settings": {},
  "is_active": true,
  "max_members": 50,
  "max_api_keys": 20,
  "owner_id": "a1b2c3d4-0000-0000-0000-000000000001",
  "member_count": 1,
  "created_at": "2026-04-09T10:00:00Z",
  "updated_at": "2026-04-09T10:00:00Z",
  "suspended_at": null
}
The slug must be 3–50 lowercase alphanumeric characters or hyphens, starting and ending with a letter or number. Valid plans are starter, growth, and enterprise. Listing tenants
Request
GET /api/tenants/?plan=enterprise&is_active=true&skip=0&limit=20
Authorization: Bearer <access_token>
Response — 200 OK
{
  "tenants": [ { "id": "...", "name": "Acme Corp", "slug": "acme", "..." } ],
  "total": 1,
  "skip": 0,
  "limit": 20
}

Per-tenant configuration

Each tenant record includes a settings field (a free-form JSON object) that you can use to store tenant-specific configuration such as allowed LLM providers, custom system prompts, feature flags, or rate limit overrides.
Updating tenant settings
PATCH /api/tenants/{tenant_id}
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "settings": {
    "allowed_providers": ["openai"],
    "default_model": "gpt-4o-mini",
    "max_tokens_per_request": 2000,
    "custom_system_prompt": "You are Acme's internal assistant."
  }
}
You can also update name, plan, max_members, and max_api_keys in the same call. All changes are written to the audit log automatically.

Usage-based billing

The Enterprise tier tracks resource consumption per tenant using the UsageService. Every AI call, RAG query, and API request records a UsageRecord containing a resource_type (such as api_call, llm_token, or storage_mb) and a quantity. You can query usage data for a tenant through two endpoints: Aggregated summary
Request
GET /api/tenants/{tenant_id}/usage/?period=30d
Authorization: Bearer <access_token>
X-Tenant-ID: b1c2d3e4-0000-0000-0000-000000000002
Response — 200 OK
{
  "tenant_id": "b1c2d3e4-0000-0000-0000-000000000002",
  "period_start": "2026-03-10T10:00:00Z",
  "period_end": "2026-04-09T10:00:00Z",
  "totals": {
    "api_call": 4820,
    "llm_token": 312400,
    "storage_mb": 128
  },
  "daily_breakdown": [
    { "date": "2026-04-08", "totals": { "api_call": 210, "llm_token": 14300 } },
    { "date": "2026-04-09", "totals": { "api_call": 195, "llm_token": 12800 } }
  ]
}
The period query parameter accepts 7d, 30d, or 90d. Detailed records
Request
GET /api/tenants/{tenant_id}/usage/details?resource_type=llm_token&period=7d&limit=50
Authorization: Bearer <access_token>
Usage data integrates with Stripe Metered Billing. You can push totals from the summary endpoint to a Stripe metered subscription item at the end of each billing period to charge tenants based on actual consumption. Both usage endpoints require the usage:read permission, which is granted to the owner and admin roles by default.