ALWEO API
Dokumentation Read in English

Utskicks-API

Skicka orderbekräftelser, kvitton och formulärsvar från era egna system. Mejlen signeras med er domän och går ut från samma servrar som er vanliga e-post hos Alweo.

Kom igång

  1. Domänen ska ha e-post hos Alweo, med SPF, DKIM och DMARC på plats. Hälsokollen i panelen visar om allt stämmer.
  2. En administratör skapar en nyckel i Alweo-panelen under E-post → Utskicks-API. Nyckeln är knuten till en domän och visas bara en gång, så spara den direkt.
  3. Lägg nyckeln i ert system, helst som en miljövariabel och aldrig i koden.
  4. Skicka ett första mejl med exemplet nedan.

Bas-adressen är https://alweo.se/api/v1. Allt skickas och tas emot som JSON i UTF-8.

Hela API:t finns också som OpenAPI-fil (3.1) som kan läsas in i Postman, Insomnia eller en kodgenerator.

Autentisering

Skicka nyckeln i rubriken Authorization:

Authorization: Bearer alw_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Nycklar börjar med alw_. Vi sparar bara ett kontrollvärde av nyckeln, inte själva nyckeln. Den kan alltså inte visas igen. En borttappad nyckel tar ni bort i panelen och skapar en ny.

Använd nyckeln bara från en server. Lägg den aldrig i en webbsida eller app där besökare kan läsa den. Den som har nyckeln kan skicka mejl från er domän.

Testnycklar

När ni bygger och provar kopplingen kan ni använda en testnyckel. Den skapar ni på samma ställe i panelen genom att kryssa i Testnyckel. Testnycklar börjar med alw_test_.

{ "id": "6f1c…", "test": true }

Byt till en vanlig nyckel när kopplingen fungerar.

Skicka ett mejl

POST/api/v1/emails
FältTypBeskrivning
from krävssträngAvsändare, antingen order@ertforetag.se eller Webbshoppen <order@ertforetag.se>. Adressen måste ligga på nyckelns domän.
to krävssträng eller listaEn eller flera mottagare.
cc valfristräng eller listaKopia.
bcc valfristräng eller listaDold kopia.
subject krävssträngÄmnesrad, högst 900 tecken.
html html eller textsträngMejlet som HTML.
text html eller textsträngMejlet som vanlig text. Skicka gärna både html och text, det ger bättre leverans.
reply_to valfristrängAdress som svar ska gå till.
headers valfriobjektEgna rubriker, till exempel {"X-Order": "1234"}.
attachments valfrilistaBilagor, se Bilagor.

Högst 50 mottagare totalt i to, cc och bcc. Ska samma mejl till många, skicka ett anrop per mottagare så att ingen ser någon annans adress.

curl https://alweo.se/api/v1/emails \
  -H "Authorization: Bearer $ALWEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Webbshoppen <order@ertforetag.se>",
    "to": ["kund@example.com"],
    "subject": "Tack för din order",
    "html": "<p>Vi har tagit emot din order.</p>",
    "text": "Vi har tagit emot din order."
  }'

Svar

{ "id": "6f1c2a7e-3b4d-4f5a-9c8e-1d2b3c4d5e6f" }

Spara id om ni vill följa leveransen. Om någon mottagare fanns på spärrlistan togs den bort ur utskicket, och svaret visar vilka:

{ "id": "6f1c…", "suppressed": ["gammal@example.com"] }

Svaret 200 betyder att vår mejlserver har tagit emot mejlet för leverans. Om det sedan kommer fram ser ni under Hämta status eller via webhooks.

Bilagor

Varje bilaga är ett objekt med filens innehåll kodat i base64:

FältBeskrivning
filenameFilnamnet mottagaren ser, till exempel faktura-1234.pdf.
contentFilens innehåll i base64.
content_type valfriTill exempel application/pdf.
"attachments": [
  { "filename": "faktura-1234.pdf", "content": "JVBERi0xLjQK…", "content_type": "application/pdf" }
]

Högst 20 bilagor och 10 MB sammanlagt per mejl, räknat på filernas storlek före base64-kodningen. Större filer skickar ni hellre som en länk.

Hämta status

GET/api/v1/emails/{id}

Visar ett mejl som skickats med samma nyckel, och hur leveransen gått för varje mottagare.

{
  "id": "6f1c…",
  "from": "order@ertforetag.se",
  "recipients": 1,
  "subject": "Tack för din order",
  "status": "sent",
  "error": null,
  "created_at": "2026-10-09T05:41:12.000Z",
  "delivery": {
    "kund@example.com": {
      "status": "delivered",
      "detail": "250 2.0.0 OK …",
      "at": "2026-10-09T05:41:14.000Z"
    }
  }
}
VärdeBetyder
status: "sent"Vår server tog emot mejlet för leverans.
status: "failed"Mejlet kunde inte skickas, orsaken står i error.
deliveredMottagarens server tog emot mejlet.
delivery_delayedMottagarens server svarade med ett tillfälligt fel. Vi försöker igen automatiskt.
bouncedMejlet kunde inte levereras. detail visar svaret från mottagarens server.

Leveransstatus uppdateras ungefär varannan minut, så delivery är tomt direkt efter utskicket. Status följs i tre dygn. Ibland tar mottagarens server först emot mejlet och skickar en studs senare. Den studsen kommer som ett vanligt mejl till avsändaradressen och syns inte här.

Webhooks

Med en webhook skickar vi en händelse till er server så fort något händer, i stället för att ni frågar efter status. En administratör lägger till adressen i panelen under E-post → Utskicks-API → Webhooks. Adressen måste börja med https://, och ett företag kan ha högst fem webhooks. När webhooken skapas visas en hemlighet som börjar med whsec_. Den visas bara en gång.

