Tenant Management
Manage tenants in your Approved Contact account. Tenants represent organizations or business units that can have their own phone numbers, settings, and webhook configurations. This is essential for multi-tenant applications or managing multiple customer accounts.
Creating Tenants
Create a new tenant with custom settings, webhook configuration, and domain assignment. Tenants are automatically assigned an owner based on your authentication credentials.
Example: Create a Tenant
curl -X POST https://api.approvedcontact.com/api/v1/tenants \
-u "your-email@example.com:your-password" \
-H "Content-Type: application/json" \
-d '{
"tenantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"domain": "customer.example.com",
"settings": {
"webhookPrimaryUri": "https://customer.example.com/webhooks/messages",
"webhookSecondaryUri": "https://backup.example.com/webhooks/messages",
"webhookSecret": "your-secure-secret-key"
}
}'
import requests
import base64
import uuid
credentials = base64.b64encode(b'your-email@example.com:your-password').decode()
response = requests.post(
'https://api.approvedcontact.com/api/v1/tenants',
headers={'Authorization': f'Basic {credentials}'},
json={
'tenantId': str(uuid.uuid4()), # Optional - auto-generated if not provided
'domain': 'customer.example.com',
'settings': {
'webhookPrimaryUri': 'https://customer.example.com/webhooks/messages',
'webhookSecondaryUri': 'https://backup.example.com/webhooks/messages',
'webhookSecret': 'your-secure-secret-key'
}
}
)
tenant = response.json()
print(f"Created tenant: {tenant['tenantId']}")
var client = new HttpClient();
var credentials = Convert.ToBase64String(
Encoding.ASCII.GetBytes("your-email@example.com:your-password"));
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", credentials);
var request = new
{
tenantId = Guid.NewGuid().ToString(), // Optional
domain = "customer.example.com",
settings = new
{
webhookPrimaryUri = "https://customer.example.com/webhooks/messages",
webhookSecondaryUri = "https://backup.example.com/webhooks/messages",
webhookSecret = "your-secure-secret-key"
}
};
var response = await client.PostAsJsonAsync(
"https://api.approvedcontact.com/api/v1/tenants",
request
);
var tenant = await response.Content.ReadFromJsonAsync();
Console.WriteLine($"Created tenant: {tenant.TenantId}");
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const credentials = Buffer.from('your-email@example.com:your-password').toString('base64');
axios.post(
'https://api.approvedcontact.com/api/v1/tenants',
{
tenantId: uuidv4(), // Optional
domain: 'customer.example.com',
settings: {
webhookPrimaryUri: 'https://customer.example.com/webhooks/messages',
webhookSecondaryUri: 'https://backup.example.com/webhooks/messages',
webhookSecret: 'your-secure-secret-key'
}
},
{
headers: { 'Authorization': `Basic ${credentials}` }
}
)
.then(response => {
console.log(`Created tenant: ${response.data.tenantId}`);
});
Create Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
tenantId |
GUID | No | Tenant ID (auto-generated if not provided) |
domain |
string | No | Custom domain for this tenant |
settings |
object | No | Tenant settings including webhooks |
owner and billableOwner fields
are automatically set based on your authentication credentials and cannot be specified in the request.
This ensures proper billing and access control.
Listing Tenants
Retrieve all tenants associated with your owner account or get details about a specific tenant.
List All Tenants
curl -X GET https://api.approvedcontact.com/api/v1/tenants \
-u "your-email@example.com:your-password"
Get Specific Tenant
curl -X GET https://api.approvedcontact.com/api/v1/tenants/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
-u "your-email@example.com:your-password"
Response Example
{
"tenantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"owner": "owner@approvedcontact.com",
"billableOwner": "billing@approvedcontact.com",
"domain": "customer.example.com",
"createdDate": "2025-01-11T10:30:00Z",
"settings": {
"webhookPrimaryUri": "https://customer.example.com/webhooks/messages",
"webhookSecondaryUri": "https://backup.example.com/webhooks/messages",
"webhookSecret": "***hidden***"
}
}
Updating Tenants
Update tenant settings, including webhook configuration, custom domains, and other preferences. The owner and billable owner cannot be changed after creation.
Update Tenant Settings
curl -X PUT https://api.approvedcontact.com/api/v1/tenants/3fa85f64-5717-4562-b3fc-2c963f66afa6 \
-u "your-email@example.com:your-password" \
-H "Content-Type: application/json" \
-d '{
"domain": "new-domain.example.com",
"settings": {
"webhookPrimaryUri": "https://new-webhook.example.com/messages",
"webhookSecret": "new-secure-secret"
}
}'
Updatable Fields
| Field | Type | Description |
|---|---|---|
domain |
string | Custom domain for the tenant |
settings |
object | All tenant settings (see webhook section) |
owner and billableOwner fields
cannot be changed after tenant creation. Contact support if you need to transfer tenant ownership.
Webhook Configuration
Configure webhooks at the tenant level to receive notifications for all messages and order status updates for that tenant's phone numbers.
Webhook Settings
{
"settings": {
"webhookPrimaryUri": "https://your-app.com/webhooks/messages",
"webhookSecondaryUri": "https://backup-app.com/webhooks/messages",
"webhookSecret": "your-webhook-secret-key",
"webhookBasicAuthUsername": "webhook-user",
"webhookBasicAuthPassword": "webhook-pass"
}
}
Webhook Configuration Options
| Field | Description |
|---|---|
webhookPrimaryUri |
Primary webhook endpoint URL |
webhookSecondaryUri |
Fallback webhook endpoint (optional) |
webhookSecret |
Secret key for HMAC signature verification |
webhookBasicAuthUsername |
Username for HTTP Basic Authentication (optional) |
webhookBasicAuthPassword |
Password for HTTP Basic Authentication (optional) |
Best Practices
Tenant Organization
- One Tenant Per Customer: For SaaS applications, create one tenant per customer account
- Consistent Naming: Use customer domain names or IDs for easy identification
- Separate Environments: Use different tenants for development, staging, and production
Webhook Configuration
- Always configure a secondary webhook URI for high availability
- Use HTTPS endpoints only
- Rotate webhook secrets periodically (every 90 days)
- Monitor webhook delivery success rates
Multi-Tenant Architecture
# Example: SaaS application tenant provisioning
class TenantProvisioner:
def provision_customer(self, customer_id, customer_domain):
# Create tenant
tenant = api.create_tenant({
'tenantId': str(uuid.uuid4()),
'domain': customer_domain,
'settings': {
'webhookPrimaryUri': f'https://api.yourapp.com/webhooks/{customer_id}',
'webhookSecret': generate_secure_secret()
}
})
# Provision phone numbers for tenant
numbers = api.provision_numbers({
'tenantId': tenant['tenantId'],
'phoneNumbers': get_available_numbers(area_code=customer_area_code)
})
return {
'tenant': tenant,
'numbers': numbers
}
Monitoring
- Track tenant creation dates and activity
- Monitor phone number usage per tenant
- Set up alerts for webhook delivery failures
- Regular audit of tenant settings and access