Hoppa till innehållet

API och guider

Ett anrop.
Ett id att följa.

Skicka mejl via API. Följ varje försök med mejlets id och ta emot händelser som signerade webhooks.

Be om en inbjudan

Nycklar skapar du i kundappen när du har fått åtkomst.

Kom igång

Skicka ett mejl och följ försöken.

Mejl skickas genom HTTP-API:t. Det finns inget SMTP-gränssnitt.

  1. Skapa en testnyckel.I kundappen, med behörigheten send. Nyckeln visas en gång. Testläget kräver ingen verifierad domän.
  2. Lägg adressen och nyckeln i miljövariabler.Exemplen läser båda därifrån. Lägg aldrig nyckeln i koden.
    Miljövariabler
    export LEMONITE_MAIL_URL=https://api.mail.lemonite.se
    export LEMONITE_MAIL_API_KEY=ms_test_…

  3. Skicka ett testmejl.Svaret är 202 med mejlets id.
    curl · testmejl
    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"
    }'

    JSON · 202
    {
      "id": "01a1cfe9-db7e-70db-821a-4c89abc80b69",
      "status": "queued",
      "recipients": [
        {
          "id": "01a1cfea-0c41-7a2e-9d55-3f0e8b6c2a17",
          "kind": "to",
          "address": "delivered@kund.example",
          "status": "queued"
        }
      ]
    }

  4. Följ mejlets id. Försöken och serverns svar finns i mejlloggen och i GET /v1/emails/{id}.
    curl · GET /v1/emails/{id}
    curl "$LEMONITE_MAIL_URL/v1/emails/01a1cfe9-db7e-70db-821a-4c89abc80b69" \
      -H "Authorization: Bearer $LEMONITE_MAIL_API_KEY"

  5. Gå över till skarpt läge. Verifiera avsändardomänen under Domäner, skapa en skarp nyckel och byt nyckel i miljön. Koden är densamma.

Authorization: Bearer

Nycklar och behörigheter.

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örigheter
BehörighetGer
sendSkicka mejl och kalenderinbjudningar, och läsa ett mejl eller en händelse med dess id.
readLista och läsa mejl, händelser, inkommande mejl och mätvärden. Aldrig innehåll.
contentLäsa innehållet i ett mejl medan det finns kvar, och det råa inkommande mejlet. Ingår aldrig i read.
webhooksHantera 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.
suppressionsLä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.

Testläge och skarpt läge

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.

Lägen
TestlägeSkarpt läge
AvsändardomänValfri adress, ingen domän behövsVerifierad domän
SkickasAldrig. Händelserna simuleras direkt.Till mottagarens server
WebhooksTill adresser i testlägeTill adresser i skarpt läge
Inkommande mejl, klagomål, spärrhändelserNejJa
SpärrlistanSamma listaSamma lista

POST /v1/emails

Skicka ett mejl.

curl · 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

Fält i begäran
FältTypInnehåll
fromsträngAvsä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).
tolista eller strängMottagare. Minst en.
cc, bcclistaKopia 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.
subjectsträngÄmne, en rad, högst 998 tecken.
textsträngMeddelandet som vanlig text. Krävs.
htmlsträngMeddelandet som HTML.
reply_tosträngSvarsadress.
headersobjektHögst 20 huvuden, ett värde på en rad var. Bara X-*, In-Reply-To, References, List-Unsubscribe och List-Unsubscribe-Post.
attachmentslistaBilagor, se nedan.
metadataobjektEgna 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.

Bilagor

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.

Tillåtna bilagor
ÄndelseSkickas somInnehållet ska vara
.pdfapplication/pdfBörjar med %PDF-
.png, .jpg, .jpeg, .gif, .webpimage/png, image/jpeg, image/gif, image/webpFormatets signatur
.txt, .csvtext/plain, text/csv (utf-8)Giltig UTF-8 utan NUL-byte
.icstext/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.

JSON · attachments
{
  "attachments": [
    {
      "filename": "kvitto-1043.pdf",
      "content": "JVBERi0xLjcK…"
    },
    {
      "filename": "logo.png",
      "content": "iVBORw0KGgo…",
      "content_id": "logo",
      "disposition": "inline"
    }
  ]
}

