AtlatestRenderedmarkdown
Readme

sigil-postmark

A Sigil library for the Postmark email API. Send transactional and broadcast email, query bounces, and parse delivery / bounce / complaint / open / click webhooks — all with a single server-token header, no request signing.

Designed to drop in as a replacement for sigil-ses when you'd rather not fight AWS sandbox approval.

Features

  • Single send — plain text + HTML with To / Cc / Bcc / ReplyTo, tagging, metadata, and message streams.
  • Batch send — up to 500 messages per request, one HTTP round trip.
  • Bounce queries — list bounces with filters, fetch by ID, re-activate inactive addresses.
  • Webhook parsing — typed records for bounce, spam-complaint, delivery, open, and click events. Includes both JSON-string and pre-parsed dict input.

Quickstart

(import (postmark api))

(define client
  (postmark-client server-token: (getenv "POSTMARK_SERVER_TOKEN")))

;; Single send
(let ((result (postmark-send client
                "[email protected]"
                "[email protected]"
                "Hello from Sigil"
                text: "Plain-text body."
                html: "<h1>Hello</h1><p>HTML body.</p>"
                tag: "newsletter"
                reply-to: "[email protected]")))
  (display (postmark-email-result-message-id result)))

;; Send to multiple recipients
(postmark-send client
  "[email protected]"
  '("[email protected]" "[email protected]")
  "Issue #42"
  text: "Content…"
  bcc: "[email protected]")

;; Batch send — hand-build each payload
(postmark-send-batch client
  (list
    (build-send-payload "[email protected]" "[email protected]"
      "Subject A" text: "Body A")
    (build-send-payload "[email protected]" "[email protected]"
      "Subject B" text: "Body B")))

;; Query bounces
(postmark-list-bounces client count: 100 type: "HardBounce")

;; Reactivate a bounced address
(postmark-activate-bounce client 12345)

Webhook parsing

Configure a Postmark webhook to POST to your HTTP handler, then:

(import (postmark webhook))

(let ((ev (postmark-parse-webhook json-body)))
  (when ev
    (cond
      ((postmark-hard-bounce-event? ev)
       ;; deactivate the address
       (remove-subscriber (postmark-webhook-event-recipient ev)))
      ((postmark-spam-complaint-event? ev)
       (unsubscribe (postmark-webhook-event-recipient ev)))
      ((postmark-delivery-event? ev)
       (log-delivered (postmark-webhook-event-message-id ev))))))

postmark-webhook-event carries:

  • type'bounce, 'spam-complaint, 'delivery, 'open, 'click
  • message-id — Postmark message ID
  • recipient — affected address
  • details — event-specific dict (bounce type code, user agent, click target, …)
  • raw — the original parsed dict, for any field not exposed above

Environment variables

Consumers typically read a single variable:

  • POSTMARK_SERVER_TOKEN — per-server API token from the Postmark console.

The bundled examples/live-send.sgl script also honours:

  • POSTMARK_FROM — verified sender (default [email protected])
  • POSTMARK_TO — recipient for the integration test

Dependencies

  • sigil-stdlib ^0.13.0
  • sigil-http ^0.13.0
  • sigil-json ^0.13.0

(No sigil-crypto — Postmark does not sign requests.)

Building

sigil deps install
sigil build
sigil test

License

BSD-3-Clause