Skip to content

Multi-Tenancy

Entity Model

Entity model
┌───────────────────────────────────────────┐
│              Your Platform                │
│         (Account-level API key)           │
└───────────────────┬───────────────────────┘
                    │
      ┌─────────────┼─────────────┐
      │             │             │
      ▼             ▼             ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│  Entity A │ │  Entity B │ │  Entity C │
├───────────┤ ├───────────┤ ├───────────┤
│ • Data    │ │ • Data    │ │ • Data    │
│ • Config  │ │ • Config  │ │ • Config  │
│ • Users   │ │ • Users   │ │ • Users   │
└───────────┘ └───────────┘ └───────────┘

Each entity is fully isolated—data never mixes between entities.

Creating Entities

Create an entity for each of your customers:

Create entitytypescript
import SpaceInvoices from "@spaceinvoices/js-sdk";

const sdk = new SpaceInvoices("YOUR_API_KEY");

const _entity = await sdk.entities.create({
  name: "Acme Corporation",
  address: "123 Business Ave",
  city: "San Francisco",
  post_code: "94102",
  country: "United States",
  currency_code: "USD",
});

Per-Entity Operations

All operations are scoped to an entity:

Entity-scoped operationstypescript
// List invoices for a specific entity
const _invoices = await sdk.invoices.list({ entity_id: "ent_123" });

// Create customer in a specific entity
const _customer = await sdk.customers.create(
  { name: "New Customer", email: "customer@example.com" },
  { entity_id: "ent_123" },
);

Entity Settings

Customize defaults and number formats per entity:

Update settingstypescript
await sdk.entities.update("ent_123", {
  settings: {
    default_invoice_note: "Thank you for your business!",
    default_invoice_payment_terms: "Payment due within 30 days.",
    number_formats: {
      invoice: "INV-{YYYY}-{NUM}",
      estimate: "EST-{YYYY}-{NUM}",
      credit_note: "CN-{YYYY}-{NUM}",
    },
  },
});

Number format placeholders: {NUM} (sequential), {YYYY} (year), {YY} (2-digit year), {MM} (month), {DD} (day).

Listing Entities

List entitiestypescript
// Basic listing
const _entities = await sdk.entities.list();

// With pagination
const _paginated = await sdk.entities.list({ limit: 20, next_cursor: "ent_abc..." });

// With search
const _searched = await sdk.entities.list({ search: "acme" });

API Key Types

There are two types of API keys, each with different access scopes:

Key TypePrefixScopeUse Case
Account keysk_*All entities + account managementYour backend server
Entity keyek_*Single entity onlyCustomer-facing integrations
API key types
┌─────────────────────────────────────────────────────┐
│                    Account                          │
│               sk_* (Account Key)                    │
│          Access all entities + management           │
└──────────────┬──────────────────┬───────────────────┘
               │                  │
       ┌───────▼───────┐  ┌──────▼────────┐
       │   Entity A    │  │   Entity B    │
       │ ek_* (Entity  │  │ ek_* (Entity  │
       │     Key)      │  │     Key)      │
       ├───────────────┤  ├───────────────┤
       │ • Invoices    │  │ • Invoices    │
       │ • Customers   │  │ • Customers   │
       │ • Items       │  │ • Items       │
       │ • Settings    │  │ • Settings    │
       └───────────────┘  └───────────────┘

  sk_*  →  Full access (create entities, manage account)
  ek_*  →  Scoped access (single entity only)

Create an entity-scoped API key to give a customer access to their entity only:

Create entity API keytypescript
import SpaceInvoices from "@spaceinvoices/js-sdk";

// Use your account-level key (sk_*) to create entity keys
const sdk = new SpaceInvoices("YOUR_ACCOUNT_KEY");

const _apiKey = await sdk.entityApiKeys.create({
  name: "Customer Portal Key",
});
// Returns an ek_* key scoped to this entity only

Data Isolation

Each entity is a fully isolated silo. There is no cross-entity access:

  • Invoices, customers, items, and all other resources belong to exactly one entity
  • Entity keys can only read and write data within their entity
  • Account keys can access all entities but still operate on one entity at a time (via the x-entity-id header on entity-scoped endpoints)

Common Patterns

One Entity Per Customer

The most common pattern — each of your customers gets their own entity. This gives each customer their own invoice numbering, settings, and data.

Your Platform
├── Entity: "Customer A Corp" → their invoices, customers, items
├── Entity: "Customer B LLC" → their invoices, customers, items
└── Entity: "Customer C Inc" → their invoices, customers, items

Multiple Entities Per Customer

Some customers need separate invoicing for different business units (e.g., different countries, brands, or departments). Create multiple entities and group them by customer on your side.

Giving Your Customers Access

ApproachHowBest For
Entity API keyCreate an ek_* key and use it only in a controlled server-side or launch flowCustomers who need isolated access without full user management
Your backend as proxyYour server uses sk_*, customers call your APIFull control over access

Next Steps