Ga naar inhoud

Mailspace-mailboxen

Mailspace is het plan: je schaft het aan voor een domein en je resizet of zegt het op. Deze pagina gaat over alles binnen de mailboxlijst van één mailomgeving — de mailboxen zelf, de app-wachtwoorden en filterregels van elke mailbox, en het afwezigheidsbericht.

Elke route op deze pagina is genest onder één mailomgeving, dus de mailspace-GUID is altijd het eerste padsegment. Haal die op met GET /api/mailspace.

OAuth-scopes: reads vereisen mailspace:read, writes vereisen mailspace:write — dezelfde twee scopes die de endpoints op planniveau gebruiken, dus een token dat een mailomgeving kan resizen, kan ook de mailboxen ervan verwijderen. Sessie- en API-sleutel-credentials slaan de scopecontroles volledig over (zie OAuth).

Er is geen step-up-authenticatie op deze API. Het dashboard bevestigt je identiteit opnieuw voordat een mailbox definitief wordt verwijderd, een mailboxwachtwoord wordt ingesteld of een app-wachtwoord wordt aangemaakt; de API heeft geen equivalente prompt, omdat een bearertoken bij elk verzoek opnieuw authenticeert. Die drie acties schrijven in plaats daarvan elk een auditregel met de gebruikte credential erin. Geen enkel endpoint op deze pagina accepteert het eigen wachtwoord van de aanroeper in de request body.

Mailboxen worden geadresseerd met een GUID, niet met een adres

Een mailbox heeft als sleutel de GUID van zijn CloudPress-record — .../mailboxes/9f3c…, nooit .../mailboxes/sales@example.com. Twee redenen: het adres is veranderlijk (een update kan het herschrijven), en het bevat punten, waarvoor een padsegment speciaal beperkt zou moeten worden. Dezelfde GUID is het mailbox_id-segment voor app-wachtwoorden, mailregels en afwezigheidsberichten.

App-wachtwoorden zijn de uitzondering: die hebben geen lokaal record, dus is het padsegment het credential-ID van de mailserver zelf (een String).


Gedeelde controles

Elk endpoint op deze pagina doorloopt dezelfde zes controles, in deze volgorde, voordat de actie iets doet. De eerste die faalt, antwoordt het verzoek.

Van toepassing op Voorwaarde Reactie
alle de mailserver is niet geconfigureerd op het platform 503 stalwart_unavailable
alle mailspace-GUID onbekend, of niet zichtbaar voor je credential 404, lege body
alleen writes je gebruiker heeft geen bewerkrecht op de eigen workspace van de mailomgeving 403 not_authorized
alle — inclusief reads de mailomgeving is geblokkeerd door support of wegens een onbetaalde factuur 403 mailspace_suspended
alleen writes de mailomgeving zelf staat ingepland voor verwijdering 403 pending_delete
alle de mailomgeving heeft nog geen tenant op de mailserver 409 not_provisioned

Daarbovenop zoekt elk endpoint dat een mailbox noemt die mailbox binnen deze mailomgeving op, en antwoordt 404 unknown_mailbox als de mailbox daar niet staat — dus een GUID die bij de mailomgeving van een andere workspace hoort, is een 404, geen 403.

Write-gating hangt af van de HTTP-methode, niet van de actienaam

De twee write-gates beslissen op basis van de methode. GET en HEAD gaan zonder meer door; al het andere wordt gecontroleerd. De muterende acties met een eigen naam — restore, force_delete, toggle, move, adopt — worden dus precies zo gecontroleerd als een gewone POST of PATCH, en er is geen actienaam die eraan ontsnapt.

Concreet: een lid met alleen-lezenrechten dat een mailspace:write-token heeft krijgt 403 not_authorized op elke write op deze pagina, inclusief DELETE .../force_delete en POST .../mail_rules/adopt. De scope van het token is geen vervanging voor de rechtencontrole, en die controle draait tegen de workspace die eigenaar is van de mailomgeving — niet tegen de workspace in X-Auth-Account.

Een HEAD van een read-endpoint wordt behandeld als de read die het is, dus antwoordt dezelfde status als de bijbehorende GET.

Reads overleven de bewaartermijn van de mailomgeving, writes niet

De mailomgeving met soft delete verwijderen (DELETE /api/mailspace/:id) zet deze API niet stil. De hele bewaartermijn kun je nog mailboxen opvragen, een mailbox lezen, app-wachtwoorden opvragen, filterregels opvragen en de afwezigheidsstatus lezen — maar elke write antwoordt 403 pending_delete. Herstel de mailomgeving eerst.

Die asymmetrie is bewust: force_delete op een mailbox is onomkeerbaar, en die binnen de bewaartermijn laten draaien zou juist de mail wissen die het herstellen van de mailomgeving terug moet brengen.

Deze statussen wijken af van de endpoints op planniveau

Dezelfde twee foutcodes hebben hier andere HTTP-statussen dan op Mailspace, omdat de planendpoints ze uit hun eigen controller opgooien en deze uit de gedeelde keten komen:

Code Op deze pagina Op mailspace.md
pending_delete 403 422
not_provisioned 409 422

Een geweigerde rechtencontrole verschilt ook: op deze pagina is de body {"errors":["Not Authorized"],"code":"not_authorized"}, terwijl de endpoints op planniveau dezelfde melding teruggeven met helemaal geen code-veld. Vertak op de code waar die er is, en nooit alleen op de status.

Een mailomgeving die zowel geblokkeerd is als op verwijderen wacht, gedraagt zich verschillend per methode. De blokkadecontrole maakt bewust een uitzondering voor een mailomgeving die op verwijderen wacht — een met soft delete verwijderde mailomgeving is standaard al geblokkeerd op de mailserver — dus antwoordt een write pending_delete in plaats van mailspace_suspended, en komt een read door beide controles heen en antwoordt 200.


Mailboxen opvragen

GET /api/mailspace/:mailspace_id/mailboxes

Scope: mailspace:read.

Geeft de actieve mailboxen van de mailomgeving terug, plus, apart, de mailboxen die binnen hun soft-delete-respijtperiode zitten. Een mailbox die ingepland staat voor verwijdering staat in pending en nooit in mailboxes, dus de twee bakjes overlappen nooit.

Dit is een live read tegen de mailserver, en die is niet goedkoop

De mailserver is het systeem van record voor welke mailboxen bestaan, dus elke aanroep kost een JMAP-rondgang — en het kan als bijwerking lokale records aanmaken: een mailbox die upstream bestaat maar uit onze tabel is weggedreven, wordt hier alsnog aangemaakt.

Er is geen paginering, en de onderliggende principal-query is begrensd op 500 mailboxen. Het q-filter wordt na het ophalen op dat resultaat toegepast, dus zoekt binnen diezelfde 500 en niet daarvoorbij. De standaard rate limit geldt — poll spaarzaam.

Een leeg mailboxes-array is gezaghebbend

De upstream read is strikt: een mailomgeving waarvan de mailboxen niet konden worden gelezen antwoordt 503 mailboxes_unavailable, nooit 200 met een leeg array. mailboxes: [] betekent dus dat de mailserver is gevraagd en er geen heeft, en je kunt je eigen administratie ermee verzoenen.