Händelser

TypSkickas närInnehåll i data
email.sentVår server har tagit emot mejlet.email_id, from, to (lista), subject
email.deliveredMottagarens server tog emot mejlet.email_id, to, detail
email.delivery_delayedTillfälligt fel, vi försöker igen.email_id, to, detail
email.bouncedMejlet kunde inte levereras.email_id, to, detail
email.testNi trycker på Skicka testhändelse i panelen.message, webhook_id
email.suppressedAdressen har lagts på spärrlistan efter en permanent studs.email_id, to, reason

Varje händelse är en POST med JSON. För mejl med flera mottagare kommer en händelse per mottagare, utom email.sent.

POST https://er-server.se/alweo-webhook
Content-Type: application/json
User-Agent: Alweo-Webhooks/1
Alweo-Signature: t=1760000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

{
  "type": "email.delivered",
  "created_at": "2026-10-09T05:41:14.000Z",
  "data": {
    "email_id": "6f1c…",
    "to": "kund@example.com",
    "detail": "250 2.0.0 OK …"
  }
}

Skicka en testhändelse

Vid varje webhook i panelen finns knappen Skicka testhändelse. Den skickar direkt en signerad händelse av typen email.test och visar vad er server svarade och hur lång tid det tog. Då vet ni att adressen nås och kan kontrollera att signaturen godkänns.

{ "type": "email.test", "created_at": "…", "data": { "message": "Testhändelse från Alweo. Svara med 2xx.", "webhook_id": "12" } }

Svara och nya försök

Svara med en 2xx-kod inom 10 sekunder. Ett annat svar, eller inget svar alls, räknas som misslyckat. Vi försöker då igen efter 1, 5, 15, 60 och 180 minuter, alltså högst sex försök. Senaste svaret syns vid webhooken i panelen.

Samma händelse kan i sällsynta fall komma två gånger, och ordningen är inte garanterad. Använd email_id, to och type för att känna igen en händelse ni redan tagit hand om.

Kontrollera signaturen

Rubriken Alweo-Signature visar att händelsen kommer från oss och inte har ändrats på vägen. Den har formen t=<tid>,v1=<signatur>, där:

Räkna fram samma värde och jämför. Använd den råa kroppen precis som den kom, inte JSON som tolkats och kodats om. Avvisa gärna händelser där t är mer än fem minuter gammal.

const crypto = require("crypto");
const express = require("express");
const app = express();

app.post("/alweo-webhook", express.raw({ type: "application/json" }), (req, res) => {
  const rubrik = req.get("Alweo-Signature") || "";
  const t = (/t=(\d+)/.exec(rubrik) || [])[1];
  const v1 = (/v1=([0-9a-f]{64})/.exec(rubrik) || [])[1];
  if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.sendStatus(400);

  const vantat = crypto.createHmac("sha256", process.env.ALWEO_WEBHOOK_SECRET)
    .update(t + "." + req.body.toString("utf8")).digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(vantat), Buffer.from(v1))) return res.sendStatus(401);

  const handelse = JSON.parse(req.body);
  console.log(handelse.type, handelse.data);
  res.sendStatus(200);
});

Spärrlistan

När ett mejl studsar permanent, till exempel för att adressen inte finns, läggs adressen på ert företags spärrlista. Det skyddar er domäns rykte, eftersom upprepade utskick till döda adresser får andra mejlservrar att misstro avsändaren.

Gränser och nivåer

GränsVärde
Mottagare per mejl1–50, räknat på to, cc och bcc tillsammans
BilagorHögst 20 stycken och 10 MB sammanlagt
Hela anropetHögst 15 MB JSON
Per nyckel och dygn1 000 mejl, räknat bakåt 24 timmar från anropet
Per månad och företagBeror på nivån och räknas i mottagare per kalendermånad (svensk tid)
NivåMottagare per månadPris
Gratis100 kr i en månad. Provet börjar när första nyckeln skapas.
Start10 0001 788 kr/år exkl. moms
Pro50 0003 588 kr/år exkl. moms

Nivån väljs i panelen under E-post → Utskicks-API. Behöver ni mer än dygnstaket eller Pro, mejla hello@alweo.se. Vi går igenom utskicken innan gränsen höjs.

Felkoder

Ett fel svarar alltid med JSON i samma form:

{ "statusCode": 403, "name": "invalid_from", "message": "Nyckeln får bara skicka från @ertforetag.se" }
KodnameBetyder
401unauthorizedNyckel saknas, är felskriven eller har tagits bort.
402trial_endedProvmånaden är slut. Välj Start eller Pro i panelen.
403invalid_fromAvsändaren ligger inte på nyckelns domän.
404not_foundMejlet finns inte, eller skickades med en annan nyckel.
422validation_errorNågot fält saknas eller är fel. message säger vilket.
422recipients_suppressedAlla mottagare finns på spärrlistan.
429rate_limit_exceededNyckelns dygnstak är nått.
429monthly_quota_exceededMånadstaket för nivån är nått.
500internal_errorNågot gick fel hos oss. Försök igen.
502send_failedMejlservern kunde inte ta emot mejlet. Försök igen om en stund.
503not_configuredUtskick är tillfälligt avstängt.

Fel med kod 4xx försvinner inte av att ni försöker igen, utan anropet måste rättas. Vid 500, 502 och 503 kan ni försöka igen efter en stund, gärna med växande väntetid. Pågående störningar visas på driftstatus.

Tips för bra leverans

Frågor om API:t: hello@alweo.se