Menu

Topic 4 of 8

Designing Multi Tenant APIs

Learn Designing Multi Tenant APIs for free with explanations, exercises, and a quick test (for API Engineer).

Published: January 21, 2026 | Updated: January 21, 2026

Why this matters

API Engineers frequently build platforms that serve many customers (tenants) through one API. Good multi-tenant design prevents data leaks, enables per-tenant limits and analytics, simplifies onboarding/offboarding, and supports growth without building one-off stacks.

  • Real tasks: expose tenant-scoped resources, enforce isolation in queries, implement per-tenant rate limits/quotas, run migrations per tenant, and provide cross-tenant admin views safely.
  • Teams expect: clear tenancy model, predictable URLs/headers, secure auth mapping, and easy observability per tenant.

Who this is for

  • API Engineers and Backend Developers building SaaS or internal platforms with multiple organizations/customers.
  • Architects deciding between path/header/subdomain tenant routing and isolation levels.

Prerequisites

  • Comfortable with HTTP methods, status codes, and authentication (e.g., OAuth2/JWT).
  • Familiarity with relational or NoSQL data modeling and indexes.
  • Basic understanding of API gateways, caching, and rate limiting.

Concept explained simply

Tenancy means multiple customers share the same platform while believing they have their own space. The API must always know which tenant a request is for and confine access, limits, and data accordingly.

  • Tenant identification: Where does the API learn the tenant? Commonly from an authenticated token claim, an HTTP header, a path parameter, or a subdomain.
  • Isolation: Ensure no data crosses tenant boundaries. Combine app-level checks with database-level protections (e.g., row-level security).
  • Scoping: Users belong to tenants; tokens must carry tenant context and scopes suitable for the tenant (or a controlled cross-tenant admin scope).

Mental model

Picture a building with many floors (tenants). Every call must first pick a floor, then operate only on rooms on that floor. Elevators (auth) encode the floor you’re allowed to reach. Maintenance staff (admins) have special keys but still log every cross-floor action.

Key design choices

1) How to pass tenant context
  • Path segment: /tenants/{tenantId}/projects. Easy to route and cache; explicit in logs.
  • Header: X-Tenant-ID: acme. Clean URLs; requires gateway awareness and strict server-side validation.
  • Subdomain: https://acme.api.example.com. Nice UX, but needs DNS/wildcard support and may complicate gateways.

Best practice: determine tenant from authenticated identity (token claim like tenant_id), optionally cross-check path/header to avoid confusion.

2) Isolation patterns
  • Data layers: shared DB (with row-level security), shared DB per schema, or separate DB per tenant.
  • API layer: always parameterize queries by tenant and enforce policies on every request.
  • Caches: include tenant in cache keys; never mix tenants.
3) Auth and scopes
  • Tokens carry sub (user/service), tenant_id, and scopes (e.g., projects:read).
  • Cross-tenant admin requires explicit elevated scope (e.g., tenants:all) and stricter auditing.
4) Rate limits, quotas, and analytics
  • Track and limit at least per-tenant; optionally per-subject within tenant.
  • Emit metrics with tenant_id tag for billing and health checks.
5) Pagination, search, and sorting
  • Always filter by tenant_id first; then apply sort and cursor.
  • Cursor should encode tenant to avoid cross-tenant leakage when reused.
6) Idempotency and concurrency
  • Scope idempotency keys to tenant + endpoint to avoid collisions.
  • Use optimistic concurrency (If-Match/ETag) with tenant-aware checks.

Worked examples

Example 1: Path-based tenant with token cross-check
Request:
GET /tenants/acme/projects?limit=50
Authorization: Bearer eyJ... (claims: {"sub":"u1","tenant_id":"acme","scope":"projects:read"})

Server steps:
1) Extract tenant from token (acme).
2) Cross-check with path param (acme). If mismatch, 400 or 403.
3) Query: SELECT * FROM projects WHERE tenant_id = 'acme' ORDER BY id DESC LIMIT 50;
4) Return only acme's projects.
    
Example 2: Header-based tenant with RLS
Request:
POST /projects
Authorization: Bearer ... (tenant_id: "zeus")
X-Tenant-ID: zeus
Body: {"name":"Roadmap"}