Metadata

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 · metadata
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 igen utan dubbletter

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.

Mottagare på spärrlistan

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.

Gränser per konto

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.

Pausade utskick

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.

Skräppostkontroll

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}

Följ ett mejl.

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.

JSON · GET /v1/emails/{id}
{
  "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
    }
  ]
}

Mottagarens fält
FältInnehåll
statusMottagarens status, se nedan.
attemptsAntal försök hittills, 0 före det första.
last_smtp_responseSenaste svaret: code, enhanced_code, text och source. null före första svaret.
next_attempt_atNär nästa försök görs, medan status är deferred.
on_suppression_listOm adressen står på spärrlistan nu.
complained_atNär mottagaren markerade mejlet som skräppost, annars null.

Status

Status
StatusBetyder
I köMottaget, inget försök än.
VäntarTillfälligt svar. next_attempt_at anger när nästa försök görs.
LevereratMottagarservern tog emot mejlet.
StudsatMottagarservern avvisade mejlet permanent.
MisslyckatInga 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.
Bara för en mottagare: adressen stod på spärrlistan, och inget leveransförsök gjordes.
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.

Omförsök

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.

Vem svarade?

source: remote

Mottagarservern

451 4.7.1 Try again later

Serverns eget svar, ordagrant.

source: engine

Lemonite Mail

Connection refused

Ingen server nåddes, så svaret är vårt. mx_host är då null.

Lista och innehåll

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.

Parametrar
ParameterInnehåll
idExakt ett mejls id.
recipientBörjan av en mottagaradress (anna@) eller exakt en domän (kund.example).
statusEtt mejls status.
created_from, created_toRFC 3339-tid med sekunder och zon, från och med respektive före. Skriv + som %2B.
cursor, limitnext_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

Prova fallen din kod behöver hantera.

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.

Testmottagare
MottagareSvarStatus
delivered@250 2.0.0Levererat
deferred@451 4.7.1, sedan 250 2.0.0Levererat
bounced@550 5.1.1Studsat
failed@451 4.7.1, sedan inga fler försökMisslyckat

Mejl till alla andra adresser levereras. Ett mejl till delivered@, bounced@ och deferred@ blir partially_delivered.

application/problem+json

Fel och gränser.

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.

JSON · 403
{
  "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"
}

JSON · 422
{
  "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'."
    }
  ]
}

Felkoder
StatuscodeNär
400invalid_jsonKroppen är inte den JSON som beskrivs, eller har ett okänt fält.
400invalid_parameterEn parameter är ogiltig, upprepad eller okänd. parameter namnger den.
400invalid_idempotency_keyIdempotency-Key har fel form.
400invalid_pathEn adress i sökvägen har ett . eller ..-led.
401unauthorizedNyckeln saknas, är okänd eller återkallad.
403missing_scope_send, missing_scope_read, missing_scope_content, missing_scope_webhooks, missing_scope_suppressionsNyckeln saknar behörigheten. required_scopes anger vilka som räcker.
403sender_domain_not_verifiedAvsändardomänen är inte verifierad för kontot. domain namnger den.
403sender_domain_lapsedDomänens DNS-poster har saknats längre än fristen. domain namnger den.
403inbound_domain_not_verifiedtrack_replies i skarpt läge utan verifierad inkommande domän för arrangören.
403sending_pausedSkarpa utskick är pausade för kontot. Inget lades i kö. Kontakta supporten.
404not_foundFinns inte för den här nyckeln: annat konto, annat läge eller inget sådant id.
409idempotency_key_reusedSamma Idempotency-Key med en annan kropp.
409calendar_uid_exists, calendar_event_cancelledUID:t finns redan, eller händelsen är avbokad.
409webhook_limit_reached, webhook_disabled, delivery_not_resendableHögst 10 webhookadresser, adressen är avstängd eller leveransen pågår.
409complaint_removal_requires_operatorEn spärr efter klagomål hävs bara av Lemonite.
408request_timeoutKroppen kom inte fram inom 60 sekunder. Skicka igen över en snabbare förbindelse.
410content_purgedInnehållet är raderat. purged_at anger när.
413payload_too_largeKroppen är större än 15 MB.
415unsupported_media_typeKroppen är inte application/json.
422validation_failedEtt fält är ogiltigt. errors namnger varje fält.
422duplicate_recipientSamma adress två gånger i to, cc och bcc.
422recipient_suppressedAlla mottagare står på spärrlistan.
422attachment_type_not_allowed, inline_not_referencedEn bilaga är inte tillåten, eller en inbäddad bild används inte i HTML-texten.
429rate_limitedFör många anrop. Vänta Retry-After sekunder.
429send_limit_reachedMejlet skulle gå över kontots gräns för mottagare per timme eller dygn. Inget lades i kö. Vänta Retry-After sekunder.
500content_unreadableInnehållet finns men kan inte läsas. Det hjälper inte att försöka igen. Kontakta oss.
500internal_errorEtt oväntat fel. Försök igen.

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.

