Tenant Provisioning
Create, configure, and manage tenant lifecycle programmatically with CoreSDK.
Tenant Provisioning
Phase 2. The programmatic tenant provisioning API ships Phase 2. In Phase 1, tenants are declared statically in
coresdk.tomlunder[[tenants]].
CoreSDK exposes a full tenant management API — create tenants with metadata and plan limits, suspend or delete them, and bulk-provision at scale.
Creating tenants
A tenant requires a unique ID, a display name, and a plan tier. Additional metadata is freeform JSON.
use coresdk_engine::{CoreSDK, tenant::{TenantCreate, Plan}};
use serde_json::json;
let tenant = sdk.tenants().create(TenantCreate {
id: "acme".to_string(),
name: "Acme Corp".to_string(),
plan: Plan::Business,
metadata: json!({
"region": "us-east-1",
"salesforce_id": "0011U00001LkWnEQAV",
"support_tier": "priority",
}),
}).await?;
println!("Created tenant: {}", tenant.id);tenant = await sdk.tenants.create({
"id": "acme",
"name": "Acme Corp",
"plan": "business",
"metadata": {
"region": "us-east-1",
"salesforce_id": "0011U00001LkWnEQAV",
"support_tier": "priority",
},
})
print(f"Created tenant: {tenant.id}")tenant, err := sdk.Tenants().Create(ctx, coresdk.TenantCreate{
ID: "acme",
Name: "Acme Corp",
Plan: coresdk.PlanBusiness,
Metadata: map[string]any{
"region": "us-east-1",
"salesforce_id": "0011U00001LkWnEQAV",
"support_tier": "priority",
},
})
if err != nil {
return err
}
fmt.Printf("Created tenant: %s\n", tenant.ID)const tenant = await sdk.tenants.create({
id: "acme",
name: "Acme Corp",
plan: "business",
metadata: {
region: "us-east-1",
salesforceId: "0011U00001LkWnEQAV",
supportTier: "priority",
},
});
console.log(`Created tenant: ${tenant.id}`);Tenant metadata and plan limits
Plans map to built-in limit presets. You can also override individual limits per tenant.
use coresdk_engine::tenant::{TenantCreate, Plan, Limits};
sdk.tenants().create(TenantCreate {
id: "enterprise-corp".to_string(),
name: "Enterprise Corp".to_string(),
plan: Plan::Enterprise,
// Override specific limits on top of the plan preset
limits: Some(Limits {
requests_per_minute: Some(50_000),
storage_gb: Some(500),
seats: Some(1000),
..Default::default()
}),
metadata: json!({ "contract_end": "2027-01-01" }),
}).await?;await sdk.tenants.create({
"id": "enterprise-corp",
"name": "Enterprise Corp",
"plan": "enterprise",
"limits": {
"requests_per_minute": 50_000,
"storage_gb": 500,
"seats": 1000,
},
"metadata": {"contract_end": "2027-01-01"},
})sdk.Tenants().Create(ctx, coresdk.TenantCreate{
ID: "enterprise-corp",
Name: "Enterprise Corp",
Plan: coresdk.PlanEnterprise,
Limits: &coresdk.Limits{
RequestsPerMinute: ptr(50_000),
StorageGB: ptr(500),
Seats: ptr(1000),
},
Metadata: map[string]any{"contract_end": "2027-01-01"},
})await sdk.tenants.create({
id: "enterprise-corp",
name: "Enterprise Corp",
plan: "enterprise",
limits: {
requestsPerMinute: 50_000,
storageGb: 500,
seats: 1000,
},
metadata: { contractEnd: "2027-01-01" },
});Built-in plan presets:
| Plan | req/min | Storage | Seats |
|---|---|---|---|
| Free | 500 | 1 GB | 5 |
| Starter | 2,000 | 10 GB | 25 |
| Business | 10,000 | 100 GB | 200 |
| Enterprise | custom | custom | custom |
Tenant lifecycle: suspend and delete
Suspending a tenant blocks all API access while preserving data. Deletion is permanent and cascades to all tenant data.
// Suspend (reversible — blocks API access, data retained)
sdk.tenants().suspend("acme", SuspendReason::PaymentFailed).await?;
// Reactivate
sdk.tenants().reactivate("acme").await?;
// Delete permanently (cascades to all tenant data)
sdk.tenants().delete("acme").await?;
// Soft-delete with 30-day grace period before purge
sdk.tenants().delete_with_grace("acme", Duration::days(30)).await?;# Suspend
await sdk.tenants.suspend("acme", reason="payment_failed")
# Reactivate
await sdk.tenants.reactivate("acme")
# Delete permanently
await sdk.tenants.delete("acme")
# Soft-delete with grace period
from datetime import timedelta
await sdk.tenants.delete_with_grace("acme", grace_period=timedelta(days=30))// Suspend
err := sdk.Tenants().Suspend(ctx, "acme", coresdk.SuspendReasonPaymentFailed)
// Reactivate
err = sdk.Tenants().Reactivate(ctx, "acme")
// Delete permanently
err = sdk.Tenants().Delete(ctx, "acme")
// Soft-delete with grace period
err = sdk.Tenants().DeleteWithGrace(ctx, "acme", 30*24*time.Hour)// Suspend
await sdk.tenants.suspend("acme", { reason: "payment_failed" });
// Reactivate
await sdk.tenants.reactivate("acme");
// Delete permanently
await sdk.tenants.delete("acme");
// Soft-delete with grace period
await sdk.tenants.deleteWithGrace("acme", { graceDays: 30 });Bulk provisioning
Provision thousands of tenants in a single API call. CoreSDK processes bulk operations transactionally — partial failures are reported per-item without rolling back successful creates.
use coresdk_engine::tenant::BulkCreate;
let results = sdk.tenants().bulk_create(vec![
TenantCreate { id: "tenant-001".into(), plan: Plan::Starter, ..Default::default() },
TenantCreate { id: "tenant-002".into(), plan: Plan::Starter, ..Default::default() },
TenantCreate { id: "tenant-003".into(), plan: Plan::Business, ..Default::default() },
]).await?;
for result in &results {
match result {
Ok(t) => println!("Created: {}", t.id),
Err(e) => eprintln!("Failed: {}", e),
}
}results = await sdk.tenants.bulk_create([
{"id": "tenant-001", "plan": "starter"},
{"id": "tenant-002", "plan": "starter"},
{"id": "tenant-003", "plan": "business"},
])
for r in results:
if r.ok:
print(f"Created: {r.tenant.id}")
else:
print(f"Failed: {r.error}")results, err := sdk.Tenants().BulkCreate(ctx, []coresdk.TenantCreate{
{ID: "tenant-001", Plan: coresdk.PlanStarter},
{ID: "tenant-002", Plan: coresdk.PlanStarter},
{ID: "tenant-003", Plan: coresdk.PlanBusiness},
})
for _, r := range results {
if r.Err != nil {
fmt.Printf("Failed: %v\n", r.Err)
continue
}
fmt.Printf("Created: %s\n", r.Tenant.ID)
}const results = await sdk.tenants.bulkCreate([
{ id: "tenant-001", plan: "starter" },
{ id: "tenant-002", plan: "starter" },
{ id: "tenant-003", plan: "business" },
]);
for (const r of results) {
if (r.ok) {
console.log(`Created: ${r.tenant.id}`);
} else {
console.error(`Failed: ${r.error}`);
}
}Next steps
- Quotas & Rate Limits — enforce per-tenant usage caps
- Custom Domains & Branding — map domains to tenants
- Tenant Isolation — policy namespaces and audit streams