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).

# Registrarbeheer, nameservers en bestaande registraties

De voorraad-, import- en synchronisatiefuncties hieronder lezen de bestaande registrarkoppeling van het portaal en koppelen bevestigde registrarregistraties aan lokale domeinen. Ze kopen geen registratie, verhuizing of abonnement en maken geen factuur. Alleen een persoonlijke verbinding van een actuele interne beheerder met recente passkeyverificatie en expliciete `admin:read`/`admin:write`-rechten heeft toegang. `--account` blijft het goedgekeurde beheerbedrijf; het doelbedrijf gebruikt een afzonderlijk modern accountnummer.

## Voorraad lezen

```sh
binadit admin domains registrar list --account 1 --limit 100 --output json
binadit admin domains registrar get 501 --account 1 --output json
```

De overeenkomstige routes zijn `GET /api/v1/accounts/{context}/admin/domains/registrar/portfolio?limit=100&cursor=0` en `GET .../portfolio/{provider_id}`. Een pagina bevat maximaal 100 registraties; `meta.next_cursor` is de volgende offset. Gebruik `--cursor` voor een volgende pagina of de bestaande begrensde `--all`-optie. Het detailantwoord levert `version`, `local_version`, `owner_account_id` en eventuele `owner_company_name`. De ETag bevestigt dezelfde registrarversie. Registrarwachtwoorden, verhuiscodes en volledige persoonsgegevens komen niet terug.

`owner_requires_reconciliation: true` betekent dat de bestaande bedrijfsbinding onbekend, dubbel, geblokkeerd of gearchiveerd is. Eerst die binding herstellen; import maakt hiervan geen willekeurig bedrijf. Een ontbrekende eigenaar blijft bij globale synchronisatie ongebonden met legacywaarde `0`, nooit automatisch klantnummer `1` of het nummer van een menselijke gebruiker.

## Import beoordelen en uitvoeren

Lees iedere registratie eerst. Dit voorbeeld maakt het invoerbestand uit het echte detailantwoord; vervang de voorbeeldnummers door het bedoelde registrarobject, beheerbedrijf en doelbedrijf.

```sh
umask 077
binadit admin domains registrar get 501 --account 1 --output json > registrar-review.json
jq --argjson target 99 '.data | {domains:[({provider_id,version,local_version} + (if .owner_account_id != null and .owner_account_id != $target then {confirm_owner_account_id:.owner_account_id} else {} end))]}' registrar-review.json > registrar-import.json
binadit admin domains registrar import --from-file registrar-import.json \
  --target-account 99 --confirm-target-account 99 --account 1 --dry-run
binadit admin domains registrar import --from-file registrar-import.json \
  --target-account 99 --confirm-target-account 99 --account 1 --yes
```

Controleer de gekozen eigenaar en de inhoud van het bestand vóór de laatste opdracht. Het bestand bevat alleen `domains`, met één tot 25 unieke `{provider_id,version,local_version,confirm_owner_account_id?}`-regels. Unix-bestanden moeten privé zijn (`0600`); `--from-file -` leest stdin. Velden worden niet via losse commandoregelargumenten aangeleverd.

Het doelbedrijf geldt voor nieuwe of ongebonden lokale registraties. Een bestaande DNS-eigenaar blijft eigenaar. Als dat een ander bedrijf is, vereist iedere betreffende regel de exacte `confirm_owner_account_id` uit de inspectie. Dat is een bevestiging van behoud, geen overdracht. De server vergelijkt zowel eigenaar als lokale versie opnieuw onder dezelfde schrijflock. In de browser staat het bestaande bedrijf bij de domeinkeuze; de expliciete importbevestiging en de bestaande geldige browseraanmelding met passkey/authenticator behouden deze selectie. De API en CLI behouden hun afzonderlijke eisen aan recente beheerdersverificatie.