Gränser

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.

Gränser
RäknasGräns
Per API-nyckel600 anrop per minut
Per klientadress, utan giltig nyckel60 anrop per minut
Provhändelse och omsändning av webhooks30 per minut för kontot
POST /v1/emails över 2 MB4 samtidigt per serverinstans, högst 1 per konto. Fler får 429 med Retry-After: 1

SPF / DKIM / DMARC / Return-Path

Verifiera avsändardomänen.

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.

DNS-poster för en avsändardomän
PostTypNamnVärdeKrävs
SPFTXT@v=spf1 include:spf.mail.lemonite.net ~allJa
DKIMCNAMEms1._domainkeyms1.<domänens id>.dkim.mail.lemonite.netJa
DKIMCNAMEms2._domainkeyms2.<domänens id>.dkim.mail.lemonite.netJa
DMARCTXT_dmarcv=DMARC1; p=noneRekommenderas
Return-PathCNAMElm-bouncesbounces.mail.lemonite.netRekommenderas

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.

Har domänen redan en SPF-post?
Lägg till include: i den befintliga posten. En domän kan bara ha en. Två SPF-poster gör båda ogiltiga.
Två DKIM-poster
Domänen signerar med nyckeln bakom den ena. Den andra står redo, så att nyckeln kan bytas utan att du ändrar DNS igen. Båda krävs.
Två DKIM-signaturer
Varje mejl signeras först med domänens egen nyckel. Den signaturen avgör DMARC. Mejlet får också en andra signatur med Lemonites domän, så att klagomål från leverantörer som rapporterar per signerande domän når Lemonite, oavsett avsändare. Den andra kräver ingen DNS-post hos dig.
Return-Path
Rekommenderad: en CNAME från 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.
Saknas
Ingen post hittades. Kontrollera namnet och lägg in posten. Nya poster kan ta en stund att synas.
Skiljer sig
Jämför hittat värde med förväntat. Vissa DNS-leverantörer lägger till domännamnet en gång till.
Om posterna försvinner
Tjänsten kontrollerar verifierade domäner var sjätte timme. Saknas SPF eller DKIM fortsätter sändningen i 48 timmar. Är posterna fortfarande borta efter det avvisas skarpa mejl från domänen med 403 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

Krav från de stora leverantörerna.

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 och vem som uppfyller dem
KravGällerMed Lemonite Mail
SPF eller DKIMAlla avsändareBåda, med din domän.
SPF, DKIM och DMARCMassavsändareSPF 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ändareDKIM signerar med din domän. Med Return-Path stämmer även SPF.
Giltig omvänd DNS och TLSAlla avsändareTjänstens servrar.
Meddelanden enligt RFC 5322Alla avsändareTjänsten bygger mejlet.
Skräppostandel under 0,3 %Alla avsändareDin del: skicka bara mejl mottagaren väntar sig. Följ klagomålsandelen under Mätvärden.
Avregistrering med ett klickMassavsändare, bara marknadsföringGäller inte transaktionsmejl.

Avregistrering

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.

Klagomål från Gmail

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

