Tenants & Projects
The ownership hierarchy - organizations and their configuration containers.
Tenants and projects form the ownership hierarchy: they answer "who is sending, and with what configuration?"
In the dashboard: Managing Tenants & Projects walks through creating and configuring them.
How they relate
- A tenant is an organization using Outpost. All other data - projects, messages, campaigns, stats - is scoped under a tenant.
- A project is a configuration container under a tenant. It holds API keys, webhook configs, and SMS compliance preferences. A tenant needs at least one project to generate an API key and start sending.
- Both are stats dimensions - you can ask "how much has this tenant/project spent this month?" See Stats.
Tenants
A tenant is intentionally minimal: an ID, a name, and a status (active / disabled / deleted).
Status controls access immediately. A tenant's status directly controls whether its API keys work. Disabling a tenant flips a denormalized tenantIsActive flag on every one of its keys, so requests are rejected with 401 on the very next call - without slowing down authentication.
Deletion is soft. Deleting a tenant marks it deleted and deactivates its keys; the record and all its data stay in the database for auditing. Deleted tenants disappear from all reads. Restoring one requires developer intervention - there is no API for it.
Projects
Projects are Outpost's configuration boundary. Unlike communications and campaigns (which downstream services own and Outpost auto-materializes), projects are always created explicitly because they require deliberate configuration choices.
A project owns:
- API keys - up to 10 per project. See API Keys.
- Webhook configs - up to 10 per project. See Webhooks.
- Compliance settings - whether sends include periodic "Reply STOP" reminder footers (
optOutRemindersEnabled, default on) and an optional sender identity prefix prepended to every outbound message (identityEnabled+identity, max 20 characters). How these drive message assembly is covered in Messages - compliance footers.
Limits are enforced atomically. A tenant can have at most 20 projects, enforced with an atomic conditional counter rather than a count query, so concurrent creates cannot slip past the cap. Soft-deleting a project frees a slot.
Status cascades like tenants. Disabling or deleting a project deactivates its API keys via the same denormalized-flag mechanism.
Design notes
- Why soft-delete? Tenants and projects are roots of large resource trees. Hard deletion would require cascading deletes across messages, stats, and events - expensive and risky. Soft-delete preserves audit data while revoking access instantly.
- Future direction for tenants: tenant management is expected to move upstream to the LXS Directory Service, at which point Outpost will auto-materialize tenant records on first reference. The minimal data model anticipates this.
API reference
POST /v1/tenants- create a tenantGET /v1/tenants- list tenantsPOST /v1/tenants/:tenantId/projects- create a project under a tenantGET /v1/projects- list projectsPATCH /v1/projects/:projectId- update a project (status, compliance settings)
Calling from TypeScript? See Generating a Typed Client.