Skip to main content
CoreSDK
Multi-Tenancy

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.toml under [[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:

Planreq/minStorageSeats
Free5001 GB5
Starter2,00010 GB25
Business10,000100 GB200
Enterprisecustomcustomcustom

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

On this page