De API gebruikt `POST /api/v1/accounts/{context}/admin/domains/registrar/import`. De body voegt `target_account_id` en `confirm_target_account_id` toe aan dezelfde beoordeelde `domains`-lijst. U kunt een geldig aanvraagbestand uit het bovenstaande bestand maken:

```sh
jq --argjson target 99 '. + {target_account_id:$target,confirm_target_account_id:$target}' registrar-import.json > registrar-api-request.json
binadit api /admin/domains/registrar/import --method POST --from-file registrar-api-request.json --account 1 --yes
```

De versies zijn de echte 64 hextekens uit GET. `local_version` mag alleen ontbreken of `null` zijn als er nog geen lokale DNS-rij bestaat. Stuur voor een directe API-POST een duurzame `Idempotency-Key`; `X-Binadit-Dry-Run: true` of `dry_run: true` valideert zonder import of operatierecord. De CLI regelt de sleutel. Een exacte herhaling speelt het oorspronkelijke resultaat terug, ook wanneer de import zelf de lokale versie heeft veranderd.

De uitkomst noemt per domein `imported`, `linked` of `skipped`, het lokale domeinnummer en de daadwerkelijke `owner_account_id`. DNS-records, een bestaande DNS-providerroute, lopende factuurafspraken en bestaande commerciële pakketkeuzes blijven behouden. Contactpersonen worden alleen binnen het bedrijf van de daadwerkelijke domeineigenaar gekoppeld. Een vreemde of onbekende contactpersoon geeft geen toegang tot gegevens van een ander bedrijf.

## Afwijzing en herstel

Een gewijzigde registrar- of lokale versie geeft `412`: inspecteer dezelfde registratie opnieuw en beoordeel de nieuwe gegevens. Een oorspronkelijke domeinbestelling, onduidelijke bedrijfsbinding of andere registraridentiteit geeft `409`; onderzoek de bestaande registratie of bestelling. Een gekoppeld domein krijgt geen nieuwe lokale identiteit. Alle geselecteerde lokale registraties en hun unieke naamclaims worden samen opgeslagen; een latere lokale fout draait die gehele import terug.

Bij een verloren antwoord: volg de oorspronkelijke operatie of herhaal exact dezelfde aanvraag met dezelfde idempotentiesleutel. Start geen registratie of verhuizing om een importprobleem te omzeilen. Deze gids beschrijft de lokaal geteste import-/inspectiecode; globale synchronisatie en overdracht van eigendom hebben afzonderlijke beheer- en factuurplannen. Dit is geen verklaring van productie-uitrol of algemene beschikbaarheid.

De import normaliseert de gedocumenteerde datumvelden van de registrar naar geldige database-datums; de bestaande portaalkeuze `creation_date`/`renewal_date` blijft leidend. Een nulwaarde voor `deleted_at` betekent niet verwijderd. Tijdzone-offsets worden naar UTC omgerekend; ongeldige kalenderdatums geven vóór opslag een gecontroleerde leveranciersfout.

Op 29 oktober 2026 controleerde een uitsluitend leesproef via de bestaande geconfigureerde registrarkoppeling één begrensde voorraadpagina (`limit:1`) en het bijbehorende detailantwoord. De object-ID’s kwamen overeen; alleen type- en vormmetadata werden gerapporteerd. De daadwerkelijke datumvelden hadden de ondersteunde SQL-datumtijdvorm, de verwijderdatum was leeg/nul en contacthandles en nameservergroep waren strings. Er werden geen object-ID’s, namen, adressen, contactgegevens, sleutels of leveranciersantwoorden weergegeven. Dit bewijst huidige antwoordcompatibiliteit, geen uitgevoerde productie-import.

## Het volledige portfolio synchroniseren