Die code dekt elke fout van die ene read en alleen die read; een storing ergens anders in het endpoint is een 500. De hele reactie is de foutenvelop, dus pending wordt er niet naast teruggegeven — ook al komt dat uit lokale records en is het nog steeds bekend. Probeer het opnieuw in plaats van de mailomgeving als leeg te behandelen. Zie Leesfouten.

Params
  • q: String (optional) | niet-hoofdlettergevoelige substringmatch op het primaire adres van de mailbox. Geldt alleen voor mailboxespending is een korte, vaste to-dolijst en wordt nooit gefilterd.
Teruggegeven params
  • mailboxes: Array | actieve mailboxen
    • id: String | de mailbox-GUID — de sleutel voor elk ander endpoint op deze pagina
    • email: String | het primaire adres
    • display_name: String
    • status: String | active of suspended, gelezen uit het lokale record
    • quota_mb: Integer | 0 betekent geen limiet per mailbox; de mailbox blijft begrensd door de opslagpool van het pakket
    • used_mb: Integer | naar boven afgerond op hele megabytes
    • aliases: Array | Array<String>, de adressen na het primaire adres
    • stalwart_id: String | het principal-ID van de mailserver zelf
    • scheduled_deletion_at: DateTime | null op een actieve mailbox
  • pending: Array | mailboxen binnen hun soft-delete-respijtperiode, oudste verwijderdatum eerst
    • id: String | de mailbox-GUID
    • email: String
    • status: String | in dit bakje altijd pending_deletion
    • scheduled_deletion_at: DateTime
    • days_until_deletion: Integer | nooit negatief; null als er geen datum is gezet

Definitief verwijderde mailboxen staan hier niet in

Mailboxen die de mailserver na het verstrijken van hun respijtperiode nog vasthoudt, worden apart bijgehouden en zijn bewust afwezig in deze reactie.

Dit endpoint berekent die kruiscontrole niet eens meer, dus een storing in dat bakje kan deze index niet laten mislukken — en het scheelt twee ronden naar de mailserver per aanroep. De lijst met herstelbare, definitief verwijderde mailboxen staat alleen op GET /purged_mailboxes.

Die scheiding is nu belangrijker, omdat de eigen read van deze index strikt is en hem wel laat mislukken: een bakje dat dit endpoint niet teruggeeft mag nooit de status ervan bepalen.

Fouten
  • 503 mailboxes_unavailable | de live mailboxread kon niet worden uitgevoerd. Het opnieuw proberen waard, en geen lege mailomgeving — zie Leesfouten

Een adres controleren

GET /api/mailspace/:mailspace_id/mailboxes/check

Scope: mailspace:read. Alleen-lezen — er wordt niets gereserveerd of aangemaakt.

Vraagt of een adres vrij is voordat je er een mailbox op probeert aan te maken. De adresnaamruimte van de mailserver is vlak over mailboxen, groepen en mailinglijsten en omvat hun aliassen, dus de lokale tabel kan dit niet zelf beantwoorden: een adres dat alleen als alias van een mailinglijst in gebruik is, leest lokaal als vrij en laat het aanmaken daarna mislukken.

Params
  • username: String (required) | alleen het lokale deel — sales, niet sales@example.com
  • domain: String (optional) | standaard het eigen maildomein van de mailomgeving
Teruggegeven params
  • available: Boolean | true, false, of null — zie de waarschuwing hieronder
  • used_by: String | "mailbox", "group" of "mailing list", of null als het adres vrij is

available: null betekent kon niet worden vastgesteld

Als de mailserver onbereikbaar is, antwoordt het endpoint nog steeds 200, met available en used_by beide null. Dat is niet "bezet" en niet "vrij". Vertak nooit op !available — een null zou als bezet worden gelezen en een volkomen geldige create blokkeren. Vertak op available === false voor bezet, en behandel null als "vraag het opnieuw".

Zelfs een true is indicatief: de naamruimte kan tussen deze aanroep en het aanmaken veranderen, en daarom doet het aanmaken zijn eigen controle.

Fouten
  • 400 invalid_address | username is leeg

Een mailbox bekijken

GET /api/mailspace/:mailspace_id/mailboxes/:id

Scope: mailspace:read. :id is de mailbox-GUID.

De volledige detailpayload. Meerdere JMAP-rondgangen per aanroep — weergavenaam, quota, gebruik, aliassen, lidmaatschappen en de IP-beperking voor inloggen staan allemaal op de mailserver, niet in onze tabel.

Teruggegeven params
  • mailbox: Object
    • alle velden uit de mailboxes-items van Mailboxen opvragen, plus:
    • status: String | hier ook pending_deletion — anders dan het mailboxes-bakje van de lijst leest dit endpoint ook een met soft delete verwijderde mailbox, en dan is scheduled_deletion_at gezet in plaats van null
    • allowed_ips: Array | Array<String>, de adressen en CIDR-ranges die mogen inloggen met het eigen wachtwoord van de mailbox. [] betekent elk adres. App-wachtwoorden hebben hun eigen aparte lijsten
    • groups: Array | Array<String>, groepsadressen waar deze mailbox lid van is
    • lists: Array | Array<String>, mailinglijstadressen waarop deze mailbox is geabonneerd
    • two_factor: Object
      • enabled: Boolean
    • app_passwords: Array | dezelfde objecten die App-wachtwoorden opvragen teruggeeft
    • created_at: DateTime
    • updated_at: DateTime

Elk live veld hier heeft een lege faalwaarde

allowed_ips, groups, lists, app_passwords en aliases komen uit upstream reads die bewust tolerant zijn: als de mailserver niet bereikbaar is, levert elk daarvan een leeg array op en antwoordt dit endpoint nog steeds 200. two_factor.enabled valt op dezelfde manier terug op false, display_name op "", en quota_mb / used_mb op 0.

Een leeg allowed_ips maakt dus geen onderscheid tussen "elk adres mag inloggen" en "de beperking kon niet worden gelezen", en two_factor.enabled: false niet tussen "niet ingeschreven" en "onleesbaar". Hetzelfde geldt voor het mailbox-object dat aanmaken en bijwerken teruggeven. Baseer geen beveiligingsbeslissing — en geen verzoening die verwijdert — op deze velden alleen.

Op Mailboxen opvragen is de annotatie veilig: die rijen worden opgebouwd uit principals die in dezelfde aanroep al zijn opgehaald.

Tweestapsverificatie wordt alleen als vlag gerapporteerd

two_factor.enabled is het hele verhaal. Het gedeelde secret en de otpauth://-URL worden nooit uitgegeven, en inschrijven hoort niet bij deze API — een leesbaar secret zou een gestolen leestoken tot tweede factor maken.

De secrets van app-wachtwoorden zijn hier eveneens afwezig; zie Een app-wachtwoord aanmaken.

Fouten
  • 404 unknown_mailbox | geen mailbox met die GUID in deze mailomgeving

Een mailbox aanmaken

POST /api/mailspace/:mailspace_id/mailboxes

Scope: mailspace:write. Geeft 201 Created terug.

