Exchange is excluded from this API/CLI release. Any historical Exchange API or CLI example in this guide is unavailable; native portal behavior is outside this exclusion. See [current release scope](/developers/guides/release-scope?lang=en).

# Filter settings, MX records and recovery

This guide covers existing filters: changing SMTP destinations and owned aliases, restoring stored MX records, changing paid products on the existing subscription agreement and deleting filters. Check the current capabilities of the selected company. Availability follows the environment's permissions and settings.

## From the portal

The existing **Edit filter** form uses the same original supplier, MX and pricing steps. Verify your identity with the offered passkey or verification code, review the settings and save once. MX changes always require recent verification. The current authentication requirements from all your active companies remain applicable at every supplier step; a newly required MFA check during the change stops further dispatch. For product changes, the form shows the unit price, existing quantity, full amount excluding VAT per billing period and effective date. A change to that agreement since opening the form requires another review. Technical administrators without ordering rights can change SMTP settings; financial product fields remain protected. Automation limits assess the full recurring amount, including the existing quantity, rather than only the unit price.

Before dispatch, the browser retains one original reference. It remains after a connection failure. Open the original status, review the displayed steps and separately confirm **reconcile** or **continue**. Reconciliation reads only supplier and accounting status and can restore proven local completion. Continuation can perform a step proven never to have been dispatched. Clicking or reloading does not create a replacement request. If no request has been prepared yet, corrected input can use the same reference. Another company in a second tab does not replace the original context.

A newly strongly verified personal API connection of the same unchanged human identity can also explicitly recover such a browser request with the CLI commands below. Portal metadata has `origin: "portal"`, `operation_id: null` and no API quote evidence; no API operation or OAuth origin is invented. Current portal permissions, company context and the original scope boundary remain mandatory. A machine, another person or a reset identity cannot adopt this request. This also works while new API writes are disabled, through GET-only reconciliation.

An original internal administrator uses their own administration context:

```sh
binadit --account "$ORIGINAL_ADMIN_CONTEXT" spam configuration-changes get "$CHANGE_ID" --administrator
binadit --account "$ORIGINAL_ADMIN_CONTEXT" spam configuration-changes reconcile "$CHANGE_ID" \
  --administrator --confirm-change "$CHANGE_ID" --input recovery.json --yes
```

The REST prefix is then `/accounts/{original_admin_context}/admin/spam/configuration-changes`. This grants no membership of the target company. The same real administrator must remain authorized. Do not use `locate` with an invented API key for browser references; the reference is already in the form and recovery message.

## Change settings

First read `GET /api/v1/accounts/{account}/spam/filters/{filter}` and retain the ETag. Then send one `PUT /api/v1/accounts/{account}/spam/filters/{filter}/configuration` with `If-Match`, a unique `Idempotency-Key` and, for example:

```json
{"destinations":[{"hostname":"mail.example.nl","port":25}],"aliases":[],"manage_dns":false}
```

Use `spam:write`; `manage_dns: true` also requires `dns.records:write`. Aliases must be currently owned DNS zones. Incoming filtering requires at least one public SMTP destination. Without automatic DNS management, change MX records yourself at the DNS provider. Automatic management preserves other record types; the portal retains original MX records and DNS history. An explicitly conflicting company binding is refused.

In the Rust CLI:

```sh
binadit --account "$ACCOUNT" spam filters get "$FILTER"
binadit --account "$ACCOUNT" api "/spam/filters/$FILTER/configuration" \
  --method PUT --from-file settings.json --version "$FILTER_ETAG" --yes
```

An input file is an ordinary private file; on Unix, use `chmod 600`. `--dry-run` validates without a supplier mutation. Do not change the original key, input or connection when repeating the same request.

## Paid products and MX restoration

Paid product changes do not belong in the PUT above. Request a quote with `POST /order-quotes`, `kind: "spam_configuration"` and `input` containing `filter_id`, `products`, `destinations`, `aliases` and `manage_dns`. Confirm that quote once through `POST /orders` with `quote_id`. The existing agreement retains its ID, quantity and billing period; the new price applies to the next period. This change creates no additional invoice or second subscription. Changing the billing period requires a separately reviewed migration.

The change retains one original request. The supplier is confirmed first, followed by the reviewed DNS changes and then the price on the existing agreement. Only confirmed partial results allow local filter settings, the quote and operation to finish. A later problem does not repeat an earlier supplier action and does not erase confirmed DNS history.

`POST /spam/filters/{filter}/actions/restore-dns` with the current filter ETag and one new request key restores stored MX records through the same DNS route. The request has an empty JSON body. Historical backups grant no rights over zones now owned by another company. Restoration also has its own immutable original request.

## Delete a filter

Internal administrators open **Delete** from the overview, review the company, filter and existing end date and confirm with a recent passkey. The form retains one original reference. By default, previously stored MX records are restored for zones demonstrably still owned by the company; disable this only deliberately. Other record types remain. A changed filter or subscription since opening requires another review.

Through the API, `DELETE /api/v1/accounts/{account}/spam/filters/{filter}` requires current `admin:write` and `spam:write`, a real internal administrator with recent strong verification, the filter ETag and one original request key. Send:

