How Distribu is organized

Distribu is multi-tenant: many distributors share the same application, but their data is strictly isolated. This page walks through the shape of that model so you know exactly what lives where, and how it stays separated.

Your company is the root

When you signed up, Distribu created a Company record for you. It has:

  • A name (what your customers see — e.g. "Acme Distributors")
  • A slug (your storefront URL — e.g. acme-distributors, so your portal is distribu.app/store/acme-distributors)
  • A billing profile (created when you pick a paid plan)

Everything else in the system — every product, order, team member, webhook — is owned by a company. There is no shared pool of products or customers across tenants.

The data model at a glance

Company
├── Memberships ────→ Users (your staff)
├── InviteTokens    (pending team invites)
├── Subscription ──→ Plan
├── Products
│   └── PriceOverrides (per-customer pricing)
├── Customers
│   ├── CustomerContacts   (sub-users under one customer)
│   ├── Addresses
│   └── PriceOverrides
├── Orders
│   ├── OrderItems ──→ Product
│   ├── Documents   (invoices, packing lists)
│   └── (frozen shipping address snapshot)
├── Documents       (per-customer file vault)
├── ApiKeys
├── Webhooks
│   └── WebhookDeliveries
└── AuditLogs

A few things worth calling out:

  • Users are global, memberships are per-company. A user record holds the email and password. A separate membership links that user to a company with a role. In the current phase every user has exactly one membership, but the model is ready for users to belong to multiple companies later.
  • Customers are per-company. Two different distributors can both have a customer called acme@example.com — they're separate customer records scoped to their company. Email uniqueness is enforced within a company, not globally.
  • Orders can be customer-less. Internal orders placed from Orders → New order in the dashboard have no customerId — useful for walk-ins and testing.
  • Shipping addresses are frozen on the order. When an order is placed we snapshot the address onto the order itself. If the customer later edits their address, historical orders still show the address as it was at the time.

How tenants stay isolated

Every piece of company-owned data is tagged with a company ID, and every request Distribu serves — dashboard pages, API endpoints, storefront loads — is scoped to the currently signed-in company. There is no "admin mode" that reaches across tenants.

When a company is deleted, every related record is removed with it so nothing is left orphaned. API keys, webhooks, products, customers, orders — all gone together.

This is also why you can't move data between companies. If you need to merge two Distribu accounts, contact support and we'll walk through it manually.

Your storefront slug

Your company's slug is the public handle for your storefront. It's auto-generated from your company name at signup (Acme Distributorsacme-distributors), and you can change it from Settings → General at any time.

The slug drives three URLs:

URLWhat it is
/store/{slug}Public catalog landing page
/store/{slug}/catalogBrowsable product grid
/store/{slug}/loginWhere customers (and contacts) sign in

Changing the slug updates all three immediately. If you had customers bookmarking the old URL, give them a heads up.

Trial and plan

Every new company starts on a 14-day free trial of the Starter plan with no credit card required. While you're trialing, every feature works exactly as it will on a paid plan — the only difference is the expiry. After 14 days you'll need to pick a plan from Billing to keep placing orders.

Plans cap usage at four levers:

  • maxProducts — how many active SKUs you can have
  • maxTeamMembers — staff + pending invites
  • maxCustomers — customer accounts (contacts don't count separately)
  • maxOrdersPerMonth — orders placed in the current calendar month

null on any of these means unlimited on that plan.

Audit log

Every meaningful change to your company's data — team invites, role changes, orders advanced, API keys created, webhooks configured — is recorded in the audit log. Each entry captures:

  • Who did it (actorId + actorType: USER, CUSTOMER, or SYSTEM)
  • What they did (action, entityType, entityId)
  • When and from where (createdAt, ipAddress)
  • Any extra context (metadata JSON)

The log is append-only. Distributors on regulated plans use it for compliance evidence; everyone else uses it for debugging "who changed that?".


Up next: Roles & permissions goes deeper on the three independent permission systems in Distribu — staff roles, customer contact roles, and API key scopes.