Params
  • username: String (required) | het lokale deel. Wordt met domain gecombineerd tot het adres
  • domain: String (optional) | standaard het eigen maildomein van de mailomgeving
  • password: String (required) | het inlogwachtwoord van de mailbox
  • display_name: String (optional)
  • quota_mb: Integer (optional) | limiet per mailbox in megabytes. 0 (de standaard) betekent geen limiet — de mailbox blijft begrensd door de opslagpool van het pakket. Een waarde groter dan het hele pakket wordt geweigerd
  • aliases: Array (optional) | Array<String> met extra adressen
  • groups: Array (optional) | Array<String> met groepsadressen in deze mailomgeving. Een vreemd adres wordt geweigerd
  • lists: Array (optional) | Array<String> met mailinglijstadressen in deze mailomgeving. Een vreemd adres wordt geweigerd

totp_secret wordt niet geaccepteerd — inschrijven voor tweestapsverificatie hoort niet bij deze API. allowed_ips wordt bij aanmaken ook niet geaccepteerd; zet die met een aansluitende update.

Teruggegeven params (201 Created)
  • mailbox: Object
    • de mailboxes-velden uit Mailboxen opvragen, plus
    • created_at: DateTime
    • updated_at: DateTime

Dit is niet de volledige payload van Een mailbox bekijken: allowed_ips, groups, lists, two_factor en app_passwords zitten er niet in. Lees de mailbox terug als je die nodig hebt.

curl -X POST https://my.cloudpress.com/api/mailspace/$MAILSPACE_ID/mailboxes \
  -H "Authorization: Bearer $CLOUDPRESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username": "sales", "password": "…", "display_name": "Sales", "quota_mb": 2048}'
Fouten
  • 400 username_blank | username ontbreekt of is leeg
  • 400 password_blank | password ontbreekt of is leeg. Wordt na username_blank gecontroleerd, dus een verzoek waarin beide ontbreken antwoordt username_blank
  • 422 create_failed | de mailbox kon niet worden aangemaakt. Eén code dekt meerdere oorzaken, alleen te onderscheiden via het errors-bericht: de mailboxlimiet van het pakket is bereikt, quota_mb is groter dan het pakket, het adres is al in gebruik door een mailbox, groep of mailinglijst in deze mailomgeving, een groups- of lists-item hoort niet bij deze mailomgeving, of de mailserver weigerde het aanmaken

Een half geconfigureerde mailbox blijft bestaan, er is geen rollback

Het mailboxrecord wordt weggeschreven vóórdat de alias-, groeps- en lijstaanroepen draaien. Als een daarvan faalt, bestaat de mailbox nog, met een 422 create_failed die beschrijft wat er misging — bewust, zodat de mailbox zichtbaar en herstelbaar is met een update in plaats van gestrand op de mailserver zonder dat er iets naar verwijst. Lees de mailbox terug na een create_failed voordat je het aanmaken opnieuw probeert.


Een mailbox bijwerken

PATCH /api/mailspace/:mailspace_id/mailboxes/:id

Scope: mailspace:write.

Een echte partiële update: elk veld is optioneel, en een weggelaten veld blijft onaangeroerd. Een veld met een lege waarde meesturen wist het — een leeg aliases-array verwijdert elke alias, een leeg allowed_ips wist de IP-beperking voor inloggen.

Params
  • display_name: String (optional)
  • quota_mb: Integer (optional) | een lege string wordt behandeld als weggelaten, niet als 0. Stuur het getal 0 om de limiet per mailbox te verwijderen
  • status: String (optional) | active of suspended. pending_deletion wordt geweigerd op een mailbox die nog niet op verwijderen wacht — een verwijdering inplannen gaat via DELETE, dat upstream blokkeert en de bewaarklok in één keer start. Opnieuw sturen op een mailbox die al is ingepland, wordt geaccepteerd en verandert niets
  • password: String (optional) | leeg of weggelaten houdt het huidige wachtwoord
  • aliases: Array (optional) | Array<String>. Vervangt de hele lijst
  • groups: Array (optional) | Array<String>. Vervangt de hele lijst. Elk adres moet al in deze mailomgeving bestaan — zie hieronder
  • lists: Array (optional) | Array<String>. Vervangt de hele lijst. Elk adres moet al in deze mailomgeving bestaan — zie hieronder
  • allowed_ips: Array or String (optional) | Array<String>, of één String gescheiden door komma's, puntkomma's of witruimte. Vervangt de hele lijst; maximaal 20 items

Lidmaatschappen worden gecontroleerd voordat er iets wordt weggeschreven

Een groups- of lists-adres dat niet bij deze mailomgeving hoort, wordt geweigerd met 422 update_failed, en er wordt niets weggeschreven — de controle draait vóór elke andere wijziging in het verzoek. Zonder die controle zou een vreemd lijstadres worden opgezocht en gepatcht, en zou een vreemd groepsadres stilletjes niets doen terwijl de aanroep succes meldde.

Diezelfde 422 dekt ook het geval waarin de lidmaatschappen helemaal niet gecontroleerd konden worden (een mislukte upstream read), wat een andere oorzaak is dan een geweigerd adres. Geen van beide is opnieuw te proberen zonder de mailbox eerst terug te lezen.

Een verkeerd opgemaakt allowed_ips-item zou zich voordoen als een onverklaarbare storing

Een IP-beperking die niet op de client past, sluit die credential buiten van webmail en van elk apparaat, en de mailserver vertelt de geweigerde client nooit dat het adres de oorzaak is — JMAP antwoordt een kale 403 en IMAP verbreekt simpelweg de verbinding.

Daarom wordt de lijst geparseerd voordat er iets wordt weggeschreven. Een geweigerde lijst is een 400 die het aanstootgevende item noemt, en er wordt helemaal niets weggeschreven — niet de weergavenaam, niet het wachtwoord, niets. Items worden genormaliseerd en ontdubbeld, en een gemaskeerde range wordt in gemaskeerde vorm opgeslagen: 10.0.0.5/8 wordt opgeslagen als 10.0.0.0/8, en dat is ook wat er daadwerkelijk op past.

Heractiveren via update is een tweede herstelpad

Het doet dezelfde hercontrole op de mailboxlimiet van het pakket als Een mailbox herstellen, en wordt geweigerd met 422 update_failed als het pakket geen ruimte heeft. Gebruik liever het expliciete restore-endpoint — dat is het endpoint dat in de soft-delete-vorm terugrapporteert.

Het zetten van password schrijft een auditregel met de mailbox en de gebruikte credential erin — na de write, en alleen als die is geslaagd.

Teruggegeven params

allowed_ips zit niet in deze reactie, ook niet als het verzoek die heeft gezet. Lees de mailbox terug met Een mailbox bekijken om de genormaliseerde lijst te zien die de mailserver daadwerkelijk heeft opgeslagen.

Fouten
  • 400 invalid_allowed_ips | een item is geen geldig adres of range, of er zijn meer dan 20. Er is niets weggeschreven
  • 404 unknown_mailbox | geen mailbox met die GUID in deze mailomgeving
  • 422 update_failed | de mailserver weigerde de wijziging, een groups/lists-adres hoort niet bij deze mailomgeving of kon niet worden gecontroleerd, status: "pending_deletion" is gevraagd op een mailbox die nog niet was ingepland, quota_mb overschrijdt het pakket, of een heractivering zou de mailboxlimiet van het pakket doorbreken

