> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenantcore.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Enforcement

> Query the send enforcement audit log across all mailboxes.

## Overview

The enforcement log records every send limit action taken across your mailboxes. When a mailbox exceeds its daily send limit, Exchange blocks outbound mail and TenantCore logs the event. When the limit resets and the mailbox is unblocked, that is logged as well.

Use this endpoint to audit enforcement activity, debug delivery issues, or monitor send volume trends across your infrastructure.

***

## List enforcement events

Returns enforcement events across all your tenants, ordered by most recent first. Supports filtering by tenant and action type, and pagination.

```
GET /v1/enforcement/events
```

**Query parameters**

| Parameter   | Type   | Default | Description                                |
| ----------- | ------ | ------- | ------------------------------------------ |
| `tenant_id` | string | —       | Filter events to a specific tenant         |
| `action`    | string | —       | Filter by action: `blocked` or `unblocked` |
| `limit`     | number | `50`    | Number of results to return. Max `200`.    |
| `offset`    | number | `0`     | Pagination offset                          |

**Example request — all events**

```bash theme={null}
curl "https://api.tenantcore.io/v1/enforcement/events" \
  -H "Authorization: Bearer tc_live_your_key"
```

**Example request — blocks only for a specific tenant**

```bash theme={null}
curl "https://api.tenantcore.io/v1/enforcement/events?tenant_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&action=blocked" \
  -H "Authorization: Bearer tc_live_your_key"
```

**Example request — paginated**

```bash theme={null}
curl "https://api.tenantcore.io/v1/enforcement/events?limit=100&offset=100" \
  -H "Authorization: Bearer tc_live_your_key"
```

**Example response**

```json theme={null}
{
  "events": [
    {
      "id": "uuid",
      "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "mailbox_address": "sales@mail.acmecorp.com",
      "action_taken": "blocked",
      "sent_count": 26,
      "limit_value": 25,
      "message": "Mailbox blocked: sent 26, limit 25",
      "created_at": "2025-04-20T14:30:00Z"
    },
    {
      "id": "uuid",
      "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "mailbox_address": "sales@mail.acmecorp.com",
      "action_taken": "unblocked",
      "sent_count": 0,
      "limit_value": 25,
      "message": "Mailbox unblocked: sent 0, limit 25",
      "created_at": "2025-04-21T00:05:00Z"
    }
  ],
  "count": 2,
  "total": 2,
  "limit": 50,
  "offset": 0,
  "filters": {
    "tenant_id": null,
    "action": null
  }
}
```

**Response fields**

| Field     | Type   | Description                            |
| --------- | ------ | -------------------------------------- |
| `events`  | array  | List of enforcement events             |
| `count`   | number | Number of events in this response      |
| `total`   | number | Total matching events across all pages |
| `limit`   | number | The limit applied to this request      |
| `offset`  | number | The offset applied to this request     |
| `filters` | object | The filters that were applied          |

**Event fields**

| Field             | Type      | Description                                      |
| ----------------- | --------- | ------------------------------------------------ |
| `tenant_id`       | string    | The tenant this event belongs to                 |
| `mailbox_address` | string    | The affected mailbox email address               |
| `action_taken`    | string    | `blocked` or `unblocked`                         |
| `sent_count`      | number    | Send count at the time enforcement ran           |
| `limit_value`     | number    | The configured limit at the time of the event    |
| `message`         | string    | Human-readable summary of the enforcement action |
| `created_at`      | timestamp | When the enforcement event was logged            |

***

## Pagination

Use `limit` and `offset` to page through large result sets. The `total` field in the response tells you how many matching events exist across all pages.

```javascript theme={null}
async function getAllEnforcementEvents(apiKey) {
  const limit  = 200;
  let   offset = 0;
  let   all    = [];

  while (true) {
    const res = await fetch(
      `https://api.tenantcore.io/v1/enforcement/events?limit=${limit}&offset=${offset}`,
      { headers: { Authorization: `Bearer ${apiKey}` } }
    );
    const data = await res.json();
    all.push(...data.events);

    if (all.length >= data.total) break;
    offset += limit;
  }

  return all;
}
```

***

## Errors

| Status | Code               | Description                                                            |
| ------ | ------------------ | ---------------------------------------------------------------------- |
| `404`  | `tenant_not_found` | Specified `tenant_id` does not exist or belongs to a different account |
