Skip to main content
A tenant is your organisation’s own space in Kintra. Your customers, your tiers, your rewards and your API keys all belong to one tenant, and nothing in it is visible to another tenant. It is the thing an API key speaks for, so in practice a tenant is the answer to “whose data is this request about”.

How a request lands in a tenant

A gateway request carries no tenant field. The tenant comes from the API key id in X-Tenant-Key, and the server resolves it and attaches it to the request before any handler runs. There is nothing in a body or a query string that could name a different one. That has a consequence worth designing around: a key is bound to one tenant for its whole life. If you operate more than one brand or region as separate tenants, you hold one key per tenant and pick the key rather than passing an identifier. Authentication covers where keys come from and how they are rotated.

What the boundary covers

Five guarantees follow from where the tenant comes from, and they are the ones you can rely on when you write code against this surface. Reads answer for your tenant only. A list of customers is a list of your customers. A list of rewards is a list of the rewards you published. There is no filter to add and no scope to remember. A customer is addressed as the pair of your tenant and a customer id. An id that belongs to another tenant returns 404 with USER_NOT_FOUND, which is the same answer as an id that exists nowhere. The boundary does not tell you that something exists elsewhere. Membership is one record per tenant and customer. The same person can hold a membership in two tenants, and those are two memberships with separate XP, separate tier standing and separate history. Nothing is shared between them. A suspended tenant stops answering rather than answering partially. Every gateway route reloads the tenant and checks that it is still active. A tenant that is not active gets 403 with TENANT_SUSPENDED on every route, not a thinner result on some of them. An idempotency key is scoped to your tenant. The stored record is looked up as the pair of tenant and key, so a key you choose cannot collide with one another tenant chose. Inside your tenant it is one namespace: if two of your services hold two of your keys, they are still picking keys out of the same space and have to keep their values apart. Request conventions has the rest of the rules.

What the boundary does not cover

One thing is deliberately shared, and it is better to know it now than to discover it from a block explorer. XP on chain lives in a single token contract for the whole platform, not one contract per tenant. Tenant separation is enforced by the API, and the on-chain record is a per-customer balance in a shared contract. Architecture covers what that record contains and how the two sides relate. Rate limits are not a tenant boundary, and they are not a credential boundary either: the API limits by IP address, ahead of authentication, so an unauthenticated request spends the same allowance as a signed one. Holding another key buys no extra headroom, and services sharing an egress address share one allowance. Request conventions is where their behaviour is written down.

Where to go next

  • Customers for who lives inside a tenant and how they map to your own users.
  • XP and the ledger for what a balance under your tenant means.
  • Quickstart to make a signed request against your tenant now.