Een mailbox verwijderen

DELETE /api/mailspace/:mailspace_id/mailboxes/:id

Scope: mailspace:write.

Soft delete. De mailbox wordt direct geblokkeerd op de mailserver — er komt geen mail meer door — en ingepland voor definitieve verwijdering 7 dagen later. Tot dan brengt herstellen hem terug met zijn mail intact.

Idempotent. Een mailbox verwijderen die al is ingepland, meldt succes en schuift de verwijderdatum niet verder op, dus een opnieuw verstuurd verzoek kan een mailbox niet eindeloos in leven houden.

Teruggegeven params
  • mailbox: Object | de soft-delete-status, dezelfde vorm als de pending-items in Mailboxen opvragen
    • id: String
    • email: String
    • status: String
    • scheduled_deletion_at: DateTime
    • days_until_deletion: Integer
Fouten
  • 404 unknown_mailbox | geen mailbox met die GUID in deze mailomgeving
  • 422 delete_failed | de mailserver weigerde de blokkade

Een mailbox herstellen

POST /api/mailspace/:mailspace_id/mailboxes/:id/restore

Scope: mailspace:write.

Heractiveert de mailbox op de mailserver en wist de verwijderdatum. Idempotent op een mailbox die al actief is.

Een downgrade tijdens de respijtperiode kan het herstel blokkeren

De mailboxlimiet van het pakket wordt hier opnieuw gecontroleerd. Zonder dat zou de limiet triviaal te omzeilen zijn: met soft delete terug naar de limiet van een goedkopere tier, downgraden, en daarna binnen de respijtperiode herstellen om permanent boven de limiet van het nieuwe plan te zitten. Een herstel zonder ruimte antwoordt 422 restore_failedresize de mailomgeving omhoog eerst.

Teruggegeven params
  • mailbox: Object | dezelfde vorm als bij Een mailbox verwijderen; scheduled_deletion_at en days_until_deletion zijn null na een geslaagd herstel
Fouten
  • 404 unknown_mailbox | geen mailbox met die GUID in deze mailomgeving
  • 422 restore_failed | de mailboxlimiet van het pakket heeft er geen ruimte voor, of de mailserver weigerde de heractivering

Een mailbox definitief verwijderen

DELETE /api/mailspace/:mailspace_id/mailboxes/:id/force_delete

Scope: mailspace:write.

Lokaal onomkeerbaar, en het vraagt de mailserver om de mail nu te wissen in plaats van de mailbox de rest van zijn respijtperiode herstelbaar te laten.

De mailbox moet al ingepland staan voor verwijdering

Roep eerst DELETE .../mailboxes/:id aan. Een actieve mailbox wordt geweigerd met 409 not_pending_deletion, dus geen enkele losse aanroep kan een werkende mailbox wissen.

Een 200 bewijst niet dat de mail weg is

Het wissen versnellen is best effort. Als de mailserver weigert of niet bereikbaar is, wordt de fout gelogd, wordt de mailbox in plaats daarvan als herstelbaar vastgelegd, en antwoordt dit endpoint nog steeds 200. De mail blijft dan de rest van de bewaartermijn op de server staan en verschijnt in Herstelbare mailboxen opvragen.

Dat terugvalpad is een strikte lezing van de eigen wistaak van de mailserver, dus het kan niet meer stilzwijgend niets vastleggen: als die lezing mislukt, treedt de fout op voordat het lokale record wordt verwijderd, en probeert de volgende opruimronde het opnieuw. Eerder werd er geen herstelbare vermelding weggeschreven, werd het lokale record toch verwijderd, en bleef er een levende mailbox achter die het adres en alle mail vasthield zonder herstelpad.

Die fout heeft zijn eigen status: 503 delete_unavailable, niet 422 delete_failed. Het betekent dat de mailserver het verwijderen van het account wél heeft aangenomen — mail naar het adres is al gestopt — en dat alleen de registratie van wat herstelbaar blijft niet weggeschreven kon worden, dus is onbekend of de mail nog herstelbaar is. De mailbox blijft ingepland voor verwijdering, en opnieuw proberen is veilig.

Beschouw een 200 dus niet als bewijs dat er opslag is vrijgekomen — wat ook betekent dat dit geen betrouwbare manier is om ruimte te maken vóór een downgrade. Controleer de lijst met herstelbare mailboxen als het uitmaakt.

Elke aanroep schrijft een auditregel met de mailbox en de gebruikte credential erin — na de lokale verwijdering, en alleen als die is geslaagd.

Teruggegeven params
  • status: String | "deleted"
  • email: String | het adres waarvan het lokale record is verwijderd

Het mailboxrecord is weg, dus dit rapporteert de verwijdering in plaats van een record.

Fouten
  • 404 unknown_mailbox | geen mailbox met die GUID in deze mailomgeving
  • 409 not_pending_deletion | de mailbox staat niet ingepland voor verwijdering
  • 422 delete_failed | het wissen is niet voltooid — een weigering, of een fout halverwege. Een gewone storing komt hier ook terecht, omdat het verwijderen van het account het eerste is dat kan mislukken. Niet noodzakelijk definitief: probeer het opnieuw
  • 503 delete_unavailable | het verwijderen van het account is wél doorgegaan, maar CloudPress kon niet vaststellen of de mail nog herstelbaar is. De lokale registratie blijft staan, de mailbox staat nog ingepland voor verwijdering, de opruimronde probeert het opnieuw, en opnieuw proberen van jouw kant is veilig. Geen bewijs dat er niets is gebeurd

App-wachtwoorden

Een app-wachtwoord is een losstaande IMAP/SMTP/JMAP-credential voor één mailbox. Het blijft werken nadat het eigen wachtwoord van de mailbox is gewijzigd, en dat maakt het de juiste credential voor een apparaat of een script.

Deze endpoints hebben geen lokaal record: elk ervan praat met de mailserver, dus is het :id-segment het credential-ID van de mailserver (een String), geen GUID.

Een mailbox binnen zijn respijtperiode heeft geen app-wachtwoordoppervlak

Alle vier de endpoints zoeken de mailbox op met uitsluiting van mailboxen die voor verwijdering zijn ingepland, dus een mailbox die je met soft delete hebt verwijderd, antwoordt hier 404 unknown_mailbox — ook al leest Een mailbox bekijken hem nog wel. Herstel hem eerst. Een IMAP-credential aanmaken voor een mailbox die aftelt naar vernietiging is het geval dat dit dichtzet — die credential zou samen met de mailbox weer tot leven komen.

Dezelfde uitsluiting geldt voor mailregels en afwezigheidsberichten.

App-wachtwoorden opvragen

GET /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/app_passwords

Scope: mailspace:read.

Teruggegeven params
  • app_passwords: Array
    • id: String | het credential-ID, gebruikt bij bijwerken en intrekken
    • description: String | null — precies zoals de mailserver hem heeft opgeslagen doorgegeven. description is verplicht als deze API een credential aanmaakt, maar een credential die rechtstreeks op de mailserver is aangemaakt kan er geen hebben, en dan is dit null
    • allowed_ips: Array | Array<String>; [] betekent dat elk adres met deze credential mag authenticeren
    • created_at: DateTime | kan null zijn

