Multi-Tenancy¶
AMP is built multi-tenant from the ground up. Every piece of data belongs to exactly one tenant, ensuring complete isolation between organizations.
Tenant Model¶
graph TB
subgraph "Tenant A (Agency)"
A_Users[Users]
A_Missions[Missions]
A_Content[Content]
A_Brand[Brand Context]
end
subgraph "Tenant B (Startup)"
B_Users[Users]
B_Missions[Missions]
B_Content[Content]
B_Brand[Brand Context]
end
subgraph "Shared Infrastructure"
API[API Server]
DB[(Database)]
Queue[Job Queue]
end
A_Users --> API
B_Users --> API
API --> DB
API --> Queue What is a Tenant?¶
A tenant is an isolated organization within AMP. Tenants have:
- Separate data — Missions, content, brand context
- Own configuration — API keys, integrations, preferences
- Independent billing — Usage tracking and cost allocation
- Distinct users — Team members with role-based access
Tenant Structure¶
{
"id": "tnt_2xK9mPqR4vN8sT3w",
"name": "Acme Corporation",
"slug": "acme-corp",
"status": "active",
"config": {
"metricool": {
"enabled": true,
"token": "encrypted_token",
"blog_id": "xxx"
},
"provider_routing": {
"llm_preference": "claude",
"image_preference": "openai",
"fallback_enabled": true
},
"cost_limits": {
"monthly_limit_cents": 500000,
"alert_threshold_percent": 80
},
"approval": {
"require_approval": true,
"auto_approve_after_hours": 48,
"approvers": ["user_xxx", "user_yyy"]
}
},
"usage": {
"current_month": {
"missions_created": 5,
"content_generated": 234,
"api_calls": 12456,
"cost_cents": 23400
}
},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
User-Tenant Relationship¶
Users can belong to multiple tenants with different roles:
graph LR
User[Alice]
T1[Tenant: Agency]
T2[Tenant: Startup]
User -->|admin| T1
User -->|operator| T2 Roles¶
| Role | Description | Capabilities |
|---|---|---|
admin | Full tenant control | All operations + settings |
operator | Day-to-day operations | Missions, content, analytics |
viewer | Read-only access | View missions, content, analytics |
Role Permissions¶
| Operation | Admin | Operator | Viewer |
|---|---|---|---|
| View content | ✓ | ✓ | ✓ |
| Create missions | ✓ | ✓ | |
| Approve content | ✓ | ✓ | |
| View analytics | ✓ | ✓ | ✓ |
| Manage integrations | ✓ | ||
| Manage users | ✓ | ||
| Configure billing | ✓ |
Data Isolation¶
All queries are automatically scoped to the current tenant:
-- Internal query (automatic tenant filter)
SELECT * FROM missions
WHERE tenant_id = 'tnt_xxx' -- Always applied
AND status = 'active';
Enforcement Layers¶
- API Middleware — Extracts tenant from auth context
- Service Layer — Validates tenant access
- Repository Layer — Applies tenant filter to all queries
- Database — Row-level security (optional)
Cross-Tenant Access¶
Cross-tenant access is not supported through normal APIs. Even admin users cannot access other tenants' data.
Tenant Configuration¶
Provider Routing¶
Configure which AI providers the tenant uses:
{
"config": {
"provider_routing": {
"llm_preference": "claude",
"llm_fallback": ["openai", "google"],
"image_preference": "openai",
"cost_optimization": true
}
}
}
Cost Controls¶
Set spending limits:
{
"config": {
"cost_limits": {
"monthly_limit_cents": 500000,
"daily_limit_cents": 20000,
"alert_threshold_percent": 80,
"hard_stop_at_limit": true
}
}
}
When limits are reached:
- Soft limit — Alerts sent, operations continue
- Hard limit — Content generation pauses
Approval Workflows¶
Configure content approval:
{
"config": {
"approval": {
"require_approval": true,
"auto_approve_after_hours": 24,
"approvers": ["user_xxx", "user_yyy"],
"approval_order": "any",
"escalation_after_hours": 12,
"escalation_to": "user_zzz"
}
}
}
Managing Tenants¶
Create Tenant (Operator Only)¶
curl -X POST https://api.amp.dev/v1/tenants \
-H "Authorization: Bearer $OPERATOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "New Client Corp",
"slug": "new-client-corp",
"config": {
"provider_routing": {
"llm_preference": "claude"
}
}
}'
Update Tenant Configuration¶
curl -X PUT https://api.amp.dev/v1/tenants/tnt_xxx \
-H "Authorization: Bearer $AMP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"config": {
"cost_limits": {
"monthly_limit_cents": 750000
}
}
}'
View Tenant Usage¶
{
"tenant_id": "tnt_xxx",
"period": "2024-01",
"usage": {
"missions_created": 12,
"content_generated": 456,
"content_published": 423,
"api_calls": 34567,
"llm_tokens_used": 2345678,
"images_generated": 89,
"cost_cents": 45600
},
"limits": {
"monthly_limit_cents": 500000,
"percent_used": 9.12
}
}
User Management¶
Invite User to Tenant¶
curl -X POST https://api.amp.dev/v1/tenants/tnt_xxx/users \
-H "Authorization: Bearer $AMP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"role": "operator"
}'
Update User Role¶
curl -X PUT https://api.amp.dev/v1/tenants/tnt_xxx/users/user_yyy \
-H "Authorization: Bearer $AMP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"role": "admin"
}'
Remove User from Tenant¶
curl -X DELETE https://api.amp.dev/v1/tenants/tnt_xxx/users/user_yyy \
-H "Authorization: Bearer $AMP_API_KEY"
Switching Tenants¶
Users with access to multiple tenants can switch context:
List Accessible Tenants¶
{
"data": [
{
"id": "tnt_xxx",
"name": "Agency Client A",
"role": "admin",
"is_default": true
},
{
"id": "tnt_yyy",
"name": "Agency Client B",
"role": "operator",
"is_default": false
}
]
}
Set Default Tenant¶
curl -X PUT https://api.amp.dev/v1/auth/settings \
-H "Authorization: Bearer $AMP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"default_tenant_id": "tnt_yyy"
}'
Override Tenant per Request¶
curl https://api.amp.dev/v1/missions \
-H "Authorization: Bearer $AMP_API_KEY" \
-H "X-Tenant-ID: tnt_yyy"
Agency Use Case¶
Agencies managing multiple clients typically structure tenants as:
Agency Account
├── Tenant: Client A (Agency has admin access)
├── Tenant: Client B (Agency has admin access)
├── Tenant: Client C (Agency has admin access)
└── Each client can also have their own users
Benefits¶
- Clear separation — Each client's data is isolated
- Independent billing — Track costs per client
- Custom configuration — Each client has their own brand context
- Delegated access — Clients can log in to see their content
Setup Example¶
# Create tenant for new client
curl -X POST https://api.amp.dev/v1/tenants \
-H "Authorization: Bearer $AGENCY_KEY" \
-d '{
"name": "Acme Corp",
"slug": "acme-corp"
}'
# Invite client user
curl -X POST https://api.amp.dev/v1/tenants/tnt_acme/users \
-H "Authorization: Bearer $AGENCY_KEY" \
-d '{
"email": "marketing@acme.com",
"role": "viewer"
}'
Enterprise Use Case¶
Large organizations often use tenants for departments or brands:
Enterprise Account
├── Tenant: Corporate Brand
├── Tenant: Product Line A
├── Tenant: Product Line B
└── Tenant: Regional (EMEA)
Shared Brand Context¶
Enterprise tenants can share brand context elements:
curl -X POST https://api.amp.dev/v1/brand/share \
-H "Authorization: Bearer $AMP_API_KEY" \
-d '{
"source_tenant": "tnt_corporate",
"target_tenant": "tnt_product_a",
"elements": ["visual_identity", "voice.personality"]
}'
Best Practices¶
1. Use Descriptive Slugs¶
2. Set Cost Limits Early¶
Configure limits before generating content to avoid surprises.
3. Use Roles Appropriately¶
- Give
adminonly to those who need it - Use
operatorfor day-to-day work - Use
viewerfor stakeholders who just need visibility