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.
Bedrijven en gebruikers beheren
Portaallogin werkt alleen nog met passkeys. set-password en send-password-reset-email zijn vervallen. Gebruik send-setup-email uitsluitend voor de eerste passkey van een geschikte identiteit; bestaande passkeys worden nooit via een e-maillink omzeild. Zie instellen en herstel.
Deze beheerroutes gebruiken een persoonlijke OAuth-verbinding met admin:read of admin:write, een actuele interne beheerrol en passkeyverificatie van hoogstens vijf minuten oud. De API-, schrijf-, gevoelige- en beheerflags en het ingestelde releasebeleid blijven van toepassing. Het account in /api/v1/accounts/{account} is het eigen, actuele beheeraccount waarop de verbinding is goedgekeurd. Een doelbedrijf of doelgebruiker heeft een afzonderlijk expliciet ID.
| Bewerking | Methode en pad na /api/v1/accounts/{account} |
|---|---|
| Bedrijven zoeken | GET /admin/companies?search=...&cursor=...&limit=50 |
| Bedrijf en versie lezen | GET /admin/companies/{company} |
| Bedrijf met nieuwe eigenaar aanmaken | POST /admin/companies |
| Bedrijfsgegevens, bestel- en beveiligingsbeleid bijwerken | PATCH /admin/companies/{company} |
| Leeg, afgehandeld bedrijf archiveren | DELETE /admin/companies/{company} |
| Gebruikers zoeken | GET /admin/users?search=...&company_id=...&cursor=...&limit=50 |
| Gebruiker en versie lezen | GET /admin/users/{user} |
| Alleen gewijzigde oorspronkelijke blokkadelidmaatschappen beoordelen | GET /admin/users/{user}/unblock-reviews?cursor=...&limit=50 |
| Lidmaatschappen met rechten en eigen versies lezen | GET /admin/users/{user}/memberships?cursor=...&limit=50 |
| Persoonlijke gegevens of interne beheerrol bijwerken | PATCH /admin/users/{user} |
| Identiteit blokkeren of blokkade opheffen | POST /admin/users/{user}/actions/block en /unblock |
| Welkomst- of herstelmail indienen | POST /admin/users/{user}/actions/send-setup-email |
| Begrensde verzendstatussen onderzoeken | GET /admin/users/{user}/mail-deliveries?limit=50&cursor=... |
| Gebruiker archiveren | DELETE /admin/users/{user} |
Alle lijsten gebruiken begrensde cursors, maximaal 100 resultaten per pagina. Een gebruikersprojectie bevat hoogstens 100 lidmaatschappen, plus membership_count en memberships_next_cursor. Het aparte lidmaatschappenpad levert de volgende pagina's en de expliciete rechten voor een herstelbeoordeling.
CLI voor mensen en AI-agents
Gebruik binadit admin companies en binadit admin users. Het vroegere admin accounts is een alias voor admin companies; het gebruikt hetzelfde echte /admin/companies-contract. --account blijft het eigen goedgekeurde beheerbedrijf, terwijl het argument bij get, update of een actie het afzonderlijke doel-ID is. Login met expliciete admin:read admin:write-scopes en verifieer de sessie met een passkey; verlopen sterk bewijs vereist opnieuw verbinden.
binadit admin companies list --search 'Voorbeeld' --account 1 --limit 50
binadit admin companies get 42 --account 1
binadit admin companies update 42 --account 1 --version '<ETag>' --from-file company.json --dry-run
binadit admin companies update 42 --account 1 --version '<ETag>' --from-file company.json
binadit admin companies create --account 1 --from-file new-company.json
binadit admin users list --company 42 --account 1 --limit 50
binadit admin users memberships 8 --account 1 --limit 50
binadit admin users unblock-reviews 8 --account 1 --limit 50 --all
binadit admin users block 8 --account 1 --version '<ETag>' --confirm-user 8 --dry-run
binadit admin users unblock 8 --account 1 --version '<ETag>' --confirm-user 8 --from-file reviewed-memberships.json
binadit admin companies archive 42 --account 1 --version '<ETag>' --confirm-company 42
company.json bevat uitsluitend bedrijfsvelden. Bewaar bestanden met persoonsgegevens privé (0600 op Unix). --from-file - leest JSON van stdin. Portaalwachtwoorden worden niet meer ingesteld; gebruik een passkey-instellink.
Gebruik --cursor voor een volgende pagina, of bewust --all voor een begrensde verzameling. Een AI-agent moet versies en de exacte doel-ID's uit de gelezen resources gebruiken en gewijzigde lidmaatschapsrechten inhoudelijk beoordelen. --yes vervangt uitsluitend de lokale interactieve bedrijfsbevestiging bij bewuste automatisering; het verleent geen extra serverrechten. Een onzekere mutatie wordt met haar oorspronkelijke intentiesleutel onderzocht, niet met een automatisch gekozen nieuwe sleutel herhaald.
Veilige wijzigingen
Lees het doel en stuur de actuele ETag als If-Match. Stuur voor een echte API-mutatie ook een eigen Idempotency-Key. dry_run:true of X-Binadit-Dry-Run:true voert dezelfde versies, huidige bevoegdheden en bedrijfsregels uit zonder de wijziging op te slaan. Verwachte voorcontroles verbruiken geen mutatie-intentie. Een bevestigde wijziging met dezelfde sleutel geeft het oorspronkelijke resultaat terug. Bij een onbekende fout controleer je eerst de bestaande operatie.
Blokkeren en deblokkeren vragen confirm_user_id. Archivering vraagt confirm_user_id of confirm_company_id met het exacte doel-ID. Een ontbrekende versie geeft 428; een gewijzigde versie 412. Lees na een wijziging de nieuwe versie uit data.version.
Een nieuw bedrijf krijgt een nieuwe, niet-geverifieerde eigenaar. De aanmaak levert diens ID en setup_email_required:true terug. De inschrijving in de boekhouding en de herstel-/welkomstmail zijn afzonderlijke beheerstappen; deze aanmaak doet geen leverancier- of maileffect. Een gebruiker kan zijn loginadres veranderen via de mailboxbevestiging op /account/identity/email. Het bedrijfscontactadres is een zelfstandig bedrijfsgegeven.
Bankgegevens verschijnen niet in de algemene bedrijfsprojectie. Een bankwijziging gebruikt dezelfde IBAN-validatie en bestaande-mandaatcontrole als de bedrijfseigenaar. Een bestaand SEPA- of Mollie-mandaat vraagt een afzonderlijk gecontroleerde migratie.
Het recht om te bestellen (purchasing)
Besluit van de eigenaar (11 nov 2026): geld uitgeven is een apart, bewust recht naast schrijven. Elke actie die kosten of een terugkerende betaling oplevert vraagt schrijfrechten op de dienst én purchasing ("Bestellen en kosten maken"). Eigenaren hebben het impliciet, interne beheerders ook (ook als ze als klant werken). Alleen een eigenaar geeft het, met één niveau (write; read wordt met 422 geweigerd). Niemand kreeg het automatisch bij de invoering en de knop "Beheerder" in het teamscherm vult het nooit in.
| Scopes | Recht | Niveau |
|---|---|---|
orders:read / orders:write, orders:commit |
purchasing |
write (één niveau) |
account.bank:* |
alleen eigenaar (ApiScopes::ownerOnly) |
— |
operations:read (alleen eigen operaties van de verbinding) |
elk actief lidmaatschap | — |
orders:* is niet langer alleen voor eigenaren: elk API-bestelpad controleert daarnaast schrijfrechten op de dienst van elk item, dus een koppeling van een teamlid heeft bij elke aanroep account_api schrijven, purchasing en het recht op de dienst nodig.
Vraagt purchasing (door de server afgedwongen; het portaal verbergt de knoppen, of toont ze uitgeschakeld met "Je hebt het recht om te bestellen nodig" waar verbergen verwarrend is, zoals een winkelwagen met items): afrekenen in de winkelwagen, domeinnamen registreren en verhuizen, nieuwe hosting, spamfilters en Exchange-mailboxen, in Workspace een nieuwe mailbox, de Workspace-winkelwagen, een gedeelde mailbox, een pakketwijziging en Drive per mailbox, de Drive-pool, teamdrive of ontvangstdrive bestellen of vergroten en een langere Conserio-bewaartermijn, plus offertes, bevestigingen, mandjes, spamaankopen en het intrekken van een onbetaalde bestelling via de API.
Vraagt het niet: gratis wijzigingen (aliassen, instellingen, DNS, contactpersonen), opzeggen, uitzetten en verkleinen van Drive of bewaartermijn, en het terugdraaien van een lopende opzegging binnen de betaalde periode. Facturen betalen blijft account_billing schrijven; de bestellijst van het bedrijf is factuurdata (account_billing lezen). Bekende afwijking: ook een kleiner mailboxpakket vraagt purchasing, omdat elke pakketwijziging in het portaal via dezelfde ondertekende bestelgoedkeuring loopt.
Blokkade en toegangsherstel
Een beheerblokkade is een duurzame identiteitsblokkade. Zij blijft gelden als later een nieuw lidmaatschap wordt toegevoegd en verhindert een nieuwe login of OAuth-toestemming. De laatste actieve eigenaar, een interne beheerder en de eigen identiteit hebben afzonderlijke bescherming tegen blokkering of archivering.
Bij deblokkeren worden uitsluitend lidmaatschappen hersteld die deze blokkade werkelijk wijzigde. Eerder individueel uitgeschakelde of verlopen toegang wordt niet onbedoeld geactiveerd. Verwijderde lidmaatschappen blijven verwijderd. Als rechten tijdens de blokkade veranderden, geeft de standaardactie 409. Lees en beoordeel dan de actuele rechten via het lidmaatschappenpad. Een bewuste bevestiging gebruikt bijvoorbeeld:
{
"confirm_user_id": 42,
"reviewed_memberships": [
{"id": 73, "version": "<actuele 64-tekensversie uit de lidmaatschappenlijst>"}
]
}
Alleen werkelijk door deze blokkade geraakte lidmaatschappen mogen zo worden beoordeeld. Het gebruikers-If-Match blijft eveneens vereist.
Archivering en klantnummers
Een bedrijf kan worden gearchiveerd nadat zijn actieve middelen expliciet zijn overgedragen of verwijderd en de financiële afhandeling vaststaat. Open facturen, onzekere betaal-/boekhoudpogingen, terugbetalingen, abonnementen, maandregels, oude bestellingen en herkenbaar bijbehorend wachtrijwerk blokkeren de actie. Een beëindigde maandregel is pas afgehandeld als de volledige betaalde periode is gefactureerd; open correcties en een nog geclaimde facturatieproducent blokkeren eveneens. Ook verkeerd gekoppelde, nog levende Workspace-afspraken worden op hun getypeerde onderwerp gecontroleerd. Historische middelen en financiële gegevens blijven bewaard; gebruikers en passkeys worden niet als bijwerking gewist. Toegang tot hun andere bedrijven blijft afzonderlijk bepaald door de actuele lidmaatschappen.
Migratie 410000 installeert de duurzame blokkade en de allocator voor legacy-klantidentiteiten. Alle nieuwe native/API-inschrijvingen reserveren onder dezelfde databasevergrendeling een ongebruikt nummer boven bestaande, gearchiveerde, verweesde en gereserveerde legacy-eigenaars. De smalste werkelijk geïnstalleerde integerkolom begrenst het bereik. Een modern gebruikers-ID vormt nooit bewijs van legacy-eigendom. De allocator en eerdere reserveringen blijven bij rollback behouden.
Concurrente wijzigingen en regressiebewijs
Beheerrolwijzigingen gebruiken een aparte SQL-vergrendeling voor het platform, vóór een gewone transactie-read. Zo kunnen twee beheerders elkaar niet gelijktijdig als laatste bruikbare beheerder verwijderen. Geblokkeerde, gearchiveerde of niet-geverifieerde identiteiten tellen niet als vervangende beheerder of eigenaar.
Binnen een bestaande SQL-transactie gebruiken de gedeelde API-bevoegdheden en financiële effectcontrole actuele vergrendelende reads. Een oudere MariaDB REPEATABLE READ-snapshot of een eerdere requestcache kan daardoor geen ingetrokken grant, token, lidmaatschap, modulepermissie, beheerdersrol of betaling blijven goedkeuren. De oorspronkelijke token- en resourceplafonds blijven gelden. Deze transacties worden niet automatisch opnieuw uitgevoerd rond leverancier-HTTP.
tests/Integration/ApiCurrentPolicyReadTest.php is een expliciet uit te voeren MariaDB-regressiesuite. Zij weigert elke database behalve een eigen binadit_policy_trial_<12 hex> met beperkte gebruiker en Unixsocket. Gebruik een lege tijdelijke instance zonder TCP-toegang en verwijder die na de proef. De tests gebruiken twee afzonderlijke connecties en voor mutex-wachtpaden een apart PHP-proces. Ze bewijzen intrekking ná een oude snapshot, vasthouden van de actuele permissie tot commit, financiële intrekking, wederzijdse rolverlaging en allocatie na wachten. De normale HTTP-suite staat in tests/Feature/ApiCompanyUserAdminTest.php en gebruikt echte OAuth-tokens.
De bedrijfs-/gebruikersbasis en de hieronder beschreven afzonderlijke herstelmailworkflow hebben hun eigen geteste contract. Boekhoud-, supportdelegatie- en overige beheersworkflows worden pas met hun eigen contract toegevoegd; hun aanwezigheid wordt niet uit deze routes afgeleid.
E-mailverificatie herstellen
Het oude beheerveld om iemand direct als geverifieerd te markeren is vervangen door mailboxbewijs. email_verified is alleen leesbaar: de API weigert het als profielwijziging. De bestaande welkomstlink is ook beschikbaar voor een bestaande niet-geverifieerde gebruiker. API, Rust CLI en portaal gebruiken daarvoor dezelfde herstelmailworkflow.
Lees de gebruiker en diens actuele versie. Dien daarna bewust send-setup-email in zoals hieronder. Een bevestigde verzendpoging laat email_verified nog steeds op N. Alleen de ontvanger kan via de eenmalige link in de huidige mailbox een eerste passkey aanmaken; deze handeling verifieert het adres en trekt oude persoonlijke sessies in. Bestaande passkeys en MFA-verplichtingen blijven gelden. Een al gebruikte of verlopen link werkt niet opnieuw. Ook een gewijzigd loginadres of een gewijzigde identiteitsgeneratie maakt de oude link onbruikbaar.
Controleer de uitkomst daarna met GET admin/users/{user} of binadit admin users get USER --account BEHEERCONTEXT. De verzendstatus accepted is geen bewijs dat de gebruiker de link al heeft geopend of zijn adres heeft geverifieerd. Wijzig het loginadres uitsluitend via de persoonlijke mailboxbevestiging, los van bedrijfscontactgegevens.
Voor AI-agents: forceer nooit email_verified, vraag geen andere ontvanger aan en haal het gemailde token van de gebruiker niet op. Start de bestaande beoordeelde setupmailactie en laat de daadwerkelijke ontvanger het passkey- en mailboxbewijs voltooien. Controleer verificatie via de gewone gebruikersleesroute; mailacceptatie alleen bewijst geen eigendom van de identiteit. Dit is de gedocumenteerde veilige vervanging van het vroegere beheervinkje voor verificatie.
Welkomst- en herstelmail: één bewuste poging
Een mailactie gebruikt admin:write, de actuele interne beheerrol, recente passkeyverificatie, If-Match, Idempotency-Key en confirm_user_id. De ontvanger is uitsluitend het huidige loginadres van de expliciet geselecteerde gebruiker. Invoer met een ander adres, onderwerp, inhoud of eigen link wordt geweigerd. Een herstelmail vereist een geverifieerde identiteit; gebruik voor een nog niet geverifieerde nieuwe gebruiker de welkomstmail. Een geblokkeerde identiteit moet eerst afzonderlijk worden beoordeeld en gedeblokkeerd.
binadit admin users get 8 --account 1
binadit admin users send-setup-email 8 --account 1 --version '<ETag>' --confirm-user 8 --dry-run
binadit admin users send-setup-email 8 --account 1 --version '<ETag>' --confirm-user 8
binadit admin users mail-deliveries 8 --account 1 --limit 50
Alle beheerders, beheerbedrijven en beide maildoelen delen één afkoelperiode van vijf minuten per ontvanger. dry_run doet dezelfde huidige controles maar maakt geen herstelbewijs, operatie, verzendpoging of mail. Een echte aanvraag legt de hash van het actuele identiteitsgebonden herstelbewijs, de verzendpoging en de operatieverwijzing vast voordat SMTP begint. De database houdt de actuele actor en ontvanger tijdens precies één transportaanroep vergrendeld. Er is geen automatische SMTP-herhaling of failover. Een enkel SMTP-transport vereist TLS en certificaatverificatie; een bestaande lokale sendmail-configuratie is eveneens toegestaan. Een log-, failover- of roundrobin-mailer is voor deze geheime links ongeschikt en geeft gecontroleerd 503 vóór uitgifte. De arraytransport-uitzondering bestaat uitsluitend met een mailfake in tests.
Het antwoord en de geschiedenis bevatten alleen veilige statusmetadata en een ondoorzichtige mail_delivery_id. De API, CLI en browser tonen geen herstel-/welkomstlink, token, mailbody of ruwe SMTP-fout. De link gebruikt de canonieke APP_URL, nooit de binnengekomen Host-header. accepted betekent dat de transportaanroep is bevestigd; het bewijst niet dat de ontvanger de mail al heeft gezien. De oorspronkelijke wachtwoorden en passkeys veranderen niet door het versturen. De bestaande eenmalige linkconsumer voert later de gedeelde eerste-passkey- en sessiepolicy uit.
| Status | Betekenis en vervolgstap |
|---|---|
prepared |
Bewijs en poging zijn duurzaam vastgelegd; nog geen bevestigde verzending. Onderzoek de oorspronkelijke poging. |
dispatching |
Een transportpoging kan onderweg of onderbroken zijn. Geen automatische herhaling. |
accepted |
De transportaanroep bevestigde ontvangst. De metadata bevat geen geheime link. |
uncertain |
De mail kan geaccepteerd zijn maar het antwoord was onzeker. Operatiepolling toont requires_reconciliation. |
blocked |
Het huidige bewijs, de actor of de ontvanger veranderde vóór transport. Er is geen mail ingediend. |
Een herhaling met dezelfde intentiesleutel verstuurt nooit een tweede mail, ook niet na een fout. Onderzoek bij identity_mail_unconfirmed eerst de oorspronkelijke operatie en de verzendgeschiedenis; verander de sleutel niet automatisch. Voor een bewuste vervanging van een onopgeloste poging lees je het actuele gebruikers-ETag en de nieuwste verzendpoging, wacht je de afkoelperiode af en bevestig je die poging expliciet:
binadit admin users send-setup-email 8 --account 1 --version '<nieuw ETag>' --confirm-user 8 --replace-delivery '<nieuwste delivery UUID>'
De JSON-invoer gebruikt hiervoor replace_delivery_id. De nieuwe aanvraag heeft een eigen expliciet beoordeelde intentie. Zij maakt beide oude bewijssoorten ongeldig voordat één nieuwe mail wordt ingediend en koppelt de eerdere poging met superseded_by. Een oude, later alsnog bezorgde mail kan daardoor geen nieuwe passkey instellen. Zonder expliciete beoordeling weigert een onopgeloste eerdere poging met 409; omzeilen met een andere beheerder of ander maildoel werkt niet.
De native gebruikerspagina gebruikt dezelfde service en toont dezelfde veilige status. Een afzonderlijke JSON-refresh van de bewerkpagina geeft mail_version, zonder het profiel-version automatisch te vernieuwen. Onopgeslagen profielvelden mogen nooit met een via metadata verversde versie over een externe profielwijziging worden geschreven.
Migratie 411000 bewaart alleen de verzendjournalen en verwijdert die bij rollback niet. ApiAdminIdentityMailTest gebruikt echte OAuth en native requests voor previews, versies, replay, transportfouten, vervanging en verborgen gegevens. CredentialMailTransportTest test de onderhouden SMTP-instellingen en een echte synthetische loopbackserver zonder STARTTLS: deze ontvangt geen AUTH- of MAIL-commando. De expliciete MariaDB-suite AdminIdentityMailDurabilityTest vereist dezelfde beperkte socketdatabase als de beleidsproeven, bewijst de onafhankelijk gecommitteerde poging vóór SMTP en houdt gelijktijdige actor-/ontvangerwijzigingen tegen. Er worden daarbij geen echte leveranciers of klantmailboxen aangeroepen.
Een beoordeelde selectie in één lokale wijziging
POST /admin/users/actions/bulk en POST /admin/companies/actions/bulk voeren dezelfde bestaande gebruikers- en bedrijfsregels uit voor 1 tot 100 expliciet gelezen doelen. Zij vragen admin:write, de actuele interne beheerrol, recente passkeyverificatie en één Idempotency-Key. Iedere items-regel draagt zijn eigen moderne id en de oorspronkelijke, ongequote 64-tekens-version uit het gelezen resourceantwoord. Gebruik action: block, unblock of archive:
{
"action": "block",
"items": [
{"id": 8, "version": "<64-tekensversie van gebruiker 8>"},
{"id": 9, "version": "<64-tekensversie van gebruiker 9>"}
]
}
binadit admin users bulk --account 1 --from-file reviewed-users.json --dry-run
binadit admin users bulk --account 1 --from-file reviewed-users.json
binadit admin companies bulk --account 1 --from-file reviewed-companies.json
Het invoerbestand volgt dezelfde beschermde-bestand-/stdinregels als andere beheerinvoer. De CLI vervangt de meegeleverde versies niet door stilzwijgend opgehaalde actuele versies. reviewed_memberships is uitsluitend binnen een gebruikersregel voor unblock toegestaan; ban_reason uitsluitend binnen een bedrijfsregel voor block. De bestaande individuele lidmaatschapsbeoordeling blijft van toepassing. Een combinatie die alle resterende bruikbare eigenaars zou blokkeren of archiveren wordt ook in een preview geweigerd, zelfs als iedere gebruiker afzonderlijk nog een andere geselecteerde eigenaar heeft.
Alle doelen worden onder dezelfde lokale SQL-transactie en actuele bevoegdheidscontrole beoordeeld. Eén ongeldige versie, beheerder/eigen identiteit, ontbrekende eigenaar, open financiële afspraak of andere onveilige regel weigert de volledige selectie. Er is geen gedeeltelijk succes of stilzwijgend overgeslagen beheerder. Een onverwachte lokale schrijffout rolt alle doelwijzigingen terug; een bevestigde uitkomst en haar operatie worden samen vastgelegd. Deze workflow verstuurt geen mail en doet geen leverancier- of betaaloproep.
De native knoppen voor blokkeren, deblokkeren, archiveren en bulkselecties gebruiken deze gedeelde regels. Een browser verstuurt expliciete acties en gelezen doelversies, naast de recente passkeycontrole. Archivering verwijdert geen passkeys, historische lidmaatschappen, financiële gegevens of andere gebruikers en verplaatst geen middelen naar een willekeurig beheerbedrijf. Draag middelen eerst via hun afzonderlijk beoordeelde eigendomsworkflow over en handel financiële afspraken af voordat een bedrijf wordt gearchiveerd.
De aparte collectie unblock-reviews bevat uitsluitend nog bestaande, sinds de oorspronkelijke beheerblokkade gewijzigde lidmaatschappen. Iedere regel toont het echte bedrijf, de actuele rol, status, permissies en versie. Een eigenaar heeft alle bedrijfsrechten, ook als zijn lijst met overrides leeg is. Ontbrekende oorspronkelijke lidmaatschappen en later onafhankelijk toegevoegde lidmaatschappen worden niet als herstelkandidaat opgevoerd. Een pagina kan geen gewijzigde regels bevatten en toch een next_cursor hebben: lees door tot de cursor leeg is voordat je beoordeelt. De native modal doet dezelfde gecontroleerde, begrensde paginering en vraagt een expliciete bevestiging van alle gewijzigde rechten. Een metadatarefresh vervangt geen eerder gelezen profiel- of doelversie. Een te grote beoordeling vraagt een kleinere selectie, nooit stilzwijgende goedkeuring van verborgen regels.
Rol-, status- en permissieprojectie worden tijdens de beoordeling onder actuele gedeelde SQL-vergrendelingen gelezen. Ook het lidmaatschaps-ETag leest binnen een transactie de huidige volledige permissierijen; een oudere MariaDB-snapshot kan geen verouderde rechtenversie laten goedkeuren. De daadwerkelijke herstelactie controleert die versies nogmaals. Het native blokkadepad accepteert uitsluitend block of unblock; archivering gebruikt zijn eigen expliciete verwijder-/archiveerroute.
Native bedrijfsaanmaak met één welkomstpoging
Het aanmaakvenster voor interne beheerders maakt eerst het lokale bedrijf, zijn nieuwe eigenaar en een duurzaam ontvangstbewijs onder dezelfde databasevergrendeling. Het venster vraagt recente passkeyverificatie en bevriest de beoordeelde invoer, het beheerbedrijf en een nieuwe creation_intent_id. Standaard volgt na deze lokale commit één welkomstpoging via de bovenstaande 411-workflow. De optie om geen welkomstmail te sturen maakt ook geen setupbewijs. Er wordt bij bedrijfsaanmaak geen WeFact-debiteur of betaling aangemaakt.
Bij een verloren HTTP-antwoord blijft de oorspronkelijke invoer bevroren. De expliciete knop om het oorspronkelijke resultaat te controleren gebruikt precies dezelfde intentie en kan geen tweede bedrijf of welkomstpoging starten. Tijdens een lopende versturing kan hetzelfde ontvangstbewijs al dispatching teruggeven. Ook na een onzekere SMTP-uitkomst blijft de lokale aanmaak bevestigd; email_sent: false en requires_reconciliation: true vragen onderzoek van de mailgeschiedenis bij de nieuwe eigenaar. Een nieuwe of vervangende mail volgt uitsluitend de afzonderlijke, expliciet beoordeelde mailactie en afkoelperiode. Het venster toont geen setup-URL, herstelbewijs of ruwe transportfout.
De losse API-/CLI-bedrijfsaanmaak behoudt haar bestaande contract: lokale aanmaak zonder automatische mail. Een agent leest de nieuwe owner_user_id en diens actuele versie en kiest vervolgens expliciet admin users send-setup-email. Het native ontvangstbewijs en de beheerdersinterface zijn dus geen extra OAuth-identiteit of verborgen leverancierproxy.
ApiCompanyOnboardingTest bewijst versie-/contextcontrole, preview, expliciet geen mail, lokale rollback, actorintrekking na commit, verloren mailantwoord en herstel na een verloren ontvangstbewijsschrijf. CompanyOnboardingDurabilityTest voert dezelfde native requests uit op een beperkte, tijdelijke socket-only MariaDB-instance. Een tweede connectie ziet het bedrijf en de eigenaar vóór SMTP, leest tijdens de poging hetzelfde ontvangstbewijs en veroorzaakt geen extra mail. Er worden geen klantmailboxen of leveranciers aangeroepen.
Automatische WeFact-koppeling bij facturatie
De gedeelde facturatieresolver gebruikt de actuele bedrijfskoppeling. Een ontbrekend of afwijkend antwoord op een bestaande positieve WeFact-debiteur-ID maakt nooit een vervangende debiteur. Ook gearchiveerde bedrijven behouden hun bestaande debiteur-ID en expliciete administratiereferentie; een ander bedrijf kan die niet overnemen.
Een gelijk e-mailadres, btw-/KvK-nummer of bedrijfsnaam is uitsluitend een beoordelingsvoorstel. Zo'n overeenkomst verleent geen toegang tot bestaande facturen of incassoafspraken. Alleen een unieke bestaande administratiereferentie kan na exacte debtor.show-controle automatisch koppelen. Een beheerder moet overige voorstellen uitdrukkelijk beoordelen; een reeds afgewezen kandidaat wordt niet alsnog gekoppeld.
Als een nieuw contact nodig is, legt de resolver de aanmaakpoging vast vóór de ene debtor.add-aanroep. Parallelle verzoeken en een verloren antwoord starten geen tweede aanmaak. Bij een bekende ontvangen ID volgt uitsluitend gecontroleerde readback; bij een onbekende uitkomst blijft afhandeling nodig. Deze gedeelde facturatiecontrole ontsluit op zichzelf nog geen nieuwe WeFact-beheercommando's, imports of leverancierswijzigingen via de API.