Skip to main content

Multi-Tenancy

SynapseX provides complete multi-tenant architecture for B2B applications, enabling customer isolation, per-tenant customization, and centralized management.

Overview

Multi-tenancy in SynapseX means:

  • Data Isolation - Each tenant's data is completely separated
  • Custom Models - Per-tenant LoRA adapters and configurations
  • Independent Rate Limits - Separate quotas per customer
  • Billing Separation - Track usage per tenant
  • API Key Management - Unique keys per tenant
┌─────────────────────────────────────────────────────────────────────────────┐
│ MULTI-TENANT ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Tenant A │ │ Tenant B │ │ Tenant C │ │ Tenant D │ │
│ │ Pharmacy │ │ Hospital │ │ Retailer │ │ Bank │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ │ X-Tenant-ID │ X-Tenant-ID │ X-Tenant-ID │ X-Tenant-ID │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SYNAPSEX API GATEWAY │ │
│ │ │ │
│ │ • Authenticate tenant │ │
│ │ • Apply rate limits │ │
│ │ • Route to tenant context │ │
│ │ • Load tenant LoRA │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────┼───────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Tenant A │ │ Tenant B │ │ Tenant C │ │
│ │ Context │ │ Context │ │ Context │ │
│ │ │ │ │ │ │ │
│ │ • LoRA v3 │ │ • LoRA v5 │ │ • LoRA v2 │ │
│ │ • RAG docs │ │ • RAG docs │ │ • RAG docs │ │
│ │ • Settings │ │ • Settings │ │ • Settings │ │
│ │ • Feedback │ │ • Feedback │ │ • Feedback │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Tenant Management

Create Tenant

import requests

response = requests.post(
"https://api.synapsex.ai/v1/tenants",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
"name": "Farmácia Santa Casa",
"slug": "farmacia_santa_casa",
"tier": "pro",
"contact_email": "admin@farmacia.com",
"settings": {
"default_model": "synapsex-chat",
"max_tokens_per_request": 2048,
"enable_rerank": True,
"rerank_tier": "quantum_cpu",
"custom_system_prompt": "You are a pharmacy assistant for Farmácia Santa Casa."
}
}
)

tenant = response.json()
print(f"Tenant ID: {tenant['id']}")
print(f"API Key: {tenant['api_key']}")

Tenant Tiers

TierRate LimitTokens/DayFeatures
free20 req/min10,000Basic
pro100 req/min100,000+ Quantum CPU
business500 req/min1,000,000+ Training
enterpriseCustomUnlimited+ Quantum GPU, SLA

List Tenants

response = requests.get(
"https://api.synapsex.ai/v1/tenants",
headers={"Authorization": "Bearer sk-admin-xxx"},
params={"tier": "pro", "limit": 50}
)

for tenant in response.json()['tenants']:
print(f"{tenant['name']} ({tenant['slug']}): {tenant['tier']}")

Update Tenant

response = requests.patch(
"https://api.synapsex.ai/v1/tenants/tenant_abc123",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
"tier": "business",
"settings": {
"rerank_tier": "quantum_gpu"
}
}
)

Delete Tenant

response = requests.delete(
"https://api.synapsex.ai/v1/tenants/tenant_abc123",
headers={"Authorization": "Bearer sk-admin-xxx"}
)

Tenant Authentication

Using Tenant API Key

Each tenant gets a unique API key:

from openai import OpenAI

# Tenant-specific client
client = OpenAI(
api_key="sk-farmacia-santa-casa-xxx", # Tenant's API key
base_url="https://api.synapsex.ai/v1"
)

response = client.chat.completions.create(
model="synapsex-chat",
messages=[{"role": "user", "content": "What medications interact with aspirin?"}]
)

Using X-Tenant-ID Header

For platform-level access with tenant routing:

response = requests.post(
"https://api.synapsex.ai/v1/chat/completions",
headers={
"Authorization": "Bearer sk-platform-xxx", # Platform key
"X-Tenant-ID": "farmacia_santa_casa" # Route to tenant
},
json={
"model": "synapsex-chat",
"messages": [{"role": "user", "content": "..."}]
}
)

Tenant Settings

Configuration Options

response = requests.patch(
"https://api.synapsex.ai/v1/tenants/tenant_abc/settings",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
# Model settings
"default_model": "synapsex-chat-32k",
"max_tokens_per_request": 4096,
"default_temperature": 0.7,

# Reranking
"enable_rerank": True,
"rerank_tier": "quantum_cpu",
"rerank_k": 4,

# Custom behavior
"custom_system_prompt": "You are a helpful assistant for...",
"allowed_topics": ["healthcare", "products", "orders"],
"blocked_topics": ["competitors", "legal_advice"],

# RAG
"enable_rag": True,
"rag_top_k": 5,
"rag_threshold": 0.7,

# Rate limits (overrides tier defaults)
"rate_limit_rpm": 150,
"daily_token_limit": 500000
}
)

Get Settings

response = requests.get(
"https://api.synapsex.ai/v1/tenants/tenant_abc/settings",
headers={"Authorization": "Bearer sk-admin-xxx"}
)

settings = response.json()
print(f"Model: {settings['default_model']}")
print(f"Rerank: {settings['rerank_tier']}")

Per-Tenant RAG

Upload Documents

