Skip to main content

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.
GET /v1/tenants
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
FieldTypeDescription
tenant_idstringMicrosoft tenant GUID
tenant_namestringDisplay name pulled from Microsoft
tenant_domainstringThe .onmicrosoft.com domain
default_domainstringThe primary verified custom domain, if set
domain_countnumberTotal custom domains on this tenant
mailbox_countnumberTotal mailboxes across all domains
discovery_completedbooleanWhether the initial discovery sync has completed
exchange_bootstrap_statusstringready, pending, or failed — whether Exchange automation is set up
consented_attimestampWhen admin consent was given
last_sync_attimestampLast successful discovery sync

Get tenant

Returns a single tenant by its Microsoft tenant GUID.
GET /v1/tenants/{tenant_id}
Path parameters
ParameterTypeDescription
tenant_idstringThe 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
StatusCodeDescription
404tenant_not_foundTenant 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
ParameterTypeDescription
tenant_idstringThe 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
FieldTypeDescription
statusstringOverall sync status
run_idstringUnique sync identifier
tenant_idstringTenant ID
bootstrapobjectExchange readiness
smtp_authobjectSMTP AUTH readiness
resultobjectDiscovery output
StatusCodeDescription
404tenant_not_foundTenant does not exist or belongs to a different account
403access_deniedYou 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
ParameterTypeDescription
tenant_idstringThe 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
StatusCodeDescription
404tenant_not_foundTenant 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.