```json
{"confirm_resource_id":"7","restore_dns":true}
```

MX restoration also requires `dns.records:write`. The generic CLI uses the same endpoint, for example:

```sh
binadit --account "$ACCOUNT" api "/spam/filters/$FILTER" --method DELETE \
  --from-file deletion.json --version "$FILTER_ETAG" --yes
```

The supplier filter is deleted once. The reviewed MX changes are then performed and the same existing subscription is terminated at the end of the current period. This creates no invoice or new subscription. An already terminated subscription receives a read-only check of its exact known supplier ID, debtor and end date before the filter supplier is contacted. The original financial reservation remains until local completion; concurrent resumption is refused. No second termination is dispatched. Without a linked subscription, there is no financial step. Ambiguous or duplicate agreements remain blocked.

A proven deletion is retained as a local tombstone with its original evidence. Only that verified tombstone releases a domain name or alias for reuse. A manually changed local status field alone does not. An uncertain DELETE result remains held: absence or a later filter with the same name does not prove that the original DELETE was accepted. Use the existing status and recovery commands; do not send another DELETE or key. Metadata shows `action: "delete"` and, when needed, `termination_review` with the date and `already_terminated`. `completion_verified: true` also requires healthy original DNS and financial partial evidence and the local tombstone.

A browser request remains a browser request. The same original internal administrator can use their real personal API connection to read the known reference and perform GET-only reconciliation with `--administrator`, including while new API writes are disabled. Damaged completed evidence remains blocked; the portal does not report healthy completion based only on local status.

## Recover an uncertain result

For `spam_configuration_requires_reconciliation`, the original UUID is in `errors.original_change_id`. Preserve that UUID. Do not create a new key, quote or filter to bypass an uncertain change.

```sh
binadit --account "$ACCOUNT" spam configuration-changes get "$CHANGE_ID"
```

The metadata contains the supplier phase, child statuses, current versions and `completion_verified`. A paid change also shows the reviewed EUR unit price, retained quantity, full period amount, reviewed effective date and billing period. `business_completion_verified` alone does not yet confirm that the original HTTP and quote records are also healthy. Credentials, supplier evidence and original private input are not returned.

A currently strongly verified company owner can reconcile the existing request. This requires `spam:read` and available `spam:write`, plus DNS read/write rights for DNS and ordering rights for a paid change. New writes may be disabled for **reconcile**. In that maintenance mode, a new read-access token does not have to receive a write scope: the server checks the current owner, available original write rights and retained original scope boundary. When writes are enabled, normal token write-scope access remains required. Continuation always requires current write access. Create `recovery.json` with the actual values from the metadata:

```json
{"confirm_change_id":"oorspronkelijke UUID","confirm_filter_id":7,"confirm_filter_version":"huidige filterversie","version":"huidige verzoekversie","confirm_no_supplier_mutation":true}
```

```sh
binadit --account "$ACCOUNT" spam configuration-changes reconcile "$CHANGE_ID" \
  --confirm-change "$CHANGE_ID" --input recovery.json --yes
```

The REST route is `POST /spam/configuration-changes/{change}/actions/reconcile`. This route reads supplier and accounting status and can restore proven local completion. It repeats no PUT, PATCH, DELETE or accounting EDIT. The old principal, original operation, quote and child IDs are preserved. A different supplier ID with the same domain name is not ownership evidence.

A remaining step never performed requires explicit **continue**. Read the metadata again, review the original change and use the same fields with `confirm_continue_original: true` instead of `confirm_no_supplier_mutation`. Then:

```sh
binadit --account "$ACCOUNT" spam configuration-changes continue "$CHANGE_ID" \
  --confirm-change "$CHANGE_ID" --input continuation.json --yes
```

Continuation requires enabled writes and current rights. It first checks steps already started and performs only remaining steps demonstrably never dispatched. An uncertain supplier action remains blocked until readback evidence confirms the original result. Recovery uses no new `Idempotency-Key`, dry run or automatic retry.

## The UUID is missing

Use `spam configuration-changes locate --input original.json` when a lost HTTP response hid the UUID. The file contains `original_principal_id`, `original_key` and `original_request` with the exact `method`, full account `path` and original JSON `body`. This is a read action; no new operation is created. The same current connection can locate its own exact request. A different connection requires the currently strongly verified company owner. The REST route is `POST /spam/configuration-changes/actions/locate`.

## Contract for AI agents

Preserve company, principal, original key, method, path, complete JSON, filter ETag and returned original UUID before subsequent actions. Use exact versions and explicit original UUID confirmation. Distinguish configuration, quote confirmation, deletion, MX restoration, GET-only reconciliation and never-dispatched continuation. Do not issue a new key after an error, timeout or new grant. A completed API request record is also different from a queued background task; see the [original operation contract](/developers/guides/original-operations?lang=en).

Changing existing settings, MX restoration and deletion are different from ordering a new filter or adopting a historical background task. The general release tracks those remaining caller integrations separately; this guide claims neither a complete public release nor completed production activation.