Het portaal opent via **Domeinen → Registrar synchroniseren** een afzonderlijke bevestigingspagina. Dit betreft het volledige portfolio van de bestaande registrarkoppeling, ook registraties buiten het gekozen beheerbedrijf. De bevestiging noemt dit expliciet. Het portaal vernieuwt alleen lokale metadata: contactpersonen, domeinmetadata, ontbrekende versleutelde verhuiscodes, nameservergroepen en providerdetectie. Registraties, verhuizingen, DNS-records en facturen worden niet bij een leverancier gewijzigd. Bestaande eigenaren, bedrijfsbindingen, DNS-routes en commerciële abonnementen blijven behouden; onbekende registraties blijven ongebonden.

De zeven fasen zijn `holders`, `domains`, `tokens`, `nameservers_start`, `nameservers_collect`, `nameservers_apply` en `providers`. Iedere stap verwerkt maximaal 25 bronobjecten. Nameserverobservaties worden eerst volledig verzameld; pas daarna wordt per groep de bestaande canonieke keuze van de grootste waargenomen set toegepast. Een lege observatie wist geen bestaande set. Nieuwe groepen krijgen geen stilzwijgend bedrijf of globale toegang. De bron is `domain_observation`; dit is geen nieuwe leveranciersconfiguratie of gezag om DNS-records te wijzigen.

Bewaar één oorspronkelijke UUID. De CLI toont de run-UUID in `data.id`:

```sh
binadit admin domains registrar sync start \
  --intent 1fe95bbe-8449-4ea3-a6b2-3f013a2047bc \
  --confirm-portfolio 1 --account 1 --yes --output json
binadit admin domains registrar sync status RUN_UUID --account 1 --output json
binadit admin domains registrar sync run RUN_UUID \
  --confirm-portfolio 1 --max-pages 25 --account 1 --yes --output json
```

Vervang `RUN_UUID` door de oorspronkelijke `data.id`. `--account` en `--confirm-portfolio` bevestigen het beheerbedrijf, niet een nieuwe eigenaar voor alle registraties. `--max-pages` begrenst één CLI-aanroep (1–1000, standaard 25). Een volgende normale aanroep leest dezelfde run en vervolgt vanaf de bevestigde fase. Zonder onduidelijke openstaande aanvraag kun je zo nodig opnieuw persoonlijk inloggen met een recente passkey. Bij een onduidelijke aanvraag is eerst het oorspronkelijke ontvangstbewijs nodig; een nieuwe login geeft een andere persoonlijke verbinding. Achtergrondverlenging of uitvoering door een machinegrant is niet toegestaan.

De Rust-CLI legt vóór iedere nieuwe pagina de exacte fase, cursor, versie, idempotentiesleutel en publieke persoonlijke `principal_id` vast in een privéjournal met schema `binadit-registrar-sync/v2`. De identiteit komt uit `GET /api/v1/me`, met hetzelfde verworven bearer-token dat voor de uiteindelijke pagina wordt gebruikt. Een gewijzigde verbinding wordt vóór verzending geweigerd. Er staan geen leveranciersgegevens, contactadressen, toegangstokens of verhuiscodes in het journal. De publieke principal verwijst alleen naar de historische eigenaar en geeft geen toegang. De CLI controleert de oorspronkelijke proceslock en journalinhoud opnieuw na authenticatie, vlak vóór verzending en vóór lokale publicatie van een ontvangstbewijs. De server bewaakt daarnaast fase, versie en SQL-locks. Gebruik voor `run` geen eigen `--idempotency-key`: elke pagina heeft haar eigen oorspronkelijke sleutel.

Na een verloren of onduidelijk antwoord stopt de CLI direct. Inspecteer de oorspronkelijke operatie en veilige runstatus. `--recover-original` controleert welke persoonlijke verbinding actief is. Binnen dezelfde verbinding kan de exacte oorspronkelijke pagina-aanvraag worden teruggespeeld. Na een nieuwe login leest de CLI uitsluitend het afzonderlijke oorspronkelijke ontvangstbewijs; zij verstuurt de oude pagina niet onder die nieuwe verbinding:

