Skip to main content
POST /v1/tenants provisions a new isolated Knock2 sub-tenant under your parent account. Use this endpoint to programmatically onboard customers in multi-tenant SaaS products — each sub-tenant gets its own API key, tracking script, and data isolation boundary. The response includes a one-time API key and a ready-to-embed script URL for the new tenant. Provisioning a tenant immediately enables IP-to-company identification and person identification for that tenant.

Endpoint

Request Body

string
required
A human-readable display name for the tenant (e.g. "Acme Corp"). Shown in the Knock2 dashboard.
string
required
The primary website domain for the tenant (e.g. acme.com). Knock2 uses this to scope visitor identification to the correct site, and to derive the tenant’s product_slug (see below).
string
A brief description of the tenant’s product or business (e.g. "B2B project management SaaS"). Providing this helps Knock2 tune ICP scoring for the tenant’s specific market.
array
An optional array of credit allocations to apply immediately at provisioning time — equivalent to following up with a PUT /v1/tenants/{product_slug}/limits call. Each entry has the same shape as that endpoint’s request body:
  • type (credits | contacts | accounts)
  • value (number, in natural units for the chosen type)
  • period (billing_period | month | week | day | lifetime)
  • is_enforced (boolean, default true)
See Replace Tenant Limits for the full semantics.
object
An optional Company Profile + Buyer Persona configuration to apply immediately at provisioning time — equivalent to following up with a PATCH /v1/tenants/{product_slug}/scoring-config call. Every field within it is itself optional; send only what you have.
  • name, category, overview, linkedin_company_url — Company Profile fields (note overview here is a nested shorthand for the same concept as the top-level overview field above — if both are supplied, the top-level overview wins).
  • persona_description, company_description — plain-English Buyer Persona descriptions used to score contacts and accounts.
  • persona_weight — a number between 0 and 1 weighting persona fit against company fit when scoring.
See Get Scoring Config for the full field reference.
object
An optional tracking-script exclusion configuration to apply immediately at provisioning time — equivalent to following up with a PATCH /v1/tenants/{product_slug}/script-config call.
  • pages_to_ignore — an array of regex patterns matched against window.location.pathname in the browser. A visitor’s page fully skips the tracking script — no session, no identification, no credits spent — if it matches any pattern in this list.
Every pattern is validated with a regex compile check before being saved; a pattern that fails to compile returns 400 and the tenant is still created (this field is applied after the tenant row itself, so a rejected pattern here doesn’t roll back provisioning — fix the pattern and call Update Script Config directly instead). See Get Script Config for the full field reference.
string
deprecated
Deprecated and ignored. Earlier versions of this API let callers choose their own product_slug. As of KNO-1546, the slug is always derived server-side from domain, namespaced under your own account — see below. A value supplied here is silently ignored; read the authoritative slug from the response.

How product_slug is derived

You no longer choose a product_slug. It’s computed from the cleaned domain you provide, namespaced under your own account’s slug — for example, acme.com provisioned by a parent whose own slug is yourco_com becomes acme_com_yourco_com. This guarantees a child’s slug can never collide with, or be squatted ahead of, a future direct signup for that same domain under a different account. Because the derivation is deterministic, provisioning is idempotent per domain per parent: calling this endpoint twice for the same domain under the same parent always resolves to the same slug, and the second call 409s (see below) rather than creating a duplicate. If a tenant for that domain was previously deactivated, this endpoint does not resurrect it — use POST /v1/tenants/{product_slug}/activate instead.

Example Request

Response

A successful request returns 201 Created with a TenantCreateData body.
string
The server-derived, parent-namespaced slug identifier for the newly provisioned tenant. Use this value (not anything you sent) in every subsequent /v1/tenants/{product_slug} call.
string
The API key for the new tenant. Returned only once at creation time — store it immediately. Its default scopes are accounts:read, contacts:read, filter_sets:read, filter_sets:write, and tenants:read — enough for the child to read its own data and remaining allocation, but not to raise its own limits.
string
The tracking script URL pre-configured for this tenant. Embed it in the tenant’s site to begin visitor identification.
api_key is returned only once, at the moment of tenant creation. Store it in a secure secrets manager immediately — Knock2 does not store or expose it again after this response.

Side Effects

Provisioning a tenant immediately enables IP-to-company identification and person identification for that tenant. Visitor identification and lead scoring are active as soon as the tracking script is installed on the tenant’s site. If limits was supplied, the allocation set is written and enforced immediately. API-created tenants are always combined billing (billing_mode: "parent") — usage rolls up to the calling key’s own subscription, same as before this endpoint gained per-child limits.

Required Scope

This endpoint requires the tenants:write scope on your parent API key. Keys that lack this scope receive a 403 error. A key belonging to a child tenant (one that itself has a parent_product_slug) can never create sub-tenants of its own, regardless of scope.

Error Responses