AbsoluteJS

@absolutejs/dispatch-postmark

@absolutejs/dispatch-postmarkv0.1.0betaMessaging

Postmark-backed EmailAdapter for @absolutejs/dispatch. Maps EmailMessage to Postmark's sendEmail params; surfaces the MessageID as DispatchResult.id.

#Installation

BASH
bun add @absolutejs/dispatch-postmark

#Capabilities

Overview

Postmark-backed EmailAdapter for @absolutejs/dispatch.

Docs: absolutejs.com/documentation/dispatch#postmark

API

mapMetadata

By default the adapter:

Extracts metadata.tag (string) into Postmark's Tag field

Show 6 more

(a single-string analytics segment per message)

Maps every OTHER string-valued entry into Postmark's Metadata

(a string→string map)

Filters out non-string values (Postmark Metadata values must be

strings)

Override to customize:

Error mapping

Postmark's response shape:

ErrorCode !== 0 (and not undefined) → adapter throws with

Postmark ErrorCode : <Message>. @absolutejs/dispatch's error path records the exception on the dispatch.email.send span, bumps the failed counter, and emits dispatch.email.failed.

Show 2 more

ErrorCode === 0 (or undefined) → treated as success.

DispatchResult.id = response.MessageID.

Outcomes

What you can build

Build on the supported package contract

Use @absolutejs/dispatch-postmark through its supported public entry points.

Hardening checklist

Production guidance

Make every external boundary explicitPin the deployed @absolutejs/dispatch-postmark version, replace example or memory-backed dependencies with durable implementations, bound external calls, protect credentials, and emit enough evidence to retry or recover safely.

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/dispatch-postmark example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#Usage

Partial snippet

Working example for Usage.

TS
import { ServerClient } from "postmark";
import { createDispatcher } from "@absolutejs/dispatch";
import { createPostmarkAdapter } from "@absolutejs/dispatch-postmark";

const postmark = new ServerClient(process.env.POSTMARK_SERVER_TOKEN!);

const dispatcher = createDispatcher({
  email: createPostmarkAdapter({
    client: postmark,
    defaultFrom: "no-reply@acme.io",
    // Optional — defaults to Postmark's transactional stream.
    // messageStream: 'broadcast',
  }),
});

await dispatcher.email({
  to: "alice@example.com",
  subject: "Welcome to Acme",
  text: "Click here to verify: ...",
  // metadata.tag → Postmark Tag (single-string analytics segment);
  // other string entries → Postmark Metadata (string→string map):
  metadata: { tag: "onboarding", campaign: "welcome-v2" },
});

#API

Partial snippet

Working example for API.

TS
createPostmarkAdapter({
  client,             // Required — your `new ServerClient(serverToken)`
  defaultFrom?,       // Required if your messages don't set `from`
  messageStream?,     // Default: Postmark's transactional stream
  mapMetadata?,       // Customize EmailMessage.metadataPostmark Tag/Metadata
})

#mapMetadata

Partial snippet

By default the adapter:

TS
createPostmarkAdapter({
  client: postmark,
  mapMetadata: (metadata) => ({
    Tag: typeof metadata.flow === "string" ? metadata.flow : "transactional",
    Metadata: { tenant: String(metadata.tenant ?? "unknown") },
  }),
});

#Public entry points

Supported entry points declared by this package manifest.

Package entry point declared in package.json.

@absolutejs/dispatch-postmark@absolutejs/dispatch-postmark/manifest@absolutejs/dispatch-postmark/manifest.json

#Package commands

Scripts declared by this package manifest.

bun run buildrm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/dispatch --external '@absolutejs/dispatch/*' --external @absolutejs/manifest --external @sinclair/typebox --external postmark --external 'postmark/*' && tsc --project tsconfig.build.json && absolute-manifest emit
bun run check:packagebun run format && bun run typecheck && bun run test && bun run verify-package && bun run build && bun run verify-package --artifacts
bun run formatprettier --write "./**/*.{ts,json,md}"
bun run testbun test
bun run typechecktsc --noEmit

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

3 symbols
PostmarkClientLiketypePermalinkSource

Minimal subset of Postmark's ServerClient we use. Declaring it locally keeps postmark a true peer dep — types aren't required at compile time.

TS
type PostmarkClientLike = {
    sendEmail: (params: {
        From: string;
        To: string;
        Subject: string;
        TextBody?: string;
        HtmlBody?: string;
        ReplyTo?: string;
        Cc?: string;
        Bcc?: string;
        Headers?: Array<{
            Name: string;
            Value: string;
        }>;
        Tag?: string;
        Metadata?: Record<string, string>;
        MessageStream?: string;
    }) => Promise<{
        MessageID?: string;
        SubmittedAt?: string;
        To?: string;
        ErrorCode?: number;
        Message?: string;
    }>;
};
Exported from @absolutejs/dispatch-postmark