```sh
binadit admin domains registrar sync status RUN_UUID --account 1 --output json
binadit admin domains registrar sync run RUN_UUID \
  --recover-original --confirm-portfolio 1 --account 1 --yes --output json
```

Na een geslaagd uitsluitend-lezen herstel wist de CLI alleen de bevestigde lokale openstaande markering en stopt deze aanroep. `receipt.local_pending_resolved:true` bevestigt dit lokale resultaat. Start daarna dezelfde run opnieuw zonder `--recover-original`; die afzonderlijke aanroep leest de huidige bronstatus en ETag voordat een nieuwe pagina wordt voorbereid. Een eerdere bevestigde stap wordt teruggespeeld zonder leverancierspagina opnieuw te lezen. Een nog lopende of onduidelijke stap start geen vervanger. Als de server bij de exacte sleutel definitief `operation_failed` bevestigt, stopt herstel en wordt uitsluitend die lokale openstaande markering vrijgegeven; pas een afzonderlijke bewuste aanroep mag de huidige fase opnieuw beoordelen. Verwijder het journal niet om een onduidelijk resultaat te omzeilen. In het portaal werkt **Oorspronkelijke aanvraag controleren** hetzelfde: geen automatische herhaling, gevolgd door expliciet hervatten. **Pauzeren na huidige pagina** wacht op de lopende pagina; het is geen leveranciersannulering.

Bij een uitsluitend-lezen ontvangstbewijs met `operation.status:failed` toont de CLI het oorspronkelijke operatienummer en houdt zij de openstaande markering vast. Beoordeel dit resultaat. Alleen de volgende expliciete bevestiging mag dezelfde lokale markering vrijgeven:

```sh
binadit admin domains registrar sync run RUN_UUID \
  --recover-original --confirm-failed-operation OPERATION_UUID \
  --confirm-portfolio 1 --account 1 --yes --output json
```

`OPERATION_UUID` moet exact overeenkomen met het opnieuw gelezen mislukte oorspronkelijke ontvangstbewijs. Deze Rust-optie werkt alleen samen met `--recover-original`, niet met `--dry-run`. Ook na deze bevestiging stopt de aanroep; zij voert geen volgende pagina uit. Een afzonderlijke normale `run` beoordeelt daarna de actuele bron, voortgang en versie. Deze lokale vrijgave geldt uitsluitend voor de atomische registrarstap met leveranciersreads; een mislukte operatie bij andere API-functies bewijst niet dat externe effecten ontbreken.

Een oud openstaand journaal zonder vastgelegde oorspronkelijke persoonlijke principal wordt niet overgenomen door de huidige login. Een ontbrekend, lopend, afwijkend of onleesbaar oorspronkelijk bewijs blijft eveneens vaststaan. Bewaar run, oorspronkelijke sleutel en metadata voor beheerderonderzoek. Voeg geen huidige principal toe aan oude metadata en verwijder of vervang het journal niet om herstel af te dwingen. Een oud leeg journal kan bij een nieuwe, opnieuw beoordeelde pagina wel naar schema v2 worden bijgewerkt.

Een enkele stap kan ook expliciet worden uitgevoerd met de exacte gegevens uit `status`:

```sh
binadit admin domains registrar sync step RUN_UUID \
  --phase holders --page-cursor 0 --page-size 25 --version EXACTE_SHA256 \
  --confirm-portfolio 1 --account 1 --yes
```

`--dry-run` start geen run of operatierecord, bewaart geen openstaand journaal en wijzigt geen lokale bronnen. Bij `run --dry-run` wordt alleen de eerstvolgende pagina gelezen en gevalideerd. Het kan dus wel leveranciersreads uitvoeren. Statusinspectie zelf voert geen leveranciers-HTTP uit. Ook na gewijzigde of ontbrekende leveranciersconfiguratie blijven eigen oorspronkelijke voortgang en operationele resultaten inspecteerbaar; `source_current: false` en `resumable: false` verhinderen verdere stappen met een andere bron.

