SendlySendly
Migrate from

Migrate from Postmark

Point the Postmark SDK at Sendly with a request-host override and a Sendly key

Sendly implements Postmark's POST /email and POST /email/batch. Keep the official postmark (Node) SDK — change the request host and the server token.

  • Base URL: https://api.sendly.now/api/compat/postmark
  • Auth: X-Postmark-Server-Token: <sk_...> — Postmark's header auth style; the SDK sets this from the token you pass. Use a Sendly secret key as the token.

Postmark does not publish an official Python SDK. Python senders can use the Node SDK, call the compat endpoint over plain HTTP, or use the Sendly Python SDK.

The two-variable swap

The Postmark Node client takes a requestHost (host plus path, without the scheme) and a useHttps flag, so the dialect prefix hangs off the host:

Before (Postmark)
import * as postmark from "postmark";

const client = new postmark.ServerClient("your-postmark-server-token");

await client.sendEmail({
  From: "you@yourdomain.com",
  To: "customer@example.com",
  Subject: "Hello",
  HtmlBody: "<p>Welcome aboard.</p>",
});
After (Sendly)
import * as postmark from "postmark";

const client = new postmark.ServerClient("sk_your_sendly_key", {
  useHttps: true,
  requestHost: "api.sendly.now/api/compat/postmark",
});

await client.sendEmail({
  From: "you@yourdomain.com",
  To: "customer@example.com",
  Subject: "Hello",
  HtmlBody: "<p>Welcome aboard.</p>",
});

API reference

Postmark's two send operations, with their full request and response schemas:

Supported fields

FieldSupportNotes
FromFullPlain address or "Name <you@domain.com>" form.
To / Cc / BccFullComma-separated recipient lists, as Postmark sends them.
SubjectFull
HtmlBody / TextBodyFullHtmlBody is preferred when both are present. At least one is required.
ReplyToFull
HeadersFull[{ Name, Value }].
AttachmentsFull[{ Name, Content, ContentType, ContentID }].
TagPartialSingle tag, sanitized.
MessageStream, TrackOpens, TrackLinksAcceptedAccepted and ignored.
POST /email/batchFullReturns an array of results, order preserved. Up to 100 messages per request; a longer array is refused with 422 (ErrorCode 300) and nothing is sent.

Success comes back in Postmark's shape: { To, SubmittedAt, MessageID, ErrorCode: 0, Message }.

Not supported (returns a clean Postmark error)

Template sends (sendEmailWithTemplate / TemplateId / TemplateModel) aren't implemented in this phase. Anything Sendly can't map returns Postmark's { ErrorCode, Message } error body with the matching status (for example a bad token is 401 with ErrorCode: 10), so the SDK's own error classes — InvalidAPIKeyError, ApiInputError, and friends — are thrown exactly as they are today.

On this page