Documentation

Multi-tenancy

Hard isolation between your customers, enforced on every request. Built in from day one.

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

flowchart TD
    T[Tenant]
    K["API Keys<br/>(user-bound, revocable)"]
    C[Agent Configs]
    Conv[Conversations]
    M[Messages]
    L[Logs]
    T --> K
    T --> C
    C --> Conv
    Conv --> M
    T --> L

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 through the public tenant API using a verified user token. The response returns the first user-bound API key once:

curl -X POST https://api.nimblesite.ai/api/v1/tenants \
  -H "Authorization: Bearer $USER_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.

API keys

Every chat call requires an X-API-Key header:

curl -X POST https://api.nimblesite.ai/api/v1/chat/$CONFIG_ID \
  -H "X-API-Key: $TENANT_KEY" \
  -d '{"message": "Hello"}'

Each key is bound to one user and one tenant. The API resolves it to a user_id, tenant_id, and membership role, and every subsequent operation is filtered by that tenant. There is no tenant_id in the path, no way to query across tenants, and no way to leak one tenant's data into another's response.

Use multiple keys when you want segregated traffic: production, staging, CI, partners, customer streams, or internal services. Revoking one key does not revoke the whole tenant. The tenant prepaid balance is still the hard spend cap across all keys.

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.ai/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 at rest, user-bound, role-bound, and revocable.
  • Logs are scoped by tenant_id. Your dashboard only shows your own activity.
  • Prepaid credit is tenant-scoped. Empty balance stops billable routes before vendor cost is incurred.

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.
  • Tool credentials. Your tool credentials stay in your app for client-side mode, or inside your provisioned sandbox bundle for sandboxed mode.

Multi-tenancy you get for free, in one line of code

curl -H "X-API-Key: $KEY" https://api.nimblesite.ai/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.


Ship multi-tenant agents on day one. Sign up free →