AI Setu Docs
Concepts

Agent provisioning

Stand up new billable child tenants with a single authenticated API call — no human, no inbox.

Normal account creation needs a human to read an OTP email. That's a wall for an agent, a CI job, or a fleet that needs to provision its own isolated workspaces on demand. Agent provisioning removes the human from every account after the first: one human-onboarded, payment-backed parent tenant mints a provisioning key once, and from then on an agent can create as many child tenants as it needs with a single API call.

This is Tier-1: operator/internal provisioning. Provisioning keys are minted by an org owner/admin (SETTINGS_UPDATE) for that org's own use — it is not yet a self-serve, publicly documented reseller product.

Minting a provisioning key

A provisioning key (tt_prov_…) is minted from an already-authenticated, cookie-based session — never from a PAT or another provisioning key (that privilege-chaining path is closed):

mutation {
  createProvisioningKey(
    input: { name: "sandbox-fleet", maxTenants: 50, expiresInDays: 90 }
  ) {
    id
    secret # shown once
  }
}

maxTenants and expiresInDays are both optional; omitting maxTenants means unlimited child tenants for that key. The key carries exactly one scope, provision:write, and is bound to the tenant and user that minted it. Treat it as a high-privilege, server-side-only secret — it can mint billable tenants and must never ship in client code.

Provisioning a tenant

curl https://api.aisetu.ai/provision/tenant \
  -H "Authorization: Bearer $AI_SETU_PROVISIONING_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Child Co",
    "region": "in",
    "billingMode": "delegated"
  }'
{
  "tenantId": "...",
  "workspaceId": "...",
  "apiKey": "tt_live_...",
  "topUpUrl": "https://..."
}

region (eu | in) defaults to the pod's own region if omitted. billingMode defaults to delegated. Secrets in the response are shown once — there is no way to retrieve apiKey again after this call.

Programmatically, the same call is admin.tenants.provision({...}) from @ai-setu/admin, which throws a clear error if the client wasn't constructed with a provisioning key — a PAT alone cannot provision tenants, by design. An MCP provision_tenant tool is also available and registers only when AI_SETU_PROVISIONING_KEY is set on the MCP server; see MCP for the full tool list and setup.

Billing modes

ModeStatusWho pays
delegatedDefault, fully wiredThe child tenant funds itself via the returned topUpUrl — identical to a normal new org that starts at $0.
pooledNot implemented in Tier-1Would draw on the parent's balance/payment method across the tenant boundary. Calling with billingMode: "pooled" returns a validation error; cross-tenant balance draw is deliberately not half-wired.

Quotas

maxTenants on the key (if set) is enforced per call, counting only tenants previously created by that specific key — never a parent-wide or cross-key count. The N+1 call over the limit is refused before any tenant is created.

Scope and isolation

  • The provisioning verifier only ever accepts the tt_prov_ prefix; it is a separate credential kind from both workspace API keys (tt_live_ / tt_test_) and PATs (tt_pat_). A tt_prov_ key is rejected on every ordinary workspace/PAT-authenticated route, and a PAT is rejected on POST /provision/tenant.
  • The provision:write scope is checked twice — once when the credential is resolved, once again inside the provisioning service — so a bug in one layer can't turn into a privilege escalation in the other.
  • Every child tenant is tagged with the provisioning key and parent tenant that created it, and every provisioning call writes an audit log entry.

What's next

Key rotation/revocation UI, an IP allowlist and per-key rate limit, a parent-side list/suspend view of provisioned children, and pooled billing are all Tier-2 work and not available yet.

On this page