De bovenliggende uitvoering verloopt na twee uur. Nameserverobservaties verlopen na één uur; `blocked_reason: nameserver_collection_expired` stopt de run ook als de bovenliggende taak nog geldig is. Andere redenen zijn `expired`, `source_changed` en `nameserver_collection_unavailable`. Bewaar het oorspronkelijke resultaat en beoordeel een nieuwe synchronisatie; maak geen nieuwe aanvraag om een nog onduidelijke stap te omzeilen. De externe voorraad heeft geen bewezen onveranderlijke momentopname over alle pagina's en fasen. Vermijd gelijktijdige portfolio-wijzigingen bij de registrar en herhaal na zulke wijzigingen; afwezigheid op een pagina verwijdert nooit stilzwijgend lokale registraties.

### API-contract

- `POST /api/v1/accounts/{context}/admin/domains/registrar/synchronizations` met `{intent_id: UUID}` en een duurzame `Idempotency-Key` bereidt één run voor.
- `GET .../synchronizations/{run}` geeft alleen veilige aantallen, fase, cursor, context, vervaltijden en gereedheid, met de huidige `ETag`.
- `POST .../synchronizations/{run}/actions/step` met `{phase,cursor,limit?}` (`limit` 1–25), de oorspronkelijke `Idempotency-Key` en `If-Match` past één stap toe.
- `POST .../synchronizations/{run}/original-step-receipt` leest uitsluitend één exact oorspronkelijk paginabewijs na opnieuw inloggen; deze aanvraag voert geen pagina uit.

Een verwachte beleids-, bron- of versieafwijzing wordt vóór een nieuw operatierecord getoetst. Dezelfde controles gelden opnieuw onder de huidige lokale locks. Het bronresultaat, de voortgang van boven- en onderliggende taken en het uiteindelijke operatieresultaat worden samen gecommit. Een verloren antwoord ná die echte commit wordt uit de oorspronkelijke operatie hersteld. Volledige leverancierantwoorden en privéobservaties verschijnen niet in voortgang, auditresultaten of CLI-uitvoer. Deze beschrijving betreft de geteste implementatie; zij verklaart geen productie-uitrol of algemene beschikbaarheid.

### Oorspronkelijk paginabewijs na opnieuw inloggen

Bewaar vóór de eerste pagina de publieke `principal_id` uit `GET /api/v1/me`, de oorspronkelijke sleutel, run-UUID en exacte JSON-invoer. De uitsluitend-lezen route vraagt een actuele persoonlijke interne beheerder met `admin:read`, recente passkey/tweefactorverificatie en hetzelfde bedrijf en dezelfde identiteitsversie als de oorspronkelijke run. De oude persoonlijke sessie mag ingetrokken of verlopen zijn, maar haar eigenaar moet nog aantoonbaar dezelfde persoon en hetzelfde bedrijf zijn. Machinegrants en een ontbrekende oude sessie geven geen toegang.

Stuur zonder nieuwe `Idempotency-Key`, `If-Match` of bovenste `dry_run`:

```json
{"original_principal_id":"user:019a0000-0000-7000-8000-000000000001","original_key":"original-page-key-000000000001","request":{"phase":"holders","cursor":0,"limit":25}}
```

`request` moet de oorspronkelijke body exact reconstrueren, inclusief het wel of niet voorkomen van `limit` en `dry_run:false`. De server controleert oorspronkelijke methode, pad en body met dezelfde server-HMAC. De oorspronkelijke fingerprint bevatte geen `If-Match`; dit bewijs bevestigt dus geen oude verwachte versie. Er volgen geen leveranciersreads, nieuwe operaties of wijzigingen, ook niet wanneer leveranciersconfiguratie ontbreekt of API-schrijfacties uit staan.

