---
title: Multi-tenancy · BuzzKit
description: One workspace, a tenant per customer, each with isolated subscribers, credentials and sends.
canonical: https://buzzkit.dev/features/multi-tenancy
last-updated: 2026-09-02
---

# Send for your customers. One workspace, a tenant per app, one key.

A tenant is one of your customers: its own subscribers, topics, credentials, segments, workflows and messages, isolated from every other tenant. Your platform stores one workspace key and names the tenant on each request. An app with a single tenant never notices any of this.

## One key, one header

Create tenants with your workspace key and act on them with the same key. A tenant-scoped call adds a header naming the tenant, the way a Stripe platform names a connected account. Without the header, the default tenant answers.

```
POST /v1/tenants
{
  "name": "Gymly",
  "slug": "gymly",
  "metadata": { "customerId": "cus_8f2" }
}

POST /v1/messages
buzzkit-tenant: gymly
{ "to": "user_42", "title": "Leg day" }
```

## Isolated by default

Each tenant brings its own Apple and Firebase credentials, and its subscribers, topics, segments, workflows, sources and messages never mix. Members, API keys and the audit log belong to the workspace and stay shared.

```
GET /v1/subscribers
buzzkit-tenant: gymly

// Only Gymly’s subscribers, on Gymly’s credentials
{
  "data": [{ "externalId": "user_42" }],
  "total": 13460
}
```

## Keys with a smaller blast radius

A tenant key is locked to one tenant and can only reach that tenant’s data, for handing a customer or a subsystem direct access. Every tenant also gets a client key that ships in the app and can only identify subscribers and register devices.

```
// Workspace key: every tenant, named per request
Authorization: Bearer bk_ws_…
buzzkit-tenant: gymly

// Tenant key: one tenant, no header needed
Authorization: Bearer bk_tn_…

// Client key: ships in the app, client API only
Authorization: Bearer bk_pk_…
```

## Capabilities

- **Default tenant.** Every workspace starts with one, so a single app never has to learn about tenants.
- **Your customer id.** Store your own ids in the tenant’s metadata and find it by them.
- **Settings per tenant.** Pause a channel or require identity verification for one tenant only.
- **Identity secret.** A per-tenant secret proves who a subscriber is. Rotate it any time.
- **Dashboard switcher.** Inspect any tenant’s subscribers, messages and runs from the workspace switcher.
- **Audit trail.** Creating, changing and deleting tenants lands in the workspace audit log.

## Questions

### Is a tenant an environment?

No. A tenant is a customer or an app you send for, with its own data and credentials. Environments are handled by the credentials themselves: an Apple key covers sandbox and production.

### Do I need an API key per tenant?

No. Store one workspace key and pass the tenant slug in the buzzkit-tenant header. Tenant keys exist for delegating one tenant’s access and are never required.

### Can I delete a tenant?

Yes. Deleting a tenant revokes its tenant keys and hides its data. The default tenant cannot be deleted or renamed.

## Related

- [Sending](https://buzzkit.dev/features/sending.md): One POST sends to a subscriber, a topic or a segment and lands on every device.
- [Delivery](https://buzzkit.dev/features/delivery.md): A durable queue, progressive retries, and a ledger of every attempt to every device.
- [Topics & Preferences](https://buzzkit.dev/features/topics.md): Named notification categories with per-topic, per-channel choices for every subscriber.

## Start

- [Start sending](https://buzzkit.dev/dashboard)
- [API Reference](https://docs.buzzkit.dev)
- [BuzzKit on GitHub](https://github.com/buzzkit-dev/buzzkit)
