source: remote
Mottagarservern
451 4.7.1 Try again laterServerns eget svar, ordagrant.
API och guider
Skicka mejl via API. Följ varje försök med mejlets id och ta emot händelser som signerade webhooks.
Nycklar skapar du i kundappen när du har fått åtkomst.
Kom igång
Mejl skickas genom HTTP-API:t. Det finns inget SMTP-gränssnitt.
send. Nyckeln visas en gång. Testläget kräver ingen verifierad domän. export LEMONITE_MAIL_URL=https://api.mail.lemonite.se
export LEMONITE_MAIL_API_KEY=ms_test_…curl "$LEMONITE_MAIL_URL/v1/emails" \
-H "Authorization: Bearer $LEMONITE_MAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@nordverk.example",
"to": "delivered@kund.example",
"subject": "Din inloggningslänk",
"text": "Logga in med länken: https://app.example/logga-in"
}'{
"id": "01a1cfe9-db7e-70db-821a-4c89abc80b69",
"status": "queued",
"recipients": [
{
"id": "01a1cfea-0c41-7a2e-9d55-3f0e8b6c2a17",
"kind": "to",
"address": "delivered@kund.example",
"status": "queued"
}
]
}GET /v1/emails/{id}. curl "$LEMONITE_MAIL_URL/v1/emails/01a1cfe9-db7e-70db-821a-4c89abc80b69" \
-H "Authorization: Bearer $LEMONITE_MAIL_API_KEY"Authorization: Bearer
Varje anrop till /v1 har nyckeln i huvudet (header) Authorization: Bearer ms_live_…. En nyckel börjar med ms_test_ eller ms_live_ följt av 43 tecken. En hemlighetsskanner hittar den med ms_(test|live)_[A-Za-z0-9_-]{43}.
Nyckeln visas en gång, när den skapas. Behörigheterna väljs då och kan inte ändras. Skapa i stället en ny nyckel och återkalla den gamla. En återkallad nyckel får 401 från nästa anrop. Ge varje integration en egen nyckel. Ett anrop med giltig nyckel men utan behörigheten får 403 med koden missing_scope_<behörighet>.
| Behörighet | Ger |
|---|---|
| send | Skicka mejl och kalenderinbjudningar, och läsa ett mejl eller en händelse med dess id. |
| read | Lista och läsa mejl, händelser, inkommande mejl och mätvärden. Aldrig innehåll. |
| content | Läsa innehållet i ett mejl medan det finns kvar, och det råa inkommande mejlet. Ingår aldrig i read. |
| webhooks | Hantera webhookadresserna i nyckelns läge och läsa deras leveranser. En adress får mottagaradresser och serversvar, så ge bara den här behörigheten till en nyckel som lika gärna kunde ha fått read. |
| suppressions | Läsa spärrlistan, spärra en adress och häva en spärr efter studs eller en manuell spärr. Ändringar gäller båda lägena. En skarp nyckel läser listan även med read. |
En nyckel gäller ett läge och ser bara mejl, kalenderhändelser och webhookadresser i det läget. Ett mejl i det andra läget ger 404.
| Testläge | Skarpt läge | |
|---|---|---|
| Avsändardomän | Valfri adress, ingen domän behövs | Verifierad domän |
| Skickas | Aldrig. Händelserna simuleras direkt. | Till mottagarens server |
| Webhooks | Till adresser i testläge | Till adresser i skarpt läge |
| Inkommande mejl, klagomål, spärrhändelser | Nej | Ja |
| Spärrlistan | Samma lista | Samma lista |
POST /v1/emails
curl "$LEMONITE_MAIL_URL/v1/emails" \
-H "Authorization: Bearer $LEMONITE_MAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@nordverk.example",
"to": "delivered@kund.example",
"subject": "Din inloggningslänk",
"text": "Logga in med länken: https://app.example/logga-in"
}'| Fält | Typ | Innehåll |
|---|---|---|
| from | sträng | Avsändare: namn@domän eller Namn <namn@domän>. I skarpt läge en adress på en verifierad domän, och exakt den domänen (inte en underdomän). |
| to | lista eller sträng | Mottagare. Minst en. |
| cc, bcc | lista | Kopia och dold kopia. Högst 50 mottagare i to, cc och bcc tillsammans, och samma adress bara en gång. bcc står aldrig i något huvud. |
| subject | sträng | Ämne, en rad, högst 998 tecken. |
| text | sträng | Meddelandet som vanlig text. Krävs. |
| html | sträng | Meddelandet som HTML. |
| reply_to | sträng | Svarsadress. |
| headers | objekt | Högst 20 huvuden, ett värde på en rad var. Bara X-*, In-Reply-To, References, List-Unsubscribe och List-Unsubscribe-Post. |
| attachments | lista | Bilagor, se nedan. |
| metadata | objekt | Egna nycklar och värden som kommer tillbaka när du läser mejlet och i webhooks, se nedan. |
Kroppen (body) är JSON, högst 15 MB. Okända fält avvisas med 400. Adresser är ASCII med en domän i minst två led. 202 betyder att vi har tagit emot mejlet, inte att det är levererat.
Högst 20 bilagor och 10 MB sammanlagt, avkodat. content är filen i base64. Filens innehåll avgör typen. Ändelsen och content_type, om du anger den, måste stämma med den. Annars svarar API:t 422 attachment_type_not_allowed.
| Ändelse | Skickas som | Innehållet ska vara |
|---|---|---|
| application/pdf | Börjar med %PDF- | |
| .png, .jpg, .jpeg, .gif, .webp | image/png, image/jpeg, image/gif, image/webp | Formatets signatur |
| .txt, .csv | text/plain, text/csv (utf-8) | Giltig UTF-8 utan NUL-byte |
| .ics | text/calendar (utf-8) | Som text, och börjar med BEGIN:VCALENDAR |
Allt annat avvisas: arkiv (även varje fil som är en ZIP), program, skript, diskavbilder, SVG och HTML. Office-filer (.docx, .xlsx) är ZIP-paket och avvisas också. Skicka en PDF i stället. Tjänsten kontrollerar vad en fil är, inte vad den innehåller. En PDF kan ha skript och en CSV formler.
En inbäddad bild har disposition: "inline" och ett content_id, och HTML-texten ska använda den som cid:logo. Annars svarar API:t 422 inline_not_referenced.
{
"attachments": [
{
"filename": "kvitto-1043.pdf",
"content": "JVBERi0xLjcK…"
},
{
"filename": "logo.png",
"content": "iVBORw0KGgo…",
"content_id": "logo",
"disposition": "inline"
}
]
} Med metadata knyter du mejlet till något i ditt eget system, till exempel en order eller en användare. Paren kommer tillbaka i GET /v1/emails/{id}, i listan och i varje webhookhändelse om mejlet, även en studs som kommer flera dagar senare. Mottagaren ser dem aldrig.
curl "$LEMONITE_MAIL_URL/v1/emails" \
-H "Authorization: Bearer $LEMONITE_MAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@nordverk.example",
"to": "delivered@kund.example",
"subject": "Din inloggningslänk",
"text": "Logga in med länken: https://app.example/logga-in",
"metadata": {
"order_id": "1043",
"user_id": "u-77"
}
}' Högst 20 nycklar. En nyckel är 1 till 40 tecken: a–z, A–Z, 0–9, _, - och ., och stora och små bokstäver skiljs åt. Ett värde är en sträng på högst 256 tecken på en rad. Nycklar och värden får vara högst 2 048 byte tillsammans. Annars svarar API:t 422 validation_failed. Utan metadata är fältet {} när du läser mejlet.
Metadata sparas lika länge som mejlets händelser och raderas med dem, 90 dagar efter sista händelsen, inte när innehållet raderas. Alla som kan läsa mejlloggen ser den. Lägg därför ett id där, inte namn, adresser eller annat som pekar ut en person.
Skicka huvudet Idempotency-Key, 1 till 255 synliga ASCII-tecken utan mellanslag, till exempel ditt eget order-id. Samma nyckel med exakt samma kropp ger det första svaret igen, med Idempotent-Replayed: true, och inget nytt mejl. Samma nyckel med en annan kropp ger 409. Nyckeln förbrukas bara av ett godkänt anrop (202), så ett avvisat anrop kan rättas och skickas med samma nyckel. Nyckeln gäller i 24 timmar, per läge.
En mottagare som står på spärrlistan får status suppressed och inget leveransförsök görs till den. Mejlet går till de andra. Står alla mottagare på listan avvisas mejlet med 422 recipient_suppressed och sparas inte.
Varje konto har en gräns för antalet mottagare per timme och per dygn i skarpt läge, som vi bestämmer tillsammans med dig. Den räknas per klocktimme och svenskt dygn. Testläget och mottagare på spärrlistan räknas inte. Ett mejl som skulle gå över en gräns avvisas helt med 429 send_limit_reached. window anger vilken gräns (hour eller day), limit hur hög den är och Retry-After hur många sekunder tills den nollställs.
Vid för många klagomål, studsar eller en ovanligt hög volym pausas kontots skarpa utskick. Nya mejl avvisas då med 403 sending_paused, och mejl som ännu inte lämnat tjänsten hålls kvar tills pausen hävs. Testläget fungerar som vanligt. Kontakta supporten på support@lemonite.se för att häva pausen.
Ett skräppostfilter granskar mejl i skarpt läge innan de skickas. Innehållet hanteras bara i arbetsminnet, och bara resultatet sparas. Ett mejl som bedöms som skräppost skickas inte: mottagarna får status failed med svaret 550 5.7.1 och händelsen email.failed.
GET /v1/emails/{id}
Mejlet har en status, varje mottagare sin egen status och sina försök, och innehållet en egen status. Händelserna står i den ordning de hände. Tider är i UTC. Ett fält utan värde är null, aldrig utelämnat.
{
"id": "01a1cfe9-db7e-70db-821a-4c89abc80b69",
"status": "deferred",
"mode": "live",
"from": "Nordverk <noreply@nordverk.example>",
"recipients": [
{
"id": "01a1cfea-0c41-7a2e-9d55-3f0e8b6c2a17",
"kind": "to",
"address": "anna@kund.example",
"status": "deferred",
"attempts": 1,
"last_smtp_response": {
"code": 451,
"enhanced_code": "4.7.1",
"text": "Try again later",
"source": "remote"
},
"next_attempt_at": "2026-11-12T13:34:34.000000Z",
"on_suppression_list": false,
"complained_at": null
}
],
"recipient_counts": {
"queued": 0,
"deferred": 1,
"delivered": 0,
"bounced": 0,
"failed": 0,
"suppressed": 0
},
"created_at": "2026-11-12T13:19:32.222443Z",
"last_event_at": "2026-11-12T13:19:34.000000Z",
"content": {
"status": "available",
"purge_at": null
},
"metadata": {
"order_id": "1043"
},
"events": [
{
"seq": 1,
"type": "accepted",
"at": "2026-11-12T13:19:32.222443Z",
"recipient_id": null,
"attempt": null,
"mx_host": null,
"smtp_response": null,
"provider": null
},
{
"seq": 2,
"type": "attempt_deferred",
"at": "2026-11-12T13:19:34.000000Z",
"recipient_id": "01a1cfea-0c41-7a2e-9d55-3f0e8b6c2a17",
"attempt": 1,
"mx_host": "mx.kund.example",
"smtp_response": {
"code": 451,
"enhanced_code": "4.7.1",
"text": "Try again later",
"source": "remote"
},
"provider": null
}
]
}| Fält | Innehåll |
|---|---|
| status | Mottagarens status, se nedan. |
| attempts | Antal försök hittills, 0 före det första. |
| last_smtp_response | Senaste svaret: code, enhanced_code, text och source. null före första svaret. |
| next_attempt_at | När nästa försök görs, medan status är deferred. |
| on_suppression_list | Om adressen står på spärrlistan nu. |
| complained_at | När mottagaren markerade mejlet som skräppost, annars null. |
| Status | Betyder |
|---|---|
I köqueued | Mottaget, inget försök än. |
Väntardeferred | Tillfälligt svar. next_attempt_at anger när nästa försök görs. |
Levereratdelivered | Mottagarservern tog emot mejlet. |
Studsatbounced | Mottagarservern avvisade mejlet permanent. |
Misslyckatfailed | Inga fler försök görs: tiden för omförsök har gått ut, eller så kunde inget försök göras. |
suppressed | Bara för en mottagare: adressen stod på spärrlistan, och inget leveransförsök gjordes. |
partially_delivered | Bara för ett mejl: levererat till några av mottagarna, inte alla. |
Levererat betyder att mottagarservern tog emot mejlet. Det säger inget om huruvida mejlet hamnade i inkorgen eller i skräpposten, eller om det har lästs. En slutlig status ändras aldrig, med ett undantag: ett levererat mejl som studsar senare, till domänens Return-Path, blir bounced.
En mottagare som får ett tillfälligt svar, eller vars server inte går att nå, får nya försök med allt längre mellanrum. Efter 3 dygn utan leverans görs inga fler försök: mottagaren får status failed och händelsen email.failed.
source: remote
Mottagarservern
451 4.7.1 Try again laterServerns eget svar, ordagrant.
source: engine
Lemonite Mail
Connection refusedIngen server nåddes, så svaret är vårt. mx_host är då null.
GET /v1/emails kräver behörigheten read och ger {"data": [...], "next_cursor": ...}, nyast först. Skicka next_cursor som cursor tills den är null. Filtren gäller tillsammans. En okänd, upprepad eller ogiltig parameter ger 400.
| Parameter | Innehåll |
|---|---|
| id | Exakt ett mejls id. |
| recipient | Början av en mottagaradress (anna@) eller exakt en domän (kund.example). |
| status | Ett mejls status. |
| created_from, created_to | RFC 3339-tid med sekunder och zon, från och med respektive före. Skriv + som %2B. |
| cursor, limit | next_cursor från förra sidan. 1 till 100 per sida, 25 som standard. |
GET /v1/emails/{id}/content kräver content och ger ämne, text, HTML, svarsadress, huvuden och vilka bilagorna är, aldrig deras innehåll. När innehållet är raderat svarar den 410 med purged_at.
Testläge
Med en testnyckel skickas inget. Det som står före @ i mottagaradressen avgör utfallet, på vilken domän som helst. Händelserna skrivs direkt, så mejlet har sin slutliga status när du läser det. Svaren kommer från mx.simulated.invalid, och en simulerad studs spärrar inte adressen.
| Mottagare | Svar | Status |
|---|---|---|
| delivered@ | 250 2.0.0 | Levererat |
| deferred@ | 451 4.7.1, sedan 250 2.0.0 | Levererat |
| bounced@ | 550 5.1.1 | Studsat |
| failed@ | 451 4.7.1, sedan inga fler försök | Misslyckat |
Mejl till alla andra adresser levereras. Ett mejl till delivered@, bounced@ och deferred@ blir partially_delivered.
application/problem+json
Fel returneras i formatet problem details (RFC 9457). Läs code: den är stabil och upprepar sista ledet i type. title och detail är till för människor och kan ändras. Ett avvisat värde upprepas aldrig i svaret.
{
"type": "/problems/sender_domain_not_verified",
"title": "The sender domain is not verified",
"status": 403,
"code": "sender_domain_not_verified",
"detail": "Add and verify the domain of the from address before sending from it.",
"domain": "nordverk.example"
}{
"type": "/problems/validation_failed",
"title": "The request is not valid",
"status": 422,
"code": "validation_failed",
"detail": "2 fields are not valid.",
"errors": [
{
"field": "subject",
"detail": "Required."
},
{
"field": "attachments[0].filename",
"detail": "Must end in an extension such as '.pdf'."
}
]
}| Status | code | När |
|---|---|---|
| 400 | invalid_json | Kroppen är inte den JSON som beskrivs, eller har ett okänt fält. |
| 400 | invalid_parameter | En parameter är ogiltig, upprepad eller okänd. parameter namnger den. |
| 400 | invalid_idempotency_key | Idempotency-Key har fel form. |
| 400 | invalid_path | En adress i sökvägen har ett . eller ..-led. |
| 401 | unauthorized | Nyckeln saknas, är okänd eller återkallad. |
| 403 | missing_scope_send, missing_scope_read, missing_scope_content, missing_scope_webhooks, missing_scope_suppressions | Nyckeln saknar behörigheten. required_scopes anger vilka som räcker. |
| 403 | sender_domain_not_verified | Avsändardomänen är inte verifierad för kontot. domain namnger den. |
| 403 | sender_domain_lapsed | Domänens DNS-poster har saknats längre än fristen. domain namnger den. |
| 403 | inbound_domain_not_verified | track_replies i skarpt läge utan verifierad inkommande domän för arrangören. |
| 403 | sending_paused | Skarpa utskick är pausade för kontot. Inget lades i kö. Kontakta supporten. |
| 404 | not_found | Finns inte för den här nyckeln: annat konto, annat läge eller inget sådant id. |
| 409 | idempotency_key_reused | Samma Idempotency-Key med en annan kropp. |
| 409 | calendar_uid_exists, calendar_event_cancelled | UID:t finns redan, eller händelsen är avbokad. |
| 409 | webhook_limit_reached, webhook_disabled, delivery_not_resendable | Högst 10 webhookadresser, adressen är avstängd eller leveransen pågår. |
| 409 | complaint_removal_requires_operator | En spärr efter klagomål hävs bara av Lemonite. |
| 408 | request_timeout | Kroppen kom inte fram inom 60 sekunder. Skicka igen över en snabbare förbindelse. |
| 410 | content_purged | Innehållet är raderat. purged_at anger när. |
| 413 | payload_too_large | Kroppen är större än 15 MB. |
| 415 | unsupported_media_type | Kroppen är inte application/json. |
| 422 | validation_failed | Ett fält är ogiltigt. errors namnger varje fält. |
| 422 | duplicate_recipient | Samma adress två gånger i to, cc och bcc. |
| 422 | recipient_suppressed | Alla mottagare står på spärrlistan. |
| 422 | attachment_type_not_allowed, inline_not_referenced | En bilaga är inte tillåten, eller en inbäddad bild används inte i HTML-texten. |
| 429 | rate_limited | För många anrop. Vänta Retry-After sekunder. |
| 429 | send_limit_reached | Mejlet skulle gå över kontots gräns för mottagare per timme eller dygn. Inget lades i kö. Vänta Retry-After sekunder. |
| 500 | content_unreadable | Innehållet finns men kan inte läsas. Det hjälper inte att försöka igen. Kontakta oss. |
| 500 | internal_error | Ett oväntat fel. Försök igen. |
Försök igen efter 429, 500 internal_error och 503, och när anropet inte gav något svar alls: vänta längre för varje gång och skicka samma Idempotency-Key, så blir det inget andra mejl. Andra 4xx-fel går inte över av att du försöker igen. Rätta anropet.
Anrop räknas per fast tidsperiod (minut). Över gränsen är svaret 429 med huvudet Retry-After i sekunder och samma tal i retry_after, innan något annat i anropet prövas. IPv6-klienter räknas per /64.
| Räknas | Gräns |
|---|---|
| Per API-nyckel | 600 anrop per minut |
| Per klientadress, utan giltig nyckel | 60 anrop per minut |
| Provhändelse och omsändning av webhooks | 30 per minut för kontot |
| POST /v1/emails över 2 MB | 4 samtidigt per serverinstans, högst 1 per konto. Fler får 429 med Retry-After: 1 |
SPF / DKIM / DMARC / Return-Path
Skarpa mejl skickas bara från en verifierad domän, och från exakt den: kund.example gäller inte för post.kund.example, och tvärtom. Lägg till domänen under Domäner, lägg in posterna och välj Kontrollera DNS. Domänen är verifierad när SPF och båda DKIM-posterna stämmer i samma kontroll.
| Post | Typ | Namn | Värde | Krävs |
|---|---|---|---|---|
| SPF | TXT | @ | v=spf1 include:spf.mail.lemonite.net ~all | Ja |
| DKIM | CNAME | ms1._domainkey | ms1.<domänens id>.dkim.mail.lemonite.net | Ja |
| DKIM | CNAME | ms2._domainkey | ms2.<domänens id>.dkim.mail.lemonite.net | Ja |
| DMARC | TXT | _dmarc | v=DMARC1; p=none | Rekommenderas |
| Return-Path | CNAME | lm-bounces | bounces.mail.lemonite.net | Rekommenderas |
Värdena ovan visar formen. Sidan för domänen visar de exakta värdena. Kopiera dem därifrån. Namnet står relativt domänen (@ är domänen själv). Ligger avsändardomänen under en större zon hos din DNS-leverantör, använd hela namnet som domänguiden också visar.
include: i den befintliga posten. En domän kan bara ha en. Två SPF-poster gör båda ogiltiga. lm-bounces under domänen till tjänstens studsdomän. När den stämmer får varje mottagare en egen avsändaradress i kuvertet under lm-bounces. och domänen. En studs som kommer senare, efter att mejlet lämnat tjänsten, markerar då mottagaren som studsad och spärrar adressen, och en klagomålsrapport dit spärrar adressen som klagomål. SPF för kuvertet stämmer överens med avsändardomänen, så DMARC godkänns även på SPF. Utan posten är kuvertets avsändare samma adress som from, och sena studsar går till den adressen. sender_domain_lapsed, tills de är tillbaka och domänen har kontrollerats. Return-Path följer samma frist för sig. Gmail, Yahoo, Outlook.com
Google och Yahoo har sedan februari 2024 krav på alla som skickar till deras användare, och hårdare krav på massavsändare. Google räknar den som massavsändare som någon gång har skickat runt 5 000 mejl på ett dygn till Gmail-konton, från samma huvuddomän, och statusen är permanent. Yahoo anger ingen gräns. Microsoft ställer sedan maj 2025 samma krav på SPF, DKIM och DMARC för den som skickar över 5 000 mejl per dygn till Outlook.com. Räkna med att du är massavsändare.
| Krav | Gäller | Med Lemonite Mail |
|---|---|---|
| SPF eller DKIM | Alla avsändare | Båda, med din domän. |
| SPF, DKIM och DMARC | Massavsändare | SPF och DKIM klara vid verifiering. DMARC-posten lägger du in. p=none räcker. |
| From-domänen stämmer med SPF eller DKIM (alignment) | Massavsändare | DKIM signerar med din domän. Med Return-Path stämmer även SPF. |
| Giltig omvänd DNS och TLS | Alla avsändare | Tjänstens servrar. |
| Meddelanden enligt RFC 5322 | Alla avsändare | Tjänsten bygger mejlet. |
| Skräppostandel under 0,3 % | Alla avsändare | Din del: skicka bara mejl mottagaren väntar sig. Följ klagomålsandelen under Mätvärden. |
| Avregistrering med ett klick | Massavsändare, bara marknadsföring | Gäller inte transaktionsmejl. |
Kravet på avregistrering med ett klick gäller marknadsföring och mejl som mottagaren prenumererar på. Google och Yahoo undantar uttryckligen transaktionsmejl, som kvitton, bokningsbekräftelser och lösenordsåterställning. Skickar du ett nyhetsbrev eller en avisering som mottagaren prenumererar på, lägg in List-Unsubscribe med en https-adress och List-Unsubscribe-Post: List-Unsubscribe=One-Click i headers (RFC 8058). Båda ingår i domänens DKIM-signatur. Yahoo kräver att avregistreringen gäller inom två dygn.
Gmail skickar inga klagomål per mejl, så ett klagomål från en Gmail-mottagare ger ingen händelse och ingen spärr. Andelen syns bara samlad i Googles Postmaster Tools. Lägg till din avsändardomän där för att följa den.
Standard Webhooks
Lägg till en HTTPS-adress och välj händelser, under Webhooks i kundappen eller med en nyckel som har behörigheten webhooks. En adress tar emot händelser i sitt eget läge, test eller skarpt. Hemligheten (whsec_…) visas en gång. Högst 10 adresser per konto.
webhook-id. En mottagares slutliga status följs aldrig av en annan, med ett undantag: ett levererat mejl som studsar senare går från delivered till bounced. | Huvud | Innehåll |
|---|---|
| webhook-id | Händelsens id, evt_ och 32 hexsiffror. Samma vid varje försök och varje omsändning. |
| webhook-timestamp | När just det här försöket signerades, i Unix-sekunder. |
| webhook-signature | v1,<base64>: HMAC-SHA256 över {webhook-id}.{webhook-timestamp}.{kroppen}, med de 32 byten efter whsec_ som nyckel. Två, åtskilda av mellanslag, under byte av hemlighet. |
| content-type | application/json |
| user-agent | lemonite-mail-webhooks/1 |
Jämför signaturen i konstant tid, inte med ==, så att svarstiden inte avslöjar hur stor del som stämde. Kroppen ska vara byten som kom, före all tolkning: läs den rå i ditt ramverk.
using System.Security.Cryptography;
using System.Text;
public static class LemoniteMailWebhook
{
/// <summary>Checks a webhook from Lemonite Mail.</summary>
/// <param name="secret">The endpoint's secret, whsec_…</param>
/// <param name="id">The webhook-id header.</param>
/// <param name="timestamp">The webhook-timestamp header.</param>
/// <param name="signatures">The webhook-signature header.</param>
/// <param name="body">The request body exactly as it arrived, before it is parsed.</param>
public static bool IsValid(
string secret, string id, string timestamp, string signatures, byte[] body, DateTimeOffset? now = null)
{
// Unix seconds, no more than five minutes from our clock either way.
var clock = (now ?? DateTimeOffset.UtcNow).ToUnixTimeSeconds();
if (timestamp.Length == 0 || !timestamp.All(char.IsAsciiDigit)
|| !long.TryParse(timestamp, out var seconds)
|| Math.Abs(clock - seconds) > 5 * 60)
{
return false;
}
var key = Convert.FromBase64String(secret.StartsWith("whsec_", StringComparison.Ordinal) ? secret[6..] : secret);
byte[] signed = [.. Encoding.UTF8.GetBytes($"{id}.{timestamp}."), .. body];
var expected = HMACSHA256.HashData(key, signed);
// During a secret rotation there are two signatures, separated by a space.
foreach (var part in signatures.Split(' ', StringSplitOptions.RemoveEmptyEntries))
{
if (!part.StartsWith("v1,", StringComparison.Ordinal))
{
continue;
}
var given = new byte[expected.Length];
// FixedTimeEquals compares in constant time.
if (Convert.TryFromBase64String(part[3..], given, out var length)
&& length == expected.Length
&& CryptographicOperations.FixedTimeEquals(given, expected))
{
return true;
}
}
return false;
}
}Pröva din kod mot testvektorn från Standard Webhooks. Den ska godtas när klockan är tidsstämpeln, och avvisas om ett enda tecken i kroppen ändras.
hemlighet whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw
webhook-id msg_p5jXN8AQM9LWM0D4loKWxJek
webhook-timestamp 1614265330
kropp {"test": 2432232314}
webhook-signature v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE= Tio försök, med väntan 0 s, 10 s, 1 min, 10 min, 1 h, 3 h, 6 h, 12 h, 24 h, 24 h (±10 %): knappt tre dygn från det första till det sista. Sedan är leveransen exhausted. Svarar adressen 410 Gone stängs den av direkt. En adress utan lyckat svar på fem dygn, med misslyckade försök varje dag, stängs av, och ägarna får ett mejl. En avstängd adress får inget. Slå på den igen och skicka om det du behöver. Svarets första 1 KB sparas i leveransloggen. Leveranserna sparas i 30 dagar.
Vid byte signerar både den gamla och den nya hemligheten varje anrop under en överlappning, som standard 24 timmar och högst sju dygn. Lägg in den nya hos din tjänst under överlappningen. Din kod godtar anropet när någon av signaturerna stämmer. Överlappning 0 tar bort den gamla direkt.
https, ett värdnamn eller en publik IP-adress, högst 2048 tecken, utan användarnamn och lösenord. Tjänsten ansluter bara till publika adresser, aldrig till privata nät eller loopback. Ett försök utan tillåten adress misslyckas med destination_not_allowed. Valfri port.
| Anrop | Gör |
|---|---|
| GET /v1/webhooks | Adresserna i nyckelns läge. |
| POST /v1/webhooks | Lägg till: url, events och mode (som standard nyckelns). Svaret har secret, en gång. |
| GET /v1/webhooks/{id} | En adress. |
| POST /v1/webhooks/{id}/update | Ny url, nya events eller båda. |
| POST /v1/webhooks/{id}/rotate-secret | Ny hemlighet, en gång. overlap_hours 0 till 168, 24 som standard. |
| POST /v1/webhooks/{id}/disable, …/enable | Stäng av och slå på. |
| POST /v1/webhooks/{id}/test | Skicka en webhook.test nu. |
| GET /v1/webhooks/{id}/deliveries | Leveranser med varje försök och svaret från din adress, nyast först. |
| POST /v1/webhooks/{id}/deliveries/{delivery_id}/resend | Ett nytt försök nu, med samma webhook-id och kropp. |
| POST /v1/webhooks/{id}/remove | Ta bort adressen, dess hemligheter och leveranser. |
| Typ | När |
|---|---|
| email.delivered | En mottagare fick mejlet. |
| email.deferred | Ett försök fick ett tillfälligt svar. Fler försök följer. |
| email.bounced | Mottagarservern avvisade mottagaren permanent, direkt eller senare till Return-Path. |
| email.failed | Inga fler försök för mottagaren. |
| email.suppressed | En mottagare stod på spärrlistan och hoppades över. |
| email.complained | En mottagare markerade mejlet som skräppost. Adressen spärras. Bara skarpt läge. |
| suppression.added | En adress spärrades: efter en studs eller ett klagomål, av en ägare eller med en nyckel. Bara skarpt läge. |
| suppression.removed | En spärr hävdes: av en ägare, med en nyckel eller av Lemonite efter ett klagomål. Bara skarpt läge. |
| inbound.received | Ett mejl togs emot på en inkommande domän. Innehåller mejlet. Bara skarpt läge. |
| inbound.rejected | Mottagaren avvisade ett mejl till en inkommande domän: DMARC, skräppost eller storlek. Bara kuvert och skäl, en per mottagare. Bara skarpt läge. |
| calendar.reply | En deltagare svarade på en kalenderinbjudan. Innehåller kommentaren. Bara skarpt läge. |
| webhook.test | Provhändelse, skickad på begäran till en adress. |
Hoppa över en typ du inte känner igen, och ett fält i data du inte känner igen. Bara inbound.received och calendar.reply innehåller vad någon har skrivit. Kroppen är högst 64 KB, utom för inbound.received, som kan bli omkring 25 MB.
{
"id": "evt_01a1d0a2c4f37e2b9a6d5c4b3a291807",
"type": "email.bounced",
"timestamp": "2026-11-12T13:19:34.120000Z",
"version": 1,
"data": {
"email_id": "01a1cfe9-db7e-70db-821a-4c89abc80b69",
"mode": "live",
"recipient": {
"id": "01a1cfea-0c41-7a2e-9d55-3f0e8b6c2a17",
"kind": "to",
"address": "anna@kund.example",
"status": "bounced"
},
"email_status": "bounced",
"attempt": 1,
"mx_host": "mx.kund.example",
"smtp_response": {
"code": 550,
"enhanced_code": "5.1.1",
"text": "User unknown",
"source": "remote"
},
"next_attempt_at": null,
"suppressed": true,
"occurred_at": "2026-11-12T13:19:34.000000Z",
"metadata": {
"order_id": "1043"
}
}
}inbound.received
in.kund.example. MX-posten får bara peka på tjänstens mottagare, så en domän vars mejl går till egna brevlådor kan inte användas. inbound.received.I skarpt läge. Alla adresser på domänen tas emot, till exempel svar+8f2c@in.kund.example.| Post | Typ | Namn | Värde | Prioritet |
|---|---|---|---|---|
| MX | MX | @ | mx.mail.lemonite.net | 10 |
| Verifiering | TXT | _lemonite-mail | lemonite-mail-verify=<32 hexsiffror> |
Sidan för domänen visar de exakta värdena. Token i TXT-posten är unik för din domän. Varje mejl kommer till din tjänst som en händelse. Under Inkommande i kundappen syns mottagna och avvisade mejl: kuvert, äkthetskontroll, skräppostfiltrets bedömning och, så länge innehållet finns kvar, huvuden och bilagor. Själva texten visas inte.
Högst 15 MB per mejl och 10 mottagare per mejl. SPF, DKIM, DMARC, ARC och avsändarens omvända DNS kontrolleras och resultatet följer med. Mejl vars avsändardomän har DMARC p=reject och inte klarar kontrollen avvisas, liksom mejl som skräppostfiltret avvisar. Allt annat tas emot, med bedömningen. Ett mejl till flera adresser på dina domäner kommer en gång per adress.
parse_status är ok, partial (en gräns kortade av något, men det som lästes finns med) eller failed (message är då null, och det råa mejlet finns kvar). html är som avsändaren skrev den: sanera den innan du visar den. Bilagor har innehållet i base64. calendar är null utom när mejlet har en kalenderdel, till exempel ett svar på en inbjudan.
{
"id": "evt_01a1d0a2c4f37e2b9a6d5c4b3a291807",
"type": "inbound.received",
"timestamp": "2026-11-12T13:19:34.120000Z",
"version": 1,
"data": {
"inbound_id": "01a1d1f0-7c3b-7a4d-9e5f-0a1b2c3d4e5f",
"inbound_domain_id": "01a1d1f0-0000-7a4d-9e5f-0a1b2c3d4e60",
"received_at": "2026-11-13T09:12:01.000000Z",
"envelope": {
"mail_from": "anna@kund.example",
"rcpt_to": "svar+8f2c@in.nordverk.example",
"client_ip": "203.0.113.7",
"helo": "mail.kund.example"
},
"authentication": {
"spf": "pass",
"dkim": [
{
"result": "pass",
"domain": "kund.example"
}
],
"dmarc": "pass",
"arc": "none",
"iprev": "pass"
},
"spam": {
"status": "scanned",
"score": 1.2,
"required_score": 15,
"action": "no action",
"symbols": [
"DMARC_POLICY_ALLOW"
]
},
"parse_status": "ok",
"message": {
"from": "Anna Svensson <anna@kund.example>",
"to": [
"svar+8f2c@in.nordverk.example"
],
"cc": [],
"reply_to": null,
"subject": "Sv: Ditt ärende 1043",
"date": "2026-11-13T10:11:58+01:00",
"message_id": "<c2f1@kund.example>",
"in_reply_to": "<01a1cfe9@nordverk.example>",
"references": [
"<01a1cfe9@nordverk.example>"
],
"text": "Tack, det löste sig.",
"html": "<p>Tack, det löste sig.</p>",
"attachments": [
{
"filename": "kvitto.pdf",
"content_type": "application/pdf",
"size": 48213,
"content_id": null,
"disposition": "attachment",
"blocked": null,
"content": "JVBERi0xLjcK…"
},
{
"filename": "faktura.exe",
"content_type": "application/octet-stream",
"size": 90112,
"content_id": null,
"disposition": "attachment",
"blocked": "executable",
"content": null
}
]
},
"calendar": null,
"raw": {
"size": 152331,
"available_until": null
}
}
} En bilaga som kan köra kod eller inte går att bedöma skickas inte vidare: den har blocked med skälet och content null, och finns bara kvar i det råa mejlet. Namn, angiven typ och innehåll bedöms, och ett arkiv bedöms efter namnen i det, utan att packas upp. Ingen virussökning görs, så en tillåten bilaga är inte garanterat ofarlig. Hoppa över ett skäl du inte känner igen.
| blocked | Bilagan är |
|---|---|
| executable | Ett program, efter innehåll eller namn. |
| script | Ett skript. |
| disk_image | En diskavbild. |
| office_macro | En Office-fil med makron. |
| office_legacy | En Office-fil i det äldre formatet, som kan innehålla dolda makron. |
| archive_uninspectable | Ett arkiv som inte är ZIP, eller en ZIP vars fillista inte går att läsa. |
| archive_contains_blocked | En ZIP som innehåller något av det här, eller ett annat arkiv. |
| html | En webbsida, SVG eller MHT, som en webbläsare skulle köra. |
| tnef | En winmail.dat från Outlook. Ett mötessvar i den läses, men filerna i den skickas inte vidare. |
| message_contains_blocked | Ett bifogat mejl med en stoppad bilaga, på vilket djup som helst. |
| message_uninspectable | Ett bifogat mejl som inte går att bedöma helt. |
| too_large | Över gränsen för avkodad storlek. |
Ett mejl som mottagaren nekar för gott sparas som uppgifter utan innehåll, ett per mottagare på dina domäner, och kommer som inbound.rejected till dina adresser i skarpt läge. Mejlet togs aldrig emot. Ett tillfälligt nej (4xx) är inget avvisat mejl: avsändarens server försöker igen. Hoppa över ett skäl du inte känner igen.
| reason | Svar | När |
|---|---|---|
| dmarc_policy | 550 5.7.1 | Avsändardomänen har DMARC p=reject och mejlet klarade inte kontrollen. |
| spam | 550 5.7.1 | Skräppostfiltret avvisade mejlet. |
| too_large | 552 5.3.4 | Mejlet var större än 15 MB. |
{
"id": "evt_01a1d0a2c4f37e2b9a6d5c4b3a291807",
"type": "inbound.rejected",
"timestamp": "2026-11-12T13:19:34.120000Z",
"version": 1,
"data": {
"rejection_id": "01a1d1f4-2b3c-7d4e-8f50-6a7b8c9d0e1f",
"inbound_domain_id": "01a1d1f0-0000-7a4d-9e5f-0a1b2c3d4e60",
"rejected_at": "2026-11-13T09:00:00.000000Z",
"envelope": {
"mail_from": "vd@avsandare.example",
"rcpt_to": "svar+42@in.nordverk.example",
"client_ip": "203.0.113.7",
"helo": "mail.avsandare.example"
},
"reason": "spam",
"smtp_response": {
"code": 550,
"enhanced_code": "5.7.1",
"text": "Message refused as spam"
}
}
} Hämta det råa mejlet med en nyckel som har behörigheten content, eller som ägare i kundappen. Det finns kvar i en timme efter att alla dina adresser för inbound.received har svarat 2xx, i en timme efter tolkningen om ingen adress tar emot händelsen, och i ett dygn efter sista leveransen om någon leverans gavs upp. Sedan raderas innehållet, och raw.available_until anger när. Inkommande mejl är skarpa: en testnyckel ser inga.
| Anrop | Behörighet | Ger |
|---|---|---|
| GET /v1/inbound | read | Mottagna mejl, nyast först, med cursor och limit. Aldrig ämne eller text. |
| GET /v1/inbound/{id} | read | Ett mottaget mejl: kuvert, storlek, skräppostbedömning, SPF, DKIM och DMARC, och innehållets status. |
| GET /v1/inbound/{id}/content | content | Medan innehållet finns kvar: avsändare, mottagare, ämne, datum och vilka bilagorna är, även de stoppade. Aldrig text eller bilagornas innehåll. |
| GET /v1/inbound-rejections | read | Avvisade mejl, nyast först, med cursor och limit. |
| GET /v1/inbound-rejections/{id} | read | Ett avvisat mejl. |
| GET /v1/inbound/{id}/raw | content | Mejlet som det kom, som message/rfc822. 410 när det är raderat. |
POST /v1/calendar/events
Varje deltagare får ett eget mejl med svarsknappar i Outlook, Gmail och Apple Kalender. Varje inbjudan är ett vanligt mejl i mejlloggen, med egen status, egna försök och samma lagringstider. Med attendee_visibility: "private", som är standard, ser varje deltagare bara sig själv och arrangören. Välj "shared" för att visa alla, som i ett vanligt möte.
{
"from": "Nordverk <kalender@cal.nordverk.example>",
"organizer": {
"address": "kalender@cal.nordverk.example",
"name": "Nordverk"
},
"attendees": [
{
"address": "anna@kund.example",
"name": "Anna Svensson",
"role": "required"
},
{
"address": "bo@kund.example",
"role": "optional"
}
],
"summary": "Årsmöte",
"description": "Dagordning i mejlet.",
"location": "Storgatan 1, Uppsala",
"start": "2027-03-14T18:00:00",
"end": "2027-03-14T20:00:00",
"time_zone": "Europe/Stockholm",
"url": "https://nordverk.example/moten/42",
"track_replies": true,
"attendee_visibility": "private",
"text": "Välkommen till årsmötet.",
"html": "<p>Välkommen till årsmötet.</p>"
}{
"id": "01a1d2b7-0c3e-7a4d-9e5f-0a1b2c3d4e5f",
"uid": "01a1d2b7-0c3e-7a4d-9e5f-0a1b2c3d4e5f@cal.nordverk.example",
"mode": "live",
"sequence": 0,
"status": "confirmed",
"organizer": "kalender@cal.nordverk.example",
"track_replies": true,
"attendee_visibility": "private",
"created_at": "2026-11-12T14:00:00.000000Z",
"updated_at": "2026-11-12T14:00:00.000000Z",
"attendees": [
{
"address": "anna@kund.example",
"role": "required",
"answer": "needs_action",
"answered_at": null,
"delegated_from": null,
"delegated_to": null,
"email_id": "01a1d2b8-1d4f-7b5e-8f60-1b2c3d4e5f60"
},
{
"address": "bo@kund.example",
"role": "optional",
"answer": "needs_action",
"answered_at": null,
"delegated_from": null,
"delegated_to": null,
"email_id": "01a1d2b9-2e50-7c6f-9071-2c3d4e5f6071"
}
]
}| Fält | Innehåll |
|---|---|
| from | Som för ett mejl, och samma krav på verifierad domän i skarpt läge. |
| organizer | address och name. Svaren går hit. Kan inte vara deltagare och ändras aldrig. |
| attendees | 1 till 50: address, name och role (required, som standard, eller optional). Samma adress bara en gång. |
| summary | Krävs. En rad, högst 998 tecken. Också ämnet i varje inbjudan. |
| description, location | Valfria. Beskrivning högst 10 000 tecken, plats en rad och högst 1 000. |
| start, end, time_zone | Krävs. Lokal tid med sekunder, utan zon, i en tidszon ur IANA-databasen, till exempel Europe/Stockholm. |
| url | Valfri https- eller http-adress. |
| uid | Valfri, bara när händelsen skapas: iCalendar-UID, unikt i kontot. Annars <id>@<arrangörens domän>. |
| track_replies | true: deltagarnas svar tas emot. Bestäms när händelsen skapas. |
| attendee_visibility | private (standard) eller shared. Bestäms när händelsen skapas. |
| reset_answers | Bara vid uppdatering, true som standard: alla svar nollställs. |
| text, html | Som för ett mejl. Outlook visar HTML-texten som händelsens beskrivning. |
Inga cc, bcc, headers eller bilagor: varje inbjudan går bara till sin deltagare. Okända fält ger 400, allt annat fel 422 med fältet. Idempotency-Key fungerar som för ett mejl.
| Anrop | Behörighet | Gör |
|---|---|---|
| POST /v1/calendar/events | send | Skapa händelsen och bjud in varje deltagare. |
| POST /v1/calendar/events/{id}/update | send | Skicka en ny version till varje deltagare i attendees. |
| POST /v1/calendar/events/{id}/cancel | send | Avboka för alla deltagare. |
| GET /v1/calendar/events/{id} | read eller send | Händelsen med varje deltagares svar. |
| GET /v1/calendar/events | read | Händelserna, nyast först. uid, cursor och limit. |
attendees får en avbokning. Svaren nollställs om du inte skickar reset_answers: false. attendees. Avbokningen går till alla deltagare. En avbokad händelse kan inte ändras igen (409 calendar_event_cancelled). email_id är null. Står alla på listan avvisas händelsen med 422 recipient_suppressed. Med track_replies: true kommer svaren till arrangörens adress och tas emot som inkommande mejl. Arrangörens domän ska därför vara en verifierad inkommande domän i skarpt läge, annars 403 inbound_domain_not_verified. Varje svar som hör till en händelse kommer som calendar.reply till dina adresser i skarpt läge, också svar från Outlook i formatet winmail.dat, och deltagarens svar syns på händelsen.
proposed. Det ändrar inget. Godta det genom att uppdatera händelsen.{
"id": "evt_01a1d0a2c4e64b7f8a9b0c1d2e3f4a5b",
"type": "calendar.reply",
"timestamp": "2026-11-12T14:10:02.000000Z",
"version": 1,
"data": {
"attendee": {
"address": "anna@kund.example",
"answer": "accepted",
"answered_at": "2026-11-12T14:10:00.000000Z",
"delegated_from": null,
"delegated_to": null
},
"event": {
"id": "01a1d2b7-0c3e-7a4d-9e5f-0a1b2c3d4e5f",
"uid": "01a1d2b7-0c3e-7a4d-9e5f-0a1b2c3d4e5f@cal.nordverk.example",
"sequence": 0,
"status": "confirmed"
},
"reply": {
"method": "REPLY",
"attendee": "anna@kund.example",
"answer": "accepted",
"sequence": 0,
"dtstamp": "2026-11-12T14:10:00.000000Z",
"comment": null,
"delegated_to": null,
"proposed": null,
"stale": false,
"verified": true,
"matched_by": "attendee",
"source": "icalendar"
},
"inbound_id": "01a1d1f0-7c3b-7a4d-9e5f-0a1b2c3d4e5f"
}
}Händelsens uppgifter sparas i 90 dagar efter senaste aktiviteten. Vad händelsen handlar om, tider och namn inräknade, finns bara i inbjudningarnas krypterade innehåll och raderas med det.
/v1/suppressions
Kontot har en spärrlista, gemensam för båda lägena. En spärrad mottagare hoppas över och får status suppressed. Står alla mottagare i ett mejl på listan avvisas det med 422. Stora och små bokstäver i adresser räknas som samma. Anropen kräver behörigheten suppressions. En skarp nyckel läser listan även med read.
Kommer du från en annan leverantör importerar Lemonite din befintliga spärrlista när du börjar. Det finns inget anrop för att importera en hel lista.
| reason | Spärrad när | Hävs av |
|---|---|---|
| hard_bounce | Ett skarpt mejl studsade permanent på adressen. | En ägare, eller en nyckel med suppressions |
| manual | En ägare eller en nyckel spärrade adressen. | En ägare, eller en nyckel med suppressions |
| complaint | Mottagaren markerade ett mejl som skräppost. | Bara Lemonite, på din begäran |
| Anrop | Gör |
|---|---|
| GET /v1/suppressions | Spärrarna, nyast först. Filter: address, reason, created_from, created_to. Bläddra med cursor och limit. |
| GET /v1/suppressions/{address} | En spärr, eller 404 om adressen inte är spärrad. |
| POST /v1/suppressions | Spärra {"address"}: 201 med spärren, eller 200 med den som redan fanns. |
| POST /v1/suppressions/{address}/remove | Häv spärren: 204. 409 complaint_removal_requires_operator för ett klagomål. |
{address} i sökvägen kodas som ett led, som med encodeURIComponent. En hävd spärr syns inte längre någonstans, och nya mejl till adressen skickas som vanligt igen.
{
"id": "01a1d0e2-7c3b-7a4d-9e5f-0a1b2c3d4e5f",
"address": "anna@kund.example",
"reason": "hard_bounce",
"created_at": "2026-11-12T13:19:34.000000Z",
"source": {
"email_id": "01a1cfe9-db7e-70db-821a-4c89abc80b69",
"recipient_id": "01a1cfea-0c41-7a2e-9d55-3f0e8b6c2a17",
"provider": null
},
"created_by": {
"kind": "system",
"id": null
}
} När en mottagare markerar ett mejl som skräppost skickar vissa leverantörer en rapport. Lemonite tar emot den, antingen via leverantörens klagomålsflöde eller till domänens Return-Path, och godtar den bara när den pekar ut en mottagare på ett sätt som bara tjänsten kan ha skapat. Mottagaren får händelsen complained i historiken och complained_at, adressen spärras som complaint, och dina webhooks får email.complained och suppression.added. Mejlet är fortfarande levererat. Ett klagomål räknas en gång per mottagare.
Microsoft (Outlook.com, Hotmail) och Yahoo (även AOL) skickar rapporter per mejl. Gmail gör det inte: ett klagomål från en Gmail-mottagare ger ingen händelse och ingen spärr, och andelen syns bara i Googles Postmaster Tools.
En spärr efter klagomål hävs bara av Lemonite, med en skriftlig motivering, när du ber om det. Mottagaren har sagt att den inte vill ha mejlen, så be om ett nytt samtycke först.
GET /v1/metrics
Mätvärdena räknas fram ur leveranshistoriken, per dag eller timme, för ett läge och en eller alla avsändardomäner. Inget innehåll används. En period räknar mottagarna av de mejl som togs emot under den, så siffrorna för en period kan ändras medan dess mejl fortfarande är på väg. I API:t kräver de behörigheten read och gäller nyckelns läge.
| Parameter | Innehåll |
|---|---|
| interval | day (standard) eller hour. |
| time_zone | En tidszon ur IANA-databasen, UTC som standard. Dygnen börjar vid lokal midnatt. |
| from, to | RFC 3339-tid. Som standard de senaste 30 dygnen, eller de senaste 48 timmarna med interval=hour. Högst 90 dygn bakåt, och högst 7 dygn med interval=hour. |
| domain | En avsändardomän. Alla tal utom webhooks gäller då bara den. |
Det som passerar en gräns över hela perioden visas först i vyn Mätvärden, och i API-svaret under deviations, med gränserna i thresholds. Historiken sparas i 90 dagar.
Innehåll och historik
Innehållet är ämne, text, HTML, svarsadress, egna huvuden och bilagor. Det sparas krypterat, bara så länge det behövs för leveransen.
| Mejlet | Innehållet |
|---|---|
| Levererat till alla | Innehållet raderas när sista mottagaren har fått mejlet, inom någon minut. |
| Någon studsade eller misslyckades | Innehållet finns kvar ett dygn för felsökning och raderas sedan. |
| De enda som inte fick mejlet var spärrade | Raderas som vid leverans. |
| Ännu på väg | Finns kvar så länge mejlet kan behöva skickas, högst fem dygn. |
| Inkommande mejl | Raderas en timme efter att dina adresser har tagit emot händelsen. |
content.status är purged och GET …/content svarar 410. Visa innehåll bara när statusen är available. För ett levererat mejl är den det nästan aldrig. GET /v1/emails/{id} 404. Webhookleveranser sparas i 30 dagar. Spärrar finns kvar tills de hävs. Börja med testläget