Multi-tenancy
Nimblesite is multi-tenant from the first line of code. Every config, conversation, message, and log row has a tenant_id. Every query is filtered by it. Tenants cannot see each other's data, conversations, or configs.
If you're building a SaaS product on top of Nimblesite, your customers map one-to-one to tenants.
The model
Tenant
├─ API Key (hashed)
├─ Agent Configs
│ └─ Conversations
│ └─ Messages
└─ Logs
A tenant is the unit of isolation. One tenant = one customer (or one environment, or one project — however you want to model it).
Creating tenants
Tenants are created by admin calls (typically from your own backend, not from customer-facing code):
curl -X POST https://api.nimblesite.dev/api/v1/admin/tenants \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Acme Corp"}'
The response includes an api_key. Show it once, store it securely. We hash it at rest and never return it again.
The API key
Every chat call requires an X-API-Key header:
curl -X POST https://api.nimblesite.dev/api/v1/chat/$CONFIG_ID \
-H "X-API-Key: $TENANT_KEY" \
-d '{"message": "Hello"}'
The key identifies the tenant. We resolve it to a tenant_id, then every subsequent query is scoped:
WHERE tenant_id = :tenant_id
No tenant_id in the path, no way to query across tenants, no way to leak one tenant's data into another's response.
Per-tenant configs
Each tenant has its own set of agent configs. Tenant A's configs endpoint will never return Tenant B's configs:
curl https://api.nimblesite.dev/api/v1/configs \
-H "X-API-Key: $TENANT_A_KEY"
This means you can ship one product with per-customer agent variants — different system prompts, different tool lists, different models — without building that scaffolding yourself.
Per-tenant prompts
Prompts support template variables, so one config can serve many tenants with tenant-specific personalisation:
{
"system_prompt": "You are the assistant for {tenant_name}. Today is {date}. Be helpful."
}
{tenant_name} is resolved from the tenant that owns the chat call. Your customers get a per-tenant assistant without duplicating configs.
Isolation guarantees
- Configs are scoped by
tenant_id. Cross-tenant reads are impossible. - Conversations and messages are scoped by
tenant_id. You cannot load another tenant's conversation history. - API keys are hashed with SHA-256 + per-key salt at rest.
- Logs are scoped by
tenant_id. Your dashboard only shows your own activity.
What you still own
Multi-tenancy is solved at the Nimblesite layer. Things you still own:
- User-to-tenant mapping. If one tenant has 500 users, you decide how to scope conversations and rate limits within that tenant.
- Tool execution trust boundary. Your tools run in your app. If tenant A's tool accidentally touches tenant B's data, that's a bug in your app, not ours.
- Provider API keys. If you bring your own provider keys, you decide whether to share one key across tenants or issue one per tenant.
Multi-tenancy you get for free, in one line of code
curl -H "X-API-Key: $KEY" https://api.nimblesite.dev/api/v1/chat/$CONFIG_ID -d ...
That's the whole thing. You ship your product, point each customer's backend at a different API key, and Nimblesite keeps them apart.