# Report an objection

> report_objection: Records an objection to direct marketing for one record, by record id or email hash.

Source: https://emailmovers.com/mydatahub/docs/reference/mcp/report_objection

Records an objection to direct marketing for one record, by record id or email hash. Scope licensee suppresses it for your organisation at once; scope emailmovers suppresses it database-wide within one working day and tells every licensee holding it. Free; it needs suppressions:write, and repeating the same objection returns the same suppression. Call it whenever a contact objects, in any channel. Lawful basis is UK GDPR Article 6(1)(f) legitimate interests; email audiences include corporate subscribers only by default (PECR), so sole traders and ordinary partnerships are left out unless the toggle is changed.

| Property | Value |
| --- | --- |
| Tool name | `report_objection` |
| Position in tools/list | 21 of 22 |
| Cost | Free |
| Scope | `suppressions:write` |
| Annotations | readOnlyHint false, destructiveHint false, idempotentHint true, openWorldHint false |
| Kind | Write; idempotent, not destructive, closed world |
| REST equivalent | [`POST /v1/objections`](https://emailmovers.com/mydatahub/docs/reference/rest/report-objection.md) |

> **Not yet live.** MyDataHub v2 is built and tested locally and is not yet live. The v2 hosts open at launch, date to confirm. This is what `tools/list` returns from https://mydatahub.emailmovers.com/mcp once v2 launches.

## Input

The schema sets `additionalProperties` to false, so a member that is not listed is refused.

| Member | Type | Required | Description |
| --- | --- | --- | --- |
| `record_id` | string | no | Format: a contact id: contact_ followed by a 26 character ULID in upper case Crockford base32, such as contact_01JA9X2V7XN3M9R6T1Y5W8ZAK8. |
| `email_sha256` | string | no | SHA-256 of the trimmed, lower cased address, when the record id is not known. |
| `channel` | enum: `email`, `telephone`, `post`, `web_form`, `other` | yes |  |
| `received_at` | string (date-time) | yes | RFC 3339 date and time, with Z or an offset such as +01:00. |
| `scope` | enum: `licensee`, `emailmovers` | yes | licensee suppresses the record for your organisation at once; emailmovers suppresses it database-wide within one working day. |
| `note` | string | no |  |

## Example call

The `params` of a `tools/call` request:

```json
{
  "name": "report_objection",
  "arguments": {
    "record_id": "contact_01JA9X2V7XN3M9R6T1Y5W8ZAK8",
    "channel": "email",
    "received_at": "2026-10-01T08:30:00Z",
    "scope": "emailmovers",
    "note": "Replied asking not to be contacted again."
  }
}
```

## Output

The result carries `structuredContent` that matches this schema, and one line of text that leads with the number.

| Member | Type | Always present | Description |
| --- | --- | --- | --- |
| `suppression_id` | string | yes | The list the record now sits on. |
| `record_id` | string or null | yes |  |
| `scope` | enum: `licensee`, `emailmovers` | yes |  |
| `status` | enum: `suppressed`, `pending` | yes | suppressed now, or pending until the database-wide overlay applies. |
| `suppressed_at` | string (date-time) or null | yes |  |
| `effective_by` | string (date-time) | yes |  |

## Errors

A failed call returns `isError` true. The text content leads with the sentence a person acts on, then the whole problem as JSON, with `code`, `detail`, `next_step` and `did_you_mean`. A 401 and a step-up 403 are answered at HTTP level so the client can start authorisation. See [Errors](https://emailmovers.com/mydatahub/docs/errors.md).