Händelser till din tjänst.

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.

  1. Verifiera signaturen. Med ett bibliotek för Standard Webhooks (för .NET Svix, för Node.js och Python standardwebhooks), eller som i exemplen nedan. Godta tidsstämplar inom fem minuter. Tolka kroppen först när signaturen stämmer, och tolka exakt de byte som signerades.
  2. Svara med 2xx inom 15 sekunder. Gör det tunga arbetet efteråt. Allt annat än 2xx, även omdirigeringar, är ett misslyckat försök.
  3. Räkna med dubbletter och att ordningen kan variera. Känn igen en händelse på 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.
Huvuden
HuvudInnehåll
webhook-idHändelsens id, evt_ och 32 hexsiffror. Samma vid varje försök och varje omsändning.
webhook-timestampNär just det här försöket signerades, i Unix-sekunder.
webhook-signaturev1,<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-typeapplication/json
user-agentlemonite-mail-webhooks/1

Verifiera

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.

C# · verifiera signaturen
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.

Testvektor
hemlighet          whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw
webhook-id         msg_p5jXN8AQM9LWM0D4loKWxJek
webhook-timestamp  1614265330
kropp              {"test": 2432232314}
webhook-signature  v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=

Nya försök

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.

Byte av hemlighet

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.

Adressen

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.

Webhookanrop
AnropGör
GET /v1/webhooksAdresserna i nyckelns läge.
POST /v1/webhooksLä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}/updateNy url, nya events eller båda.
POST /v1/webhooks/{id}/rotate-secretNy hemlighet, en gång. overlap_hours 0 till 168, 24 som standard.
POST /v1/webhooks/{id}/disable, …/enableStäng av och slå på.
POST /v1/webhooks/{id}/testSkicka en webhook.test nu.
GET /v1/webhooks/{id}/deliveriesLeveranser med varje försök och svaret från din adress, nyast först.
POST /v1/webhooks/{id}/deliveries/{delivery_id}/resendEtt nytt försök nu, med samma webhook-id och kropp.
POST /v1/webhooks/{id}/removeTa bort adressen, dess hemligheter och leveranser.

Händelser

Händelsetyper
TypNär
email.deliveredEn mottagare fick mejlet.
email.deferredEtt försök fick ett tillfälligt svar. Fler försök följer.
email.bouncedMottagarservern avvisade mottagaren permanent, direkt eller senare till Return-Path.
email.failedInga fler försök för mottagaren.
email.suppressedEn mottagare stod på spärrlistan och hoppades över.
email.complainedEn mottagare markerade mejlet som skräppost. Adressen spärras. Bara skarpt läge.
suppression.addedEn adress spärrades: efter en studs eller ett klagomål, av en ägare eller med en nyckel. Bara skarpt läge.
suppression.removedEn spärr hävdes: av en ägare, med en nyckel eller av Lemonite efter ett klagomål. Bara skarpt läge.
inbound.receivedEtt mejl togs emot på en inkommande domän. Innehåller mejlet. Bara skarpt läge.
inbound.rejectedMottagaren 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.replyEn deltagare svarade på en kalenderinbjudan. Innehåller kommentaren. Bara skarpt läge.
webhook.testProvhä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.

email.bounced · JSON
{
  "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

Ta emot mejl.

  1. Lägg till en inkommande domän. Under Inkommande, Domäner i kundappen. Använd en underdomän, till exempel 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.
  2. Lägg in posterna och välj Kontrollera DNS.Domänen är verifierad när båda stämmer i samma kontroll. TXT-posten visar att domänen är din.
  3. Lägg till en webhookadress för inbound.received.I skarpt läge. Alla adresser på domänen tas emot, till exempel svar+8f2c@in.kund.example.
DNS-poster för en inkommande domän
PostTypNamnVärdePrioritet
MXMX@mx.mail.lemonite.net10
VerifieringTXT_lemonite-maillemonite-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.

Vad som tas emot

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.

Händelsen

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.

inbound.received · JSON
{
  "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
    }
  }
}

Stoppade bilagor

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.

