Tenants API
REST API endpoints for creating and managing tenants in your HelloJohn instance.
Tenants API
Tenants are the top-level isolation unit in HelloJohn. Each tenant has its own users, organizations, API keys, and configuration. This API is available on the Control Plane and requires a master API key.
Note: The Tenants API is used for multi-tenant SaaS platforms that manage many customer tenants programmatically. If you are building a single-product app, you typically have one tenant and don't need this API.
Tenant Object
{
"id": "tnt_01HABCDEF654321",
"name": "Acme Corp",
"slug": "acme-corp",
"status": "active",
"plan": "pro",
"user_count": 250,
"org_count": 12,
"auth_config": {
"allowed_origins": ["https://app.acme.com"],
"session_duration": "30d",
"mfa_required": false,
"password_min_length": 8
},
"public_metadata": {},
"private_metadata": {},
"created_at": "2024-01-10T09:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}GET /v1/tenants
List all tenants in your HelloJohn instance.
Authentication: Master API key (mk_live_...)
Query parameters:
| Parameter | Type | Description |
|---|---|---|
q | string | Search by name or slug |
status | string | active, suspended, deleted |
plan | string | Filter by plan |
limit | integer | Default 20, max 100 |
cursor | string | Pagination cursor |
curl "https://api.hellojohn.dev/v1/tenants" \
-H "Authorization: Bearer mk_live_master_key_here"POST /v1/tenants
Create a new tenant.
Authentication: Master API key
Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Tenant display name |
slug | string | — | URL-safe identifier (auto-generated if omitted) |
plan | string | — | free, starter, pro, enterprise |
owner_email | string | — | Create an owner user automatically |
auth_config | object | — | Initial auth configuration |
public_metadata | object | — | Custom public data |
private_metadata | object | — | Custom private data (not exposed to frontend) |
curl -X POST "https://api.hellojohn.dev/v1/tenants" \
-H "Authorization: Bearer mk_live_master_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"slug": "acme-corp",
"plan": "pro",
"owner_email": "admin@acme.com",
"auth_config": {
"allowed_origins": ["https://app.acme.com"],
"session_duration": "30d"
}
}'Response: 201 Created — Returns tenant object with auto-generated API keys.
{
"id": "tnt_01HABCDEF654321",
"name": "Acme Corp",
"slug": "acme-corp",
"status": "active",
"publishable_key": "pk_live_...",
"secret_key": "sk_live_...",
"created_at": "2024-01-15T10:00:00Z"
}GET /v1/tenants/:id
Fetch a single tenant by ID or slug.
Also supported: GET /v1/tenants/slug/:slug
PATCH /v1/tenants/:id
Update a tenant.
Body (all optional):
| Field | Type | Description |
|---|---|---|
name | string | Display name |
slug | string | URL identifier |
plan | string | Billing plan |
status | string | active or suspended |
auth_config | object | Auth settings (merged, not replaced) |
public_metadata | object | Replaces entire public_metadata |
private_metadata | object | Replaces entire private_metadata |
Auth Config Options
| Key | Type | Default | Description |
|---|---|---|---|
allowed_origins | array | [] | CORS-allowed origins |
session_duration | string | 30d | Session lifetime |
access_token_ttl | string | 1h | Access token lifetime |
mfa_required | boolean | false | Require MFA for all users |
password_min_length | integer | 8 | Minimum password length |
password_require_uppercase | boolean | false | Require uppercase characters |
password_require_number | boolean | false | Require numeric characters |
password_require_symbol | boolean | false | Require symbol characters |
email_verification_required | boolean | true | Require email verification |
sign_up_enabled | boolean | true | Allow new sign-ups |
DELETE /v1/tenants/:id
Delete a tenant and all associated data. This is irreversible.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
confirm | string | ✅ | Must be the tenant slug to confirm |
curl -X DELETE "https://api.hellojohn.dev/v1/tenants/tnt_01HABCDEF654321?confirm=acme-corp" \
-H "Authorization: Bearer mk_live_master_key_here"Response: 204 No Content
POST /v1/tenants/:id/suspend
Suspend a tenant. All sign-ins are rejected; existing sessions remain valid until they expire.
curl -X POST "https://api.hellojohn.dev/v1/tenants/tnt_01HABCDEF654321/suspend" \
-H "Authorization: Bearer mk_live_master_key_here" \
-H "Content-Type: application/json" \
-d '{"reason": "Outstanding invoice"}'Response: 200 OK
POST /v1/tenants/:id/restore
Restore a suspended tenant to active status.
Response: 200 OK
GET /v1/tenants/:id/stats
Get usage statistics for a tenant.
curl "https://api.hellojohn.dev/v1/tenants/tnt_01HABCDEF654321/stats" \
-H "Authorization: Bearer mk_live_master_key_here"Response:
{
"tenant_id": "tnt_01HABCDEF654321",
"users": {
"total": 250,
"active_last_30d": 187,
"new_last_30d": 23
},
"sessions": {
"active": 94,
"created_last_30d": 1203
},
"organizations": {
"total": 12
},
"mfa": {
"enrolled_users": 65,
"enrollment_rate": 0.26
}
}