Integrate Skickamejl without guessing

This page is written for AI agents, coding assistants, and automation tools that need to add transactional email to a product. Use it as the source of truth for sending email through Skickamejl.se.

API base URL

https://skickamejl.se

Local development usually runs at http://localhost:5121.

Authentication

Send the server API token in X-Api-Key.

MCP clients use Authorization: Bearer <server-api-token>.

Never put this token in browser JavaScript or public client code.

Send endpoint

POST /api/messages

Successful requests return 202 Accepted.

Use broadcast campaigns for marketing or bulk mail

Do not loop over POST /api/messages for newsletters. Use the campaign endpoints so Skickamejl can snapshot recipients, throttle batches, track campaign statistics, and enforce unsubscribe handling.

Flow

  1. Create a list with POST /api/contact-lists.
  2. Import addresses with POST /api/contact-lists/{id}/import.
  3. Create a draft with POST /api/campaigns.
  4. Optionally snapshot recipients with POST /api/campaigns/{id}/prepare.
  5. Start background sending with POST /api/campaigns/{id}/send.
  6. Read progress with GET /api/campaigns/{id} and GET /api/campaigns/{id}/recipients.

Required unsubscribe variable

Broadcast campaign content must include {{unsubscribeUrl}} or a clear unsubscribe link. Skickamejl replaces {{unsubscribeUrl}} with a signed recipient-specific URL at send time.

{
  "name": "Launch campaign",
  "contactListId": "<contactListId>",
  "fromAddress": "hello@example.com",
  "subject": "Product launch",
  "textBody": "Hi {{name}}\n\nUnsubscribe: {{unsubscribeUrl}}",
  "htmlBody": "<p>Hi {{name}}</p><a href=\"{{unsubscribeUrl}}\">Unsubscribe</a>"
}

Do this first

These steps are enough for a clean first integration.

1

Create or select a server

In the Skickamejl UI, create a server. Each server has message streams and one server API token.

2

Use the transactional stream by default

For receipts, login codes, password resets, order updates, and operational mail, use messageStream: "transactional".

3

Send plain addresses only

Use from@example.se, not Name <from@example.se>. Display names belong in your message content or templates, not the API address fields.

4

Provide text or HTML body

At least one of textBody or htmlBody is required. Sending both is recommended.

5

Handle accepted, failed, and suppressed states

A 202 means Skickamejl accepted the message for delivery. Store the returned messageId for support and diagnostics.

Use MCP when the caller is an AI agent

MCP is the recommended path when an AI assistant, coding agent, or automation tool can connect to remote MCP servers. REST is still the right choice for normal backend code and product integrations.

Why MCP exists here

The Skickamejl MCP server exposes email actions as explicit tools, so agents do not have to guess endpoint paths, headers, payload shapes, or retry behavior. Use it to send test transactional emails and inspect email workflows from an agent.

Endpoint
https://skickamejl.se/mcp
Auth
Authorization: Bearer <server-api-token>
Main use case
Connect AI agents to send and inspect transactional emails.

mcp.json

{
  "mcpServers": {
    "skickamejl": {
      "type": "http",
      "url": "https://skickamejl.se/mcp",
      "headers": {
        "Authorization": "Bearer <server-api-token>"
      }
    }
  }
}

Safe first test

Use the Skickamejl MCP server to send a test transactional email to <recipient@example.com> with subject "MCP test" and text body "This was sent through MCP."

Before the first call to a sending tool, ask the human for approval. Sending email is an external action and should not happen silently.

The minimal correct API call

Replace <server-api-token> with the token from the selected server.

curl "https://skickamejl.se/api/messages" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: <server-api-token>" \
  -d '{
    "from": "no-reply@example.se",
    "to": "customer@example.com",
    "subject": "Your receipt",
    "textBody": "Thanks for your purchase.",
    "htmlBody": "<p>Thanks for your purchase.</p>",
    "messageStream": "transactional",
    "tag": "receipt",
    "metadata": {
      "orderId": "12345"
    }
  }'

Request fields