Deze lijst is een van de bewust tolerante reads

Als de mailserver niet kan worden gelezen, antwoordt dit endpoint 200 met een leeg array in plaats van een 503 — anders dan de mailboxindex. Dat is bewust en verandert niet: een app-wachtwoord intrekken vereist het id ervan, dus een lege lijst valt hier niet vernietigend te gebruiken. Lees hem dus niet als bewijs dat de mailbox geen credentials heeft. Zie Leesfouten.

created_at is de enige geschiedenis die een app-wachtwoord heeft — de mailserver houdt geen tijdstempel van laatste gebruik bij, dus is er hier niets om een actieve credential van een vergeten credential te onderscheiden behalve de beschrijving. Juist daarom is het de moeite waard een description van null echt af te handelen in plaats van hem weg te denken.

Deze reactie bevat nooit secret; zie hieronder.

Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering

Een app-wachtwoord aanmaken

POST /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/app_passwords

Scope: mailspace:write. Geeft 201 Created terug.

Params
  • description: String (required) | waar de credential voor is. Het is de enige manier om er twee van elkaar te onderscheiden bij het intrekken

Het secret wordt exact één keer teruggegeven, hier

secret verschijnt in deze reactie en nergens anders. De mailserver houdt geen leesbare kopie, dus kunnen noch App-wachtwoorden opvragen noch Een mailbox bekijken het teruggeven. Sla het op zodra je het ontvangt; een verloren secret kan alleen worden ingetrokken en vervangen.

Elk aanmaken schrijft een auditregel met de mailbox en de gebruikte credential erin.

Teruggegeven params (201 Created)
  • app_password: Object
    • id: String | het nieuwe credential-ID
    • description: String | zoals ingestuurd, getrimd
    • allowed_ips: Array | bij aanmaken altijd [] — de nieuwe credential is onbeperkt. Zet die vast met Een app-wachtwoord beperken tot IP-adressen
    • created_at: DateTime | in de aanmaakreactie altijd null; de eigen tijdstempel van de mailserver verschijnt bij een latere read
    • secret: String | de enige keer dat dit wordt uitgegeven
Fouten
  • 400 description_blank | description ontbreekt of is leeg. Er is niets aangemaakt
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 422 app_password_create_failed | de mailserver weigerde het aanmaken

Een app-wachtwoord beperken tot IP-adressen

PATCH /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/app_passwords/:id

Scope: mailspace:write. :id is het credential-ID.

Zet één credential vast op een set adressen. Dit is per credential — het raakt het eigen inlogwachtwoord van de mailbox nooit aan, dus het kan niemand buitensluiten van webmail.

Params
  • allowed_ips: Array or String (verplicht) | Array<String>, of één String gescheiden door komma's, puntkomma's of witruimte. Maximaal 20 items. Stuur een lege waarde om de beperking te wissen

allowed_ips is verplicht, en een lege lijst betekent onbeperkt

Dit endpoint is geen partiële update: allowed_ips is het enige dat het wegschrijft, dus de sleutel weglaten drukt helemaal geen bedoeling uit. Een PATCH zonder die sleutel wordt geweigerd met 400 allowed_ips_missing en schrijft niets weg.

Elke manier om "wissen" uit te drukken werkt nog steeds — [], "", null en allowed_ips[]= verwijderen allemaal de beperking. Precies daar draait het om: een lege lijst wordt bovenstrooms opgeslagen als een lege map, en dat betekent onbeperkt, dus "niet meegestuurd" lezen als "wissen" zou een bewust beperkte credential stilzwijgend losmaken en toch 200 antwoorden.

Stuur de volledige lijst — die vervangt, hij vult niet aan.

Net als bij de mailbox wordt de lijst geparseerd voordat er iets wordt weggeschreven: een verkeerd item is een 400 die het noemt, zonder dat er iets is weggeschreven. Items worden genormaliseerd, en een gemaskeerde range wordt gemaskeerd opgeslagen.

Teruggegeven params
  • app_password: Object
    • id: String
    • allowed_ips: Array | Array<String> — een genormaliseerde echo van wat er is weggeschreven, geen teruglezing van de credential. Hij kan nog steeds afwijken van wat je hebt ingestuurd: een gemaskeerde range wordt gemaskeerd opgeslagen

Alleen die twee velden. description en created_at worden niet teruggegeven.

Fouten
  • 400 allowed_ips_missing | de sleutel allowed_ips ontbrak in het verzoek. Er is niets weggeschreven — stuur een lege waarde om de beperking te wissen
  • 400 invalid_allowed_ips | een item is geen geldig adres of range, of er zijn meer dan 20. Er is niets weggeschreven
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 422 app_password_update_failed | de mailserver weigerde de wijziging. Een onbekend credential-ID komt hier naar boven — er is geen lokale 404 voor

Een app-wachtwoord intrekken

DELETE /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/app_passwords/:id

Scope: mailspace:write.

De credential authenticeert onmiddellijk niet meer. Het eigen wachtwoord van de mailbox en elk ander app-wachtwoord blijven onaangeroerd.

Teruggegeven params
  • status: String | "revoked"
  • id: String | het credential-ID dat is ingetrokken
Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 422 app_password_delete_failed | de mailserver weigerde het intrekken. Een onbekend credential-ID komt hier naar boven — er is geen lokale 404 voor

Mailregels

De filterregels van een mailbox zijn Sieve. Ze draaien van boven naar beneden, dus de volgorde waarin de lijst terugkomt is de evaluatievolgorde, en stop_processing slaat werkelijk alles onder de regel die het zette over — herordenen is een gedragsverandering, geen cosmetica.

Een write op de regels is een herschrijving van het hele script

Een mailbox heeft precies één actief Sieve-script, en elke regel — plus het afwezigheidsbericht — is een blok daarbinnen. Er is geen "werk regel 3 bij"-aanroep op de mailserver, dus elke mutatie hier leest het script, wijzigt de lijst in het geheugen, en compileert en heractiveert het geheel opnieuw.

Twee gevolgen:

  • Elke muterende reactie geeft de hele regellijst terug, niet alleen de regel die je hebt aangeraakt. Dat is geen opvulling: een client die een verouderde lijst vasthoudt en daaruit wegschrijft, verwijdert alles wat hij was vergeten. Lees de lijst opnieuw na elke write.
  • Gelijktijdige writers worden voor je geserialiseerd. Elke muterende actie houdt een row lock op de mailbox vast tijdens de volledige read-modify-write, dus twee clients die regels op dezelfde mailbox wegschrijven, kunnen elkaar niet overschrijven. Writes van afwezigheidsberichten nemen dezelfde lock.

Een script dat buiten CloudPress is geschreven, wordt nooit impliciet overschreven

unmanaged: true betekent dat het actieve script van de mailbox niet door onze regelbouwer is geschreven — met de hand aangepast, of geschreven door een andere mailclient. Eroverheen opslaan zou het eigen script van de klant vernietigen, dus wordt elke write op het script (regels en afwezigheidsbericht) geweigerd met 409 script_unmanaged totdat Een eigen filterscript overnemen expliciet wordt aangeroepen.