DB policy (conceptual):
CREATE POLICY tenant_isolation ON projects
  USING (tenant_id = current_setting('app.tenant_id'))
  WITH CHECK (tenant_id = current_setting('app.tenant_id'));

App sets current_setting('app.tenant_id') = 'zeus' per request.
Insert is allowed only with tenant_id='zeus'.
    
Example 3: Cross-tenant admin listing with explicit scope
Request:
GET /admin/tenants/summary
Authorization: Bearer ... (scopes: ["tenants:all","analytics:read"])  // service account

Server rules:
- Endpoint exists under /admin/* only.
- Requires tenants:all scope.
- Queries aggregate by tenant_id; no raw PII returned by default.
- Audit log entry with requester, reason, and filters.
    

Learning path

  1. Start with tenant identification patterns (path/header/token claims).
  2. Add strict isolation at the API and database layers.
  3. Implement per-tenant rate limiting and metrics.
  4. Design pagination and idempotency with tenant awareness.
  5. Add admin-only cross-tenant operations with auditing.

Common mistakes and self-check

  • Mistake: relying only on client-supplied tenant headers. Self-check: ensure tenant is derived from authenticated identity and cross-checked with any client hint.
  • Mistake: forgetting tenant in cache keys. Self-check: inspect cache key format; it must include tenant_id.
  • Mistake: cursors that work across tenants. Self-check: verify cursor encodes tenant and becomes invalid across tenants.
  • Mistake: global rate limit only. Self-check: confirm you have per-tenant and optional per-subject limits.
  • Mistake: missing audits for admin cross-tenant actions. Self-check: look for structured audit logs on /admin routes.

Practical projects

  • Build a small SaaS-like API (e.g., projects/tasks) with /tenants/{tenantId} paths, JWT with tenant_id, and tenant-scoped queries.
  • Add per-tenant rate limiting counters and an endpoint /tenants/{tenantId}/usage exposing current usage.
  • Implement admin summary /admin/tenants/summary requiring a special scope and emitting audit logs.

Exercises

Do these to cement the concepts. You can take the quick test after exercises. The test is available to everyone; only logged-in users get saved progress.

Exercise 1 — Model tenant routing for a project API

Design endpoints and auth checks for listing and creating projects under a tenant. Choose either path-based or header-based tenant routing, and describe server-side validation.

  • Deliverable: concrete HTTP examples and validation rules.
  • Goal: explicit, unambiguous tenant context and secure cross-checks.
Exercise 2 — Enforce tenant isolation in data access

Write pseudocode or SQL policy that guarantees only rows for the authenticated tenant are returned/modified, and show an example query.

  • Deliverable: code snippet + short explanation.
  • Goal: defense-in-depth at API and DB layers.
  • Checklist before you move on:
    • I can explain how tenant_id is determined and cross-checked.
    • My cache, pagination, and idempotency keys include tenant context.
    • I can describe per-tenant limits, metrics, and audits.

Mini challenge

You need to support both tenant users and reseller admins who manage multiple tenants. Describe your URL and auth approach so that normal users are always scoped to their single tenant, while reseller admins can switch tenants deliberately and safely. Include how logs and audits will show the effective tenant for every request.

Next steps

  • Harden cross-tenant admin routes with explicit scopes, reason codes, and rate limits.
  • Add tenant-aware observability: logs/metrics/traces tagged with tenant_id and requester.
  • Plan lifecycle events: onboarding, suspension, export, and deletion per tenant.

Practice Exercises

2 exercises to complete

Instructions

Design list/create endpoints for projects in a multi-tenant SaaS. Choose path-based or header-based routing. Show at least two HTTP requests (list, create) and describe server-side validation using token claims. Include how to respond on tenant mismatch.

Expected Output
Two concrete HTTP examples with Authorization header, either /tenants/{tenantId}/projects or X-Tenant-ID header, plus a short validation algorithm and expected 400/403 on mismatch.

Designing Multi Tenant APIs — Quick Test

Test your knowledge with 10 questions. Pass with 70% or higher.

10 questions70% to pass

Have questions about Designing Multi Tenant APIs?

AI Assistant

Ask questions about this tool