# Register dataset for tenant
response = requests.post(
"https://api.synapsex.ai/v1/tenants/farmacia_santa_casa/datasets/register",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
"name": "product_catalog",
"type": "documents",
"data_use": {"allow_rag": True}
}
)

dataset_id = response.json()['id']

# Upload documents
response = requests.post(
f"https://api.synapsex.ai/v1/tenants/farmacia_santa_casa/datasets/{dataset_id}/upload/docs",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
"docs": [
{
"doc_id": "med_001",
"title": "Aspirin 500mg",
"text": "Pain reliever and anti-inflammatory. Dosage: 1-2 tablets every 4-6 hours...",
"metadata": {"category": "analgesics", "price": 12.99}
}
]
}
)

RAG in Action

When the tenant makes a request:

# Tenant request
response = client.chat.completions.create(
model="synapsex-chat",
messages=[{"role": "user", "content": "What pain medications do you have?"}]
)

# Response includes RAG context automatically
print(response.choices[0].message.content)
# "We have several pain medications including Aspirin 500mg ($12.99)..."

Per-Tenant LoRA

Training Flow

  1. Collect feedback from tenant users
  2. Trigger training when threshold reached
  3. Deploy LoRA adapter for tenant
  4. Automatic loading on inference
# Check training readiness
response = requests.get(
"https://api.synapsex.ai/v1/tenants/farmacia_santa_casa/feedback/stats",
headers={"Authorization": "Bearer sk-admin-xxx"}
)

if response.json()['ready_for_training']:
# Trigger training
response = requests.post(
"https://api.synapsex.ai/v1/tenants/farmacia_santa_casa/train/lora",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={"epochs": 3, "lora_r": 16}
)
print(f"Training job: {response.json()['job_id']}")

LoRA Loading

When a request comes in for a tenant:

1. Request arrives with X-Tenant-ID: farmacia_santa_casa
2. System loads base model + farmacia_santa_casa LoRA adapter
3. Response generated with tenant-specific adaptations
4. LoRA unloaded (or cached for next request)

Usage Tracking

Get Tenant Usage

response = requests.get(
"https://api.synapsex.ai/v1/tenants/farmacia_santa_casa/usage",
headers={"Authorization": "Bearer sk-admin-xxx"},
params={"period": "current_month"}
)

usage = response.json()
print(f"Requests: {usage['requests']}")
print(f"Tokens: {usage['tokens']}")
print(f"Rerank calls: {usage['rerank_calls']}")
print(f"Training jobs: {usage['training_jobs']}")

Usage by Day

response = requests.get(
"https://api.synapsex.ai/v1/tenants/farmacia_santa_casa/usage/daily",
headers={"Authorization": "Bearer sk-admin-xxx"},
params={"from": "2024-01-01", "to": "2024-01-31"}
)

for day in response.json()['days']:
print(f"{day['date']}: {day['requests']} requests, {day['tokens']} tokens")

All Tenants Usage

response = requests.get(
"https://api.synapsex.ai/v1/admin/usage/tenants",
headers={"Authorization": "Bearer sk-admin-xxx"},
params={"period": "current_month", "sort": "tokens_desc"}
)

for tenant in response.json()['tenants']:
print(f"{tenant['name']}: {tenant['tokens']:,} tokens")

Billing Integration

Webhook for Usage

Configure webhooks for billing integration:

response = requests.post(
"https://api.synapsex.ai/v1/webhooks",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
"url": "https://your-billing-system.com/webhook",
"events": ["usage.daily", "usage.limit_reached"],
"secret": "webhook-secret"
}
)

Usage Webhook Payload

{
"event": "usage.daily",
"timestamp": "2024-01-15T00:00:00Z",
"data": {
"tenant_id": "tenant_abc123",
"tenant_slug": "farmacia_santa_casa",
"period": "2024-01-14",
"metrics": {
"requests": 1500,
"tokens": 450000,
"rerank_calls": 1200,
"quantum_rerank_calls": 800
}
}
}

Self-Service Trial

Enable customers to self-onboard:

Trial Configuration

response = requests.post(
"https://api.synapsex.ai/v1/admin/trial/config",
headers={"Authorization": "Bearer sk-admin-xxx"},
json={
"enabled": True,
"duration_days": 14,
"limits": {
"requests_per_day": 100,
"tokens_per_day": 10000
},
"features": {
"rerank_tier": "classic",
"enable_rag": True,
"enable_training": False
}
}
)

Trial Signup Endpoint

POST /public/trial/signup
{
"email": "customer@company.com",
"company_name": "Acme Corp",
"use_case": "Customer support automation"
}

Response:

{
"tenant_id": "trial_xyz789",
"api_key": "sk-trial-xyz789-xxx",
"expires_at": "2024-01-29T00:00:00Z",
"limits": {
"requests_per_day": 100,
"tokens_per_day": 10000
}
}

Best Practices

Security

Do:

  • Use tenant-specific API keys
  • Validate X-Tenant-ID on all requests
  • Implement IP whitelisting for enterprise
  • Audit tenant data access

Don't:

  • Share API keys between tenants
  • Allow cross-tenant data access
  • Store tenant secrets in logs

Performance

Do:

  • Cache tenant settings
  • Pre-load frequently used LoRAs
  • Use connection pooling per tenant
  • Set appropriate rate limits

Don't:

  • Load LoRA on every request
  • Allow unlimited token consumption
  • Skip tenant validation

Next Steps