HTTP 200 geeft de oorspronkelijke `operation.id`, `status` en `receipt.read_only:true`. Alleen `succeeded` bevat een veilige voortgangsprojectie in `data`; `running` en `failed` geven `data:null`. Controleer de exacte run, bedrijfscontext en geldige faseovergang voordat je een lokale openstaande aanvraag als opgelost beschouwt. Lees daarna de huidige status en ETag voordat je een nieuwe pagina bevestigt. Een ontbrekend, lopend, afwijkend of onleesbaar bewijs houdt de oorspronkelijke aanvraag vast; dien geen vervangende pagina in. Een mislukte oorspronkelijke operatie vraagt eerst beoordeling en een afzonderlijke bewuste vervolgstap. De Rust-CLI in deze bronversie verwerkt dit oorspronkelijke ontvangstbewijs met schema-v2-provenance en lokale bestandcontroles. Productievrijgave en uitrol houden hun afzonderlijke controles; herstel van andere API-functies valt buiten dit contract.

## Bestaande registratie wijzigen: verlenging en contacten

De bestaande registratie kan haar nameservergroep, contactrollen of instelling voor automatische verlenging wijzigen. Dit is geen nieuwe registratie, verhuizing, herstelbestelling of onmiddellijke betaalde verlenging. De normale routes vragen `domains:write`, de actuele domein-ETag in `If-Match` en één duurzame `Idempotency-Key`. Bewaar die sleutel, de exacte JSON en de eerste `operation.id`; een onduidelijk antwoord rechtvaardigt geen nieuwe aanvraag.

| POST onder `domains/{domain}/actions/` | Beoordeelde JSON |
| --- | --- |
| `nameservers` | `nameserver_group_id` en `nameserver_group_version` uit de groepsbeoordeling |
| `contacts` | `role`: `owner`, `admin`, `tech` of `all`; `holder_id` van een beschikbaar contact binnen het bedrijf |
| `cancel` | `confirm_domain` met de exacte domeinnaam |
| `resume` | Dezelfde exacte `confirm_domain` |

Lees het domein met `binadit domains get ID --account KLANT --output json`; de CLI voegt de HTTP-ETag toe in `meta.etag`. Onder `domains/options/nameserver-groups` staan de beschikbare groepen; het detail geeft `data.version`. De [DNS-gids](/developers/guides/dns-mutations?lang=nl) beschrijft de volledige nameserverbeoordeling en het onderscheid tussen een gekopieerde `api-*`-lijst, een live registrargroep en een uitsluitend lokale keuze.

Voorbeeld van opzeggen aan het einde van de bestaande betaalde periode:

```sh
umask 077
binadit domains get 41 --account 99 --output json > domain-review.json
jq '.data | {confirm_domain:.domainname}' domain-review.json > cancel.json
binadit domains actions run 41 cancel --account 99 --from-file cancel.json \
  --version "$(jq -r '.meta.etag' domain-review.json)" --dry-run
```

Controleer de naam, het bedrijf en de bestaande overeenkomst. Voer bewust dezelfde opdracht zonder `--dry-run` en met `--yes` uit. Opzeggen gebruikt bij de registrar `autorenew: off` en beëindigt toekomstige facturering via dezelfde overeenkomst. Een reeds betaalde registratieperiode blijft behouden. Bij portaalbilling eindigt het bestaande jaaritem aan het juiste periode-einde; bij WeFact wordt hetzelfde abonnement beëindigd per einde van zijn huidige periode. Er ontstaat geen extra abonnement, nieuw factuurcontract of restitutie.

Vraag daarna de abonnementsstatus op met `binadit api /domains/41/subscription --account 99 --output json`, oftewel `GET /api/v1/accounts/99/domains/41/subscription` met `domains:read`. `billing_agreement` toont het bestaande lokale abonnementsnummer, de status en begin-/einddatum; `cancellation_requested_on` en `expires_on` onderscheiden de opzegging van de betaalde registratieperiode. Een nog niet ingegaan WeFact-abonnement kan eindigen op de dag vóór zijn geplande start. Deze opvraag leest het portaal en verstuurt geen leveranciersverzoek. Controleer tevens het geverifieerde oorspronkelijke operatieresultaat voordat je een opzegging als afgerond behandelt.

