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

# Contact Exclusions API: Block Individual People from Outreach

> Block a specific person by email or LinkedIn URL from Topo outreach. Manage opt-outs, unsubscribes, and bounced contacts with time-bound or permanent exclusions.

Contact exclusions prevent Topo from sending outreach to a specific person, regardless of which sequences or lists they appear in. Each rule targets an individual by `email` or `linkedin_url` (at least one is required on create). Exclusions can be permanent or time-limited via the optional `until` field, and carry a structured `reason` code to help you report on and audit your blocklist.

<Tip>
  Connect your CRM's unsubscribe or opt-out webhook to `POST /v1/contact-exclusions` to keep Topo's blocklist in sync automatically. No more manually maintaining a suppression list.
</Tip>

<Note>
  Read endpoints require the `contact_exclusions:read` scope. Create, update, and delete endpoints require `contact_exclusions:write`. Account exclusions have their own `account_exclusions:*` scopes.
</Note>

## Create an exclusion

`POST /v1/contact-exclusions` requires `reason` and at least one of `email` or `linkedin_url`. Optional fields include `message` (a free-form operator note) and `until` (an RFC 3339 timestamp after which the exclusion expires — omit for a permanent block).

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.topo.io/v1/contact-exclusions \
  -H "Authorization: Bearer topo_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada@analytical.io",
    "reason": "UNSUBSCRIBED"
  }'
```

## List and manage exclusions

`GET /v1/contact-exclusions` returns every contact exclusion in your workspace with the standard [pagination envelope](/api-reference/pagination-filtering). Filter by `email`, `reason`, or creation timestamps.

`GET /v1/contact-exclusions/{exclusion_id}` fetches a single rule. `PATCH` updates mutable fields (`reason`, `message`, `until`). `DELETE` permanently removes the exclusion.

To block an entire company domain instead of one person, use [account exclusions](/api-reference/account-exclusions).

## Exclusion reasons

Every contact exclusion carries a `reason` field. Valid values are:

| Value                 | Description                                             |
| --------------------- | ------------------------------------------------------- |
| `UNSUBSCRIBED`        | Person has opted out.                                   |
| `CONTACT_REFUSED`     | Contact explicitly asked not to be reached.             |
| `BOUNCED`             | Email hard-bounced.                                     |
| `WRONG_PERSON`        | Contact is not the right person at the company.         |
| `LEFT_COMPANY`        | Contact has left the company.                           |
| `BAD_TIMING`          | Not a good time — revisit later.                        |
| `OUT_OF_OFFICE`       | Temporarily unavailable.                                |
| `MEETING`             | Already in progress with this contact.                  |
| `INTERESTED`          | Contact has expressed interest through another channel. |
| `COMPETITOR`          | Account is a direct competitor.                         |
| `REFERRAL`            | Came in through a referral channel; handle separately.  |
| `EXCLUDE_FROM_SEARCH` | Suppress from Topo's prospecting search.                |
| `EXCLUDE_FROM_CRM`    | Imported CRM suppression.                               |
| `OTHER`               | None of the above.                                      |
| `UNKNOWN`             | Reason not recorded.                                    |

## Webhook: `contact_exclusion.created`

When a contact exclusion is created, Topo can push a `contact_exclusion.created` event to your [webhook subscriptions](/api-reference/webhooks). This is a **resource event** — it is not tied to a sequence run, so the payload has no `sequence_id` or `sequence_template_id`.

Deliveries are sent only to subscriptions whose `sequence_template_ids` is `null` (all templates). The payload includes:

| Field          | Description                   |
| -------------- | ----------------------------- |
| `exclusion_id` | UUID of the new exclusion     |
| `email`        | Excluded email, if set        |
| `linkedin_url` | Excluded LinkedIn URL, if set |
| `reason`       | Exclusion reason code         |

Subscribe to `contact_exclusion.created` when you need to mirror Topo's blocklist into an external system the moment someone opts out.
