Skip to main content

The two-level model

Every GetSigned resource is scoped by two IDs:
IDWhat it representsWhere it comes from
app_idYour API client (your SaaS product)Derived from your client_id — set automatically
tenant_idA customer within your productYou supply this on every request

What is a tenant?

A tenant is any unit of ownership within your platform. Depending on your product:
  • For a healthcare SaaS: a clinic or practice (tenant_id = "clinic-001")
  • For a legal platform: a law firm (tenant_id = "firm-greenwood")
  • For an HR tool: a company (tenant_id = "company-acme")
You decide what a tenant is. GetSigned doesn’t validate or resolve tenant IDs — it just uses them to scope all data storage and retrieval. Data from Tenant A is never visible to Tenant B, even through the same API credentials.

Setting tenant_id

Pass tenantId on every envelope creation request:
curl -X POST https://api.getsigned.ca/v1/envelopes \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "tenantId": "acme-corp",
    "subject": "NDA",
    ...
  }'
If you’re sending envelopes for a single organization (your own), use a fixed tenantId.

Listing envelopes for a tenant

All list endpoints are filtered by the token’s app_id. To further filter by tenant:
curl "https://api.getsigned.ca/v1/envelopes?tenantId=acme-corp" \
  -H "Authorization: Bearer $TOKEN"
This returns only envelopes for acme-corp. Your API credentials cannot access envelopes belonging to another app’s tenants — the isolation is enforced at the database level.

Data isolation guarantee

GetSigned enforces multi-tenant isolation at two levels:
  1. Application level — your API token can only access records where app_id matches your registered application. No cross-app leakage.
  2. Tenant levelGET /v1/envelopes?tenantId=X only returns records matching both your app_id AND tenantId=X. Omitting tenantId returns all your tenants’ data, scoped to your app.
If your SaaS serves multiple customers and each customer should only see their own documents, always pass tenantId in your API calls and always filter by tenantId in your own data layer. Do not rely on a UI filter alone.

One set of credentials, many tenants

You don’t need a separate GetSigned application per tenant. One client_id / client_secret pair serves all your tenants. tenantId is just a tag — it costs nothing to create a new one. This means:
  • No per-customer credential management
  • No per-customer onboarding in GetSigned
  • Billing is at the application level (across all your tenants)

Webhook routing

Webhooks fire to your configured endpoint for all events across all tenants. The payload always includes tenantId, so you can route events to the right customer in your system:
{
  "event": "envelope.completed",
  "data": {
    "envelopeId": "env_01HX...",
    "tenantId": "acme-corp",
    ...
  }
}