Overview
A tenant in TenantCore represents a Microsoft 365 tenant that has been connected to your account via admin consent. Each tenant is owned by the user who performed the consent flow. You can only access tenants you connected.
TenantCore recommends 12 domains per tenant and 3 mailboxes per domain as the optimal cold email structure on Microsoft tenants. Microsoft imposes no hard limit on custom domains per tenant — this structure is the recommended approach for maximizing deliverability and minimizing single-domain risk.
List tenants
Returns all tenants connected to your account, ordered by connection date, most recent first.
Example request
curl https://api.tenantcore.io/v1/tenants \
-H "Authorization: Bearer tc_live_your_key"
Example response
{
"tenants": [
{
"id": "uuid",
"tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenant_name": "Acme Corp",
"tenant_domain": "acmecorp.onmicrosoft.com",
"default_domain": "acmecorp.onmicrosoft.com",
"domain_count": 12,
"mailbox_count": 36,
"status": null,
"discovery_completed": true,
"exchange_bootstrap_status": "ready",
"consented_at": "2025-01-15T14:32:00Z",
"last_sync_at": "2025-04-20T08:00:00Z"
}
],
"count": 1
}
Response fields
| Field | Type | Description |
|---|
tenant_id | string | Microsoft tenant GUID |
tenant_name | string | Display name pulled from Microsoft |
tenant_domain | string | The .onmicrosoft.com domain |
default_domain | string | The primary verified custom domain, if set |
domain_count | number | Total custom domains on this tenant |
mailbox_count | number | Total mailboxes across all domains |
discovery_completed | boolean | Whether the initial discovery sync has completed |
exchange_bootstrap_status | string | ready, pending, or failed — whether Exchange automation is set up |
consented_at | timestamp | When admin consent was given |
last_sync_at | timestamp | Last successful discovery sync |
Get tenant
Returns a single tenant by its Microsoft tenant GUID.
GET /v1/tenants/{tenant_id}
Path parameters
| Parameter | Type | Description |
|---|
tenant_id | string | The Microsoft tenant GUID |
Example request
curl https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
-H "Authorization: Bearer tc_live_your_key"
Example response
{
"id": "uuid",
"tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenant_name": "Acme Corp",
"tenant_domain": "acmecorp.onmicrosoft.com",
"default_domain": "mail.acmecorp.com",
"domain_count": 8,
"mailbox_count": 24,
"status": null,
"discovery_completed": true,
"exchange_bootstrap_status": "ready",
"smtp_auth_org_enabled": true,
"consented_at": "2025-01-15T14:32:00Z",
"last_sync_at": "2025-04-20T08:00:00Z",
"connected_by": "you@example.com"
}
Errors
| Status | Code | Description |
|---|
404 | tenant_not_found | Tenant does not exist or belongs to a different account |
Sync tenant
Triggers a discovery sync for a connected tenant.
This endpoint:
- Runs Exchange bootstrap (if needed)
- Ensures SMTP AUTH readiness
- Discovers domains
- Syncs mailboxes
- Updates tenant metadata
This is the first API call you should make after connecting a tenant.
POST /v1/tenants/{tenant_id}/sync
Path parameters
| Parameter | Type | Description |
|---|
tenant_id | string | The Microsoft tenant GUID |
Example request
curl -X POST \
https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/sync \
-H "Authorization: Bearer tc_live_your_key"
Example response
{
"status": "completed",
"run_id": "sync_20250420_080000_single",
"tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"bootstrap": {
"status": "ready",
"message": "Exchange bootstrap already ready",
"skipped": true
},
"smtp_auth": {
"status": "ready",
"message": "SMTP AUTH already ready",
"skipped": true
},
"result": {
"status": "success",
"tenant_name": "Acme Corp",
"default_domain": "acmecorp.onmicrosoft.com",
"domain_count": 8,
"user_mailbox_count": 24,
"mailbox_error": null
}
}
Response Fields
| Field | Type | Description |
|---|
status | string | Overall sync status |
run_id | string | Unique sync identifier |
tenant_id | string | Tenant ID |
bootstrap | object | Exchange readiness |
smtp_auth | object | SMTP AUTH readiness |
result | object | Discovery output |
| Status | Code | Description |
|---|
404 | tenant_not_found | Tenant does not exist or belongs to a different account |
403 | access_denied | You do not own this tenant |
Delete tenant
Removes a tenant and all associated records from your TenantCore account. The Microsoft 365 tenant itself is not affected — only your local records are deleted.
DELETE /v1/tenants/{tenant_id}
This operation is irreversible. All domains, mailboxes, and sync history for this tenant will be permanently removed from TenantCore. The Microsoft tenant and its mailboxes are not modified.
Path parameters
| Parameter | Type | Description |
|---|
tenant_id | string | The Microsoft tenant GUID |
Example request
curl -X DELETE \
https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
-H "Authorization: Bearer tc_live_your_key"
Example response
{
"status": "deleted",
"tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenant_name": "Acme Corp",
"message": "Tenant and all associated records removed. The Microsoft tenant itself was not affected."
}
Errors
| Status | Code | Description |
|---|
404 | tenant_not_found | Tenant does not exist or belongs to a different account |
Connecting new tenants
New tenants cannot be connected via the API. Connecting a tenant requires a Microsoft admin consent flow that must be completed through the TenantCore app at app.tenantcore.io. Once connected, tenants are immediately available via the API.
It is highly recommended to connect all your tenants through the app before beginning any automation or scripting. The API assumes tenants are already connected and fully bootstrapped. Automating against tenants that have not completed the consent flow and Exchange setup will result in errors.