Skäl för stoppad bilaga
blockedBilagan är
executableEtt program, efter innehåll eller namn.
scriptEtt skript.
disk_imageEn diskavbild.
office_macroEn Office-fil med makron.
office_legacyEn Office-fil i det äldre formatet, som kan innehålla dolda makron.
archive_uninspectableEtt arkiv som inte är ZIP, eller en ZIP vars fillista inte går att läsa.
archive_contains_blockedEn ZIP som innehåller något av det här, eller ett annat arkiv.
htmlEn webbsida, SVG eller MHT, som en webbläsare skulle köra.
tnefEn winmail.dat från Outlook. Ett mötessvar i den läses, men filerna i den skickas inte vidare.
message_contains_blockedEtt bifogat mejl med en stoppad bilaga, på vilket djup som helst.
message_uninspectableEtt bifogat mejl som inte går att bedöma helt.
too_largeÖver gränsen för avkodad storlek.

Avvisade mejl

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.

Skäl för avvisat mejl
reasonSvarNär
dmarc_policy550 5.7.1Avsändardomänen har DMARC p=reject och mejlet klarade inte kontrollen.
spam550 5.7.1Skräppostfiltret avvisade mejlet.
too_large552 5.3.4Mejlet var större än 15 MB.
inbound.rejected · JSON
{
  "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"
    }
  }
}

Det råa mejlet

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 för inkommande mejl
AnropBehörighetGer
GET /v1/inboundreadMottagna mejl, nyast först, med cursor och limit. Aldrig ämne eller text.
GET /v1/inbound/{id}readEtt mottaget mejl: kuvert, storlek, skräppostbedömning, SPF, DKIM och DMARC, och innehållets status.
GET /v1/inbound/{id}/contentcontentMedan 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-rejectionsreadAvvisade mejl, nyast först, med cursor och limit.
GET /v1/inbound-rejections/{id}readEtt avvisat mejl.
GET /v1/inbound/{id}/rawcontentMejlet som det kom, som message/rfc822. 410 när det är raderat.

POST /v1/calendar/events

Skicka en kalenderinbjudan.

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.

JSON · POST /v1/calendar/events
{
  "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>"
}

