# Admin

> WhaBuzz staff only (platform admin console session).

Canonical: https://docs.whabuzz.com/api/admin/

WhaBuzz staff only (platform admin console session).

Base URL `https://api.whabuzz.com`. Every request needs `Authorization: Bearer <key>` unless the operation says otherwise; see [Authentication](https://docs.whabuzz.com/authentication.md). Errors follow the [two-source contract](https://docs.whabuzz.com/errors.md).

Operations on this page:

- [`GET /v1/admin/tenants`](#adminListTenants): All tenants (approval queue with status=pending_approval)
- [`POST /v1/admin/tenants/{tenant_id}/approve`](#adminApproveTenant): Approve a tenant
- [`POST /v1/admin/tenants/{tenant_id}/reject`](#adminRejectTenant): Reject a tenant
- [`POST /v1/admin/tenants/{tenant_id}/suspend`](#adminSuspendTenant): Suspend a tenant
- [`POST /v1/admin/tenants/{tenant_id}/reinstate`](#adminReinstateTenant): Reinstate a suspended tenant
- [`GET /v1/admin/numbers`](#adminListNumbers): Every number across tenants
- [`GET /v1/admin/health`](#adminHealth): Pipeline health
- [`GET /v1/admin/audit`](#adminAudit): Audit log
- [`GET /v1/admin/billing`](#adminBilling): Billing across tenants
- [`GET /v1/admin/mail/last`](#adminLastMail): Last email sent to an address (EMAIL_MODE=log only)
- [`GET /v1/admin/apps`](#adminListApps): Platform apps
- [`POST /v1/admin/apps`](#adminCreateApp): Create a platform app
- [`POST /v1/admin/apps/{app_id}/keys`](#adminCreateAppKey): Create an app (platform) API key

## All tenants (approval queue with status=pending_approval) {#adminListTenants}

`GET /v1/admin/tenants`

**Auth:** Console session token. **Operation id:** `adminListTenants`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `status` | query | `pending_approval` or `active` or `rejected` or `suspended` | no |  |
| `limit` | query | integer | no |  |
| `cursor` | query | string | no | `next_cursor` from the previous page. |

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/tenants" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Tenants

```json
{
  "data": [
    {
      "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
      "name": "Acme Fitness",
      "status": "pending_approval",
      "created_via": "signup",
      "contact_email": "owner@acmefitness.in",
      "website": "https://acmefitness.in",
      "tax_id": "36ABCDE1234F1Z5",
      "tax_id_type": "gstin",
      "email_domain": "acmefitness.in",
      "flags": [],
      "created_at": "2026-10-16T08:00:00Z"
    }
  ]
}
```

**Common errors.** Shape and meanings are on the [Errors page](https://docs.whabuzz.com/errors.md).

| HTTP | WhaBuzz code | Meaning |
|---|---|---|
| 403 | `forbidden` | Not allowed for this caller |

## Approve a tenant {#adminApproveTenant}

`POST /v1/admin/tenants/{tenant_id}/approve`

**Auth:** Console session token. **Operation id:** `adminApproveTenant`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `tenant_id` | path | string (uuid) | yes |  |

cURL:

```bash
curl -X POST "https://api.whabuzz.com/v1/admin/tenants/$TENANT_ID/approve" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Approved

```json
{
  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
  "status": "active",
  "approved_at": "2026-10-16T09:00:00Z",
  "billing_status": "trialing",
  "trial_ends_at": "2026-10-30T09:00:00Z"
}
```

## Reject a tenant {#adminRejectTenant}

`POST /v1/admin/tenants/{tenant_id}/reject`

**Auth:** Console session token. **Operation id:** `adminRejectTenant`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `tenant_id` | path | string (uuid) | yes |  |

**Request body** (`application/json`, required)

| Field | Type | Required | Description |
|---|---|---|---|
| `reason` | string | yes |  |

Request example:

```json
{
  "reason": "Website does not match the business name."
}
```

cURL:

```bash
curl -X POST "https://api.whabuzz.com/v1/admin/tenants/$TENANT_ID/reject" \
  -H "Authorization: Bearer $CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Website does not match the business name."
}'
```

**Responses**

**200** Rejected

```json
{
  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
  "status": "rejected",
  "rejected_reason": "Website does not match the business name."
}
```

## Suspend a tenant {#adminSuspendTenant}

`POST /v1/admin/tenants/{tenant_id}/suspend`

**Auth:** Console session token. **Operation id:** `adminSuspendTenant`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `tenant_id` | path | string (uuid) | yes |  |

**Request body** (`application/json`, required)

| Field | Type | Required | Description |
|---|---|---|---|
| `reason` | `abuse` or `admin` | yes |  |
| `note` | string | no |  |

Request example:

```json
{
  "reason": "abuse",
  "note": "Spam reports from Meta quality alerts"
}
```

cURL:

```bash
curl -X POST "https://api.whabuzz.com/v1/admin/tenants/$TENANT_ID/suspend" \
  -H "Authorization: Bearer $CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "abuse",
  "note": "Spam reports from Meta quality alerts"
}'
```

**Responses**

**200** Suspended

```json
{
  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
  "status": "suspended",
  "suspended_reason": "abuse"
}
```

## Reinstate a suspended tenant {#adminReinstateTenant}

`POST /v1/admin/tenants/{tenant_id}/reinstate`

**Auth:** Console session token. **Operation id:** `adminReinstateTenant`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `tenant_id` | path | string (uuid) | yes |  |

cURL:

```bash
curl -X POST "https://api.whabuzz.com/v1/admin/tenants/$TENANT_ID/reinstate" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Active again

```json
{
  "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
  "status": "active"
}
```

## Every number across tenants {#adminListNumbers}

`GET /v1/admin/numbers`

**Auth:** Console session token. **Operation id:** `adminListNumbers`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `connection_state` | query | `pending` or `connected` or `disconnected` | no |  |

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/numbers" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Numbers

```json
{
  "data": [
    {
      "tenant_id": "a578246e-b97f-48e6-ae42-939ec3ccf917",
      "tenant_name": "WhaBuzz Demo",
      "phone_number_id": "1013622581841046",
      "display_phone_number": "+1 469-231-1132",
      "connection_state": "connected",
      "quality_rating": "GREEN",
      "messaging_limit_tier": "TIER_250",
      "last_event_at": "2026-10-16T05:12:03Z"
    }
  ]
}
```

## Pipeline health {#adminHealth}

`GET /v1/admin/health`

**Auth:** Console session token. **Operation id:** `adminHealth`.

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/health" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Health

```json
{
  "retries_due": 4,
  "oldest_due_retry_at": "2026-10-16T09:58:00Z",
  "dead_24h": 0,
  "endpoints_circuit_open": 1,
  "tokens": {
    "expiring": 0,
    "invalid": 0
  },
  "partitions_through": {
    "events": "2027-04",
    "event_payloads": "2027-04",
    "webhook_deliveries": "2027-04"
  },
  "kv_reconcile": {
    "last_run_at": "2026-10-16T10:00:00Z",
    "keys_rewritten": 0
  }
}
```

## Audit log {#adminAudit}

`GET /v1/admin/audit`

**Auth:** Console session token. **Operation id:** `adminAudit`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `tenant_id` | query | string (uuid) | no |  |
| `action` | query | string | no |  |
| `limit` | query | integer | no |  |
| `cursor` | query | string | no | `next_cursor` from the previous page. |

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/audit" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Entries

```json
{
  "data": [
    {
      "id": 4012,
      "tenant_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
      "actor_user_id": "6b5a4938-2716-4a5b-8c7d-9e0f1a2b3c4d",
      "action": "tenant.approve",
      "target_type": "tenant",
      "target_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
      "details": {},
      "created_at": "2026-10-16T09:00:00Z"
    }
  ]
}
```

## Billing across tenants {#adminBilling}

`GET /v1/admin/billing`

**Auth:** Console session token. **Operation id:** `adminBilling`.

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/billing" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Billing

```json
{
  "billing_enabled": false,
  "tenants": [
    {
      "tenant_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
      "name": "Acme Fitness",
      "billing_status": "past_due",
      "past_due_since": "2026-11-03T04:00:00Z",
      "last_snapshot": {
        "period": "2026-11-01",
        "active_numbers": 2,
        "total_paise": 88500
      },
      "open_invoices": 1
    }
  ]
}
```

## Last email sent to an address (EMAIL_MODE=log only) {#adminLastMail}

`GET /v1/admin/mail/last`

**Auth:** Console session token. **Operation id:** `adminLastMail`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `email` | query | string (email) | yes |  |

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/mail/last" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** The captured email

```json
{
  "to": "owner@acmefitness.in",
  "subject": "Confirm your WhaBuzz email",
  "links": [
    "https://app.whabuzz.com/verify-email?token=Qm9…"
  ],
  "sent_at": "2026-10-16T08:00:05Z"
}
```

**Common errors.** Shape and meanings are on the [Errors page](https://docs.whabuzz.com/errors.md).

| HTTP | WhaBuzz code | Meaning |
|---|---|---|
| 404 | `not_found` | Not found |

## Platform apps {#adminListApps}

`GET /v1/admin/apps`

**Auth:** Console session token. **Operation id:** `adminListApps`.

cURL:

```bash
curl -X GET "https://api.whabuzz.com/v1/admin/apps" \
  -H "Authorization: Bearer $CONSOLE_TOKEN"
```

**Responses**

**200** Apps

```json
{
  "data": [
    {
      "id": "3e53b65e-0000-4000-8000-000000000001",
      "name": "fisique-crm",
      "tenants": 1
    }
  ]
}
```

## Create a platform app {#adminCreateApp}

`POST /v1/admin/apps`

**Auth:** Console session token. **Operation id:** `adminCreateApp`.

**Request body** (`application/json`, required)

Request example:

```json
{
  "name": "pariq"
}
```

cURL:

```bash
curl -X POST "https://api.whabuzz.com/v1/admin/apps" \
  -H "Authorization: Bearer $CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "pariq"
}'
```

**Responses**

**201** Created

```json
{
  "id": "6f1e2d3c-4b5a-4697-8a8b-9c0d1e2f3a4b",
  "name": "pariq"
}
```

## Create an app (platform) API key {#adminCreateAppKey}

`POST /v1/admin/apps/{app_id}/keys`

**Auth:** Console session token. **Operation id:** `adminCreateAppKey`.

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `app_id` | path | string (uuid) | yes |  |

**Request body** (`application/json`, required)

Request example:

```json
{
  "name": "Pariq production",
  "environment": "live"
}
```

cURL:

```bash
curl -X POST "https://api.whabuzz.com/v1/admin/apps/$APP_ID/keys" \
  -H "Authorization: Bearer $CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Pariq production",
  "environment": "live"
}'
```

**Responses**

**201** Key, shown once

```json
{
  "id": "2a3b4c5d-6e7f-4809-9a1b-2c3d4e5f6a7b",
  "app_id": "6f1e2d3c-4b5a-4697-8a8b-9c0d1e2f3a4b",
  "prefix": "wb_live_EXAMPLEKEY0000",
  "key": "wb_live_EXAMPLEKEY000000000000000000000000"
}
```
