Skip to main content
AutoSage uses a strict resource hierarchy. Each level is both an ownership boundary and an isolation boundary for the resources below it.

The hierarchy

Organization
  └── Environment                 API key boundary
        └── Tenant                Customer, credits, and quota boundary
              └── Knowledge base  Retrieval boundary
                    ├── Documents
                    ├── Agents
                    └── Chats
The top-level account for billing, members, roles, and environments. Organization administration normally uses an authenticated user session.
An isolated deployment context such as development, staging, or production. Every API key belongs to exactly one environment and cannot reach another one.
The resource owner for a customer or project. A tenant has its own credit pool, quotas, knowledge bases, and data. In a multi-customer product, create one tenant per customer.
The retrieval boundary for documents, connected data, agents, and chats. Documents are indexed in a private partition for that knowledge base.
See Core concepts for the product-level view of these objects.

How API keys narrow access

An API key always belongs to one environment. Its optional resource lists determine what it can reach inside that environment:
Key settingBehavior
tenant_ids: []Access every tenant in the key’s environment, subject to scopes
tenant_ids: ["..."]Access only the listed tenants
knowledge_base_ids: ["..."]Narrow access further to the listed knowledge bases
admin:full satisfies required scopes, but populated tenant and knowledge-base allowlists still constrain access when a specific resource is resolved. Tenant listing is the exception: an admin:full key can discover every tenant in its environment. Reserve it for trusted server-side provisioning. See Access & scopes.

The multi-customer pattern

Use two levels of isolation in a customer-facing application:
  1. Create one tenant per customer account to separate data, credits, and quotas.
  2. Pass a stable external_subject_id per end user to separate chat ownership and durable memory inside that tenant.
For example, a support platform could map customer account acme to one tenant, then use the application’s own stable user IDs as external subjects:
Tenant: acme
  ├── external_subject_id: user_1042
  └── external_subject_id: user_7819
1

Create a tenant for the customer

curl -X POST "https://api.autosage.ai/api/v1/tenants" \
  -H "Authorization: Bearer $AUTOSAGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "environment_id": "ENVIRONMENT_ID",
    "name": "Acme",
    "external_id": "acme"
  }'
2

Create a chat for an end user

curl -X POST "https://api.autosage.ai/api/v1/chats" \
  -H "Authorization: Bearer $AUTOSAGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "CHAT_UUID",
    "tenant_id": "ACME_TENANT_ID",
    "knowledge_base_id": "KB_ID",
    "model": "MODEL_ID",
    "external_subject_id": "user_1042",
    "message": "What is covered by my plan?"
  }'
3

Keep passing the same subject

Include external_subject_id=user_1042 whenever you list, read, update, or continue that API-key-owned chat. A chat created for one external subject cannot be accessed as another subject.
Use a small, workload-based set of API keys per environment, not one key per customer. For example, keep provisioning and runtime permissions on separate keys. Tenants isolate customer resources; stable external subjects isolate individual users’ conversations and memories.

Next steps

Access & scopes

Give each API key only the permissions and resources it needs.

Tenant API

Create tenants and configure their quotas and memory settings.