from
Required. Plain email address, max 320 characters.
to
Required. Plain recipient email address, max 320 characters.
subject
Required. Max 200 characters.
textBody
Optional if htmlBody is present. Max 10,000 characters.
htmlBody
Optional if textBody is present. Max 20,000 characters.
replyTo
Optional. Plain email address.
messageStream
Optional. Defaults to transactional. Do not use inbound streams for sending.
tag
Optional. Max 120 characters. Use stable values such as welcome, receipt, or password-reset.
metadata
Optional object with up to 20 string keys. Keys may contain letters, numbers, dots, colons, hyphens, and underscores.

Response shape

{
  "messageId": "msg_...",
  "deliveryId": "...",
  "jobId": "...",
  "serverId": "00000000-0000-0000-0000-000000000000",
  "status": "queued",
  "messageStream": "transactional",
  "queuedAtUtc": "2026-06-25T12:00:00+00:00"
}

Persist messageId. It is the best support reference for later troubleshooting.

Let Home Assistant react to Skickamejl events

Use the Home Assistant integration when a smart home, operations dashboard, or local automation should know that Skickamejl queued, delivered, bounced, or failed a transactional email.

Integration contract

Repository
MRCCollective/home-assistant-skickamejl
Home Assistant event
skickamejl_email_event
Webhook URL source
Copy the copy_to_skickamejl attribute from sensor.skickamejl_webhook_url.
Public URL rule
For hosted Skickamejl.se, use a public HTTPS webhook URL. Home Assistant Cloud/Nabu Casa cloudhooks are preferred when available.

Skickamejl webhook setup

  1. Install the Home Assistant integration through HACS as a custom repository.
  2. Configure Skickamejl in Home Assistant and open the Webhook-URL entity.
  3. Copy copy_to_skickamejl. Do not use a local 192.168.x.x URL for hosted Skickamejl.se.
  4. Paste that URL into the server or stream webhook settings in Skickamejl.
  5. Enable Skickat/köat for send events, and add delivery, bounce, open, click, or subscription events when those automations matter.

Webhook payload fields

{
  "event": "email.sent",
  "eventType": "Queued",
  "templateId": "account-created",
  "templateAlias": "account-created",
  "messageId": "msg_...",
  "deliveryId": "...",
  "recipient": "customer@example.com",
  "deliveryStatus": "Queued"
}

Agents should prefer stable template identifiers, aliases, tags, and metadata when creating Home Assistant automations.

Automation example

alias: React when Skickamejl sends an account email
triggers:
  - trigger: event
    event_type: skickamejl_email_event
conditions:
  - condition: template
    value_template: "{{ trigger.event.data.template_id == 'account-created' }}"
actions:
  - action: persistent_notification.create
    data:
      title: "Skickamejl"
      message: "Account email was sent to {{ trigger.event.data.recipient_address }}."

Use trigger.event.data.template_id, delivery_id, message_id, recipient_address, and status for reliable automation conditions.

How agents should react

Skickamejl uses standard HTTP status codes and a JSON problem response with a code extension when possible.

Status Code Agent action
400 invalid_message_stream, recipient_suppressed, validation errors Fix the request. Do not retry unchanged.
401 missing_api_key, invalid_api_key Ask for a valid server token. Do not invent credentials.
404 unknown_message_stream Use transactional or a stream key that exists on the server.
413 Request body too large Reduce body size below 64 KB.
429 Rate limited Retry with backoff.
502 backend_send_failed Retry later or alert an operator if repeated.

Sender domains and DNS

For production sending, add a sender domain in Skickamejl and follow the DNS settings shown in the UI.

  • DKIM is verified through a TXT record.
  • Return-Path is verified through a CNAME record.
  • DMARC is detected through a TXT record at _dmarc.your-domain.
  • New domains start as pending until DNS verification succeeds.

Rules for AI agents

  • Never expose X-Api-Key in frontend code.
  • Prefer server-side sending from backend code, jobs, or trusted serverless functions.
  • Use stable tags and metadata so humans can debug deliveries later.
  • Validate inputs before sending. Do not retry validation errors.
  • Keep transactional mail separate from marketing mail.
  • Link humans to Swagger when they need the full OpenAPI view.