The one rule: a customer is a tenant, not a dataset
A tenant is Splendor’s hard isolation boundary. Every query, handle, and stored record is scoped to one tenant, and the API never lets data cross that line — it is enforced at the auth, query, handle, and storage layers, independent of your application code. A dataset is a namespace within a tenant. Datasets are co-queryable: a single search can target several at once, and there is no per-dataset access control. They organize kinds of data, not owners of data. So the mapping for a platform is:How access works
Your backend holds a platform API key (a machine-to-machine credential). With it you can:- Provision a tenant per end-customer (
POST /v1/platform/tenants). - Act inside any of your tenants by sending its id in the
X-Splendor-Tenant-Idheader alongside the platform key — search, ingest, export, everything. - Tear a tenant down completely when a customer leaves (
DELETE /v1/platform/tenants/{id}).
Your own data vs. your customers’ data
The platform key is your reseller credential: it reaches only the customer tenants you provision, never your own workspace. That is deliberate — if the key leaks, the blast radius is customer tenants you can rotate and contain, never your own internal corpus. That does not mean a platform has no data of its own. Your platform account is itself a tenant, so you can run Splendor for your own internal search — your docs, logs, screenshots — right alongside the customer tenants you serve. You just reach that internal data with a different credential: your console login, or a tenant key (spltk.v1.…) minted for your own tenant (see Authentication), never the platform key.
Two ways to host internal data, depending on how much isolation you want:
- Use your platform tenant as the internal workspace. Your internal data lives in your own account and no platform key can ever read it — the most isolated option.
- Provision a dedicated internal tenant like any customer (
POST /v1/platform/tenants). The platform key can reach it, so one credential operates everything uniformly — at the cost of folding internal data into the platform key’s blast radius.
Worked example: a screenshot search app
Say you run a screenshot search product. Each user’s screenshots are private personal data, so each user is a tenant:- Tenant = one of your users.
- Dataset = a device or capture source within that user, e.g.
iphone,mac,ipad— or a singlescreenshotsdataset withdeviceandcaptured_atfields if you prefer to filter rather than partition. - Search =
content_filter: "images"withsemantic: true. A query like “coffee shop meeting with Sarah” is encoded into image-embedding space and matches screenshots of that scene, even when they contain no readable text.
Worked example: document search for companies
Say you offer document search to companies. Each company’s documents must be isolated, so each company is a tenant:- Tenant = one of your customer companies.
- Dataset = a content type within that company, e.g.
pages,comments,attachments. - Search = full-text, SQL, or
semantic: trueover one or more of those datasets.
When to deviate
A single shared tenant with a dataset-per-customer is only acceptable when the data is low-sensitivity and you are willing to own isolation in your own application layer (and accept that a bug there can cross customers). For anything personal, confidential, or regulated — screenshots, documents, health or financial data — use tenant-per-customer. It is the design Splendor is built around.Next
Provision tenants
Create, use, and delete a customer tenant with a platform API key.
Tenancy & isolation
The guarantees behind the tenant boundary.