Mailregels opvragen meldt de vlag, dus controleer die voordat je wegschrijft in plaats van er via de 409 achter te komen. En let op: de vlag kan tussen je read en je write opduiken — het opslaan leest het script opnieuw, dus een script_unmanaged op een write die je veilig achtte, is verwacht en geen bug.

Een niet-herkende match_type wordt stil omgezet in all

match_type accepteert precies all en any. Alles anders — ANY, or, een typefout — wordt niet geweigerd: het wordt stil vervangen door all, en de write slaagt met een 2xx en zonder fout. Een regel die je bedoelde als "een van deze voorwaarden" wordt zo "elk van deze voorwaarden", wat er meestal op neerkomt dat hij de mail waarvoor hij geschreven is niet meer matcht, en niets vertelt je dat.

In tegenstelling tot een verkeerd voorwaardeveld field of actietype type, die met 400 invalid_rule worden geweigerd, wordt deze niet gevalideerd. Stuur hem in kleine letters, en lees match_type terug uit de reactie.

Regelvocabulaire

Een regel is match_type over een lijst voorwaarden, plus een lijst acties. Meerdere values in één voorwaarde worden met OR gecombineerd, wat match_type ook zegt.

Voorwaardevelden en de comparators die elk daarvan accepteert:

veld comparators opmerkingen
from, to, cc, subject contains, not_contains, is, not_is, starts_with, ends_with, matches
body contains, is
header zoals from hierboven heeft ook header_name nodig
size greater_than, less_than values moeten hele getallen bytes zijn
attachment has_any, has_type has_any heeft geen values nodig

Actietypes: move, copy, forward, mark_read, star, add_label, discard, reject, keep, stop. move, copy, forward, add_label en reject hebben elk een value nodig — een map, een adres, een label of een weigerbericht. Een forward-waarde moet een geldig e-mailadres zijn.

Niet alles wat leesbaar is, is ook schrijfbaar. Deze API schrijft alleen de velden from, to, cc, subject, body en de acties move, forward, mark_read, star, discard. Een regel buiten die subset wordt nog steeds vermeld en draait nog steeds — die komt terug met editable: false, en kan aan- of uitgezet, verplaatst of verwijderd worden, maar niet herschreven. Zo een regel insturen bij aanmaken of bijwerken wordt geweigerd met 422 unsupported_rule.

Regelnamen zijn verplicht en zijn begrensd op 200 tekens.

Mailregels opvragen

GET /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules

Scope: mailspace:read. Kost één scriptfetch plus een blobdownload op de mailserver.

Teruggegeven params
  • mailbox: Object
    • id: String | de mailbox-GUID
    • email: String
  • mail_rules: Array | in evaluatievolgorde
    • id: String | de eigen uuid van de regel, uit de metadata van het script. Regels hebben geen lokaal record
    • name: String | kan leeg zijn bij een regel die elders is geschreven
    • display_name: String | name, of "Untitled rule" als die leeg is — wat een UI zou moeten tonen
    • enabled: Boolean
    • match_type: String | all (elke voorwaarde moet matchen) of any
    • stop_processing: Boolean
    • editable: Boolean | false als de regel Sieve gebruikt die deze API niet schrijft. De regel kan nog wel aan- of uitgezet, verplaatst of verwijderd worden
    • conditions: Array
      • field: String
      • comparator: String
      • values: Array | Array<String>, met OR gecombineerd
      • header_name: String | null tenzij field gelijk is aan header
    • actions: Array
      • type: String
      • value: String | null voor de acties die geen waarde aannemen
  • unmanaged: Boolean | true betekent dat het script buiten CloudPress is geschreven en dat elke write wordt geweigerd totdat het is overgenomen
Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 422 mail_rules_unavailable | het script van de mailbox kon niet worden gelezen

Een mailregel aanmaken

POST /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules

Scope: mailspace:write. Geeft 201 Created terug.

De nieuwe regel wordt achteraan de lijst toegevoegd, dus die evalueert na elke bestaande regel. Er is geen manier om er een op een positie tussen te voegen; maak hem aan en verplaats hem daarna.

Params
  • name: String (required) | maximaal 200 tekens
  • enabled: Boolean (optional) | standaard true
  • match_type: String (optional) | all (standaard) of any. Elke andere waarde wordt stil omgezet in all in plaats van geweigerd — zie de waarschuwing hierboven
  • stop_processing: Boolean (optional) | standaard false
  • conditions: Array (optional) | objecten met field, comparator, values (Array<String>) en header_name. Eén enkele waarde mag als value in plaats van values worden gestuurd — die wordt in zijn geheel genomen en niet op komma's gesplitst
  • actions: Array (optional) | objecten met type en value

Andere keys dan deze worden weggegooid in plaats van opgeslagen. Zie het regelvocabulaire hierboven voor de geaccepteerde waarden van field, comparator en type. Een regel heeft minstens één voorwaarde en minstens één actie nodig.

Teruggegeven params (201 Created)
  • mail_rule: Object | de aangemaakte regel, in de vorm van Mailregels opvragen
  • mail_rules: Array | de hele nieuwe lijst, in evaluatievolgorde
  • unmanaged: Boolean | altijd false na een geslaagde write
Fouten
  • 400 invalid_rule | een field van een voorwaarde of een type van een actie staat niet in het vocabulaire. Wordt in het verzoek opgevangen in plaats van stil weggegooid, wat een typfout in een regel zou veranderen die iets anders matcht
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 409 script_unmanaged | het script is buiten CloudPress geschreven — neem het eerst over
  • 422 invalid_rule | de regel zou compileren naar Sieve die niets matcht: een lege of te lange naam, geen voorwaarden, geen acties, een voorwaarde zonder waarde, een comparator die niet op het veld van toepassing is, een header-voorwaarde zonder header_name, een niet-numerieke size, of een forward naar een verkeerd opgemaakt adres
  • 422 unsupported_rule | de combinatie is door een andere mailclient op te slaan maar hier niet te schrijven — de reactie noemt de ondersteunde velden en acties
  • 422 mail_rules_unavailable | het script van de mailbox kon niet worden gelezen
  • 422 save_failed | het opnieuw gecompileerde script kon niet worden weggeschreven

Een geweigerd aanmaken schrijft niets — het bestaande script blijft precies zoals het was.

Een mailregel bijwerken

PATCH /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules/:rule_id

Scope: mailspace:write. Let op: het segment heet rule_id, niet id.

Herschrijft één regel ter plekke, met behoud van zijn id en zijn positie in de evaluatievolgorde.

PATCH-semantiek met één scherpe kant: elk veld dat je weglaat houdt zijn opgeslagen waarde, maar conditions of actions meesturen vervangt dat hele array. Er is geen samenvoeging per element — de elementen hebben geen ids.

Params
Teruggegeven params
  • mail_rule: Object | de bijgewerkte regel
  • mail_rules: Array | de hele lijst
  • unmanaged: Boolean | false
Fouten
  • De fouten van aanmaken, plus:
  • 404 unknown_rule | geen regel met die id in het script van deze mailbox
  • 409 rule_not_editable | de opgeslagen regel gebruikt Sieve die deze API niet kan herschrijven, dus herschrijven zou hem stil in een andere regel veranderen. Aan- of uitzetten, verplaatsen en verwijderen werken er nog wel op