Lees vóór hervatten opnieuw de actuele domeinversie en beoordeel dezelfde overeenkomst. Gebruik daarna `domains actions run 41 resume` met dezelfde vorm van domeinbevestiging en de **nieuwe** ETag. Hervatten zet `autorenew: on` en herstelt diezelfde factuurafspraak. Een verstreken registrardeadline, gewijzigd of dubbel contract, onduidelijke eerdere leverancierstap of niet beschikbare boekhoudkoppeling wordt niet omgezet in een gewone betaalde verlenging. Daarvoor is eerst afzonderlijke beoordeling nodig.

Contactwijziging gebruikt een bestaand bedrijfscontact, bijvoorbeeld een privébestand met `{"role":"owner","holder_id":23}` en `binadit domains actions run 41 contacts --account 99 --from-file contacts.json --version DOMEIN_ETAG --dry-run`. Beoordeel daarna de echte actie met `--yes`. `all` kiest in de API hetzelfde contact voor alle rollen; het portaal kan eigenaar, administratie en techniek afzonderlijk laten beoordelen. Een werkelijk ongeregistreerd domein zonder registrarobject kan alleen de lokale contactkeuze opslaan. Een registratie bij een andere leverancier wordt niet stilzwijgend lokaal afgehandeld. Een eventuele updatevergoeding, trade of nieuwe registratie wordt niet automatisch goedgekeurd.

### Dezelfde acties als interne beheerder

De eigen goedgekeurde context blijft in de URL en in `--account`. Iedere POST onder `/api/v1/accounts/{operator}/admin/domains/{domain}/actions/{nameservers|contacts|cancel|resume}` voegt `target_account_id` toe aan de bestaande actievelden hierboven. Deze routes vragen actuele persoonlijke passkeyverificatie, interne beheerdersrechten, `admin:write` en de ETag van het echte doeldomein. Zij maken geen klantlidmaatschap of klantgrant.

Een beheerder kan de doeldomeinversie al lezen via `GET admin/dns/zones/{id}`. Voor één volledige nameserverkeuze is er een SQL-only beoordeling die tevens de juiste groepsversie geeft:

```sh
binadit api /admin/domains/41/nameserver-review/99/7 --account 900 --output json
```

Hier zijn `41` het doeldomein, `99` het klantbedrijf en `7` de geselecteerde groep; `900` is het eigen beheerbedrijf. Het antwoord bevat beide versies, `context_account_id`, `target_account_id` en de delegatie. De route vraagt `admin:read` en dezelfde echte persoonlijke passkeybeheerder. Een verkeerde doelbinding of voor de klant onbeschikbare groep wordt geweigerd, zonder leveranciers-HTTP. Gebruik voor een beheerdersmutatie `binadit api /admin/domains/41/actions/cancel --method POST --account 900 --from-file admin-cancel.json --version DOMEIN_ETAG --dry-run`, met bijvoorbeeld `{"target_account_id":99,"confirm_domain":"voorbeeld.nl"}`; voer pas na beoordeling uit met `--yes` in plaats van `--dry-run`.

### Eén oorspronkelijk verzoek, ook bij verloren antwoorden

Status staat onder `domains/changes/{change}`; voor beheeracties onder `admin/domains/changes/{change}`. Gebruik `.../by-operation/{operation}` om het bestaande journal te vinden aan de hand van de eerste HTTP-operatie. Bij een beheeractie blijft deze lookup bij het **operatorbedrijf**, ook al hoort de registratie bij het doelbedrijf. Het antwoord bevat `id` (journal), `operation_id`, `zone_id`, `version` (journal) en `zone_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
```

Voor een beheeractie voeg je `--administrator` toe aan `domains changes` en blijft `--account` het oorspronkelijke operatorbedrijf. De oorspronkelijke HTTP-operatie en het journal zijn verschillende nummers. Gebruik het journalnummer bij `--confirm-mutation`.

