Core concepts
Tenants and scope
Every tool call, staged write, ledger row and stored memory is scoped by an identity. That identity is set once, from your API key, and nothing downstream can change it.
The rule
Scope comes from the credential. Never from the request body. Never from the model.
This is the entire multi-tenant boundary. A model can hallucinate an organization id into its tool arguments; a compromised client can put one in a request body. Neither reaches your endpoint, because Tether builds the outbound envelope from the authenticated key and ignores everything else.
// This is accepted. The organizationId is silently ignored.
{ "prompt": "show me open tickets", "organizationId": 999 }
The AiChatRequest type still carries organizationId and locationId fields. They are
legacy, they are not read, and no value you put in them has any effect. Treat them as absent.
The three levels
| Level | Source | Meaning |
|---|---|---|
| Tenant | The API key | Which of your customers is asking |
| Scope | X-Tether-Scope-Id | A narrower boundary inside that customer — a site, ledger, region, workspace |
| User | X-Tether-User-Id | The individual acting, for attribution and confirmation |
Only the tenant is mandatory. Scope and user are optional headers you set per request.
curl -X POST https://api.trytether.ge/v1/chat \
-H "X-Api-Key: $TETHER_SECRET_KEY" \
-H "X-Tether-Scope-Id: 9" \
-H "X-Tether-User-Id: 431" \
-H "X-Tether-User-Role: shift_lead" \
-d '{ "prompt": "what is still open?" }'
What each level actually gates
Tenant decides the tool catalog, the tool endpoint and signing secret, the plan and its ceilings, the spend budget, the conversation history, and the knowledge corpus. Two tenants share nothing.
Scope is passed through to your endpoint as tenant.scope_id, and gates tools registered
requires_scope: true. A tool that cannot answer without knowing which site should declare
that, so the model asks rather than guessing across all of them.
User is passed through, attributed on staged writes, and used for durable preference memory. Preferences learned from one user are not injected into another's turns.
Naming
The wire format uses organization_id and scope_id. The names are older than the concepts
they now carry: organization_id is the tenant, and scope_id is whatever subdivision of that
tenant you decide it is.
What Tether stores against a tenant
Conversations, staged actions and their execution records, the spend ledger, request telemetry, extracted user preferences, and any documentation you ingest for retrieval.
Not your business records. Tether has no table for your orders, customers, or inventory, because it never receives them — only the tool results it passes to the model within a turn.
Related
- Authentication — headers and key handling
- Scoping multi-site tenants
- Security model