JSON · 202
{
  "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 i begäran
FältInnehåll
fromSom för ett mejl, och samma krav på verifierad domän i skarpt läge.
organizeraddress och name. Svaren går hit. Kan inte vara deltagare och ändras aldrig.
attendees1 till 50: address, name och role (required, som standard, eller optional). Samma adress bara en gång.
summaryKrävs. En rad, högst 998 tecken. Också ämnet i varje inbjudan.
description, locationValfria. Beskrivning högst 10 000 tecken, plats en rad och högst 1 000.
start, end, time_zoneKrävs. Lokal tid med sekunder, utan zon, i en tidszon ur IANA-databasen, till exempel Europe/Stockholm.
urlValfri https- eller http-adress.
uidValfri, bara när händelsen skapas: iCalendar-UID, unikt i kontot. Annars <id>@<arrangörens domän>.
track_repliestrue: deltagarnas svar tas emot. Bestäms när händelsen skapas.
attendee_visibilityprivate (standard) eller shared. Bestäms när händelsen skapas.
reset_answersBara vid uppdatering, true som standard: alla svar nollställs.
text, htmlSom 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.

Ändra och avboka

Kalenderanrop
AnropBehörighetGör
POST /v1/calendar/eventssendSkapa händelsen och bjud in varje deltagare.
POST /v1/calendar/events/{id}/updatesendSkicka en ny version till varje deltagare i attendees.
POST /v1/calendar/events/{id}/cancelsendAvboka för alla deltagare.
GET /v1/calendar/events/{id}read eller sendHändelsen med varje deltagares svar.
GET /v1/calendar/eventsreadHändelserna, nyast först. uid, cursor och limit.
Uppdatera
Skicka hela händelsen på nytt med ändringen. Innehållet sparas bara i inbjudningarna. Nya deltagare bjuds in, och den som inte längre finns i attendees får en avbokning. Svaren nollställs om du inte skickar reset_answers: false.
Avboka
Skicka händelsen utan attendees. Avbokningen går till alla deltagare. En avbokad händelse kan inte ändras igen (409 calendar_event_cancelled).
Spärrade deltagare
En deltagare på spärrlistan får ingen inbjudan, och dess email_id är null. Står alla på listan avvisas händelsen med 422 recipient_suppressed.

Svar

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.

verified
Svaret ändrar bara något när det kom från deltagarens egen adress och mottagarens kontroller (DMARC, eller SPF eller DKIM för samma domän) knyter det dit. Annars är det false, och svaret ändrar inget.
stale
Svaret gällde en äldre version av händelsen, eller var äldre än det svar som redan finns. Det ändrar inget.
COUNTER
Ett förslag på ny tid, i proposed. Det ändrar inget. Godta det genom att uppdatera händelsen.
delegated
Deltagaren lämnade över till någon annan, som läggs till som deltagare. Den nya deltagarens svar kommer som vanligt.
calendar.reply · JSON
{
  "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.

Kalender

/v1/suppressions

Spärrlistan.

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.

Varför en adress är spärrad och vem som häver det
reasonSpärrad närHävs av
hard_bounceEtt skarpt mejl studsade permanent på adressen.En ägare, eller en nyckel med suppressions
manualEn ägare eller en nyckel spärrade adressen.En ägare, eller en nyckel med suppressions
complaintMottagaren markerade ett mejl som skräppost.Bara Lemonite, på din begäran
Anrop för spärrlistan
AnropGör
GET /v1/suppressionsSpä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/suppressionsSpärra {"address"}: 201 med spärren, eller 200 med den som redan fanns.
POST /v1/suppressions/{address}/removeHä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.

JSON · spärr
{
  "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
  }
}

Klagomål

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

Följ leveranserna över tid.

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.

Parametrar
ParameterInnehåll
intervalday (standard) eller hour.
time_zoneEn tidszon ur IANA-databasen, UTC som standard. Dygnen börjar vid lokal midnatt.
from, toRFC 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.
domainEn avsändardomän. Alla tal utom webhooks gäller då bara den.
Studsandel
Studsade av levererade och studsade. Stora leverantörer brukar vilja se den under 2 %; över 5 % granskas avsändaren.
Klagomålsandel
Klagomål av levererade. Google och Yahoo kräver under 0,3 % och rekommenderar under 0,1 %. Gmail skickar inga klagomål per mejl, så deras andel syns bara i Googles Postmaster Tools.
Leveranstid
Från anropet till API:t till att mottagarservern tog emot mejlet, för levererade mottagare: median, de långsammaste 5 % och den längsta. Målet är 10 sekunder.
Fick vänta
Andelen mottagare som fick minst ett tillfälligt svar, och de mottagardomäner som oftast bad oss vänta. Över 10 % markeras.
Webhooks
Andelen leveranser till dina webhooks som lyckades, av dem som lyckades eller gavs upp, och tiden från händelsen till det lyckade anropet. Under 95 % markeras. Leveranserna sparas i 30 dagar.

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

Levererat innehåll raderas.

Innehållet är ämne, text, HTML, svarsadress, egna huvuden och bilagor. Det sparas krypterat, bara så länge det behövs för leveransen.

När innehållet raderas
MejletInnehållet
Levererat till allaInnehållet raderas när sista mottagaren har fått mejlet, inom någon minut.
Någon studsade eller misslyckadesInnehållet finns kvar ett dygn för felsökning och raderas sedan.
De enda som inte fick mejlet var spärradeRaderas som vid leverans.
Ännu på vägFinns kvar så länge mejlet kan behöva skickas, högst fem dygn.
Inkommande mejlRaderas en timme efter att dina adresser har tagit emot händelsen.
När innehållet är raderat
Tid, mottagare, status och serversvar finns kvar. 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.
Historiken
Ett mejl med mottagare, händelser och metadata raderas 90 dagar efter sista händelsen, ett inkommande mejl 90 dagar efter att det togs emot, och en kalenderhändelse 90 dagar efter sista aktiviteten. Sedan svarar GET /v1/emails/{id} 404. Webhookleveranser sparas i 30 dagar. Spärrar finns kvar tills de hävs.

Dataskydd

Börja med testläget

Berätta vad du bygger.

Be om en inbjudan