`reconcile` verstuurt alleen leveranciers-GET's en kan hetzelfde lokale of HTTP-ontvangstbewijs herstellen. Het herhaalt geen onzekere registrar-PUT of financiële wijziging. Een nog nooit verstuurde oorspronkelijke stap kan uitsluitend met het aparte `continue` en `confirm_continue_original:true` worden uitgevoerd. Een volledig nooit verstuurd verzoek kan met `abandon` en `confirm_abandon_original:true` atomisch zijn registrar- en financiële reservering vrijgeven. Een mogelijk verstuurde of al voltooide stap kan niet worden geannuleerd als ongebruikt.

Een opzegging die al vóór het voorbereiden van leveranciersstappen stopte, kan door dezelfde oorspronkelijke persoonlijke CLI-verbinding worden vervolgd met de bestaande domeinschrijfrechten. Dit geldt uitsluitend voor exact dezelfde ondertekende aanvraag zonder effectplan, effecten of verzendmarkers; ook de bijbehorende financiële reservering moet nog geheel ongestart zijn. De server controleert verbinding, gebruiker, identiteitsgeneratie, bedrijf en oorspronkelijke scopes opnieuw. Gebruik het bestaande wijzigingsnummer en de actuele beoordelingversies, geen nieuwe opzegging of login. Na een mogelijke verzending blijft de afzonderlijke herstelroute voor een geverifieerde bedrijfseigenaar of interne beheerder gelden.

Lees vóór iedere herstelactie de laatste metadata en maak een beschermd bestand met precies `confirm_mutation_id`, `confirm_zone_id`, `confirm_zone_version`, `version` en de ene bijbehorende bevestiging. Herstel stuurt geen nieuwe `Idempotency-Key`, `If-Match`, queryparameters of dry-run. Rust gebruikt hiervoor `--input`, niet `--from-file`; de commando's accepteren geen nieuwe `--version`. Een resterend onduidelijk resultaat geeft CLI-exitcode `6` en behoudt hetzelfde oorspronkelijke verzoek.

Huidige rechten blijven verplicht. Een verse persoonlijke leesverbinding kan tijdens een schrijfpauze het oorspronkelijke resultaat lezen, GET-only reconciliëren of een nooit verstuurde reservering vrijgeven binnen het oorspronkelijke scopeplafond. Doorgaan vraagt actuele schrijfrechten en ingeschakelde schrijfacties. De veilige metadata toont geen registrarinloggegevens, volledige leveranciersantwoorden of privéfactuurgegevens.

### Het portaal

Domeindetails, het bewerkvenster en de knoppen voor opzeggen, hervatten en contacten openen eerst een eigen beoordelingspagina. Groepsmigratie toont 25 domeinen per pagina; een contactbatch bevat maximaal 100 gekozen domeinen. Iedere gekozen registratie heeft een eigen oorspronkelijke UUID, actuele bedrijfsrechten en sterke verificatie. De uitvoering stopt bij een onduidelijk resultaat. Het portaal bewaart dat nummer na herladen en biedt expliciet status, uitsluitend-lezen herstel, doorgaan of annuleren vóór verzending. Een onbekend serverrecord wordt niet als succes gebruikt: alleen het expliciet sluiten van datzelfde ongebruikte nummer maakt het definitief niet uitvoerbaar.

Houder- en nameserverwijzigingen zijn aparte goedkeuringen. Domeinopzegging wijzigt geen hostingabonnement en verstuurt niet impliciet een mail; behandel andere producten afzonderlijk. Browserroutes vereisen een normale portaal- en CSRF-sessie en zijn geen API-authenticatiealternatief. Deze gids beschrijft de lokaal gebouwde en gecontroleerde paden, geen verklaring dat de applicatie of CLI-binary al in productie is uitgerold.
