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.
Binadit MailSig en gegevens per mailbox
Binadit MailSig is gratis bij Workspace. Een bedrijf beheert zijn handtekening één keer; de mailserver zet haar vanuit elk mailprogramma in uitgaande berichten, boven geciteerde antwoorden. Mailboxprofielen leveren naam, functie, telefoon en andere gegevens van de medewerker. Beheerders kunnen dezelfde optionele velden invullen voor gewone en gedeelde mailboxen. Deze acties maken geen productbestelling, betaalde werkplek of factuurregel.
Gebruik de schermen Gegevens en Handtekeningen in de Workspace, de klanten-API of de getypeerde Rust-CLI. De API gebruikt steeds dezelfde portaalservices. De cliënt krijgt geen token van de handtekeningendienst en benadert die dienst niet rechtstreeks.
Vormgeving door de beheerder — dienst 0.3.0, beleid van 2026-11-02
De Workspace-beheerder bepaalt de vormgeving en wijst het ontwerp of de variant toe aan iedere gewone of gedeelde mailbox. Medewerkers mogen alleen vrijgegeven profielgegevens invullen: mobile, showMobile, photo, workdays, pronouns, language en ingestelde custom.<key>-waarden. Andere zelfbewerkingsrechten worden geweigerd. Medewerkers kiezen geen vormgeving en plakken geen HTML; beheerders gebruiken de beheerde ontwerpeditor.
De oude medewerkerskeuze en HTML per mailbox zijn uit de API- en CLI-invoer en -uitvoer verwijderd. Onbekende oude eigenschappen geven 422, ook bij false, null of een dry run. Oude vormgevingswijzigingen uit de medewerkersdienst veranderen de portaaltoewijzingen niet. Vaste ontwerpen en varianten blijven voor bevoegd Workspace-beheer beschikbaar.
Toegang en versies
Alle onderstaande paden beginnen met /api/v1/accounts/{account}/workspaces/{workspace}. Bedrijf en workspace moeten bij de huidige verbinding horen. Lezen vraagt workspace.mailboxes:read; wijzigen vraagt workspace.mailboxes:write. Beperkingen tot specifieke workspaces blijven gelden. Een machine-integratie kan de volledige MailSig-inrichting automatiseren. Geef voor testmail recipient_mailbox mee: de integer-ID van een actieve gewone mailbox binnen dezelfde Workspace. Het portaal bepaalt en controleert het actuele adres; mailboxen van andere workspaces, verwijderde en geschorste mailboxen worden geweigerd. Persoonlijke verbindingen kunnen dit veld weglaten voor hun eigen geverifieerde adres; daarvoor blijft de bestaande sterke verificatie gelden. Gevoelige acties moeten in beide gevallen aanstaan. Er is geen vrij to-adres, onderwerp of bericht.
Lees eerst de bron. Antwoorden bevatten data.workspace_id en data.version; lokale leesacties geven ook een ETag. Gebruik voor handtekeningwijzigingen de versie uit GET /signatures/settings. Alle handtekeningonderdelen delen één revisie: een andere wijziging maakt de oude versie ongeldig. Profielen en profielinstellingen hebben eigen versies. Gelijke nummers in de tabellen voor persoonlijke en gedeelde mailboxen zijn verschillende objecten.
Elke schrijfactie vraagt If-Match en Idempotency-Key. dry_run: true of X-Binadit-Dry-Run: true controleert actuele invoer, rechten en versie zonder leveranciersaanvragen, opgeslagen gegevens of mail. Het rendert en schoonmaakt geen HTML, verwerkt geen afbeelding en belooft geen bereikbaarheid van de dienst. POST /signatures/preview rendert alleen een voorbeeld: geen nieuwe intentie, sleutel, versievoorwaarde of dry-runvlag.
Dezelfde geslaagde aanvraag met dezelfde sleutel en inhoud geeft het oorspronkelijke ontvangstbewijs, ook als de oude versie inmiddels is gewijzigd. Andere inhoud met dezelfde sleutel geeft een conflict. Onderzoek bij een timeout, 502, vastgehouden of mislukte operatie de oorspronkelijke operatie; maak geen vervangende sleutel en herhaal testmail/upload niet automatisch. De CLI bewaart zijn intentie totdat het exacte bedrijf, de workspace en het antwoord zijn geverifieerd. Er is geen automatische herhaling van schrijfacties.
Endpointinventaris
| Methode en pad | Invoer of antwoord |
|---|---|
GET/PUT /mailboxes/{mailbox}/profile |
Persoonlijk profiel; data.owner_kind=mailbox, owner_id, profile |
GET/PUT /shared-mailboxes/{shared}/profile |
Gedeeld profiel; owner_kind=shared_mailbox |
GET/PUT /profile-settings |
profile_settings: land, afdelingen, vestigingen, eigen velden, zelf bewerkbare velden |
GET /profiles/export |
CSV: alle gewone/gedeelde profielgegevens |
POST /profiles/import/preview |
CSV controleren, geen operatie of wijzigingen |
POST /profiles/import |
Oorspronkelijke privécontrole atomair bevestigen |
POST /profiles/bulk |
Afdeling/vestiging atomair voor gecontroleerde mailboxen wijzigen |
GET/PUT /signatures/company |
Bedrijfsvelden {value,source} en expliciete IBAN-toestemming |
GET/PUT /signatures/variants |
Beheerde nieuw/antwoord-ontwerpen en standaardmarkering |
GET /signatures/variables?lang=nl |
Variabelengroepen en bloksyntax uit de dienst |
GET/PUT /signatures/onboarding |
Instelhulp: step (1–4), dismiss boolean; uitlezen geeft required, step, dismissed |
GET/PUT /signatures/settings |
Aan/uit, telefoonvoetteksten, voettekst en afbeeldingsbeleid |
GET/PUT /signatures/templates |
{ "templates": [...] }; vervangt de volledige geordende lijst |
GET/PUT /signatures/rules |
{ "rules": [...] }; vervangt de volledige geordende lijst |
GET/PUT /signatures/campaigns |
{ "campaigns": [...] }; vervangt de volledige geordende lijst |
GET /signatures/images |
Afbeeldingsmetadata van deze workspace |
POST /signatures/images |
content_base64, mime, kind, optionele verwerkingsinstellingen |
POST /signatures/banner |
Tekst, achtergrond, tekstkleur, breedte en hoogte |
DELETE /signatures/images/{image} |
Optioneel { "photo": true }; geeft removedFromServer |
POST /signatures/validate |
{ "html": "..." }; schone HTML, wijzigingen, waarschuwingen, fouten; kan afbeeldingen overnemen |
POST /signatures/preview |
Precies één template: {html,text?} of variant: ID; reply?, mailbox?/sample?, footer?; HTML/tekst, fields, unknownFields, bytes |
POST /signatures/testmail |
{ "mailbox": "anna@example.test", "variant": "new" }; reply kan ook; machines voegen recipient_mailbox: ID toe |
GET /signatures/status |
Volledigheid, DNS/TLS voor afbeeldingen, identiteitsstatus en dagtellers |
GET /signatures/gallery |
Ingebouwde Nederlandse en Engelse ontwerpen |
POST /signatures/gallery/{design}/import |
{ "language": "nl" } of en; slaat een nieuw lokaal sjabloon op |
Antwoorden gebruiken data.<onderdeel>, bijvoorbeeld settings, templates, preview, validate, testmail of gallery. Wijzigingen voegen free: true en het oorspronkelijke operation-ontvangstbewijs toe. Leverancierssleutels, private ID's en ruwe foutdetails worden niet teruggegeven. De volledige actuele schema's en operatie-ID's staan in OpenAPI.
Profielgegevens
De sleutels volgen de bundel: titleBefore, firstName, infix, lastName, titleAfter, displayName, pronouns, jobTitle, jobTitleEn, department, location, phone, mobile, showMobile, workdays, photo, language, custom, template, variant.
Namen zijn gewone tekst; witruimte wordt opgeschoond zonder hoofdletters te veranderen. Telefoon en mobiel accepteren tekst of { "display": "030 123 4567", "e164": "+31301234567" }. Beide weergaven moeten hetzelfde nummer aangeven. Het standaardland is NL; geldige nummers worden opgeslagen als E.164 met een leesbare schrijfwijze. Een ongeldig nummer geeft een validatiefout. showMobile bepaalt of het mobiele nummer zichtbaar is.
Beheerders mogen alle hierboven genoemde velden instellen voor gewone én gedeelde mailboxen, ook gegevens die een medewerker zelf mag bewerken en een foto die bij de workspace hoort. Voor een volledige handtekening is bij een gewone mailbox alleen firstName of lastName nodig en bij een gedeelde mailbox displayName. Elk ander veld is optioneel; lege velden komen niet in de handtekening. E-mail en login komen uit de echte mailbox en zijn niet via het profiel te wijzigen. Afdelingen, vestigingen, afbeeldingen en sjablonen moeten bij deze workspace horen. Talen gebruiken een tweelettercode, eventueel met landcode, zoals nl of en-GB.
Profielantwoorden bevatten alleen-lezen employeeChangedAt: een object met per veld of custom.<key> het ISO-tijdstip van de laatste medewerkerswijziging, zolang een beheerder deze niet heeft vervangen. Interne herhaalmarkeringen ontbreken. Kopieer deze metadata niet naar PUT-invoer: een zelf opgegeven wijzigingsgeschiedenis wordt geweigerd. De wijziging van een beheerder gaat ook door bij velden die voor medewerkers zijn vrijgegeven.
Profielinstellingen accepteren defaultCountry, departments, locations, customFields en selfEditable. Vestigingen hebben key, name en optioneel line1, postcode, city, country, phone. Maximaal tien eigen velden hebben key, label, type: text|choice|boolean, met options bij een keuzelijst. selfEditable bevat alleen mobile, showMobile, photo, workdays, pronouns, language en ingestelde custom.<key>-waarden. De beheerder bepaalt de vormgeving. Profielwijzigingen worden gelogd; bij foto's wordt de inhoud niet in de audit gekopieerd. Portaal, API en CLI gebruiken dezelfde atomaire CSV-controle hieronder.
CSV controleren en gegevens in bulk wijzigen
GET /profiles/export geeft data.csv (maximaal 2 MiB), met beide soorten mailboxen op sleutel type en email. De export bevat bekende gegevenskolommen en ingestelde custom.<key>-waarden. Ontwerptoewijzingen, foto's en alleen-lezen wijzigingsmetadata zijn geen CSV-kolommen. Onbekende of dubbele kolommen, onbekende of dubbele adressen, onjuist mailboxsoort en ongeldige waarden laten de hele import mislukken.
POST /profiles/import/preview accepteert {"csv":"..."} (UTF-8, maximaal 64 KiB en 500 rijen). Het leest actuele gegevens en geeft changes, een privé versleuteld preview_token en de SHA256 daarvan als version/ETag. Het maakt geen profiel, auditregel of operatie. Controleer elke voorgestelde rij. Binnen tien minuten accepteert POST /profiles/import alleen {"preview_token":"..."} met de gecontroleerde ETag, oorspronkelijke Idempotency-Key en actuele sterke verificatie. De controle bindt de oorspronkelijke verbinding, bedrijf/workspace, instellingen en elke profielversie. Eén ongeldige of verouderde rij voorkomt alle wijzigingen. dry_run:true controleert alles zonder op te slaan. Gebruik bij een onzekere uitkomst exact dezelfde controle en sleutel; maak niet automatisch een nieuwe preview en herhaal geen POST automatisch. CSV- en controlebestanden bevatten privémedewerkersgegevens: bescherm ze en commit ze niet.
POST /profiles/bulk accepteert owners:[{kind:"user"|"shared",id,version}] en niet-lege fields met alleen department en/of location (null wist). Lees de workspace/instellingen-ETag via /profiles/export; elke mailbox heeft ook de eigen actuele profielversie nodig. De hele batch gebruikt één lokale transactie met dezelfde sterke verificatie, oorspronkelijke sleutel en dry-run-controles.
Upload een foto via het bestaande handtekening-afbeeldingenendpoint met kind:"photo" en zet daarna de teruggegeven ID in photo bij een gewoon of gedeeld profiel; PUT photo:null wist de profielverwijzing. De twee verzoeken hebben elk een actuele ETag en oorspronkelijke sleutel. Een voltooide upload blijft bewaard als het toewijzen daarna mislukt; controleer de oorspronkelijke uitkomst in plaats van opnieuw te uploaden. Verwijder een ongebruikte foto uit de dienst met de bestaande afbeeldingsactie en photo:true.
binadit workspace mailbox profile export 7 --file profiles.csv --account 42
# Edit the protected CSV, then inspect the proposed changes before committing.
binadit workspace mailbox profile import 7 --input profiles.csv --review-file profile-review.json --account 42
binadit workspace mailbox profile import 7 --input profile-review.json --commit --confirm-workspace 7 --account 42 --yes
# The shared-mailbox aliases use the same reviewed workspace-wide CSV.
binadit workspace shared-mailbox profile export 7 --file shared-profiles.csv --account 42
binadit workspace mailbox profile bulk 7 --input department-change.json --version WORKSPACE_PROFILE_VERSION --account 42 --dry-run
Sjablonen, regels en afbeeldingen
Een sjabloon heeft id, name, html, text of null, language (nl of en) en optioneel source (galerij-ID of custom). Een regel heeft id, name, één when-voorwaarde, new, reply, recipients: all|external en campaign: true|false. reply: null gebruikt het sjabloon voor nieuwe mail; reply: "none" onderdrukt het. Voorwaarden zijn precies één van all: true, domains, departments, locations, mailboxes, sharedMailboxes, of custom: {key,present:true} / {key,equals:...}. De eerste passende regel wint. Verwezen ID's en bronnen moeten in deze workspace bestaan.
Een campagne heeft id, name, image, beschrijvende alt, UTC RFC3339 from/until en rules-ID's. Er is geen link. De bannergenerator accepteert tekst en twee hexkleuren, bijvoorbeeld #0B5FFF en #FFFFFF, plus afmetingen.
Bekijk altijd de wijzigingen en fouten uit validate vóór het opslaan van HTML. Alleen de teruggegeven HTML wordt opgeslagen: linkelementen verdwijnen maar de tekst blijft, scripts worden verwijderd en toegestane externe afbeeldingen worden overgenomen. Validatie kan dus afbeeldingen maken en gebruikt het schrijfintentieprotocol. Sjablonen bevatten geen links, volgpixels of metingen van geopende mail. Website, e-mail en telefoon staan als gewone tekst.
Een afbeeldingsupload is maximaal 5 MiB. JSON bevat de bytes in content_base64, plus mime en kind: logo|photo|banner|other. Verwerkingsopties zijn width, round, zes hextekens in border, whitePlate en crop: "x,y,w,h". De dienst verwerkt ondersteunde invoerformaten; WebP/SVG worden voor mail omgezet en niet als WebP/SVG ingevoegd. Afbeeldingen zijn openbaar via hun adres: zet hier niets vertrouwelijks in. Een verwijderd logo of een banner kan blijven staan om oude mail intact te houden. Foto's verdwijnen meteen; controleer removedFromServer.
settings.imageHost is auto of none. Het portaal berekent eigen-domein/gedeelde modus uit echte DNS en de serverinstelling. sig.<klantdomein> wordt pas gebruikt na controle van de CNAME; anders wordt waar mogelijk de gedeelde afbeeldingenserver gebruikt. Lever geen eigen afbeeldingshostnamen aan. Het herschrijven van Verzonden-kopieën (updateSentCopy) blijft false.
Bedrijfsgegevens, varianten en de HTML-editor (MailSig 0.2)
GET /signatures/company geeft dertien vaste velden: name, legalName, kvk, btw, iban, address, phone, email, website, tagline, brandColor, logo, locations. Elk veld bevat value en source (account of custom). PUT wijzigt alleen de meegestuurde velden. Een lege eigen waarde verbergt een veld bewust en is iets anders dan de accountstandaard. Terugzetten kan met {"source":"account"}. Accountwaarden volgen latere bedrijfswijzigingen; de actuele waarden zijn onderdeel van de handtekening-ETag, zodat een accountwijziging een oude beoordeling ongeldig maakt.
Het algemene telefoonnummer neemt geen mobiel nummer over. Het algemene e-mailadres is een bestaand info@, contact@, hallo@ of hello@ op het eerste maildomein, nooit het persoonlijke contactadres van het account. IBAN blijft leeg totdat je zelf een waarde kiest of expliciet useAccountIban:true meestuurt. IBAN terugzetten, ook met company reset --all, verwijdert die toestemming. address bevat line1, postcode, city, country; phone is null of {display,e164}. logo verwijst naar een eigen geüpload logo. locations gebruikt dezelfde profielinstellingen, houdt source:custom en wordt bij terugzetten leeggemaakt. Medewerkers zonder vestiging krijgen het bedrijfsadres. In het portaal staan deze gegevens op Bedrijfsgegevens en in de eerste-startwizard.
Open in het portaal Bedrijfsgegevens → Merk en logo → Nieuw logo uploaden (ook in stap 1 van de instelhulp). Kies een PNG-, JPG-, WebP-, GIF- of SVG-bestand van maximaal 5 MiB en klik op Opslaan of Doorgaan. Het bestand wordt het bedrijfslogo en wordt samen met je overige bedrijfswijzigingen opgeslagen. De keuzelijst met bestaande logo’s toont eerder geüploade logo’s; daarmee upload je geen bestand. Via API/CLI blijven uploaden en het bedrijfslogo instellen twee afzonderlijke aanvragen, zoals hieronder beschreven.
{"name":{"source":"custom","value":"Example BV"},"tagline":{"source":"custom","value":"Clear advice"},"iban":{"source":"account"}}
GET/PUT /signatures/variants gebruikt {"variants":[...]} voor volledige vervanging. Elk item heeft id, name, eventueel description, een new-ontwerp-ID, eventueel reply (null = hetzelfde, "none" = geen), eventueel default. Er mag één standaard zijn; de ontwerpen daarvan komen in de eerste regel Iedereen. Verwijzingen moeten in deze workspace bestaan; een gebruikte variant kan niet worden verwijderd. Een vast mailbox-template gaat vóór variant, daarna geldt de eerste passende regel. Campagnes en ontvangers blijven uit de regel komen. De Workspace-beheerder wijst template of variant toe aan gewone en gedeelde profielen. Medewerkers kunnen deze toewijzing of eigen HTML niet via zelfservice wijzigen.
{"variants":[{"id":"standard","name":"Standard","description":"Full company details","new":"full","reply":"short","default":true}]}
GET /signatures/variables?lang=nl geeft syntax en groups van de dienst, inclusief ingestelde eigen velden; en is ook geldig. Het portaal bewaart deze metadata tien minuten in de cache. Houd geen afzonderlijke hardgecodeerde variabelenlijst bij. Het voorbeeldantwoord bevat de platte tekenreeksmap fields (ook lege waarden), unknownFields en UTF-8-bytegroottes bytes.html/bytes.text. Daarmee werken variabelen invoegen, blokken en spellingssuggesties. Tot 2048 HTML-bytes is de handtekening tijdens het schrijven in webmail zichtbaar; grotere handtekeningen worden op de server toegevoegd. Een voorbeeld accepteert precies één tijdelijk ontwerp of opgeslagen variant, blijft alleen-lezen en initialiseert nooit de externe bundel.
{"variant":"standard","reply":true,"mailbox":"anna@example.test"}
binadit workspace signatures company show 7 --account 42
binadit workspace signatures company set 7 --input company.json --version "$SIG_VERSION" --account 42 --dry-run
binadit workspace signatures company set 7 --input company.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures company reset 7 --field name --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures company reset 7 --all --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures variant list 7 --account 42
binadit workspace signatures variant put 7 --input variants.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures variables 7 --language en --account 42
binadit workspace mailbox profile put 7 23 --input profile-variant.json --version "$PROFILE_VERSION" --account 42 --yes
Voorbeeld profile-variant.json: {"variant":"standard","template":null}. Lees na iedere geslaagde wijziging de actuele versie opnieuw. Iedere wijziging bewaart de oorspronkelijke verzoeksleutel totdat een strikt passend ontvangstbewijs is gecontroleerd; een onjuist of onzeker antwoord wordt nooit automatisch herhaald.
Getypeerde CLI-voorbeelden
Bescherm JSON- en afbeeldingsbestanden met rechten voor alleen de eigenaar. --input - leest JSON van standaardinvoer; een upload leest het beschermde binaire --file. Een actuele versie bestaat uit 64 kleine hextekens; vervang de voorbeeldvariabelen door de echte data.version.
binadit workspace mailbox profile get 7 23 --account 42
binadit workspace mailbox profile put 7 23 --account 42 --input profile.json --version "$PROFILE_VERSION" --dry-run
binadit workspace mailbox profile put 7 23 --account 42 --input profile.json --version "$PROFILE_VERSION" --yes
binadit workspace shared-mailbox profile get 7 31 --account 42
binadit workspace profile-settings get 7 --account 42
binadit workspace profile-settings put 7 --account 42 --input profile-settings.json --version "$PROFILE_SETTINGS_VERSION" --yes
binadit workspace signatures settings get 7 --account 42
binadit workspace signatures gallery list 7 --account 42
# Save disabled settings once to initialize the bundle before a first preview.
binadit workspace signatures settings put 7 --input settings.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures gallery import 7 klassiek --language en --version "$SIG_VERSION" --account 42 --yes
# Read settings again for a fresh version after every successful change.
binadit workspace signatures template get 7 --account 42
binadit workspace signatures template put 7 --input templates.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures rule put 7 --input rules.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures campaign put 7 --input campaigns.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures validate 7 --input html.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures preview 7 --input preview.json --account 42
binadit workspace signatures image list 7 --account 42
binadit workspace signatures image upload 7 --file logo.png --mime image/png --input image-options.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures image banner 7 --input banner.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures image delete 7 1234567890abcdef --photo --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures enable 7 --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures testmail 7 --input testmail.json --version "$SIG_VERSION" --account 42 --yes
binadit workspace signatures status 7 --account 42
binadit workspace signatures disable 7 --version "$SIG_VERSION" --account 42 --yes
Voorbeeld profile.json: {"firstName":"Anna","lastName":"de Vries","jobTitle":"Adviseur","phone":"030 123 4567","showMobile":false,"language":"nl"}.
Voorbeeld templates.json (gewone tekst, geen links):
{"templates":[{"id":"standard","name":"Standard","html":"<p>{{naam}}<br>{{functie}}<br>{{bedrijf}} · {{telefoon}}</p>","text":null,"language":"en","source":"custom"}]}
Voorbeeld rules.json: {"rules":[{"id":"everyone","name":"Iedereen","when":{"all":true},"new":"standard","reply":null,"recipients":"all","campaign":false}]}.
Voorbeeld preview.json: {"template":{"html":"<p>{{naam}}<br>{{functie}}</p>"},"mailbox":"anna@example.test","footer":true}.
Voorbeeld image-options.json: {"kind":"logo","width":160,"whitePlate":true}. Voorbeeld banner.json: {"text":"Vrijdag zijn wij gesloten","background":"#0B5FFF","foreground":"#FFFFFF","width":600,"height":120}. Voorbeeld testmail.json: {"mailbox":"anna@example.test","variant":"reply"}.
API-codevoorbeelden
Dit Python-voorbeeld leest de actuele bedrijfsversie en verstuurt één oorspronkelijke aanvraag om de bedrijfsnaam te wijzigen. Bewaar sleutel en exacte inhoud als het antwoord verloren gaat; deze code herhaalt geen schrijfactie automatisch.
import os, uuid, json, requests
url = "https://my.binadit.com/api/v1/accounts/42/workspaces/7/signatures/company"
headers = {"Authorization": "Bearer " + os.environ["BINADIT_TOKEN"]}
r = requests.get(url, headers=headers, timeout=30, allow_redirects=False)
r.raise_for_status()
# Read variants and the service variable catalog through the same scoped portal API.
for section in ["variants", "variables?lang=en"]:
catalog = requests.get(url.removesuffix("company") + section, headers=headers, timeout=30, allow_redirects=False)
catalog.raise_for_status()
assert catalog.json()["data"]["workspace_id"] == 7
intent = {"key": str(uuid.uuid4()), "version": r.json()["data"]["version"], "body": {"name": {"source": "custom", "value": "Example BV"}}}
# Exclusive creation: an existing unresolved intent must be inspected, never overwritten.
with os.fdopen(os.open("mailsig-intent.json", os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600), "w") as f:
json.dump(intent, f)
f.flush()
os.fsync(f.fileno())
headers.update({"If-Match": intent["version"], "Idempotency-Key": intent["key"]})
r = requests.put(url, headers=headers, json=intent["body"], timeout=30, allow_redirects=False)
r.raise_for_status()
result = r.json()
assert result["data"]["workspace_id"] == 7 and result["operation"]["account_id"] == 42
assert result["operation"]["action"] == "workspace.signatures.company.put"
assert result["operation"]["request_status"] == "succeeded"
print(result["operation"]["id"])
# Keep the intent file for review. Remove it manually only after the original outcome is verified.
Hetzelfde in JavaScript (token uit de omgeving, nooit in een browserpagina of URL):
import {open} from 'node:fs/promises';
import {randomUUID} from 'node:crypto';
const url = 'https://my.binadit.com/api/v1/accounts/42/workspaces/7/signatures/company';
const headers = {Authorization: `Bearer ${process.env.BINADIT_TOKEN}`};
const read = await fetch(url, {headers, redirect: 'error'});
if (!read.ok) throw new Error(`Read failed: ${read.status}`);
const {data} = await read.json();
for (const section of ["variants", "variables?lang=en"]) {
const catalog = await fetch(url.replace(/company$/, section), {headers, redirect: "error"});
if (!catalog.ok || (await catalog.json()).data?.workspace_id !== 7) throw new Error("Review workspace catalog");
}
const intent = {key: randomUUID(), version: data.version, body: {name: {source: 'custom', value: 'Example BV'}}};
const journal = await open('mailsig-intent.json', 'wx', 0o600);
try { await journal.writeFile(JSON.stringify(intent)); await journal.sync(); }
finally { await journal.close(); }
const result = await fetch(url, {method: 'PUT', redirect: 'error',
headers: {...headers, 'Content-Type': 'application/json', 'If-Match': intent.version, 'Idempotency-Key': intent.key},
body: JSON.stringify(intent.body)});
if (!result.ok) throw new Error(`Inspect the original intent: ${result.status}`);
const receipt = await result.json();
if (receipt.data?.workspace_id !== 7 || receipt.operation?.account_id !== 42 ||
receipt.operation?.action !== 'workspace.signatures.company.put' ||
receipt.operation?.request_status !== 'succeeded') throw new Error('Inspect original intent');
console.log(receipt.operation.id);
// Retain the journal for review; never overwrite or automatically retry an unresolved request.
PHP en C# gebruiken de gedeelde transporthelpers, die redirects weigeren en mutaties nooit automatisch herhalen. Sla de PHP-helper op als binadit.php of de C#-helper als Binadit.cs. Deze voorbeelden lezen instellingen, het mailboxprofiel, de status, varianten en variabelen en voeren daarna uitsluitend een dry run van een bedrijfsnaamwijziging uit. Gebruik een werkmap die alleen voor de eigenaar toegankelijk is, met een beschermde gebruikers-ACL op Windows. Het ontvangstbestand bevat verzoekmetadata en geen token; bewaar het totdat het oorspronkelijke resultaat is beoordeeld. Een echte wijziging vereist een nieuwe expliciete controle van de actuele bedrijfsversie en een afzonderlijk opgeslagen oorspronkelijke verzoeksleutel.
<?php
require 'binadit.php';
$token = BinaditExample::accessToken();
$base = '/api/v1/accounts/42/workspaces/7';
$settings = BinaditExample::api($token, 'GET', $base.'/signatures/settings');
$company = BinaditExample::api($token, 'GET', $base.'/signatures/company');
$profile = BinaditExample::api($token, 'GET', $base.'/mailboxes/23/profile');
$status = BinaditExample::api($token, 'GET', $base.'/signatures/status');
$variants = BinaditExample::api($token, 'GET', $base.'/signatures/variants');
$variables = BinaditExample::api($token, 'GET', $base.'/signatures/variables?lang=en');
if (($settings['data']['data']['workspace_id'] ?? null) !== 7
|| ($profile['data']['data']['owner_id'] ?? null) !== 23
|| ($status['data']['data']['workspace_id'] ?? null) !== 7) {
throw new RuntimeException('Review the requested workspace and mailbox');
}
$key = bin2hex(random_bytes(16));
$intent = ['key' => $key, 'version' => $company['data']['data']['version'],
'path' => $base.'/signatures/company', 'body' => ['name' => ['source' => 'custom', 'value' => 'Example BV'], 'dry_run' => true]];
$mask = umask(0077);
try { $file = fopen('mailsig-profile-intent.json', 'x'); }
finally { umask($mask); }
if ($file === false) { throw new RuntimeException('Inspect the existing original intent'); }
try {
$json = json_encode($intent, JSON_THROW_ON_ERROR);
if (fwrite($file, $json) !== strlen($json) || !fflush($file) || !fsync($file)) {
throw new RuntimeException('Intent persistence failed; no request was submitted');
}
} finally { fclose($file); }
$reply = BinaditExample::api($token, 'PUT', $intent['path'], $intent['body'], $intent['version'], $key);
if (($reply['data']['data']['dry_run'] ?? null) !== true) { throw new RuntimeException('Expected a dry-run result'); }
echo "Company validation finished; no change was saved.\n";
// Keep the journal. Do not automatically resend a request after a transport error.
using System.Text.Json;
using System.Text.Json.Nodes;
using var api = new BinaditExample();
string token = await api.AccessToken();
const string root = "/api/v1/accounts/42/workspaces/7";
var settings = await api.Api(token, "GET", root + "/signatures/settings");
var company = await api.Api(token, "GET", root + "/signatures/company");
var profile = await api.Api(token, "GET", root + "/mailboxes/23/profile");
var status = await api.Api(token, "GET", root + "/signatures/status");
var variants = await api.Api(token, "GET", root + "/signatures/variants");
var variables = await api.Api(token, "GET", root + "/signatures/variables?lang=en");
if (settings.Data?["data"]?["workspace_id"]?.GetValue<long>() != 7 ||
profile.Data?["data"]?["owner_id"]?.GetValue<long>() != 23 ||
status.Data?["data"]?["workspace_id"]?.GetValue<long>() != 7)
throw new InvalidOperationException("Review the requested workspace and mailbox");
string key = Guid.NewGuid().ToString();
string version = company.Data!["data"]!["version"]!.GetValue<string>();
var body = new JsonObject { ["name"] = new JsonObject { ["source"] = "custom", ["value"] = "Example BV" }, ["dry_run"] = true };
string path = root + "/signatures/company";
var options = new FileStreamOptions { Mode = FileMode.CreateNew, Access = FileAccess.Write, Share = FileShare.None };
if (!OperatingSystem.IsWindows()) options.UnixCreateMode = UnixFileMode.UserRead | UnixFileMode.UserWrite;
await using (var journal = new FileStream("mailsig-profile-intent.json", options))
{
await JsonSerializer.SerializeAsync(journal, new { key, version, path, body });
await journal.FlushAsync();
journal.Flush(flushToDisk: true);
}
var reply = await api.Api(token, "PUT", path, body, version, key);
if (reply.Data?["data"]?["dry_run"]?.GetValue<bool>() != true)
throw new InvalidOperationException("Expected a dry-run result");
Console.WriteLine("Company validation finished; no change was saved.");
// Retain the journal; a transport error must never trigger an automatic retry.
HTML uit een voorbeeld is onbetrouwbare documentinhoud. Toon haar alleen in een iframe met sandbox="" (geen scripts of same-origin) en een strenge CSP; voeg haar nooit in de DOM van het portaal in. Vergelijk breed/smal en licht/donker; donkere modus is een benadering.
Status en grenzen
identity: synced betekent dat de handtekening in de webmail/JMAP-identiteit staat. server is een gewone melding: de handtekening is groter dan Stalwarts identiteitslimiet van 2048 bytes en wordt bij het versturen ingevoegd, maar is niet zichtbaar tijdens het typen. pending en error betekenen dat de synchronisatie nog niet klaar is. Het portaal bundelt wijzigingen tot hoogstens één bundel per tien seconden. Een testmailbevestiging bewijst geen aflevering in de inbox; de dienst beperkt testmail tot tien berichten per workspace per uur.
Ontbrekende DNS voor eigen afbeeldingen is een aanbeveling, geen mailstoring: gedeelde hosting kan blijven werken. MailSig helpt bedrijfsregistratiegegevens te vermelden; het verklaart geen juridische naleving. Lees na synchronisatie de status en beoordeel waarschuwingen vóór het aanzetten. Live SMTP-/DKIM-/weergaveacceptatie en uitrol staan los van lokale API-/CLI-tests.
Voorbeeld settings.json: {"enabled":false,"imageHost":"auto"}. De asynchrone bundel moet eerst zijn klaargezet; een te vroeg voorbeeld geeft 409 en zet handtekeningen niet zelf aan.
Volledig automatisch inrichten en beheren
Gebruik een machineverbinding met workspace.mailboxes:read en workspace.mailboxes:write, beperkt tot de bedoelde Workspace. Met operations:read kan een taak haar eigen ontvangstbewijzen controleren. Deze verbinding vraagt geen browser of herhaalde passkey. Zonder sleutelhanger kan een geheimenbeheerder de clientsleutel via stdin aan iedere CLI-opdracht geven: --service-client-id ID --service-secret-stdin. Lees JSON dan uit een beschermd bestand. Zet sleutels nooit in een repository, opdrachtargumenten of taaklog. Zie de CLI-handleiding.
Alle 35 operaties zijn beschikbaar: bedrijfsgegevens, persoonlijke en gedeelde profielen, CSV, eigen velden, logo's/foto's, HTML-sjablonen, nieuwe/antwoordvarianten, geordende regels, campagnes, medewerkersrechten, voorbeeldweergave, validatie, inschakelen, status en uitschakelen. Verwijder een sjabloon, variant, regel of campagne met een PUT van de volledige actuele lijst zonder dat item. Pas verwijzingen eerst aan; alleen een lijst zonder verwijzingen kan leeg worden gemaakt. De instelhulp heeft /signatures/onboarding; die schakelt handtekeningen niet zelf in.
Voor een nieuwe, lege configuratie zijn de extra API-aanroepen:
POST /signatures/gallery/klassiek/importmet{"language":"nl","placement":"default"}: volledig sjabloon en kort antwoordsjabloon, plus de standaardvariant en Iedereen-regel.extramaakt een extra variant. Zonderplacementblijft de bestaande enkele-sjabloonimport werken. Het nieuwe antwoord bevatsource,placementenvariant.PUT /signatures/onboardingmet{"step":4,"dismiss":true}: instelhulp afronden.POST /signatures/testmailmet{"mailbox":"anna@example.test","variant":"new","recipient_mailbox":23}: stuur een test naar gewone mailbox 23 van dezelfde Workspace. ID's van gedeelde mailboxen tellen niet als gewone mailbox-ID's.
Lees vóór elke schrijfactie de actuele handtekeningversie en gebruik If-Match en een eigen bewaarde Idempotency-Key. De directe CLI-opdrachten zijn:
set -eu
umask 077
# Existing service profile; no interactive browser login in the job.
cli() { binadit --profile "$PROFILE" --account "$ACCOUNT" --no-input --output json "$@"; }
version() { cli workspace signatures settings get "$W" | jq -er '.data.version'; }
# Verify templates/variants/rules are empty before this initial gallery import.
cli workspace signatures template get "$W" > templates-before.json
cli workspace signatures variant list "$W" > variants-before.json
cli workspace signatures rule get "$W" > rules-before.json
jq -e '.data.templates == []' templates-before.json >/dev/null
jq -e '.data.variants == []' variants-before.json >/dev/null
jq -e '.data.rules == []' rules-before.json >/dev/null
cli workspace signatures gallery import "$W" klassiek --language en --placement default --version "$(version)" --yes > gallery-result.json
# Optional: update company, images and personal/shared profiles with their own current versions.
cli workspace signatures onboarding put "$W" --input onboarding.json --version "$(version)" --yes > onboarding-result.json
cli workspace signatures enable "$W" --version "$(version)" --yes > activation-result.json
attempt=0
while :; do
cli workspace signatures status "$W" > status.json
if jq -e '.data.status.sync | .pending == false and (.revision | type == "number") and .pushedRevision == .revision' status.json >/dev/null; then break; fi
attempt=$((attempt + 1))
if [ "$attempt" -ge 24 ]; then echo 'Synchronization not confirmed; inspect status.json. No write was retried.' >&2; exit 1; fi
sleep 5
done
# Check image DNS/TLS and mailbox identity/complete/missing before acceptance.
jq -e --arg mailbox 'anna@example.test' '{variant: .data.gallery.variant.id, mailbox: $mailbox, footer: true}' gallery-result.json > preview.json
cli workspace signatures preview "$W" --input preview.json > preview-result.json
cli workspace signatures testmail "$W" --input testmail.json --version "$(version)" --yes > testmail-result.json
Het shellvoorbeeld hierboven geeft JSON-resultaten en wacht hoogstens twee minuten op synchronisatie. Pas het echte mailboxadres aan in de invoer. Gebruik een bestaande machineverbinding, een private werkmap (umask 077) en controleer vooraf dat de collecties leeg zijn. Wacht na inschakelen met een begrensde statuscontrole totdat sync.pending false is en sync.pushedRevision == sync.revision. Controleer DNS/TLS, identity, complete en missing, bekijk een voorbeeld en stuur daarna pas de testmail. Alleen uitlezen mag automatisch herhaald worden. Stop na een onzekere schrijfactie en onderzoek de oorspronkelijke operatie; voer het hele inrichtingsblok niet opnieuw uit. Een testmailbevestiging bewijst verzending naar de dienst, niet aflevering in de inbox; de limiet blijft tien per Workspace per uur. Uitschakelen via {"enabled":false} bewaart ontwerp en Workspace.
Gratis ontwerpen en logo-effecten
Alle galerijontwerpen en logo-effecten zijn gratis inbegrepen bij Workspace. Ze maken geen productbestelling, betaalde werkplek of factuur aan. De Workspace-beheerder bepaalt het ontwerp; medewerkersrechten en het beleid zonder links en tracking blijven hetzelfde.
Nieuw zijn atelier (serifnaam en ruime typografie), horizon (dunne lijn in de huisstijlkleur), studio (foto naast de persoonsgegevens) en compact-logo (compact ontwerp met logo), elk in Nederlands en Engels. Elk ontwerp met een logo kan een bewegend logo tonen; de tekst blijft stil. Bestaande ontwerpen blijven beschikbaar.
Open in het portaal Bedrijfsgegevens, kies een nieuw logobestand en selecteer Logo-animatie (gratis). Zachte glans en Subtiele zoom zijn optioneel. Standaard laat Geen extra effect de upload ongewijzigd. De upload in de beeldbank heeft dezelfde opties. Gebruik voor een stilstaand logo PNG of JPG zonder extra effect; een bestaande bewegende GIF behoudt zijn animatie.
Voor API/CLI-uploads is animation gelijk aan none (standaard), shine of breathe. Effecten werken alleen met kind:logo en PNG-, JPEG- of WebP-bronbestanden tot 4 miljoen pixels en 4096 pixels per zijde. De weergavebreedte is maximaal 320 px. Uitsnijden wordt één keer vóór de animatie toegepast; round, whitePlate en border moeten uitstaan. De bewegende uitvoer is begrensd tot 1 MiB. Het portaal verwerkt het bestand lokaal en uploadt de GIF via zijn bestaande MailSig-verbinding; de client benadert MailSig niet rechtstreeks. dry_run controleert formaat, afmetingen en opties zonder de animatie te verwerken of uploaden.
Het eerste en laatste beeld tonen het volledige logo. Het effect duurt ongeveer één seconde en het laatste beeld heeft een pauze van 30 seconden; de maildienst kan de animatie herhalen. Het mailprogramma en de instellingen van de ontvanger bepalen het afspelen. Het stilstaande eerste beeld blijft dus altijd bruikbaar. Er komt geen JavaScript, hyperlink of volgpixel in de mail.
Bewaar de eerste JSON als logo-options.json. De CLI-optie --mime beschrijft het oorspronkelijke bestand (image/png in dit voorbeeld); het portaal maakt er na verwerking GIF van. Bewaar de laatste JSON als company-logo.json en gebruik de echte afbeeldings-ID uit het antwoord. Iedere wijziging gebruikt een actuele versie en een eigen oorspronkelijke aanvraagsleutel; het bestaande herstel bij onzekere antwoorden blijft gelden. De API gebruikt het bestaande POST /signatures/images met content_base64, mime en deze opties, gevolgd door het bestaande PUT /signatures/company.
{"kind":"logo","width":180,"animation":"shine"}
binadit workspace signatures gallery list 7 --account 42
binadit workspace signatures gallery import 7 atelier --language en --placement default --version "$SIG_VERSION" --account 42 --yes --no-input
# Read the current signature version again before the next write.
binadit workspace signatures image upload 7 --file logo.png --mime image/png --input logo-options.json --version "$SIG_VERSION" --account 42 --yes --no-input
# Use the returned image ID in company[logo], then read a fresh version.
binadit workspace signatures company set 7 --input company-logo.json --version "$SIG_VERSION" --account 42 --yes --no-input
{"logo":{"source":"custom","value":"IMAGE_ID_FROM_UPLOAD"}}