Exchange valt buiten deze API/CLI-release. Eventuele historische Exchange-voorbeelden in deze gids zijn niet beschikbaar; dit zegt niets over bestaande portaalfuncties. Zie het [actuele releasebereik](/developers/guides/release-scope?lang=nl).

# DNS-wijzigingen en herstel

Het portal bewaart een oorspronkelijke DNS-wijziging voordat een schrijfactie naar de DNS-provider vertrekt. De records en versiehistorie in het portal worden samen bijgewerkt zodra de vereiste providerstatus is bevestigd. Bij externe nameservers werkt een wijziging uitsluitend de lokale records en historie bij; het portal verstuurt die records niet naar de externe provider.


## Gewone recordwijzigingen: één opdracht

Deze voorbeelden met één opdracht vereisen CLI `0.1.0-preview.20261102.4` of nieuwer. Download de actuele ondertekende CLI via de [downloadpagina](/developers/cli?lang=nl).

Maak, wijzig en verwijder een gewoon DNS-record rechtstreeks; een aparte opdracht om te beoordelen/toe te passen is niet nodig. Het portaal maakt intern het exacte plan en voert de bestaande canonieke schrijver uit onder één oorspronkelijke API-operatie en idempotentiesleutel. Actuele bedrijfs-/resourcerechten, bronbinding, ETag-controles en blijvende leveranciersmarkeringen blijven behouden. Gewone recordwijzigingen krijgen geen extra eis voor een menselijke verbinding of passkey.

```bash
binadit dns records create example.test --name _verification --type TXT --value example --ttl 3600 --account 123 --yes
binadit dns records update example.test 12 --name _verification --type TXT --value changed --ttl 3600 --account 123 --yes
binadit dns records delete example.test 12 --account 123 --yes
# Optional validation only: no saved plan, operation or provider write.
binadit dns records create example.test --name www --type A --value 192.0.2.1 --account 123 --dry-run
```

Als `--version` ontbreekt, leest de CLI eerst de actuele records/ETag met `dns.records:read`. Een verbinding met alleen `dns.records:write` kan de bekende actuele `--version` opgeven en die leesactie overslaan. Een expliciete oude versie wordt geweigerd en nooit stil vervangen. De normale terminalbevestiging volgt de bestaande schrijfconventie; `--yes` is bedoeld voor automatisering.

Rechtstreekse API-routes beginnen na `/api/v1/accounts/{account}`:

| Methode en pad | Invoer |
| --- | --- |
| `POST /dns/zones/{zone}/records` | `name`, `type`, `value`, optioneel `ttl`, `priority`, `weight`, `port`, `comment`, `proxied` |
| `PATCH /dns/zones/{zone}/records/{record}` | Alleen gewijzigde velden; ontbrekende velden behouden de huidige waarde |
| `DELETE /dns/zones/{zone}/records/{record}` | Leeg object |

Alle drie gebruiken `dns.records:write`, de huidige zoneversie in `If-Match` en de oorspronkelijke `Idempotency-Key`. Optioneel `dry_run:true` valideert zonder toewijzing of leverancierswijziging. Methode/pad bepalen actie en doel: stuur geen `action`, `zone` of `id` in de body. Succes geeft `status:applied`, de echte zone-ID/naam, `record_action`, `requested_record_id` (null bij aanmaken), versie, interne plan-ID en DNS-journaal-ID plus de oorspronkelijke operatie. Bij externe nameservers bevestigt `published:false` alleen lokale publicatie. Het endpoint verzint geen nieuw recordnummer; lees actuele records als je die ID nodig hebt.

Een onzeker antwoord bewaart het oorspronkelijke verzoek/de sleutel en de zoneblokkade. POST, PATCH en DELETE worden niet automatisch herhaald. Dezelfde sleutel leest de bestaande uitkomst; een andere sleutel kan het geblokkeerde journaal niet omzeilen. De interne plan-ID is gelijk aan de oorspronkelijke operatie-ID; na een uitzonderlijke onderbreking zijn de bestaande geavanceerde status-/herstelacties beschikbaar. Deze controles horen bij onzekere uitkomsten, niet bij een verplichte normale beoordelingsstap. Batch-, import- en templateplannen blijven aparte geavanceerde procedures.

## Rechtstreekse API-voorbeelden in vier talen