Een mailregel verwijderen

DELETE /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules/:rule_id

Scope: mailspace:write.

Verwijdert één regel en herschrijft het script met de rest. Werkt op een regel die niet editable is.

Teruggegeven params
  • deleted_rule_id: String
  • mail_rules: Array | de resterende lijst, zodat er geen vervolgread nodig is
  • unmanaged: Boolean | false
Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 404 unknown_rule | geen regel met die id in het script van deze mailbox
  • 409 script_unmanaged | het script is buiten CloudPress geschreven — neem het eerst over
  • 422 mail_rules_unavailable | het script kon niet worden gelezen
  • 422 save_failed | het opnieuw gecompileerde script kon niet worden weggeschreven

Een mailregel aan- of uitzetten

PATCH /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules/:rule_id/toggle

Scope: mailspace:write.

Een uitgezette regel blijft in de metadata van het script staan — hij houdt zijn plek en zijn instellingen — maar levert geen Sieve op. Werkt op een regel die niet editable is: een regel uitzetten raakt niet aan wat hij matcht.

Params
  • enabled: Boolean (optional) | zet de status expliciet

enabled weglaten kantelt de regel, en dat is niet idempotent

Zonder enabled in de body kantelt dit endpoint de huidige status, wat die ook is. Een verzoek dat afbreekt nadat de write is geland en daarna opnieuw wordt verstuurd, kantelt de regel terug. Geautomatiseerde aanroepers moeten enabled altijd expliciet meesturen.

Teruggegeven params
  • mail_rule: Object | de gekantelde regel
  • mail_rules: Array | de hele lijst
  • unmanaged: Boolean | false
Fouten

Een mailregel verplaatsen

PATCH /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules/:rule_id/move

Scope: mailspace:write.

Verplaatst één regel één plek omhoog of omlaag. Regels evalueren van boven naar beneden, dus dit verandert het gedrag. Er is geen manier om een absolute positie te zetten of de hele lijst in één aanroep te herordenen — stuur herhaalde verplaatsingen. Werkt op een regel die niet editable is.

Params
  • direction: String (required) | up of down
Teruggegeven params
  • mail_rule: Object | de verplaatste regel
  • mail_rules: Array | de hele lijst, in zijn nieuwe evaluatievolgorde
  • unmanaged: Boolean | false
Fouten
  • 400 invalid_direction | direction ontbreekt of is niet up of down. Wordt gecontroleerd voordat het script wordt gelezen, dus antwoordt vóór script_unmanaged en unknown_rule
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 404 unknown_rule | geen regel met die id in het script van deze mailbox
  • 409 script_unmanaged | het script is buiten CloudPress geschreven — neem het eerst over
  • 422 invalid_move | de regel stond al bovenaan en werd omhoog verplaatst, of stond al onderaan en werd omlaag verplaatst. Wordt geweigerd in plaats van stil niets te doen
  • 422 mail_rules_unavailable | het script kon niet worden gelezen
  • 422 save_failed | het opnieuw gecompileerde script kon niet worden weggeschreven

Een eigen filterscript overnemen

POST /api/mailspace/:mailspace_id/mailboxes/:mailbox_id/mail_rules/adopt

Scope: mailspace:write. Dit is een collectieroute — er is geen rule_id.

Neemt een filterscript over dat deze API niet heeft geschreven, en vervangt het door de regels die we eruit konden parsen.

Overnemen is destructief en kan niet worden teruggedraaid

Alles in het eigen script van de klant dat ons regelmodel niet kan weergeven, is daarna weg. Precies daarom neemt niets anders op het script ooit impliciet over, en daarom antwoordt elke andere write in plaats daarvan 409 script_unmanaged. Roep eerst Mailregels opvragen aan en laat een mens zien wat er op het punt staat te worden vervangen.

Op een script dat al beheerd wordt, is het een onschuldige no-op-herschrijving, met antwoord 200.

Dit is het enige overname-endpoint. Het afwezigheidsbericht leeft in hetzelfde script, dus hier overnemen is ook wat Een afwezigheidsbericht instellen vrijgeeft.

Teruggegeven params
  • adopted: Boolean | true
  • mail_rules: Array | wat het script nu bevat
  • unmanaged: Boolean | vanaf hier false
Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 422 mail_rules_unavailable | het script kon niet worden gelezen
  • 422 save_failed | het opnieuw gecompileerde script kon niet worden weggeschreven

Er is hier geen script_unmanaged — een niet-beheerd script is het hele doel van dit endpoint.


Afwezigheidsberichten

Eén bericht per mailbox, en het leeft in hetzelfde Sieve-script als de filterregels van de mailbox — niet als een apart object. Alles wat de sectie over regels zegt over herschrijvingen van het hele script, de row lock en script_unmanaged geldt hier dus onveranderd, en de twee oppervlakken delen één overname.

Er is geen POST-route: Een afwezigheidsbericht instellen is een upsert.

Reads en writes gaan op de mailbox-GUID, en het routesegment heet mailbox_id.

Afwezigheidsstatus opvragen

GET /api/mailspace/:mailspace_id/vacation_responses

Scope: mailspace:read.

Eén rij per mailbox in de mailomgeving, gesorteerd op adres. Mailboxen die ingepland staan voor verwijdering worden weggelaten.

Dit endpoint raakt de mailserver nooit aan, en kan verouderd zijn

Het live bericht lezen kost een scriptfetch plus een blobdownload per mailbox, en dat is geen lijstoperatie. Dit antwoordt dus uit een gecachte samenvatting die elke mailbox bijhoudt, die wordt verversd zodra het script van die mailbox via CloudPress wordt gelezen of geschreven. Een mailbox waarvan het script het laatst elders is gewijzigd, is hier verouderd. Lees voor de live status het bericht van de mailbox zelf.

Teruggegeven params
  • vacation_responses: Array
    • mailbox_id: String | de mailbox-GUID
    • email: String
    • synced: Boolean | false betekent dat deze mailbox helemaal geen gecachte samenvatting heeft — zie hieronder
    • configured: Boolean | er bestaat een bericht
    • enabled: Boolean | het staat aan
    • from_date: String | YYYY-MM-DD, of null voor geen begingrens
    • to_date: String | YYYY-MM-DD, of null voor geen eindgrens

Controleer synced voordat je de rij vertrouwt

Bij een mailbox die nog geen gecachte samenvatting heeft, komen configured en enabled terug als false en de datums als null — en dat is byte voor byte hoe een mailbox zonder bericht eruitziet. De twee zijn alleen te onderscheiden via synced. Behandel synced: false als "onbekend", niet als "geen bericht", en lees het bericht van die mailbox zelf om het uit te zoeken.

Let op dat dit endpoint geen unmanaged-vlag meldt. De read per mailbox doet dat wel.

Een afwezigheidsbericht bekijken

GET /api/mailspace/:mailspace_id/vacation_responses/:mailbox_id

Scope: mailspace:read. Live gelezen uit het script van de mailbox.