Hergebruik de bestaande client voor [Python](/developers/guides/code-examples-python?lang=nl), [JavaScript/TypeScript](/developers/guides/code-examples-javascript?lang=nl), [PHP](/developers/guides/code-examples-php?lang=nl) of [C#](/developers/guides/code-examples-csharp?lang=nl). Deze helpers gebruiken HTTPS met certificaatcontrole, een begrensd antwoord en een timeout; ze volgen geen redirects en herhalen schrijfacties nooit automatisch. Zet servicegeheimen niet in browsercode.

Elk voorbeeld doet **één** rechtstreeks verzoek. Kies `BINADIT_DNS_ACTION=create`, `update` of `delete` en zet `BINADIT_DRY_RUN` expliciet op `true` voor alleen valideren of `false` voor opslaan. Bedrijf `123`, zone `example.test` en bestaand record `12` zijn fictief: vervang ze door de exacte toegestane doelen. Record-ID's komen uit de actuele recordlijst; een ontvangstbewijs van aanmaken is geen nieuw recordnummer.

Lees vóór de eerste poging `GET /api/v1/accounts/123/dns/zones/example.test/records` met `dns.records:read` en bewaar de exacte HTTP-ETag, inclusief aanhalingstekens, als `BINADIT_RESOURCE_VERSION`. Een verbinding met alleen schrijfrechten kan de al bekende actuele zone-ETag opgeven. Bewaar `BINADIT_REQUEST_KEY` en de exacte methode, URL, body en ETag blijvend vóór verzending. De aanroeper of geheimenbeheerder levert de sleutel; deze voorbeelden maken er nooit een. Een andere actie of wissel van preview naar uitvoering is een ander verzoek met een eigen sleutel en de dan geldende versie. Bewaar na een onzeker antwoord de oorspronkelijke invoer/sleutel: haal geen nieuwe ETag op om automatisch opnieuw te schrijven, wissel niet van modus en maak geen andere sleutel. Controleer eerst de oorspronkelijke operatie.

De `data` van de helper bevat de API-envelop. Alleen valideren wordt nooit als opgeslagen getoond. Werkelijk succes moet overeenkomen met bedrijf, zone, actie, gevraagd record en de geslaagde oorspronkelijke operatie. `provider_confirmed:false` betekent dat bij externe nameservers alleen records/historie in het portaal zijn toegepast.

### Python

```python
from binadit import access_token, api
import os

base = "/api/v1/accounts/123/dns/zones/example.test/records"
action = os.environ["BINADIT_DNS_ACTION"]  # create, update or delete: one request
method, path, body, record = {
    "create": ("POST", base, {"name": "_verification", "type": "TXT", "value": "example", "ttl": 3600}, None),
    "update": ("PATCH", base + "/12", {"value": "changed"}, 12),
    "delete": ("DELETE", base + "/12", {}, 12),
}[action]
dry_run = {"true": True, "false": False}[os.environ["BINADIT_DRY_RUN"]]
if dry_run:
    body["dry_run"] = True
version, key = os.environ["BINADIT_RESOURCE_VERSION"], os.environ["BINADIT_REQUEST_KEY"]
if not version or not key:
    raise ValueError("Preserve the exact zone ETag and original request key first")
reply = api(access_token(), method, path, body, version=version, key=key)["data"]
data = reply["data"]
if dry_run:
    if data.get("dry_run") is not True or data.get("action") != "dns.records." + action or data.get("account_id") != 123 or data.get("plan", {}).get("zone") != "example.test":
        raise RuntimeError("Unverified preview; preserve the original request")
    print("Validated only; DNS was not saved")
else:
    op = reply.get("operation", {})
    if (data.get("status") != "applied" or data.get("zone") != "example.test"
            or data.get("record_action") != action or "requested_record_id" not in data or data.get("requested_record_id") != record
            or not data.get("id") or op.get("id") != data["id"] or op.get("account_id") != 123
            or op.get("action") != "dns.records." + action or op.get("request_status") != "succeeded"
            or not isinstance(data.get("published"), bool)):
        raise RuntimeError("Unverified result; preserve the original request")
    print({"applied_in_portal": True, "provider_confirmed": data["published"]})
```

### JavaScript / TypeScript

```javascript
import { accessToken, api } from './binadit.mjs';

const base = '/api/v1/accounts/123/dns/zones/example.test/records';
const action = process.env.BINADIT_DNS_ACTION; // create, update or delete: one request
const choices = {
  create: ['POST', base, { name: '_verification', type: 'TXT', value: 'example', ttl: 3600 }, null],
  update: ['PATCH', base + '/12', { value: 'changed' }, 12],
  delete: ['DELETE', base + '/12', {}, 12],
};
if (!Object.hasOwn(choices, action)) throw new Error('Choose create, update or delete');
const [method, path, body, record] = choices[action];
if (!['true', 'false'].includes(process.env.BINADIT_DRY_RUN)) throw new Error('Set BINADIT_DRY_RUN to true or false');
const dryRun = process.env.BINADIT_DRY_RUN === 'true';
if (dryRun) body.dry_run = true;
const version = process.env.BINADIT_RESOURCE_VERSION, key = process.env.BINADIT_REQUEST_KEY;
if (!version || !key) throw new Error('Preserve the exact zone ETag and original request key first');
const { data: reply } = await api(await accessToken(), method, path, body, { version, key });
const data = reply.data;
if (dryRun) {
  if (data.dry_run !== true || data.action !== 'dns.records.' + action || data.account_id !== 123 || data.plan?.zone !== 'example.test')
    throw new Error('Unverified preview; preserve the original request');
  console.log('Validated only; DNS was not saved');
} else {
  const op = reply.operation ?? {};
  if (data.status !== 'applied' || data.zone !== 'example.test' || data.record_action !== action
      || data.requested_record_id !== record || !data.id || op.id !== data.id || op.account_id !== 123
      || op.action !== 'dns.records.' + action || op.request_status !== 'succeeded' || typeof data.published !== 'boolean')
    throw new Error('Unverified result; preserve the original request');
  console.log({ applied_in_portal: true, provider_confirmed: data.published });
}
```

### PHP

```php
<?php
require 'binadit.php';

$base = '/api/v1/accounts/123/dns/zones/example.test/records';
$action = getenv('BINADIT_DNS_ACTION'); // create, update or delete: one request
[$method, $path, $body, $record] = match ($action) {
    'create' => ['POST', $base, ['name' => '_verification', 'type' => 'TXT', 'value' => 'example', 'ttl' => 3600], null],
    'update' => ['PATCH', $base.'/12', ['value' => 'changed'], 12],
    'delete' => ['DELETE', $base.'/12', [], 12],
    default => throw new RuntimeException('Choose create, update or delete'),
};
$dryRun = match (getenv('BINADIT_DRY_RUN')) { 'true' => true, 'false' => false, default => throw new RuntimeException('Set BINADIT_DRY_RUN to true or false') };
if ($dryRun) $body['dry_run'] = true;
$version = getenv('BINADIT_RESOURCE_VERSION');
$key = getenv('BINADIT_REQUEST_KEY');
if (! $version || ! $key) throw new RuntimeException('Preserve the exact zone ETag and original request key first');
$reply = BinaditExample::api(BinaditExample::accessToken(), $method, $path, $body, $version, $key)['data'];
$data = $reply['data'];
if ($dryRun) {
    if (($data['dry_run'] ?? null) !== true || ($data['action'] ?? null) !== 'dns.records.'.$action || ($data['account_id'] ?? null) !== 123 || ($data['plan']['zone'] ?? null) !== 'example.test')
        throw new RuntimeException('Unverified preview; preserve the original request');
    echo "Validated only; DNS was not saved\n";
} else {
    $op = $reply['operation'] ?? [];
    if (($data['status'] ?? null) !== 'applied' || ($data['zone'] ?? null) !== 'example.test' || ($data['record_action'] ?? null) !== $action
        || ! array_key_exists('requested_record_id', $data) || $data['requested_record_id'] !== $record || empty($data['id']) || ($op['id'] ?? null) !== $data['id'] || ($op['account_id'] ?? null) !== 123
        || ($op['action'] ?? null) !== 'dns.records.'.$action || ($op['request_status'] ?? null) !== 'succeeded' || ! is_bool($data['published'] ?? null))
        throw new RuntimeException('Unverified result; preserve the original request');
    echo json_encode(['applied_in_portal' => true, 'provider_confirmed' => $data['published']], JSON_THROW_ON_ERROR)."\n";
}
```

### C#

```csharp
using System.Text.Json.Nodes;

using var client = new BinaditExample();
string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value ? value : throw new InvalidOperationException("Preserve the original request inputs first");
var root = "/api/v1/accounts/123/dns/zones/example.test/records";
var action = Required("BINADIT_DNS_ACTION"); // create, update or delete: one request
var (method, path, body, record) = action switch {
    "create" => ("POST", root, JsonNode.Parse("""{"name":"_verification","type":"TXT","value":"example","ttl":3600}""")!, (int?)null),
    "update" => ("PATCH", root + "/12", JsonNode.Parse("""{"value":"changed"}""")!, (int?)12),
    "delete" => ("DELETE", root + "/12", (JsonNode)new JsonObject(), (int?)12),
    _ => throw new InvalidOperationException("Choose create, update or delete")
};
var dryRun = Required("BINADIT_DRY_RUN") switch { "true" => true, "false" => false, _ => throw new InvalidOperationException("Use true or false") };
if (dryRun) body["dry_run"] = true;
var result = await client.Api(await client.AccessToken(), method, path, body, version: Required("BINADIT_RESOURCE_VERSION"), key: Required("BINADIT_REQUEST_KEY"));
var reply = result.Data ?? throw new InvalidOperationException("Unverified result");
var data = reply["data"] ?? throw new InvalidOperationException("Unverified result");
if (dryRun) {
    if (data["dry_run"]?.GetValue<bool>() != true || data["action"]?.GetValue<string>() != "dns.records." + action || data["account_id"]?.GetValue<int>() != 123 || data["plan"]?["zone"]?.GetValue<string>() != "example.test")
        throw new InvalidOperationException("Unverified preview; preserve the original request");
    Console.WriteLine("Validated only; DNS was not saved");
} else {
    var op = reply["operation"];
    if (data["status"]?.GetValue<string>() != "applied" || data["zone"]?.GetValue<string>() != "example.test" || data["record_action"]?.GetValue<string>() != action
        || !data.AsObject().ContainsKey("requested_record_id") || data["requested_record_id"]?.GetValue<int>() != record || string.IsNullOrEmpty(data["id"]?.GetValue<string>()) || op?["id"]?.GetValue<string>() != data["id"]?.GetValue<string>()
        || op?["account_id"]?.GetValue<int>() != 123 || op?["action"]?.GetValue<string>() != "dns.records." + action || op?["request_status"]?.GetValue<string>() != "succeeded" || data["published"] is null)
        throw new InvalidOperationException("Unverified result; preserve the original request");
    Console.WriteLine(new JsonObject { ["applied_in_portal"] = true, ["provider_confirmed"] = data["published"]!.GetValue<bool>() });
}
```

## Wijzigingen vanuit de DNS-editor

Open een domein via **DNS → DNS-records**, controleer de records en sla de wijziging op. De editor stuurt de versie die je hebt bekeken en een eigen, willekeurig wijzigingsnummer per domein mee. Een andere gebruiker, API-aanvraag of achtergrondtaak kan een verouderde versie daardoor niet ongemerkt overschrijven.

De browser bewaart alleen het oorspronkelijke wijzigingsnummer in de sessieopslag. DNS-inhoud, sleutels en sessiebewijzen worden daarin niet opgeslagen. Bij een onderbroken antwoord blijft hetzelfde nummer behouden. Er wordt geen vervangende aanvraag gemaakt om een onzekere wijziging te omzeilen.

Een bevestigde afronding betekent dat de bijbehorende lokale records en historie zijn opgeslagen. Een melding dat het resultaat controle vereist betekent dat de wijziging nog niet als afgerond mag worden behandeld.

## Versiehistorie en bedrijven

Een DNS-snapshot blijft gekoppeld aan het bedrijf waarvoor die is opgeslagen. Als een domein naar een ander bedrijf wordt verplaatst, krijgt de nieuwe eigenaar daardoor geen toegang tot de DNS-historie van het vorige bedrijf. De domeinlijst, versieaantallen, detailweergave en herstelpreview volgen dezelfde bedrijfsbinding. Het bewaren van een nieuwe versie ruimt alleen oude versies van hetzelfde bedrijf op.

## Als een antwoord wegvalt

Gebruik **Oorspronkelijke wijziging controleren**. De statuspagina leest alleen de lokale, geverifieerde bewijzen. Het openen van deze pagina verstuurt geen providerverzoek en herhaalt geen wijziging.

De pagina toont hoeveel oorspronkelijke providerstappen zijn bevestigd. Een wijziging kan meerdere stappen hebben, bijvoorbeeld records schrijven en vervolgens de nameservers informeren. Voer vervolgens een expliciete actie uit:

- **Providerstatus controleren zonder te schrijven** leest de huidige providerstatus. Als die exact overeenkomt met de oorspronkelijke wijziging, rondt het portal de lokale records en historie af. Deze actie verstuurt geen schrijfactie naar de provider.
- **Nog niet uitgevoerde oorspronkelijke stappen uitvoeren** is een afzonderlijke toestemming voor providerwrites. Deze optie kan alleen oorspronkelijke stappen uitvoeren die nog nooit zijn geprobeerd. Een onzekere schrijfactie wordt niet opnieuw verstuurd. De optie verschijnt wanneer alle reeds geprobeerde stappen bevestigd zijn.

Bij externe nameservers toont deze pagina **Wijziging in portal afronden**. Die actie rondt alleen de oorspronkelijke lokale records en historie af; zij leest of wijzigt geen externe provider. Er worden voor deze domeinen geen bevestigde providerstappen getoond.

Controleer het domein en de oorspronkelijke aanvraag voordat je een actie bevestigt. Beide herstelacties vragen recente sterke verificatie met een passkey of authenticatorcode, volgens het beleid van je bedrijf. Beheerders gebruiken een passkey. Een gewone wachtwoordcontrole geldt hier niet als sterke verificatie.

Je mag dezelfde oorspronkelijke wijziging na opnieuw aanmelden controleren en herstellen als je nog steeds dezelfde bevoegde persoon bent, bij hetzelfde bedrijf en met dezelfde geldige aanmeldgeneratie. Een gewijzigde identiteit, ingetrokken toegang, verlopen verificatie of een gewijzigde providerverbinding kan herstel blokkeren. Opgeslagen goedkeuring vervangt geen actuele toegang.

## Wat je niet moet doen bij een onzeker resultaat

Maak geen nieuwe wijziging met een ander nummer aan om de oorspronkelijke aanvraag te vervangen. Het portal bewaart een blokkade op het oorspronkelijke domein en de canonieke domeinnaam totdat de afronding aantoonbaar klopt. Ook importeren, een andere provider koppelen of de eigenaar wijzigen mag die blokkade niet omzeilen.

Een succesvolle providerwrite waarvan het antwoord ontbreekt, kan een menselijke controle vereisen. Bij het aanmaken van een Cloudflare-zone of record wordt een ontbrekend oorspronkelijk provider-ID niet afgeleid uit een toevallig gelijkend object. Het ontbreken van een bevestiging is geen toestemming om opnieuw aan te maken.

## HTTP-contract van de native editor

Dit zijn browserroutes met normale portalaanmelding, CSRF-bescherming en actuele bedrijfsrechten. Integraties en CLI-agents gebruiken de publieke API en de daarin beschreven OAuth- of servicesleutelauthenticatie; zij moeten geen browsersessie of providercredential nabootsen.

| Route | Gedrag |
| --- | --- |
| `POST /module_dns/dns-settings/edit` | Gewone directe recordwijziging met bekeken versie en oorspronkelijke UUID per domein. Inplannen gebruikt het afzonderlijke planningsproces. |
| `GET /module_dns/mutation-context/{zoneId}` | Actuele bevoegde domeincontext en versie; geen providerverzoek. |
| `GET /module_dns/mutations/{intentId}` | HTML-statuspagina; met `Accept: application/json` veilige lokale status. Geen providerverzoek. |
| `POST /module_dns/mutations/{intentId}/reconcile` | Expliciete actuele sterke toestemming voor providerreads en eventuele lokale afronding. Geen providerwrite. |
| `POST /module_dns/mutations/{intentId}/continue` | Afzonderlijke actuele sterke toestemming voor nog nooit geprobeerde oorspronkelijke providerstappen. |

De directe editor stuurt `dns_intent_ids[zoneId]` als UUID en `dns-versions[zoneId]` als de bekeken resourceversie. De server leidt de persoon, het bedrijf, de providerverbinding en het sessiebewijs zelf af. Door de browser aangeleverde eigenaar-, provider-ID- of autorisatievelden verlenen geen bevoegdheid.

Een geslaagde directe wijziging bevat `receipts[zoneId]` met `intent_id`, `completion_verified: true` en `original_receipt: true`. Alleen de bevestiging van exact hetzelfde oorspronkelijke nummer laat de browser zijn bewaarde nummer vrijgeven.

De veilige status bevat `intent_id` voor de oorspronkelijke browsergoedkeuring, `id` voor het bijbehorende DNS-journal, `zone_id`, `state`, `version`, `zone_version`, `approved_version`, `effects`, `attempted_effects`, `confirmed_effects`, `completion_verified` en `local_records_only`. Zij bevat geen DNS-inhoud, providersleutels, sessiehashes of ongefilterd resultaat van een bovenliggende taak. Gebruik voor de route altijd `intent_id`; het journal-ID is een ander nummer.

Beide herstelroutes vereisen de actuele `version`, `confirm_intent_id`, `confirm_zone_id` en `confirm_zone_version`. Alleen reconcile accepteert `confirm_read_only: true`. Alleen continue accepteert `confirm_continue_original: true`. Dit zijn verschillende, niet onderling uitwisselbare toestemmingen. Haal na een wijziging van status eerst nieuwe metadata op; herhaal geen actie met een verouderde versie.

## Aanwijzingen voor AI-agents

Bewaar het oorspronkelijke intentnummer en eventuele operationele ontvangstbewijzen bij het oorspronkelijke werk. Een transportfout, processtop of HTTP-conflict is geen afgeronde wijziging en geen aanleiding om een nieuwe idempotentiesleutel, UUID of leverancieraanvraag te maken. Status opvragen en providerstatus controleren zijn verschillende handelingen: alleen de eerste is uitsluitend lokaal.

Publieke DNS-plannen, verbindingen, achtergrondtaken en native editoracties moeten ieder hun eigen actuele toegang en oorspronkelijke bovenliggende aanvraag behouden. Hergebruik de gedeelde DNS-fasen vanuit servercode; stuur DNS-schrijfacties nooit rechtstreeks vanuit de CLI naar een DNS-dienst. Zie de [API-handleiding](/developers/api?lang=nl), [CLI-handleiding](/developers/cli?lang=nl) en [agenthandleiding](/developers/agents?lang=nl) voor de publieke toegang. Het interne technische contract staat in `docs/DNS-RECORD-PHASES.md`.

De aanwezigheid van de interne DNS-fasen is op zichzelf geen bewijs dat iedere oude DNS-aanroeper is omgezet of dat een volledige release al is uitgerold. Releasecontroles moeten de daadwerkelijke native, API- en workerpaden en de gepubliceerde versie afzonderlijk verifiëren.

## Een oorspronkelijk API-plan toepassen en herstellen

### Records, templates en import/export controleren

`binadit dns records list example.test --account 123 --output json` leest de huidige records en zoneversie. Een DNS-only zone aanmaken vraagt een echte interne platformbeheerder; DNS-rechten van een gewoon bedrijfslid geven die bevoegdheid niet. Templates lezen en eigen templates beheren gebruiken de afzonderlijke `dns.templates:read`- en `dns.templates:write`-scopes. Wijzigen en verwijderen vragen de ETag uit `dns templates get`.

Exporteer naar een nieuw privébestand met bijvoorbeeld `binadit dns records export example.test --format json --file zone.json --account 123`. JSON en CSV bewaren ook Cloudflare `proxied` en automatische TTL `1`. BIND bewaart DNS-recordgegevens en heeft geen Cloudflare-proxyveld. JSON, CSV en BIND ondersteunen onder meer CAA, SSHFP, TLSA, HTTPS, SVCB en NAPTR. CSV gebruikt verdubbelde aanhalingstekens binnen geciteerde velden; backslashes blijven letterlijke tekens. Dubbelzinnige oude CSV-escaping wordt geweigerd.

`POST dns/zones/{zone}/import-plans` accepteert `format` (`json`, `csv`, `bind`) en de tekst in `content`. Gebruik eerst `--dry-run` via de geavanceerde CLI om een voorstel zonder opgeslagen plan of providerwrite te beoordelen. Een import zonder importeerbare records wordt geweigerd; maak voor het wissen van records een expliciet verwijderplan. Een template toepassen begint met `POST dns/zones/{zone}/template-plans` en `template_id`. Ook dit maakt uitsluitend een voorstel; de afzonderlijke apply met de bekeken versie voert het uit.

Een exportbundel met meerdere domeinen importeert uitsluitend de exact overeenkomende doelzone. Ontbreekt die zone, dan wordt de bundel geweigerd. De records uit verschillende zones worden niet samengevoegd. Een gewone recordlijst of een export van één zone blijft bruikbaar als expliciete kopie naar een andere zone; controleer daarvoor het hele voorstel.

Wildcardnamen `*` en `*.sub` en servicenamen zoals `_autodiscover._tcp` zijn geldig. Labels mogen maximaal 63 tekens hebben; de volledige naam binnen de werkelijke doelzone maximaal 253. Een opgeslagen template wordt bij toepassing opnieuw tegen die doelzone gecontroleerd.

Zoeken kan met `binadit api '/dns/records/search?search=tekst' --limit 10 --account 123 --output json`. De limiet is maximaal 20 zones per pagina; `--all` leest expliciet verder. Vanaf CLI `0.1.0-preview.20261031` blijven ook rechtstreeks in de URL opgegeven `limit` en `cursor` behouden; expliciete CLI-vlaggen vervangen die waarden zonder dubbele queryparameters.

### Het oorspronkelijke plan bevestigen

Maak een plan met `POST /api/v1/accounts/{account}/dns/change-plans` en controleer de geretourneerde versie en records. `POST dns/change-plans/{plan}/apply` gebruikt de bekeken planversie in `If-Match` en een oorspronkelijke `Idempotency-Key`. Relatieve paden hieronder beginnen na `/api/v1/accounts/{account}/`.

De API gebruikt dezelfde fasen als de DNS-editor. Zij bewaart het oorspronkelijke plan, de daadwerkelijke API-aanvraag, sleutelvingerafdruk, principal en providerbron voordat een providerwrite vertrekt. Iedere HTTP-aanroep naar de provider vindt buiten een SQL-transactie plaats. Pas na bevestiging worden records, historie, planstatus, journal en het oorspronkelijke API-ontvangstbewijs samen afgerond. Een fout of verloren antwoord bewaart het oorspronkelijke journal. Een nieuwe sleutel of een nieuwe apply voor datzelfde plan mag een onzekere providerwrite niet herhalen.

### Betaalde domeinregistratie en DNS-template

Na bevestigde betaling verwerkt het portaal de bestaande registratie- of verhuisbestelling bij de registrar. Een bekende operationele fout bij het publiceren van de gekozen DNS-template houdt die betaalde registraractie niet tegen. Het portaal controleert de oorspronkelijke bestelling, bedrijfsbinding, providerbron, actuele bevoegdheden en betaalstatus opnieuw. Een onbetaalde bestelling of een gewijzigde/beëindigde toestemming blijft geblokkeerd.

Registrarstatus en DNS-status zijn afzonderlijke resultaten. Alleen een bevestigde registratie met overeenkomende domeinnaam krijgt de status `ACT`; een DNS-fout blijft als openstaande publicatie zichtbaar. De oorspronkelijke DNS-aanvraag, afgewezen/onzekere providerstap en opgeslagen bewijzen blijven bewaard. Het portaal herhaalt die stap niet automatisch, vervangt geen journal en maakt geen tweede bestelling of factuur. De registratietaak kan daarom na registratie nog wachten met een DNS-waarschuwing. Gebruik die waarschuwing niet als aanleiding om het domein opnieuw te bestellen.

`GET dns/change-plans/{plan}` leest veilige lokale metadata zonder providerverzoek. Bij een toegepaste aanvraag is `plan_id` het oorspronkelijke plan; `id` is het DNS-journal. `version` hoort bij het journal, `zone_version` bij de huidige portalzone. Deze versies zijn niet onderling uitwisselbaar. De respons bevat aantallen en geverifieerde voortgang, geen oorspronkelijke DNS-inhoud, leverancierssleutels of private bewijzen.

Een huidige bedrijfseigenaar kan na sterke persoonlijke verificatie expliciet herstellen. De oorspronkelijke service- of persoonsprincipal blijft in het journal en het oorspronkelijke API-ontvangstbewijs staan. Herstel vereist de huidige scopes `dns.records:read` en `dns.records:write` en ingeschakelde gevoelige toegang. Een servicesleutel kan deze menselijke hersteltoestemming niet geven.

Voor `POST dns/change-plans/{plan}/actions/reconcile` is de bevestiging bijvoorbeeld:

```json
{
  "confirm_plan_id": "11111111-1111-4111-8111-111111111111",
  "confirm_mutation_id": "22222222-2222-4222-8222-222222222222",
  "confirm_zone_id": 8,
  "confirm_zone_version": "HUIDIGE_ZONEVERSIE_VAN_64_HEXTEKENS",
  "version": "HUIDIGE_JOURNALVERSIE_VAN_64_HEXTEKENS",
  "confirm_no_supplier_mutation": true
}
```
Gebruik echte huidige versies uit de metadata; de teksten hierboven zijn placeholders. Reconcile leest uitsluitend de oorspronkelijke providerstatus en kan een bewezen lokale afronding voltooien. Deze actie blijft beschikbaar wanneer nieuwe API-writes uitstaan. Voor nog nooit geprobeerde resterende stappen bestaat de afzonderlijke `POST .../actions/continue`. Vervang daarbij alleen `confirm_no_supplier_mutation` door `confirm_continue_original: true`. Continue vereist ingeschakelde writes en herhaalt geen onzekere stap. Deze herstelacties gebruiken de bestaande oorspronkelijke aanvraag: stuur geen nieuwe idempotentiesleutel en gebruik geen dry-run of automatische retry.

Als een oorspronkelijke aanvraag alleen voorbereid is en geen enkele providerstap ooit is geprobeerd, kan de eigenaar haar expliciet afsluiten met `POST .../actions/abandon`. Gebruik dezelfde actuele plan-, journal- en zonebevestigingen, met uitsluitend `confirm_abandon_original: true` als actiebevestiging. Deze actie controleert de ondertekende afwezigheid van dispatchmarkers, sluit plan en oorspronkelijk ontvangstbewijs samen af en verstuurt geen providerverzoek. Een onzekere of reeds geprobeerde write kan niet zo worden vrijgegeven. Een leesfout veroorzaakt nooit automatisch abandon.

De aanvullende Rust-commando's zijn:

```sh
binadit dns change-plans get PLAN_UUID --account 123 --output json
binadit dns change-plans reconcile PLAN_UUID --account 123 --confirm-plan PLAN_UUID --confirm-mutation JOURNAL_UUID --input recovery.json --yes
binadit dns change-plans continue PLAN_UUID --account 123 --confirm-plan PLAN_UUID --confirm-mutation JOURNAL_UUID --input continuation.json --yes
binadit dns change-plans abandon PLAN_UUID --account 123 --confirm-plan PLAN_UUID --confirm-mutation JOURNAL_UUID --input abandonment.json --yes
```
Bewaar bevestigingsbestanden met beperkte bestandsrechten, of gebruik vertrouwde stdin met `--input -`. De CLI controleert plan, journal, zone en versies voordat zij verbinding maakt. Continue controleert ook de actuele capability. De herstelcommando's bewaren geen nieuwe intentie, gebruiken geen nieuwe sleutel en proberen een verstuurde actie niet automatisch opnieuw. Zij zijn aanvullingen op de oorspronkelijke CLI-inventaris; beschikbaarheid van broncode bewijst geen gepubliceerde of gecontroleerde binaire release.

## Native portal: kopiëren, een vorige versie herstellen en veilig annuleren

Het portaal gebruikt bij kopiëren en herstellen hetzelfde oorspronkelijke DNS-journal als de editor. De pagina vraagt eerst de huidige doelversie en de bronversie op. De server controleert de actuele bedrijfsrechten en bronversie opnieuw wanneer hij de oorspronkelijke goedkeuring opslaat. Kopiëren neemt alleen de goedgekeurde recordgegevens over; Cloudflare-recordidentiteiten van de bron worden nooit meegekopieerd. Herstellen kan uitsluitend vanuit een versie van hetzelfde huidige klantbedrijf. Ook een lege historische recordset kan bewust worden hersteld.

Iedere actie bewaart één oorspronkelijke UUID in de browsersessie. Bij een verbroken antwoord wordt niet automatisch opnieuw geschreven. De pagina toont de oorspronkelijke wijziging en bewaart die verwijzing ook na herladen. Na een bevestigde afronding retourneert dezelfde aanvraag hetzelfde ontvangstbewijs, ook wanneer de bronzone inmiddels is gewijzigd of verwijderd, of de geselecteerde historische versie door normale bewaartermijnen is opgeruimd. De server herleest dan geen nieuwe broninhoud. Een nog onduidelijke aanvraag vraagt expliciete beoordeling; hij wordt geen nieuwe kopie of herstelpoging.

Op de beoordelingspagina staat de domeinnaam en of de wijziging alleen lokale portalrecords betreft. Met actuele sterke verificatie kan dezelfde oorspronkelijke gebruiker een leveranciersantwoord uitsluitend laten uitlezen. Uitvoering van nog nooit verstuurde stappen vraagt een afzonderlijke bevestiging. Voor een nooit begonnen oorspronkelijke aanvraag is daarnaast **annuleren vóór verzending** beschikbaar. Dat doet geen leveranciersaanvraag, bewaart de controle-informatie en geeft alleen een aantoonbaar ongebruikte reservering vrij. Zodra een leveranciersstap mogelijk is verstuurd, blijft annuleren geblokkeerd; onderzoek het oorspronkelijke ontvangstbewijs. Een annuleringsbevestiging wordt niet als een afgeronde DNS-wijziging getoond.

Voor andere agents: de native browserroutes zijn sessie- en CSRF-gebonden, geen alternatief voor de API. Gebruik de API/CLI-change-plans hierboven. Native kopiëren/herstellen bindt `source_zone_id`/`source_version` respectievelijk `history_id`/`history_version` aan het originele goedkeuringsbewijs. Herstel heeft altijd de oorspronkelijke intentie, actuele doelversie en expliciet gekozen handeling nodig. Verzin geen nieuwe UUID om een onbekend antwoord te omzeilen. De browser bewaart alleen verwijzingen en versies; geheime leveranciergegevens en recordinhoud worden niet aan de herstelmetadata toegevoegd.

## Native portal: meerdere domeinen doorzoeken en vervangen

Zoeken en vervangen toont eerst de betrokken domeinen en aantallen werkelijk gewijzigde records. Het overzicht wordt in begrensde, lokale pagina's opgebouwd en doet geen leveranciersaanvraag. De bevestigingsknop keurt precies deze domeinen, zoek- en vervangtekst en versies goed. De vergelijking is letterlijk en hoofdletterongevoelig; reguliere expressies worden niet uitgevoerd.

Elk domein krijgt een afzonderlijke oorspronkelijke DNS-goedkeuring en ontvangstbewijs. Gewijzigde doelversies, ingetrokken rechten en niet-bevestigde leveranciersantwoorden worden per domein zichtbaar. De portal meldt pas dat alles is gelukt als ieder oorspronkelijk ontvangstbewijs is geverifieerd. Een gedeeltelijke fout blijft met de oorspronkelijke beoordelingslinks staan. Er is geen automatische herhaling en er wordt geen nieuw uitgangspunt uit gewijzigde records afgeleid wanneer dezelfde oorspronkelijke aanvraag opnieuw wordt aangeboden.

Agents gebruiken hiervoor de API-change-plans met de bestaande zoek/vervangfunctie en volgen de oorspronkelijke planstatus met de CLI. De native sessieroutes zijn geen machine-API. Maak bij een onduidelijk antwoord geen nieuwe aanvraag om de oorspronkelijke beoordeling te omzeilen.

## Geplande levering: de oorspronkelijke goedkeuring en uitvoering

Een planning is goedkeuring voor latere levering, geen bewijs dat een DNS-leverancier een wijziging heeft geaccepteerd. API `dns schedules set`, de portaalplanner en de bestaande cron gebruiken hetzelfde oorspronkelijke plan en canonieke DNS-journaal. Aanmaken gebeurt uitsluitend lokaal. Het plan bindt het daadwerkelijke bedrijf/de zone, goedgekeurde records en zoneversie, uitvoeringstijd, oorspronkelijke verbinding en haar scopeplafond en de oorspronkelijke identiteitgeneratie of echte portaalpersoon/context. API-planningen bewaren ook het oorspronkelijke HTTP-ontvangstbewijs en de geauthenticeerde herkomst daarvan. Deze private bewijzen worden nooit als API-velden of CLI-uitvoer teruggegeven.

Kies in API `execute_at` een expliciete tijdzone, een tijdstip na nu en maximaal 30 dagen vooruit. Het portaal gebruikt de UTC-afwijking voor de geselecteerde datum, inclusief zomertijdwijzigingen, en weigert ongeldige of niet-bestaande lokale tijden. Getypeerde native editor-/vervangingsvelden behouden letterlijke TXT-/commentaarbytes, HTML-achtige tekst, entiteiten en witruimte; validators controleren de oorspronkelijke waarden en het portaal maakt de weergave veilig. Levering moet binnen tien minuten na het goedgekeurde tijdstip beginnen. Het oorspronkelijke bedrijf, de identiteit, rechten, providerselectie/-credentials en machtiging moeten nog bruikbaar zijn. Een kortlevend toegangstoken mag verlopen terwijl de goedgekeurde achtergrondverbinding bruikbaar blijft; intrekking, gewijzigde identiteitgeneratie, een verlopen/inactieve machtiging, gewijzigde bron of gewijzigde zone verhindert levering. Een portaalplanning vereist geen ingeschakelde klant-API.

Op het geplande tijdstip bereidt de worker de oorspronkelijke blokkade voor en commit deze; daarna gebeurt iedere leveranciersread/-write buiten SQL. De exacte verzendgetuige wordt vóór een leverancierswrite gecommit. Alleen bevestigde leveranciersstatus publiceert portaalrecords/historie en wist de wachtende metadata, atomair met het oorspronkelijke leveringsbewijs. Externe nameservers gebruiken uitsluitend lokale recordpublicatie en claimen nooit een leveranciersbevestiging. Een onzeker resultaat, een na verzending gestopte worker of een mislukte lokale publicatie behoudt de blokkade op de oorspronkelijke payload/het journaal. Cron probeert deze vastgehouden uitvoering nooit opnieuw en reconcilieert haar niet stilzwijgend.

### Een oorspronkelijke planning inspecteren en herstellen

Lees `GET /api/v1/accounts/{account}/dns/zones/{zone}/scheduled-change`. De `data.id` is de oorspronkelijke plan-UUID. `data.delivery` geeft veilige journaal-UUID/status, huidige `zone_version`, journaal-`version`, aantallen geprobeerde/bevestigde stappen en geverifieerde afronding/annulering indien beschikbaar. Deze statuslezing doet geen leveranciersverzoek. Open in het portaal **DNS → Geplande wijzigingen → Oorspronkelijke levering beoordelen**; een vastgehouden planning opent automatisch haar oorspronkelijke ontvangstbewijs.

Een huidige, sterk geverifieerde bedrijfseigenaar kan expliciet hetzelfde origineel herstellen, ook als de oorspronkelijke API-verbinding is ingetrokken. Zowel actuele DNS-lees- als schrijfrechten blijven vereist. Reconciliatie en annulering van een nooit geprobeerd origineel mogen plaatsvinden wanneer nieuwe API-writes uitstaan; voortzetten vereist ingeschakelde writes. Het oorspronkelijke plan, bedrijf, principal, bron, HTTP-bewijs en journaal blijven ongewijzigd. Native personeelsgoedkeuringen behouden hun personeelscontext; native personeel moet voor herstel nog steeds dezelfde huidige interne beheerder zijn. Een gewijzigde providerverbinding kan niet worden gebruikt om de oorspronkelijke leveranciersuitvoering te lezen of voort te zetten. Uitsluitend lokaal annuleren van een bewezen nooit geprobeerd origineel gebruikt die vervangende verbinding niet.

Gebruik de bijpassende actie onder `/scheduled-change/actions/`:

| Actie | Expliciete bevestiging | Effect |
| --- | --- | --- |
| `reconcile` | `confirm_no_supplier_mutation: true` | Alleen leveranciers-GET; bewezen oorspronkelijke lokale publicatie afronden. |
| `continue` | `confirm_continue_original: true` | Alleen resterende oorspronkelijke stappen die nooit zijn geprobeerd, nadat alle geprobeerde stappen zijn bevestigd. |
| `abandon` | `confirm_abandon_original: true` | Alleen SQL, en uitsluitend als geen oorspronkelijke leveranciersstap ooit is geprobeerd. |

Iedere actie vereist daarnaast `confirm_plan_id`, `confirm_mutation_id`, geheel getal `confirm_zone_id`, huidige `confirm_zone_version` en huidige journaal-`version`. Haal deze uit de laatste statuslezing. Voeg geen nieuwe `Idempotency-Key`, dry-runvlag/-header, queryparameters of ander plan toe. Een geprobeerde/onbekende write kan niet via gewone planningsbediening worden opgegeven, vervangen, gepauzeerd of geannuleerd. Een bevestigd terminaal journaal met gewijzigd/ontbrekend publicatiebewijs van de bovenliggende aanvraag wordt voor beheeronderzoek geweigerd; het wordt niet als succesvol ontvangstbewijs gemeld.

De Rust-CLI biedt vier aanvullende opdrachten naast de bestaande planningsopdrachten:

```sh
binadit dns schedules get 123
binadit dns schedules review 123 --confirm-plan "$PLAN_UUID"
# Save the exact confirmations from the latest review in a private JSON file.
binadit dns schedules reconcile 123 --confirm-plan "$PLAN_UUID" \
  --confirm-mutation "$JOURNAL_UUID" --input ./schedule-review.json --yes
```
De JSON voor uitsluitend-lezen reconciliatie is:

```json
{
  "confirm_plan_id": "11111111-1111-4111-8111-111111111111",
  "confirm_mutation_id": "22222222-2222-4222-8222-222222222222",
  "confirm_zone_id": 123,
  "confirm_zone_version": "<64 lowercase hex characters from the current zone version>",
  "version": "<64 lowercase hex characters from the current journal version>",
  "confirm_no_supplier_mutation": true
}
```
Vervang de voorbeeld-UUID's en versiebeschrijvingen door de echte laatste waarden. Wijzig voor `continue` of `abandon` de opdracht en vervang de ene actiebevestiging door het afzonderlijke veld uit de tabel. De CLI controleert exact plan, journaal, numerieke zone en versies, toont alleen veilige metadata en reserveert nooit een andere lokale HTTP-intentie of probeert een oorspronkelijke actie automatisch opnieuw. Expliciet voortzetten controleert eerst de huidige serverfunctie. `--wait`, `--dry-run`, `--all`, `--set` en een nieuwe aanvraagsleutel horen niet bij deze herstelprocessen.

### Oudere wachtende planningen en annulering

Een oudere planning zonder verifieerbare oorspronkelijke goedkeuring van persoon/verbinding/bron wordt niet automatisch geleverd. Beoordeel deze en maak expliciet een nieuwe planning onder huidige geauthenticeerde bevoegdheid. Raad nooit een oorspronkelijke actor en wijzig nooit databasebewijzen om een oude planning te laten uitvoeren. Wachtende RDATA zonder toeschrijving en een wachtend plan van het vorige bedrijf worden na een domeinoverdracht niet aan de huidige klant getoond.

Gewone annulering voordat een leveringsjournaal bestaat vereist de huidige zoneversie en huidige portaalcontext/API-schrijfbevoegdheid. Dit wist wachtende lokale goedkeuringsmetadata; het beweert niet dat een historische leveranciersoperatie ongedaan is gemaakt. Zodra een oorspronkelijk journaal bestaat, inspecteer dat en gebruik alleen de expliciete herstel-/annuleringsacties voor nooit geprobeerde uitvoering. Browseropslag bewaart uitsluitend UUID's, met afzonderlijke sleutels voor planning en directe bewerking; een verloren planningsantwoord verwijst terug naar hetzelfde oorspronkelijke ontvangstbewijs. Een geaccepteerd lokaal planningsbewijs geeft uitsluitend zijn bijpassende browsersleutel vrij en beweert nooit dat leverancierslevering is afgerond.


## DNS bij domeinregistratie en verhuizing

Bij een nieuwe registratie of verhuizing via het portal of de API bewaart de bestelling de op dat moment goedgekeurde DNS-template, het bedrijf, het domein en de DNS-verbinding. Een latere templatewijziging verandert deze bestaande bestelling niet. Bestaande records van een beheerde zone blijven behouden; DNS bij Cloudflare of een externe partij blijft bij registratie ongemoeid. De levering controleert de actuele bedrijfs- en betaaltoestemming opnieuw. API-opdrachten vereisen daarnaast steeds hun oorspronkelijke geldige rechten. Betaalde native portalopdrachten blijven aan de oorspronkelijke bedrijfs- en betaalafspraak gebonden.

De DNS-bevestiging en de voortgang van dezelfde ordertaak worden samen opgeslagen. Een operationele DNS-fout houdt een betaald registrarverzoek niet tegen, maar blijft zichtbaar als afzonderlijke leveringswaarschuwing. Bij een verloren leveranciersantwoord bewaart het systeem dezelfde DNS-mutatie en dezelfde poging; herstel stuurt een al geaccepteerde wijziging niet opnieuw. Gebruik de oorspronkelijke order/operatie bij onderzoek en herstel, en maak geen nieuwe bestelling of factuur. Een nog niet geleverde oudere taak zonder controleerbare DNS-goedkeuring vereist beoordeling door support. Het systeem neemt daarvoor geen actuele template als vervangende historische toestemming aan. Handmatig aanpassen van voortgangsvlaggen is geen herstelprocedure.

Er is een beperkte beheerprocedure voor een nieuw aangemaakte zone waarvan uitsluitend de daaropvolgende record-PATCH aantoonbaar met HTTP 422 is afgewezen: `domains:reject-dns-records TASK MUTATION` beoordeelt alleen de oorspronkelijke ontvangstbewijzen en haalt de huidige zone via het portaal op. Alleen een exact gelijk gebleven SOA/NS-baseline, dezelfde betaalde bestelling en geldige huidige bevoegdheden laten bevestiging met de getoonde `--zone-version`, `--journal-version` en `--confirm` toe. Status `rejected` betekent niet uitgevoerd: de oude aanvraag en alle leveranciersbewijzen blijven bestaan. De procedure schrijft niets naar de DNS-leverancier en publiceert geen records. Pas daarna kan een afzonderlijk beoordeeld normaal templateplan de records publiceren. `domains:confirm-dns-template TASK COMPLETED_MUTATION --confirm` kan de oorspronkelijke taak uitsluitend afronden wanneer een andere bevestigde mutatie dezelfde oorspronkelijk goedgekeurde records werkelijk heeft opgeslagen. Deze beheercommando’s vervangen geen klantrechten of normale API/CLI-goedkeuring.


De controle vooraf bij zoeken en vervangen valideert ook de gewenste recordwaarden volgens dezelfde DNS-regels als het opslaan. Een ongeldige IPv4-, IPv6- of doelnaam stopt daardoor al tijdens het beoordelen, voordat het browservenster een wijzigingsnummer reserveert. De controle verandert geen records en verstuurt geen DNS-verzoek naar de leverancier.

## Afgewezen vóór voorbereiding in het portal

Een directe wijziging, kopie, herstelactie of vervanging kan worden afgewezen voordat een DNS-mutatie is voorbereid, bijvoorbeeld omdat iemand anders dezelfde zone al heeft gewijzigd. Het portal kan dan een gecontroleerd ontvangstbewijs met status `not_prepared` tonen. Dit betekent dat voor dat oorspronkelijke aanvraagnummer geen schrijfactie naar de DNS-leverancier is gestart. Een eventuele eerdere controle van leveranciersmetadata is geen schrijfactie. Het is geen bevestiging dat de gewenste records zijn opgeslagen.

Het oorspronkelijke aanvraagnummer wordt definitief gereserveerd. Ook een gelijktijdig browserverzoek dat eerst nog geen ontvangstbewijs zag, kan het daarna niet alsnog uitvoeren. Het portal verwijdert uitsluitend de bijbehorende tijdelijke browserblokkering wanneer het serverbewijs overeenkomt met het bedrijf, de zone, de actie, de beoordeelde versie en het oorspronkelijke aanvraagnummer. Controleer daarna de actuele zone en keur bewust een nieuwe wijziging goed; er volgt geen automatische nieuwe poging. Bij bulkvervanging blijven reeds bevestigde zones opgeslagen en worden afgewezen zones als **niet uitgevoerd** weergegeven.

Voor andere AI-agents: een HTTP-fout, een ontbrekend ontvangstbewijs, een `404` of een netwerkfout bewijst nooit dat er niets is uitgevoerd. Alleen het expliciete, servergecontroleerde `not_prepared_verified: true` met status `not_prepared` en nul effecten bij exact dezelfde native aanvraag mag deze browserblokkering beëindigen. Bestaande of onzekere DNS-mutaties behouden hun oorspronkelijke ontvangstbewijs en herstelprocedure. Geplande acties en de API/CLI hebben hun eigen hierboven beschreven goedkeurings- en herstelprotocollen; gebruik deze native browserstatus niet als vervanging daarvoor. Verwijder of wijzig nooit opgeslagen goedkeuringen om een poging opnieuw uitvoerbaar te maken.

## Bedrijfseigendom bij DNS-lezen

Klant-DNS- en domeinlijsten, recordzoekopdrachten, exports en historie vereisen de unieke oude service-identiteit van het huidige bedrijf. Als een resource ook een expliciet portaalbedrijfs-ID heeft, moet dit ontbreken of hetzelfde bedrijf aangeven; een conflicterend ID, inclusief nul, verleent geen toegang via het oude ID. Een historiesnapshot moet bij het oorspronkelijke bedrijf horen en het domein moet nog van het huidige bedrijf zijn. Lokale DNS-templates en nameservergroepen gebruiken dezelfde eigendomsregel. Expliciet globale gegevens blijven een gedeelde catalogus. Een ontbrekende resource geeft 404 zonder records te tonen; vraag support een tegenstrijdige bedrijfsbinding te reconciliëren in plaats van onder een ander bedrijf opnieuw te proberen. Deze regels gelden ook voor uitsluitend-lezen API-exportverzoeken en de CLI.

De native DNS-instellingen, meervoudige domeinselectie, planningsoverzicht, domeinzoekfunctie en historieschermen gebruiken dezelfde actuele controles op de primaire database. Een conflicterend bedrijfsstempel toont nooit recordgegevens of een domeinnaam via een oudere selectie die alleen het oude ID gebruikt. Teamleden met uitsluitend leesrechten behouden DNS-inzage zolang hun huidige recht geldig is. Huidige interne beheerders behouden expliciete globale beheertoegang; een oude rol of ingetrokken sessie behoudt die toegang niet. Een ander bedrijf selecteren herstelt geen tegenstrijdige eigendomsregistratie.

## Cloudflare-koppelingen via de API en Rust CLI

Een API-koppeling bewaart de oorspronkelijke bedrijfskoppeling, domeinversie, gekozen credential en richting voordat een wijziging naar Cloudflare vertrekt. Het domein blijft lokaal op zijn oude provider staan totdat de providerstatus en de lokale publicatie zijn bevestigd. Credentials worden niet in antwoorden, wijzigingsmetadata of CLI-uitvoer getoond. Dit onderdeel beschrijft de API-acties; de bestaande browserknoppen hebben een eigen contract.

Gebruik `PUT /api/v1/accounts/{account}/dns/zones/{zone}/connection` met de bekeken domein-ETag in `If-Match` en één oorspronkelijke `Idempotency-Key`. Kies expliciet:

- `none`: controleert uitsluitend zonemetadata, behoudt de lokale recordbytes en maakt geen providerzone aan.
- `pull`: leest de bestaande Cloudflare-zone en slaat de exacte getypeerde records en historie in het portal op. Een ontbrekende zone wordt niet aangemaakt.
- `push`: publiceert de bekeken lokale records en behoudt niet beoordeelde providerrecords. Alleen `allow_zone_create: true` bij deze richting geeft toestemming om een ontbrekende zone aan te maken. Hiervoor moet de credential ook aan het exacte Cloudflare-account zijn gekoppeld.

`DELETE` op dezelfde route ontkoppelt lokaal, zonder de providerzone te verwijderen. `fallback_provider` is `external` of `binadit`. `POST .../connection/actions/pull` gebruikt dezelfde oorspronkelijke fasen voor een reeds gekoppelde Cloudflare-zone.

Voorbeeld van een bekeken koppeling zonder recordsynchronisatie, met een beschermd invoerbestand:

```json
{"connection_id": 42, "direction": "none"}
```
```sh
binadit api /dns/zones/8/connection --method PUT --account 123 \
  --version BEKEKEN_DOMEIN_VERSIE --from-file connection.json \
  --idempotency-key DEZELFDE_OORSPRONKELIJKE_SLEUTEL --yes
```
Bij een onderbroken antwoord blijft dezelfde oorspronkelijke aanvraag behouden. Lees `GET /api/v1/accounts/{account}/dns/connection-changes/{change}` met het oorspronkelijke `dns_mutation_id`. Dit is SQL-only metadata en bevat onder andere `operation_id`, `direction`, `zone_version`, `version`, `completion_verified` en `requires_reconciliation`. Het lezen van deze status verstuurt geen providerverzoek.

```sh
binadit dns connection-changes get OORSPRONKELIJKE_UUID --account 123
```
Een huidig bevoegde bedrijfseigenaar met recente sterke verificatie kan expliciet herstellen. Ook wanneer nieuwe API-writes uitstaan, blijven GET-only reconciliatie en SQL-only afbreken beschikbaar als de huidige lees- en schrijfprivileges aanwezig zijn. Voor push/pull-herstel zijn daarnaast `dns.records:read` en `dns.records:write` nodig. Opgeslagen oorspronkelijke goedkeuring is geen actuele autorisatie.

Bewaar voor herstel beide bekeken versies en de exacte oorspronkelijke UUID in een beschermd JSON-bestand:

```json
{
  "confirm_mutation_id": "22222222-2222-4222-8222-222222222222",
  "confirm_zone_id": 8,
  "confirm_zone_version": "64-HEX-ACTUELE-DOMEINVERSIE",
  "version": "64-HEX-OORSPRONKELIJKE-JOURNAALVERSIE",
  "confirm_no_supplier_mutation": true
}
```
```sh
binadit dns connection-changes reconcile OORSPRONKELIJKE_UUID --account 123 \
  --confirm-mutation OORSPRONKELIJKE_UUID --input recovery.json --yes
```
Dit verstuurt één expliciete `POST .../connection-changes/{change}/actions/reconcile` zonder een nieuwe aanvraagkey. De leverancier wordt alleen met GET gelezen; exacte bevestiging kan de lokale bronkoppeling, records, historie en oorspronkelijke HTTP-receipt samen afronden.

Gebruik `continue` uitsluitend voor nog nooit uitgevoerde oorspronkelijke stappen, met `confirm_continue_original: true` in plaats van `confirm_no_supplier_mutation`. De CLI controleert eerst de actuele continuation-capability. Nieuwe writes moeten aanstaan. Gebruik `abandon` met `confirm_abandon_original: true` uitsluitend als geen enkele providerstap ooit is geprobeerd; dit maakt de oorspronkelijke blokkade in dezelfde SQL-transactie vrij. Beide opdrachten gebruiken dezelfde UUID, `--confirm-mutation` en beide actuele versies. Er wordt geen nieuwe idempotency-key of vervangende aanvraag gemaakt; `--dry-run`, `--wait` en automatische herhaling zijn hier niet toegestaan.

Als een zone- of recordcreate mogelijk is geaccepteerd maar het oorspronkelijke provider-ID ontbreekt, blijft de aanvraag geblokkeerd. Ook een gelijkend record of een inmiddels gevonden zone rechtvaardigt geen adoptie of tweede POST. Bewaar de oorspronkelijke gegevens voor operatoronderzoek.

Een lokale CLI-pending aanvraag wordt niet automatisch gewist doordat een herstelopdracht slaagt. Controleer de oorspronkelijke HTTP-receipt en volg [oorspronkelijke aanvragen](/developers/guides/original-operations?lang=nl) voor het expliciet bevestigen van die lokale receipt. Verwijder de blokkade of pending-state niet handmatig.

Als het eerste antwoord ontbreekt en de wijzigings-UUID nog onbekend is, zoek eerst de oorspronkelijke HTTP-receipt op met de behouden oorspronkelijke key en requestbody, zoals beschreven bij [oorspronkelijke aanvragen](/developers/guides/original-operations?lang=nl). Met het daar bevestigde HTTP-operation-ID vind je uitsluitend de al bestaande wijziging; deze lookup maakt niets aan en stuurt geen providerverzoek:

```sh
binadit api /dns/connection-changes/by-operation/OORSPRONKELIJKE_HTTP_UUID --account 123
```
Een veranderde of ontbrekende oorspronkelijke HTTP-binding wordt geweigerd. Na een late lokale receiptfout kan een reeds ondertekend afgerond journaal nog bestaan. Expliciete reconciliatie mag dan alleen de exacte oorspronkelijke HTTP-receipt opnieuw bevestigen; zij wijzigt het domein en journaal niet en verstuurt geen providerverzoek. De oorspronkelijke foutmelding blijft een onzekere receipt totdat deze controle slaagt.

`completion_verified` bevestigt de volledige API-afronding. `parent_receipt_verified` bevestigt daarbij de oorspronkelijke HTTP-receipt. Bij een late receiptfout blijft de veilige status leesbaar als `state: requires_reconciliation`, ook als `dns_completion_verified: true` laat zien dat het ondertekende DNS-journaal zelf al afgerond is. Gebruik de getoonde `version` en `zone_version` voor expliciete reconciliatie; stuur geen providerwrite opnieuw.

## Cloudflare-sleutels opslaan en recordsets vergelijken

`POST dns/connections` verifieert de aangeleverde Cloudflare-credential en bewaart deze versleuteld voor het huidige Binadit-bedrijf. Gebruik `name`, de write-only `api_token`, optioneel `email` voor een Global API Key en optioneel `provider_account_id`: precies 32 hexadecimale tekens van het **Cloudflare-account**. Het Binadit-bedrijf wordt door de server bepaald. Een nieuw opgeslagen credential verandert nog geen domein: de respons bevat `domains_linked: 0` en `sync_review_required: true`. Lees de huidige zone en gebruik daarna de expliciete koppelactie met de zone-ETag en de gewenste richting `none`, `pull` of `push`.

`PATCH dns/connections/{id}` en `POST dns/connections/{id}/actions/verify` vereisen de actuele **credential-ETag** uit `GET dns/connections/{id}`. Deze ETag is verschillend van een zone- of journalversie. Alleen een naam wijzigen veroorzaakt geen providerverzoek. Een gewijzigd token, emailadres of Cloudflare-account wordt opnieuw geverifieerd. Een verificatie met een definitief ongeldig token bewaart `is_active: false`; een onvolledig of onzeker providerantwoord wordt niet als geldige verificatie behandeld. Ook nieuw opgeslagen sleutels gebruiken versleutelde opslag; een onleesbare oude sleutel hoeft niet opnieuw te worden vrijgegeven om een nieuwe te kunnen opslaan.

Providerverificatie, de lijst beschikbare zones en een vergelijking versturen uitsluitend HTTPS-GET-verzoeken naar Cloudflare. `GET dns/connections/{id}/zones` geeft alleen namen terug die op dat moment bij het huidige Binadit-bedrijf horen. Lokale lijsten gebruiken `limit` en `cursor`. De providerinventaris is begrensd op 1.000 zones; een individuele vergelijking op 10.000 records en een totale begrensde antwoordgrootte. Een overschrijding of onvolledige paginarespons is een fout en wordt niet als volledige inventaris gepresenteerd. Gebruik bij een groot account een beperktere providerverbinding of een individuele bestaande zone.

`GET dns/zones/{zone}/connection/comparison` vereist de huidige rechten `dns.connections:read` en `dns.records:read`. De server verifieert het actuele bedrijf, de credential, providerzone, account-ID en lokale zoneversie rond elk providerverzoek. De vergelijking behoudt TXT-character-stringgrenzen, TTL, proxied-status, comments en overige getypeerde recordvelden. Zij wijzigt geen records, historie of providerbinding. Het portaal gebruikt dezelfde begrensde leesfunctie; gevoelige providerhandelingen vereisen recente sterke verificatie en de bedrijfscontext van de geopende pagina.

De algemene Rust-opdrachten en `binadit api` gebruiken deze API-routes. Lever een credential via een beperkt toegankelijk invoerbestand of vertrouwde stdin aan; zet tokens niet in URL's, shellargumenten of geschiedenis. Een geslaagde credentialopslag bevat geen token in het antwoord, de operatie-uitvoer of metadata. Bewaar bij een onderbroken wijziging dezelfde oorspronkelijke request key en lees het oorspronkelijke API-ontvangstbewijs; maak geen vervangende aanvraag om een onzeker resultaat te omzeilen.

### Zones die Binadit via een platformverbinding beheert

Een beheerder kan een zone van je bedrijf koppelen aan een **platformverbinding**: een Cloudflare-sleutel die Binadit opsloeg en die bij geen klantbedrijf hoort. Zo'n zone werkt als een zone op Binadit-DNS. Het portaal toont **Beheerd via Cloudflare door Binadit**. Je gebruikt de gewone recordrechten van de zone, niet de gevoelige verbindingsrechten:

| Handeling | Route | Rechten voor de zone |
| --- | --- | --- |
| Records lezen | `GET dns/zones/{zone}/records` | `dns.records:read` |
| Vergelijken met Cloudflare | `GET dns/zones/{zone}/connection/comparison` | `dns.records:read` |
| Records wijzigen | `POST dns/change-plans`, daarna `.../apply` | `dns.records:write` |
| Importeren van Cloudflare | `POST dns/zones/{zone}/connection/actions/pull` | `dns.records:write` en recente sterke aanmelding |

Wijzigingen en imports houden de zone-ETag, `Idempotency-Key`, controle, journaal, geschiedenis en oorspronkelijke bewijzen zoals hierboven beschreven. Het bewijs noemt de handelende persoon of integratie. Binadit stuurt alleen verzoeken voor de Cloudflare-zone-ID van die zone.

De verbinding zelf blijft bij Binadit. `GET dns/connections` toont haar niet, en `GET`, `PATCH` of `DELETE dns/connections/{id}` en de acties geven `404`. `PUT` of `DELETE dns/zones/{zone}/connection` op zo'n zone geeft `403` met code `dns_connection_platform_managed`. Je kunt geen andere zone aan de verbinding koppelen. Een teamlid met DNS-leesrechten kan alleen lezen en vergelijken. Een lid zonder DNS-rechten krijgt `403`. Een ander bedrijf krijgt `404`.

Toegang wordt bij elk verzoek en rond elke Cloudflare-aanroep gecontroleerd tegen het huidige bedrijf en de huidige koppeling van de zone. Verhuist de zone naar een ander bedrijf, of ontkoppelt, verplaatst of schakelt de beheerder de verbinding uit, dan mislukt het volgende verzoek zonder aanroep naar Cloudflare. De CLI gebruikt dezelfde routes:

```sh
binadit api /dns/zones/8/connection/comparison --account 123
binadit api /dns/zones/8/connection/actions/pull --method POST --account 123 --version VIEWED_ZONE_VERSION
```

### Nieuwe alleen-lezen verbinding tijdens onderhoud

Als API-schrijven uitstaat, laat OAuth schrijfrechten weg uit een nieuw uitgegeven persoonlijke verbinding. Een huidige bedrijfseigenaar kan daarmee na sterke verificatie toch een oorspronkelijke API-DNS-plan, via de API ingeplande DNS-wijziging of providerkoppeling lezen, uitsluitend met GET-verzoeken reconciliëren of een bewezen nooit verstuurde aanvraag lokaal opgeven. De server controleert de oorspronkelijke ondertekende scopegrens en de huidige portaalrechten; de nieuwe token krijgt geen schrijfrechten. Voor plannen blijft `dns.records:read` nodig. Voor koppelingen blijven `dns.connections:read` en `dns.zones:read` nodig, bij push/pull ook `dns.records:read`.

Deze uitzondering geldt uitsluitend zolang nieuwe API-schrijfacties uitstaan. Bij ingeschakeld schrijven blijven de gebruikelijke actuele scopes vereist. `continue` vereist altijd actuele token-schrijfrechten en ingeschakeld schrijven; een alleen-lezen herstelverbinding kan geen nieuwe providerstap versturen. Bewaar dezelfde oorspronkelijke plan-, journal- en operatie-ID's, bevestig de actuele versies en gebruik de bestaande herstelopdrachten; maak geen vervangende wijziging om een onzeker resultaat te omzeilen.

### Cloudflare-koppelingen in het portaal beoordelen

Na het opslaan van een sleutel kies je bij die verbinding **Domeinen controleren en koppelen**. De server leest begrensd welke Cloudflare-zones bij domeinen van het huidige portaalbedrijf passen. Deze controle koppelt niets automatisch en toont geen domeinen van andere bedrijven. Dubbele providernaamkoppelingen, een andere bestaande verbinding of een onopgeloste oorspronkelijke wijziging moeten eerst afzonderlijk worden beoordeeld. Selecteer daarna zelf welke beschikbare domeinen je wilt koppelen. Iedere geselecteerde zone krijgt haar eigen oorspronkelijke wijziging; records en registrar-nameservers blijven bij deze koppeling behouden. Het label **Gekoppeld** bevestigt de verbinding, niet dat lokale en externe records gelijk zijn; gebruik daarvoor de vergelijking.

Op de domeinpagina hebben **Opslaan**, **Pull** en **Push** dezelfde oorspronkelijke aanvraag en herstelregels als recordwijzigingen. Opslaan koppelt alleen de bron. Pull importeert de actuele records in het portaal met historie. Push voert de beoordeelde lokale records via de bestaande providerverbinding uit. Het aanmaken van een ontbrekende externe zone vereist de afzonderlijke expliciete checkbox bij push. Loskoppelen houdt zowel de lokale records als de externe zone intact. Recente sterke verificatie en de bedrijfscontext van de geopende pagina blijven verplicht, ook wanneer de API uitstaat.

Na een onzekere of onderbroken reactie bewaart de browser het oorspronkelijke aanvraagnummer en toont een link naar **Oorspronkelijke wijziging controleren**. Open die link voor status, uitdrukkelijk alleen-lezen reconciliatie of het opgeven van een bewezen nooit verstuurde wijziging. Een herhaalde knopdruk verstuurt geen tweede providerwijziging voor een onzekere oorspronkelijke aanvraag. Bewaar de browsergegevens tot de server de exacte voltooiing of een ondertekend nul-pogingenbewijs bevestigt; een opslagfout of een te grote browsercache stopt vóór een nieuwe aanvraag.

Voor API- en CLI-gebruik is `POST /api/v1/accounts/{account}/dns/connections/{connection}/actions/sync` een **alleen-lezen voorstel**. Vereist zijn de huidige `dns.connections:read`- en `dns.zones:read`-rechten en sterke verificatie. Laat een nieuwe `Idempotency-Key` weg. Het antwoord bevat `review_required: true`, `domains_linked: 0`, de actuele verbindingversie en per passende zone de versie, huidige bron, beschikbaarheid en eventuele blokkeerreden. `dry_run: true` leest zelfs de leverancier niet. De CLI gebruikt dezelfde capabilities:

```sh
binadit api /dns/connections/4/actions/sync --method POST --account 1
```
Beoordeel dit voorstel en voer iedere gewenste koppeling afzonderlijk via de bestaande zone-connectionroute uit met de exacte actuele zoneversie en een eigen bewaard oorspronkelijk request key. Een sync-voorstel is geen toestemming voor latere schrijfacties, en de server hercontroleert bedrijf, rechten, credential, bron en zoneversie bij de daadwerkelijke koppeling.

### Sleutels verwijderen en aan een bedrijf toewijzen

Een Cloudflare-sleutel verwijderen is een lokale handeling en verwijdert geen externe zone of records. Koppel eerst elke gekoppelde zone afzonderlijk los met haar eigen actuele zoneversie en oorspronkelijke aanvraag; verwijder daarna de ongewijzigde, ongekoppelde sleutel met haar actuele sleutelversie. De oude `detach`-boolean op sleutelverwijdering koppelt geen zones meer stilzwijgend los. Ook een leverancieraanvraag die de sleutel nog nodig heeft, blokkeert verwijdering of toewijzing tot die oorspronkelijke aanvraag is opgelost.

Alleen een huidig, sterk geverifieerd platformbeheerder kan een sleutel aan een bedrijf toewijzen of globaal maken. De server controleert per sleutel de getoonde versie en het actuele doelbedrijf. Een sleutel met bestaande zones mag alleen bij hun actuele bedrijf blijven; verplaatsing naar een ander bedrijf of globaal gebruik vereist eerst individuele loskoppeling. De native meervoudige toewijzing is één lokale transactie: een geweigerde opslag van één sleutel draait de hele selectie terug. Bij een gewijzigde toestand ná de commit geeft de server een fout voor onderzoek, zonder te beweren dat een reeds gecommitteerde verandering teruggedraaid is. API-toewijzing bewaart hetzelfde oorspronkelijke HTTP-ontvangstbewijs en voert bij herhaling geen nieuwe toewijzing uit.

## Opgeslagen zone opnieuw publiceren in het portaal

**Herstellen** en **Alles opnieuw wegschrijven** controleren eerst je huidige bedrijf, recente sterke verificatie en de actuele zoneversie. Daarna keur je één oorspronkelijke publicatie per domein goed. Opnieuw wegschrijven weigert een verouderde editorversie of niet-opgeslagen editorwijzigingen; herlaad eerst of sla de bedoelde wijziging via de gewone editor op. Het bewijs gebruikt dezelfde statuspagina en dezelfde afzonderlijke acties voor controleren, nog nooit uitgevoerde stappen uitvoeren en annuleren vóór een schrijfpoging als andere DNS-wijzigingen.

Herstellen publiceert de opgeslagen recordsets en behoudt andere records bij de provider. Bij Binadit DNS verwijdert opnieuw wegschrijven eerst provider-only recordsets en vervangt daarna de opgeslagen sets; providerbeheerde SOA en NS blijven behouden tenzij een NS-set uitdrukkelijk lokaal is opgenomen. Een tegenstrijdige combinatie van een CNAME met een behouden ander record wordt geweigerd. Bij Cloudflare herstelt deze actie bestaande, bekende record-ID's; andere Cloudflare-records blijven behouden. Een ontbrekende Cloudflare-zone vereist de afzonderlijke verbindingactie met expliciete toestemming voor zoneaanmaak.

De beheeractie voor het opnieuw opbouwen van DNS toont een actuele selectie en vraagt goedkeuring voordat zij per domein publiceert. Iedere zone heeft een eigen versie en oorspronkelijk aanvraagnummer. Een domein zonder verifieerbare bedrijfsbinding wordt overgeslagen en afzonderlijk gemeld; wijs het eerst uitdrukkelijk aan het juiste bedrijf toe. De uitslag onderscheidt bevestigde publicaties, aanvragen die controle vereisen en overgeslagen domeinen. Zij meldt geen totaal succes voor een gedeeltelijk uitgevoerde selectie.

Een verloren antwoord kan al een geaccepteerde schrijfactie betreffen. Bewaar daarom het oorspronkelijke bewijs. Opnieuw op de knop drukken vervangt een onzekere aanvraag niet. Controleer eerst de providerstatus; alleen stappen die bij die oorspronkelijke publicatie nooit zijn geprobeerd, kunnen daarna expliciet worden voortgezet. Status lezen of een herstelpagina openen start geen publicatie.

Voor automatisering en AI-agents: native herstellen/opnieuw wegschrijven gebruikt het canonieke oorspronkelijke DNS-journaal. Opnieuw opbouwen bestaat uit afzonderlijk beoordeelde, aan bedrijf/zone/versie gebonden publicaties, niet uit een nieuwe versieloze globale leveranciersreset. Verwijder nooit wachtende oorspronkelijke ontvangstbewijzen, leid geen geslaagde publieke verspreiding af uit private provideropslag en verzin geen nieuwe intentie na een onbekende leveranciersbevestiging. Uitsluitend bij de provider aanwezige SOA/NS en ongerelateerde Cloudflare-ID's behouden bovenstaande beschermingsregels. Aanmaken, verwijderen/deactiveren en registrar-nameserverwijzigingen hebben afzonderlijke levenscycluscontracten; deze publicatiewerkwijze geeft daarvoor geen bevoegdheid.

### Dezelfde publicatie via API en Rust CLI

De API-routes `POST dns/zones/{zone}/actions/restore` en `.../rewrite` gebruiken dezelfde portaalpublicatie, DNS-historie en oorspronkelijke leverancierspogingen. Zij schrijven niet via een afzonderlijke DNS-client vanuit de CLI. Een normale persoonlijke verbinding of een echte bedrijfsintegratie met `dns.records:write` kan een toegestane zone publiceren; zonebeperkingen blijven gelden. Lees eerst de actuele zone-ETag. Een verouderde versie wordt geweigerd voordat een operatie of leverancierspoging wordt aangemaakt.

```sh
binadit dns zones get 41 --account 123
binadit dns zones actions run 41 rewrite --account 123 --version ZONE_ETAG --dry-run
```
Beoordeel bedrijf, zone, opgeslagen records en het verschil tussen herstellen en opnieuw wegschrijven. Laat daarna `--dry-run` weg voor de bewuste publicatie. Een preview leest geen volledige actuele leverancierssnapshot en belooft geen publieke DNS-propagatie. Bewaar bij een onzeker antwoord het oorspronkelijke lokale verzoek en de operatie-ID. Geef een herstelverbinding ook `operations:read`. Als de operatie-ID in het antwoord verloren is gegaan, lees dan onder dezelfde verbinding `binadit operations list --account 123` en zoek de oorspronkelijke actie en tijd. Een vernieuwde persoonlijke login kan het oude ontvangstbewijs alleen met de exact bewaarde oorspronkelijke identiteit, request key en aanvraag lezen via de gedocumenteerde `operations/original-receipt`-workflow. Gebruik daarna `GET dns/publication-changes/by-operation/{operation}` om het bestaande journal terug te vinden, of lees rechtstreeks de ontvangen `dns_mutation_id`:

```sh
binadit dns publication-changes get JOURNAL_UUID --account 123
```
Herstel gebruikt steeds datzelfde journal, de oorspronkelijke HTTP-operatie en actuele versies. Een huidig bedrijfseigenaar met recente sterke verificatie beoordeelt bijvoorbeeld dit invoerbestand; vervang alle voorbeeldwaarden door de zojuist gelezen gegevens:

```json
{
  "confirm_mutation_id": "JOURNAL_UUID",
  "confirm_zone_id": 41,
  "confirm_zone_version": "ACTUELE_ZONE_VERSIE",
  "version": "ACTUELE_JOURNAL_VERSIE",
  "confirm_no_supplier_mutation": true
}
```
```sh
binadit dns publication-changes reconcile JOURNAL_UUID --account 123 \
  --confirm-mutation JOURNAL_UUID --input reconcile.json --yes
```
`reconcile` leest uitsluitend de leverancier en kan bewezen lokale publicatie afronden. Voor een nog nooit uitgevoerde oorspronkelijke stap gebruik je `continue` met een opnieuw beoordeeld bestand: vervang `confirm_no_supplier_mutation` door `confirm_continue_original: true`. `continue` vraagt actuele token-schrijfrechten en ingeschakeld API-schrijven; zij herhaalt geen eerdere schrijfpoging. `abandon` gebruikt `confirm_abandon_original: true` en mag alleen wanneer geen leveranciersmutatie is geprobeerd.

Geen van deze herstelopdrachten maakt een nieuwe operatie, sleutel of leveranciersjournal aan. Gebruik geen handmatige `--idempotency-key`, dry-run of queryparameters. Tijdens een schrijfpauze kan een nieuwe alleen-lezen persoonlijke verbinding met `dns.records:read` na sterke verificatie `reconcile` en `abandon` gebruiken. De oorspronkelijke ondertekende schrijfgrens en de actuele portaalrechten blijven vereist. Een andere of ruimere verbinding is geen toestemming om een onzeker resultaat te vervangen.

Voor agents: onderscheid `action=restore/rewrite`-publicatiebewijzen van verbindingsbewijzen met `direction=push/pull/detach`. Gebruik de `dns.publication-changes.*`-catalogus en huidige zone-/journaalversies. Alleen een geverifieerd ondertekend terminaal journaal plus het exacte oorspronkelijke HTTP-bewijs toont afronding aan; bevestigde provideropslag bewijst geen publieke DNS-verspreiding. Bewaar de oorspronkelijke lokale wachtende aanvraag totdat het eigen HTTP-bewijs veilig is bevestigd. Een oorspronkelijke serviceaanvraag blijft een echte serviceaanvraag wanneer een huidige menselijke eigenaar haar reconcilieert; verzin nooit een persoonlijke machtiging en vervang de bovenliggende operatie niet.


### DNS-publicatie als platformbeheerder

Een platformbeheerder gebruikt de eigen bedrijfscontext en een expliciet doelbedrijf. De API logt daarbij niet als klant in en maakt geen klantlidmaatschap aan. Gebruik de afzonderlijke routes `POST admin/dns/zones/{zone}/actions/restore` en `.../rewrite` met `target_account_id` in de JSON-body en de actuele zone-ETag in `If-Match`. Vereist zijn een huidige interne beheerdersrol, recente sterke verificatie, `admin:write` en ingeschakelde beheer-, gevoelige en schrijffuncties. Een normale bedrijfsintegratie kan deze bevoegdheid niet verkrijgen.

Bijvoorbeeld: bewaar `{"target_account_id":123}` in een lokaal beoordeeld bestand en gebruik voor bedrijfscontext 900 en zone 41:

```sh
binadit api /admin/dns/zones/41/actions/rewrite --method POST --account 900 \
  --from-file publication.json --version ZONE_ETAG --dry-run
```
Lees en beoordeel de preview voordat je dezelfde beoogde handeling zonder `--dry-run` uitvoert. `context_account_id` is de eigen beheerderscontext; `target_account_id` is het bedrijf waarvan de zone daadwerkelijk wordt gepubliceerd. De oorspronkelijke HTTP-operatie blijft in de beheerderscontext. Het DNS-journaal blijft bij het doelbedrijf. Herstel behoudt beide grenzen:

```sh
binadit dns publication-changes get JOURNAL_UUID --account 900 --administrator
binadit dns publication-changes reconcile JOURNAL_UUID --account 900 --administrator \
  --confirm-mutation JOURNAL_UUID --input reconcile.json --yes
```
Gebruik dezelfde actuele versies en bevestigingsvelden als hierboven. `--administrator` kiest de beheerdersroute; het verandert je identiteit of bedrijfscontext niet. De lookup is `GET admin/dns/publication-changes/by-operation/{operation}`. Ook `continue` en `abandon` ondersteunen de vlag. Tijdens een schrijfpauze kan een nieuwe persoonlijke beheerverbinding met `admin:read` uitsluitend lezen, GET-only reconciliëren of een bewezen nooit gestarte aanvraag lokaal opgeven, zolang de oorspronkelijke ondertekende schrijfgrens en actuele beheerrechten dit toestaan. Voortzetten vereist altijd actueel `admin:write` en ingeschakeld schrijven.

Voor agents: houd de echte uitvoerderscontext gescheiden van het expliciete doelbedrijf. Gebruik de `admin.dns.publication-changes.*`-functies voor beheerherstel; klantpublicatiefuncties geven geen toegang tot deze routes. Bewaar de oorspronkelijke operatie en het journaal en verzin nooit klantlidmaatschap, klantnabootsing, een vervangende machtiging of een nieuwe leverancierspoging na een onbekende bevestiging.


## DNS verwijderen of deactiveren in het portaal

In het DNS-overzicht behoudt **DNS deactiveren** de domeinregistratie, diensten, bestellingen en facturering. Het wist portaal-DNS-records en verwijdert een door Binadit beheerde zone uitsluitend nadat de provider heeft bevestigd dat de exacte oorspronkelijke zone afwezig is. **Verwijderen** verwijdert de lokale DNS-domeinrij alleen wanneer deze geen registratie-, dienst-, facturerings- of taakbinding heeft. Geen van beide acties verwijdert een registrarregistratie of betaalde dienst. Ontkoppel eerst expliciet een Cloudflare-verbinding; deze acties verwijderen geen Cloudflare-zone.

Controleer het getoonde domein en bevestig de DNS-only-actie met je bestaande geldige aanmelding. De browser bewaart één aanvraag voor dat bedrijf, die zone en versie. Na een onderbroken antwoord controleert de voortgangspagina automatisch dezelfde oorspronkelijke aanvraag met uitsluitend providerreads; je hoeft geen statuscontrole goed te keuren en krijgt geen interne identificaties als instructies. Afzonderlijk voortzetten kan uitsluitend een oorspronkelijke stap versturen die nooit is geprobeerd; een onzekere DELETE wordt nooit opnieuw verstuurd. Een vóór voorbereiding geweigerd origineel heeft een ondertekend, niet-verzendbaar ontvangstbewijs; beoordeel expliciet opnieuw vóór een nieuwe actie.

Bij externe DNS wijzigt verwijderen/deactiveren uitsluitend de portaalgegevens en historie. Het ontvangstbewijs zegt expliciet dat afwezigheid bij de externe provider niet is geverifieerd. Een portaalontvangstbewijs bevestigt geen publieke DNS-verspreiding.

Een voltooide verwijdering blijft via haar oorspronkelijke ontvangstbewijs beschikbaar, ook als de DNS-rij niet meer bestaat. De server controleert de ondertekende oorspronkelijke bovenliggende aanvraag, het voltooide verwijderingsbewijs en de actuele toegang, bedrijfscontext, identiteitgeneratie en verificatie van de oorspronkelijke persoon. Een afwezige rij geldt nooit als autorisatie en een vervangende rij met het oude ID wordt geweigerd. Voltooide ontvangstbewijzen keren terug naar het DNS-overzicht. Bij mislukte lokale opslag blijven bevestigde providerbewijzen behouden voor uitsluitend-lezen herstel; dien geen tweede verwijdering in.

### DNS-only verwijderen via API en Rust-CLI

`DELETE dns/zones/{zone}` en `POST dns/zones/{zone}/actions/deactivate` gebruiken hetzelfde oorspronkelijke DNS-only-verwijderingsjournaal als het portaal. Beide vereisen de huidige zone-ETag en `dns.zones:write`. Deactiveren vereist ook `confirm_domain` met de exacte huidige domeinnaam. Verwijderen weigert registratie-, dienst-, facturerings- en bestelbindingen; deactiveren behoudt deze. Ontkoppel eerst Cloudflare. Externe DNS levert een uitsluitend lokaal resultaat, zonder te beweren dat de externe zone afwezig is.

Beoordeel de huidige zone en gebruik eerst de bestaande zonecommandopreview vóór bewuste uitvoering:

```sh
binadit dns zones get 41 --account 123
binadit dns zones delete 41 --account 123 --version ZONE_ETAG --dry-run
```
Bewaar na een onzeker antwoord de oorspronkelijke lokale aanvraag en het operatiebewijs. Zoek hetzelfde journaal via `GET dns/removal-changes/by-operation/{operation}` of de geretourneerde `dns_mutation_id`. Herstel maakt geen nieuwe aanvraagsleutel, operatie of journaal:

```sh
binadit dns removal-changes get JOURNAL_UUID --account 123
binadit dns removal-changes reconcile JOURNAL_UUID --account 123 \
  --confirm-mutation JOURNAL_UUID --input reconcile.json --yes
```
De beoordeelde JSON heeft dezelfde velden als ander oorspronkelijk DNS-herstel: `confirm_mutation_id`, `confirm_zone_id`, `confirm_zone_version`, `version` en precies één expliciete booleaanse bevestiging. Gebruik de waarden uit `get`; `reconcile` vereist `confirm_no_supplier_mutation: true`. Het leest uitsluitend met GET bij de provider en kan de lokale publicatie van reeds bevestigde afwezigheid afronden. Een onzekere DELETE wordt nooit herhaald. `continue` vereist `confirm_continue_original: true`, huidige schrijfscope en ingeschakelde writes; het kan uitsluitend een nooit geprobeerde oorspronkelijke verwijdering verzenden. `abandon` vereist `confirm_abandon_original: true` en geen geprobeerde providermutatie. Een voltooide verwijdering annuleren wordt geweigerd.

Een huidige, sterk geverifieerde bedrijfseigenaar mag oorspronkelijk herstel uitvoeren. Tijdens een schrijfpauze kan een nieuwe persoonlijke verbinding met `dns.zones:read` lezen, reconciliëren of opgeven binnen het ondertekende oorspronkelijke scopeplafond en actuele native rechten. Zij kan niet voortzetten. Gewone statuslezingen ondersteunen ook echte zonegebonden servicemachtigingen. Huidige resourcebeperkingen gelden zelfs voor herhaling van een voltooide verwijdering.

Na voltooide verwijdering is `zone_deleted: true` een geverifieerd historisch resultaat. De `zone_version` is de oorspronkelijk goedgekeurde versie omdat de oude rij verdwenen is; bewaar die waarde voor herstel van het ontvangstbewijs. Een nieuwe aanvraag voor de afwezige rij wordt geweigerd, evenals een vervangende rij die het oude ID hergebruikt. Deactiveren behoudt de rij en gebruikt haar huidige versie. Publieke DNS-verspreiding blijft gescheiden van de afwezigheidsbevestiging van de provider.

Voor AI-agents: gebruik `dns.removal-changes.*`, bewaar het eerste HTTP-bewijs en ondertekende journaal en onderscheid verwijdering `action=delete/deactivate` van publicatie `restore/rewrite` en verbindingsrichting. Leid verwijderbevoegdheid nooit af uit een ontbrekende rij en voeg geen `allow_missing`, vervangende sleutel, klantnabootsing of herhaalde provider-DELETE toe. Een vastgehouden resultaat blijft vastgehouden totdat expliciet herstel zowel het oorspronkelijke DNS-journaal als het oorspronkelijke HTTP-bewijs verifieert.

### DNS-only verwijderen als platformbeheerder

Een platformbeheerder behoudt de eigen bedrijfscontext en selecteert expliciet het klantbedrijf. Gebruik `POST admin/dns/zones/{zone}/actions/delete` voor een ongebonden DNS-only-zone, of `.../deactivate` om registratie en diensten te behouden. Beide vereisen `target_account_id` en de huidige zone-ETag. Deactiveren vereist ook `confirm_domain` met het exacte domein. Deze acties gebruiken hetzelfde portaalverwijderingsjournaal en behouden zijn facturerings- en providerbeveiliging; beheer omzeilt geen betaalde-dienstbindingen of vereiste Cloudflare-ontkoppeling.

Bewaar voor context 900, doelbedrijf 123 en zone 41 `{"target_account_id":123}` als beoordeeld lokaal JSON-bestand:

```sh
binadit api /admin/dns/zones/41/actions/delete --method POST --account 900 \
  --from-file deletion.json --version ZONE_ETAG --dry-run
```
Beoordeel de preview vóór bewuste uitvoering zonder `--dry-run`. Het eerste HTTP-bewijs hoort bij context 900; het DNS-journaal hoort bij bedrijf 123. Er wordt geen klantlogin, klantlidmaatschap of vervangende identiteit gemaakt. Beheerstatus bevat zowel `context_account_id` als `target_account_id`, zodat automatisering dit onderscheid kan behouden.

```sh
binadit dns removal-changes get JOURNAL_UUID --account 900 --administrator
binadit dns removal-changes reconcile JOURNAL_UUID --account 900 --administrator \
  --confirm-mutation JOURNAL_UUID --input reconcile.json --yes
```
Gebruik dezelfde hierboven beschreven beoordeelde versies en bevestigingsvelden. De beheerlookup is `GET admin/dns/removal-changes/by-operation/{operation}`. De vlag `--administrator` geldt ook voor `continue` en `abandon`; hij selecteert de beheerroute zonder de geauthenticeerde persoon of context te wijzigen. Beheerfuncties gebruiken `admin.dns.removal-changes.*`. Klantverwijderfuncties geven geen bevoegdheid tot beheerherstel.

Elk beheerverzoek vereist de huidige interne beheerdersrol en recente sterke verificatie in de echte uitvoerderscontext. Een effect aanmaken of voortzetten vereist ook huidig `admin:write`, ingeschakelde writes en ingeschakelde beheer-/gevoelige functies. Tijdens een schrijfpauze kan een nieuwe persoonlijke `admin:read`-verbinding het origineel lezen of expliciet uitsluitend via GET reconciliëren, of een bewezen nooit geprobeerd origineel binnen zijn ondertekende oorspronkelijke scopeplafond opgeven. Zij kan geen leverancierswrite voortzetten. Een voltooid ontvangstbewijs van een verwijderde zone blijft alleen leesbaar zolang de oorspronkelijke klantbinding geldig is en het oude ID geen vervangende rij heeft.

Voor AI-agents: bewaar uitvoerderscontext, expliciet doelbedrijf, oorspronkelijk HTTP-bewijs en ondertekend DNS-journaal afzonderlijk. Verzin nooit klantlidmaatschap of klantnabootsing, leid geen toestemming af uit een afwezige zone, vervang geen onbekende oorspronkelijke aanvraag en verstuur geen onzekere provider-DELETE opnieuw. Providerafwezigheid en een succesvol gepubliceerd lokaal resultaat bewijzen geen publieke DNS-verspreiding.

## DNS-zones toevoegen in het portaal

Een beheerder kan via **Domein toevoegen** in het DNS-overzicht DNS-zones maken. Kies het bedrijf, voer de domeinnamen in en selecteer eventueel een template. Klik daarna **één keer op Domein toevoegen**. Het portaal controleert het actuele bedrijf, de rechten en de template op de achtergrond. Er is geen aparte reviewpagina, JSON-preview of goedkeuringsvakje. Je geldige passkey-aanmelding wordt hergebruikt; voor DNS toevoegen of opslaan hoef je niet opnieuw met een passkey te bevestigen. Dit maakt uitsluitend DNS; domeinregistratie en betaalde diensten zijn afzonderlijke acties.

Elke naam behoudt zijn eigen aanvraag. Na een onderbroken verbinding controleert het portaal automatisch diezelfde aanvraag en toont het begrijpelijke voortgang en een normale DNS-recordtabel. Het maakt geen vervangende zone en herhaalt geen onzekere provideraanmaak. Alleen stappen die aantoonbaar nog niet zijn verstuurd kunnen expliciet worden voortgezet. Het actuele bedrijf en de rechten van de oorspronkelijke beheerder worden nog steeds gecontroleerd.

Een goedkeuring die geen lokale zone heeft gereserveerd kan expliciet worden gesloten. Dezelfde oorspronkelijke UUID blijft daarna niet-verzendbaar. Bestaat al een lokale zone, gebruik dan de oorspronkelijke herstelpagina; de actie zonder reservering weigert dit geval. Gebonden aanmaak kan uitsluitend worden geannuleerd voordat enige providerwrite is geprobeerd; de lege lokale zone blijft expliciet extern. Een statuspagina verversen start nooit een write. Een opslagfout of onopgeloste oudere browsergoedkeuring houdt het origineel vast totdat de status is beoordeeld.

Als het opslaan van de lokale aanvraagkoppeling na een gecommitteerde reservering werd onderbroken, controleert en herstelt het portaal automatisch uitsluitend diezelfde ondertekende koppeling. Dit lokale herstel benadert de provider niet en reserveert geen tweede zone. Kan de afronding niet worden bevestigd, dan blijft de voortgang met een toelichting zichtbaar; het portaal meldt geen onterecht succes en herhaalt geen onzekere write.

### DNS-only-zones maken via beheerders-API en Rust-CLI

Gebruik `POST /api/v1/accounts/{context}/admin/dns/zones` met `domain`, `target_account_id` en optioneel `template_id`. De context is het eigen bedrijf van de beheerder; het doel is het bedrijf dat eigenaar van de DNS-zone wordt. Elk verzoek vereist de daadwerkelijke huidige interne beheerder en recente passkeyverificatie. Aanmaken vereist `admin:write` en ingeschakelde beheer-, gevoelige en schrijffuncties. Het maakt nooit een klantlogin, lidmaatschap, domeinregistratie of betaalde dienst.

Lees bij een geselecteerde template eerst `GET admin/dns/templates/{template}` en bewaar de ETag. Geef deze ETag als `If-Match` of CLI `--version`; een ontbrekende templatevoorwaarde geeft 428 en een gewijzigde template 412. Laat zonder template de versieheader weg. De nieuwe zone heeft nog geen ETag. Templaterecords worden naar de oorspronkelijke intentie gekopieerd; latere wijzigingen of verwijdering van die template kunnen de goedgekeurde records niet stilzwijgend wijzigen of herhaling van een voltooid origineel verhinderen.

Bewaar voor uitvoerderscontext 900 en klantbedrijf 123 de beoordeelde body als `creation.json`:

```json
{"domain":"example.com","target_account_id":123,"template_id":7}
```
```sh
binadit api /admin/dns/templates/7 --method GET --account 900
binadit dns zones create --administrator --account 900 \
  --from-file creation.json --version TEMPLATE_ETAG --dry-run
```
De preview retourneert het canonieke domein, de templateversie en het volledige recordplan. Zij reserveert geen zone of oorspronkelijke operatie en benadert de provider niet. Beoordeel deze en voer bewust dezelfde opdracht zonder `--dry-run` en met `--yes` uit. De CLI bewaart het oorspronkelijke HTTP-bewijs en de aanvraagsleutel. De server commit de ene lokale zone, het ondertekende journaal en het oorspronkelijke HTTP-bewijs samen vóór ieder leveranciersverzoek. Een lokaal reeds gereserveerde of bij de provider gevonden zone wordt niet op naam overgenomen.

Succes retourneert zone-`id`, `dns_mutation_id`, `context_account_id` en `target_account_id`. Bewaar deze bij het oorspronkelijke operatiebewijs. Een onderbroken of vastgehouden aanmaak moet hetzelfde origineel gebruiken; dien nooit een vervangende sleutel in om een onzekere leveranciers-POST te omzeilen. Zoek het via `GET admin/dns/creation-changes/by-operation/{operation}` of zijn journaal-UUID:

```sh
binadit dns creation-changes get JOURNAL_UUID --account 900 --administrator
binadit dns creation-changes reconcile JOURNAL_UUID --account 900 --administrator \
  --confirm-mutation JOURNAL_UUID --input reconcile.json --yes
```
Maak `reconcile.json` op basis van de laatste oorspronkelijke status, met de geretourneerde zone- en journaalversies:

```json
{
  "confirm_mutation_id":"JOURNAL_UUID",
  "confirm_zone_id":41,
  "confirm_zone_version":"ZONE_VERSION_FROM_STATUS",
  "version":"JOURNAL_VERSION_FROM_STATUS",
  "confirm_no_supplier_mutation":true
}
```
Reconciliatie doet uitsluitend provider-GET's en mag hetzelfde oorspronkelijke lokale of HTTP-afrondingsbewijs herstellen. Zij herhaalt nooit een onzekere provider-POST. Een afzonderlijke `continue`-opdracht met `confirm_continue_original: true` in plaats van de reconciliatiebevestiging mag uitsluitend oorspronkelijke stappen leveren die nooit zijn geprobeerd. Deze vereist huidig `admin:write` en ingeschakelde writes. Een afzonderlijke `abandon`-opdracht met `confirm_abandon_original: true` kan een geheel nooit geprobeerd origineel uitsluitend met SQL afsluiten; de gereserveerde lege zone blijft expliciet extern. Deze weigert iedere geprobeerde providerwrite of voltooide aanmaak.

Herstel verstuurt geen nieuwe idempotentiesleutel, `If-Match`, dry-runveld of queryparameters. Gebruik uitsluitend de ene bevestiging voor de gekozen actie. Tijdens een schrijfpauze kan een nieuwe persoonlijke `admin:read`-verbinding lezen, uitsluitend via GET reconciliëren of opgeven binnen het ondertekende oorspronkelijke scopeplafond en de actuele rechten van de oorspronkelijke beheerder. Zij kan niet voortzetten. Een ontbrekend of onjuist gevormd oorspronkelijk HTTP-resultaat blijft vastgehouden totdat expliciete oorspronkelijke reconciliatie het ontvangstbewijs verifieert en herstelt.

Voor AI-agents: vereis de exacte `admin.dns.creation-changes.*`-functie en expliciete `--administrator`-vlag. Bewaar uitvoerderscontext, klantdoel, oorspronkelijke operatie, journaal en beoordeelde versies afzonderlijk. Klant-DNS-functies verlenen geen bevoegdheid tot deze beheerroute. Verzin geen klantlidmaatschap, vervang geen onzeker origineel, neem geen bestaande providerzone over en leid geen publieke DNS-verspreiding af uit een succesvol lokaal of leveranciersbewijs.

## Nameservergroepen wijzigen in het portaal

Open de nameserverinstellingen van het domein en kies een groep. Het portaal toont automatisch de bijbehorende adressen; klik op **Nameservers opslaan**. Voor een gewone wijziging van één domein is geen extra beoordelingsvinkje nodig. Klantconfiguraties kopiëren de gekozen nameserverlijst en glue-adressen naar dat domein. De zichtbare naam is een label, geen opdracht om een gelijknamige groep bij de registrar aan te maken of te overschrijven. Nieuwe portaal- en API-configuraties gebruiken unieke interne sleutels. Een bestaande registrargroepsnaam kan daardoor de wijziging niet blokkeren of andere domeinen wijzigen. Geïmporteerde/gedeelde registrargroepen behouden hun duidelijk getoonde livegroepsgedrag; latere wijzigingen aan die livegroep kunnen gekoppelde registraties beïnvloeden.

Bij Cloudflare-nameservers legt het portaal uit hoe DNS-beheer via Binadit beschikbaar blijft en verwijst het naar de [Cloudflare-instelhulp](/developers/guides/cloudflare-connection?lang=nl). Nameserverdelegatie en de Cloudflare-API-koppeling zijn afzonderlijke stappen.

Dit wijzigt de delegatie bij de registrar, niet de DNS-recordinhoud. Een werkelijk ongeregistreerd domein zonder registrarobject krijgt uitsluitend een lokale groepskeuze: stel de publieke nameservers zelf bij de externe registrar in. Een registratie bij een andere leverancier wordt hier niet als lokale wijziging behandeld. Opgeslagen leveranciersinstellingen zijn geen bewijs dat publieke DNS al is bijgewerkt.

Een groepsmigratie vanuit het nameserveroverzicht toont maximaal 25 domeinen per pagina. Selecteer de bedoelde domeinen en bevestig de review; ieder domein heeft een eigen oorspronkelijke wijziging. De uitvoering stopt bij het eerste onduidelijke resultaat. Beoordeel de volgende pagina afzonderlijk. Wijzigingen aan houder en nameservers vragen aparte goedkeuringen; het oude bewerkformulier voert geen houderwijziging uit vóór een nog onbeoordeelde nameserverwijziging.

Het portaal gebruikt de bestaande geldige aanmelding en actuele domeinrechten. Deze gewone actie vraagt niet opnieuw om dezelfde passkey of authenticator. Interne beheerders gebruiken hun eigen bedrijfscontext. De afzonderlijke verificatieregels voor gevoelige API/CLI-acties blijven gelden. De browser bewaart het oorspronkelijke nummer. Na een verloren antwoord open je **Opgeslagen wijziging bekijken**. Status vernieuwen schrijft niets bij de registrar. Reconciliatie leest de bekende oorspronkelijke registratie; doorgaan kan uitsluitend een nog nooit verstuurde oorspronkelijke stap uitvoeren. Annuleren geeft alleen een aantoonbaar nooit verstuurde reservering vrij. Een ontbrekend serverrecord is geen voltooiingsbewijs: alleen een expliciete bevestiging kan datzelfde nog ongebruikte nummer definitief sluiten. Wis de browsermarkering niet om een onduidelijk resultaat te omzeilen.

Een oudere lokale klantgroep die ten onrechte als registrargroep is behandeld, kan dezelfde oorspronkelijke aanvraag afronden wanneer het opvragen van precies die registrargroep bewijst dat zij ontbreekt. Herstel controleert eerst actuele eigendom, de ongewijzigde oorspronkelijke groep en goedgekeurde records, en het ontbreken van een plan of fysieke leverancierspogingen. Het eerste ondertekende uitvoeringsplan legt daarna een exacte kopie voor het domein vast; de oorspronkelijke goedkeuring blijft behouden. Een authenticatiefout, timeout, algemene fout of al verstuurde schrijfactie geeft hiervoor nooit toestemming. Een bestaande registrargroep met andere records wordt via dit herstelpad niet overschreven.

### Nameserverreview en uitvoering via API en CLI

Lees eerst het domein en de beschikbare groep onder het echte klantbedrijf. `GET domains/options/nameserver-groups/{group}` geeft `data.version`; gewone domein-GET levert de ETag. De Rust-CLI bewaart die HTTP-header als `meta.etag`:

```sh
umask 077
binadit domains get 41 --account 99 --output json > domain-review.json
binadit api /domains/options/nameserver-groups/7 --account 99 --output json > group-review.json
jq '.data | {nameserver_group_id:.id,nameserver_group_version:.version}' group-review.json > nameservers.json
binadit domains actions run 41 nameservers --account 99 \
  --from-file nameservers.json --version "$(jq -r '.meta.etag' domain-review.json)" --dry-run
```
Beoordeel de delegatie in de preview. Voer daarna dezelfde opdracht zonder `--dry-run` en met `--yes` uit. De CLI bewaart de eerste HTTP-sleutel. De directe route is `POST /api/v1/accounts/{account}/domains/{domain}/actions/nameservers`, met `domains:write`, de domein-ETag in `If-Match`, een duurzame `Idempotency-Key` en precies `nameserver_group_id` plus `nameserver_group_version`. Een oude groepsversie geeft `412` vóór voorbereiding. Een exacte herhaling gebruikt dezelfde sleutel en dezelfde JSON, ook nadat de actie de domeinversie heeft veranderd.

De DNS-ingang `POST .../dns/zones/{zone}/actions/nameservers` gebruikt dezelfde velden en kern. Deze ingang vraagt `dns.zones:write` en bij een bestaande registratie ook `domains:write`. Hij verleent geen registrarrechten op basis van DNS-rechten alleen. Lokale groepskeuze retourneert `local_configuration_only:true` en `registrar_confirmed:false`.

### Het oorspronkelijke registrarverzoek herstellen

Bewaar de eerste `operation.id`. Vind het bestaande journal via `GET domains/changes/by-operation/{operation}`; voor de DNS-ingang is dat `GET dns/nameserver-changes/by-operation/{operation}`. Het antwoord bevat het oorspronkelijke journalnummer in `data.id`, afzonderlijk van `operation_id`, en de huidige `zone_version` en journal-`version`.

```sh
binadit api /domains/changes/by-operation/HTTP_UUID --account 99 --output json
binadit domains changes get JOURNAL_UUID --account 99 --output json > original.json
jq '.data | {confirm_mutation_id:.id,confirm_zone_id:.zone_id,confirm_zone_version:.zone_version,version,confirm_no_supplier_mutation:true}' original.json > reconcile.json
binadit domains changes reconcile JOURNAL_UUID --account 99 \
  --confirm-mutation JOURNAL_UUID --input reconcile.json --yes
```
Vervang de voorbeeldnummers en UUID's door de echte antwoorden. Voor een oorspronkelijk verzoek via de DNS-ingang gebruik je dezelfde opdrachten met `dns nameserver-changes` in plaats van `domains changes`. De subcommando's zijn `get`, `reconcile`, `continue` en `abandon`.

Reconciliatie doet alleen leveranciers-GET's en mag hetzelfde lokale of HTTP-ontvangstbewijs herstellen. Een onzekere PUT wordt nooit opnieuw verzonden. `continue` vraagt `confirm_continue_original:true`; `abandon` vraagt `confirm_abandon_original:true`. Gebruik steeds de vier identificatie-/versievelden uit de **laatste** `get`, plus uitsluitend de ene bevestiging voor de gekozen actie. Lees na een herstelactie de metadata opnieuw voordat je een andere actie kiest. Deze commando's sturen geen nieuwe idempotentiesleutel, `If-Match`, queryparameters of dry-run; de CLI accepteert hier geen `--version` of `--from-file`, maar gebruikt `--input`.

Herstel vraagt actuele toegang van een sterk geverifieerde eigenaar; de oorspronkelijke goedkeuring is geen vervanging voor huidige rechten. Tijdens een API-schrijfpauze kan een nieuwe persoonlijke leesverbinding binnen het oorspronkelijke scopeplafond inspecteren, GET-only reconciliëren of een nooit verstuurd verzoek annuleren. Doorgaan vraagt actuele schrijfrechten en ingeschakelde writes. CLI-exitcode `6` betekent dat hetzelfde oorspronkelijke verzoek nog onopgelost is; er is geen vervanger aangemaakt.

### Nameservers als platformbeheerder

Een beheerder houdt `--account` op het eigen goedgekeurde beheerbedrijf en kiest het klantbedrijf apart. Er wordt geen klantlidmaatschap of klantgrant nagebootst. De alleen-lezen review werkt met `admin:read`, een actuele interne beheerder en recente persoonlijke passkeyverificatie:

```sh
binadit api /admin/domains/41/nameserver-review/99/7 \
  --account 900 --output json > admin-nameserver-review.json
jq '.data | {target_account_id,nameserver_group_id,nameserver_group_version}' admin-nameserver-review.json > admin-nameservers.json
binadit api /admin/domains/41/actions/nameservers --method POST --account 900 \
  --from-file admin-nameservers.json --version "$(jq -r '.data.zone_version' admin-nameserver-review.json)" --dry-run
```
De reviewroute is `GET /api/v1/accounts/{operator}/admin/domains/{domain}/nameserver-review/{target}/{group}`. Zij leest uitsluitend lokale, gecontroleerde gegevens en geeft `zone_version`, `nameserver_group_version`, beide bedrijfsnummers en de delegatie terug. De ETag is dezelfde domeinversie. De groep moet voor het doelbedrijf beschikbaar zijn. Een verkeerde doelbinding geeft geen toegang; deze route vereist geen klantlidmaatschap en verstuurt geen leveranciersaanvraag.

Na beoordeling voer je de laatste opdracht zonder `--dry-run` en met `--yes` uit. De beheerders-POST vraagt `admin:write`, `target_account_id` plus dezelfde twee groepsvelden en de echte domein-ETag. Oorspronkelijke status en herstel staan onder `admin/domains/changes`; in Rust gebruik je `binadit domains changes get JOURNAL_UUID --administrator --account 900` en bij herstel tevens `--confirm-mutation JOURNAL_UUID --input FILE --yes`. Lees de volledige bestaande-registratieacties in de [registrargids](/developers/guides/registrar-administration?lang=nl).

Voor agents: bewaar operatorbedrijf, doelbedrijf, oorspronkelijke HTTP-operatie, journalnummer en beide reviewversies afzonderlijk. Gebruik de actuele `domains.changes.*`, `dns.nameserver-changes.*` of `admin.domains.changes.*`-capability van de gekozen ingang. Behandel een mislukte oorspronkelijke operatie niet als toestemming voor een nieuwe sleutel; lees het bestaande journal en herstel hetzelfde bewijs. Broncode en lokale controles verklaren geen productie-uitrol of gepubliceerde CLI-binary.