Teruggegeven params
  • vacation_response: Object
    • mailbox_id: String | de mailbox-GUID
    • email: String
    • configured: Boolean | er bestaat een bericht
    • enabled: Boolean | het staat aan
    • subject: String | null zodra het leeg is — ook als er een bericht bestaat zonder onderwerp
    • text_body: String | null als het niet is gezet
    • html_body: String | null als het niet is gezet. Clients die HTML weergeven, verkiezen dit boven text_body
    • from_date: String | YYYY-MM-DD, of null
    • to_date: String | YYYY-MM-DD, of null
  • unmanaged: Boolean | true betekent dat het script buiten CloudPress is geschreven en dat writes worden geweigerd totdat het is overgenomen

configured en enabled zijn met opzet losse vlaggen: een bericht kan geschreven en gedateerd zijn en toch uit staan, wat geen controle op de aanwezigheid van velden kan onderscheiden van helemaal geen bericht. configured: false met lege velden betekent dat er geen bericht is.

Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 422 mail_rules_unavailable | het script van de mailbox kon niet worden gelezen

Een afwezigheidsbericht instellen

PATCH /api/mailspace/:mailspace_id/vacation_responses/:mailbox_id

Scope: mailspace:write. Een upsert — dezelfde aanroep maakt het bericht aan en werkt het bij.

Elk veld is optioneel. Een veld weglaten houdt zijn opgeslagen waarde; stuur een lege string om er een te wissen. Dat onderscheid doet ertoe: {"enabled": false} zet het bericht uit en laat de tekst ongemoeid, en dat is bijna altijd wat je wil.

Params
  • enabled: Boolean (optional) | of het bericht daadwerkelijk uitgaat. Standaard true voor een mailbox die nog geen bericht heeft
  • subject: String (optional)
  • text_body: String (optional)
  • html_body: String (optional) | stuur "" om geen HTML-versie meer te sturen
  • from_date: String (optional) | YYYY-MM-DD. Het bericht antwoordt alleen binnen dat venster
  • to_date: String (optional) | YYYY-MM-DD

Datums worden strikt gevalideerd, en tekst in woorden wordt geweigerd

Alleen hele dagen. Een ISO 8601-datumtijd wordt geaccepteerd en teruggebracht tot de datum; alles wat geen ISO 8601 is, is een 400 invalid_date in plaats van een gok. Dat voorkomt twee stille fouten: een datum die de compiler helemaal niet kan lezen, wordt weggelaten, waardoor het bericht iedereen, voor altijd zou antwoorden in plaats van gedurende het venster dat je vroeg — en een toegeeflijke parser accepteert vrolijk "next tuesday" en lost dat op naar vandaag, wat erger is, omdat het venster er dan gezet uitziet en fout is.

Een aangezet bericht moet iets te zeggen hebben

Er een aanzetten zonder onderwerp en zonder body wordt geweigerd met 422 vacation_body_required in plaats van opgeslagen als een leeg bericht — de generator zou het blok dan helemaal weglaten en het opslaan zou succes melden terwijl de mailbox niemand antwoordde. Gebruik DELETE om een bericht te verwijderen.

Teruggegeven params
Fouten
  • 400 invalid_date | from_date of to_date is geen datum die het bericht kon eerbiedigen. Er is niets weggeschreven
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 409 script_unmanaged | het script is buiten CloudPress geschreven. De opt-in is het overname-endpoint van de mailregels — er is geen apart overnamepad voor het bericht
  • 422 vacation_body_required | een aangezet bericht zonder onderwerp en zonder body
  • 422 mail_rules_unavailable | het script kon niet worden gelezen
  • 422 save_failed | het opnieuw gecompileerde script kon niet worden weggeschreven

Een afwezigheidsbericht verwijderen

DELETE /api/mailspace/:mailspace_id/vacation_responses/:mailbox_id

Scope: mailspace:write.

Het blok van het bericht verdwijnt uit het script van de mailbox en de filterregels blijven precies zoals ze waren. Idempotent: een bericht verwijderen dat de mailbox niet heeft, is een 200.

Teruggegeven params
Fouten
  • 404 unknown_mailbox | geen zulke mailbox in deze mailomgeving, of hij staat ingepland voor verwijdering
  • 409 script_unmanaged | het script is buiten CloudPress geschreven — neem het eerst over
  • 422 mail_rules_unavailable | het script kon niet worden gelezen
  • 422 save_failed | het opnieuw gecompileerde script kon niet worden weggeschreven

Foutcodes

Alle fouten gebruiken de standaardenvelop {"errors": [...], "code": "..."} die is beschreven in Foutreacties. De enige uitzondering is een onbekende of niet-zichtbare mailspace-GUID, die een kale 404 met een lege body teruggeeft — bewust, zodat een client niet kan aftasten welke mailspace-GUID's er elders op het platform bestaan.

Gedeeld door elk endpoint op deze pagina:

Code Status Wordt gegeven wanneer
stalwart_unavailable 503 de mailserver is niet geconfigureerd
(geen — lege body) 404 de mailspace-GUID is onbekend of niet van jou
not_authorized 403 alleen writes: geen bewerkrecht op de workspace van de mailomgeving
mailspace_suspended 403 reads en writes: de mailomgeving is geblokkeerd
pending_delete 403 alleen writes: de mailomgeving staat ingepland voor verwijdering
not_provisioned 409 de mailomgeving heeft nog geen tenant op de mailserver
unknown_mailbox 404 elk endpoint dat een mailbox noemt

Per endpointgroep:

Code Status Geretourneerd door
invalid_address 400 mailbox check
username_blank 400 mailbox create
password_blank 400 mailbox create
invalid_allowed_ips 400 mailbox update, app-password update
allowed_ips_missing 400 app-password update — de sleutel is helemaal niet meegestuurd
create_failed 422 mailbox create
update_failed 422 mailbox update
delete_failed 422 mailbox delete, mailbox force_delete
delete_unavailable 503 mailbox force_delete — het verwijderen ging door, de registratie van de herstelbaarheid niet
mailboxes_unavailable 503 mailboxen opvragen — de live mailboxread kon niet worden uitgevoerd. Geen lege mailomgeving
restore_failed 422 mailbox restore
not_pending_deletion 409 mailbox force_delete
description_blank 400 app-password create
app_password_create_failed 422 app-password create
app_password_update_failed 422 app-password update
app_password_delete_failed 422 app-password revoke
invalid_rule 400 / 422 mail-rule create, update — 400 bij een onbekend veld of een onbekende actie, 422 bij een regel die niets zou matchen
unsupported_rule 422 mail-rule create, update
rule_not_editable 409 mail-rule update
unknown_rule 404 mail-rule update, delete, toggle, move
invalid_direction 400 mail-rule move
invalid_move 422 mail-rule move
script_unmanaged 409 elke mail-rule write behalve adopt; out-of-office update, delete
mail_rules_unavailable 422 elk mail-rule- en out-of-office-endpoint behalve de out-of-office-lijst
save_failed 422 elke mail-rule- en out-of-office-write
invalid_date 400 out-of-office update
vacation_body_required 422 out-of-office update

Foutmeldingen op deze API zijn altijd Engels, ook als het verzoek een Accept-Language-header meestuurt — vertak op code, niet op de melding.