# Postmark> Postmark is a reliable transactional and bulk email service that helps developers deliver and track application emails. It provides REST APIs, SMTP support, webhooks, and comprehensive email templates to replace traditional SMTP with a scalable, developer-friendly solution. ## Quick Start To use Postmark for sending emails in your application: 1. Create a Postmark account and verify your sending domain or email address 2. Get your Server API Token from your Postmark server settings 3. Use the REST API or SMTP to send emails 4. Maximum email size is 10 MB (including attachments) 5. Maximum 50 recipients per email (To, CC, BCC combined) ### Authentication All API requests require authentication using the `X-Postmark-Server-Token` header with your Server API Token: ``` X-Postmark-Server-Token: your-server-token-here ``` For testing without actually sending emails, use `POSTMARK_API_TEST` as your token. ## API Reference - [TypeScript transactional email recipe](https://postmarkapp.com/developer/integration/official-libraries#typescript): Install, shared client, template send, batch handling, webhook verification, and repair guide — complete TypeScript path from setup to production - [Send a receipt with templates](https://postmarkapp.com/developer/api/templates-api#send-a-receipt-with-templates): Task-first TypeScript examples for receipts, welcome emails, and other structured transactional sends using `TemplateAlias` and `TemplateModel` - [Webhook verification guide](https://postmarkapp.com/developer/webhooks/webhooks-overview#protecting-your-webhook): Node/TypeScript raw-body HMAC-SHA256 signature verification, event parsing, Express route setup, and idempotency pattern - [Batch send with partial-failure handling](https://postmarkapp.com/developer/user-guide/send-email-with-api/batch-emails): TypeScript `Promise.allSettled` batch example with per-recipient `MessageID` and error reporting - [Send a single email](https://postmarkapp.com/developer/api/email-api#send-a-single-email): POST to `/email` endpoint - [Send batch emails](https://postmarkapp.com/developer/api/email-api#send-batch-emails): POST to `/email/batch` endpoint - [Send with templates](https://postmarkapp.com/developer/api/templates-api#send-email-with-template): POST to `/email/withTemplate` endpoint - [Send batch with templates](https://postmarkapp.com/developer/api/templates-api#send-batch-with-templates): POST to `/email/batchWithTemplates` endpoint - [Send bulk emails](https://postmarkapp.com/developer/api/bulk-email): POST to `/email/bulk` endpoint for broadcast streams - [Template management](https://postmarkapp.com/developer/api/templates-api): Create, edit, list templates via API - [Bounce API](https://postmarkapp.com/developer/api/bounce-api): Manage bounced emails and reactivate addresses - [Message tracking](https://postmarkapp.com/developer/api/messages-api): Search and retrieve message details - [Stats API](https://postmarkapp.com/developer/api/stats-api): Get delivery, open, and click statistics - [Webhooks](https://postmarkapp.com/developer/webhooks/webhooks-overview): Configure real-time event notifications - [Server management](https://postmarkapp.com/developer/api/servers-api): Create and configure servers - [Domain management](https://postmarkapp.com/developer/api/domains-api): Verify domains and configure DKIM/SPF ## Core Concepts ### Message Streams Postmark separates emails into two types of Message Streams: - **Transactional**: One-to-one emails triggered by user actions (welcome emails, password resets, order confirmations) - **Broadcast**: Bulk emails for newsletters, announcements, marketing campaigns Specify the stream using the `MessageStream` field in your API calls. Most API endpoints default to "outbound" (transactional) stream. ### Key Limitations - **Email Address**: Must be verified before sending - **Message Size**: 10 MB total including attachments - **Recipients**: Maximum 50 total (To, Cc, Bcc combined) - **Content Size**: TextBody and HtmlBody up to 5 MB each - **Batch Sending**: 500 messages per call, 50 MB total payload - **Attachments**: Specific file types allowed (security restriction) - **Tags**: One tag per message, maximum 1000 characters ### Server Organization Postmark uses servers to isolate different applications or environments: - Each server has its own API token - Separate tracking and statistics per server - Independent settings for opens/clicks tracking - Isolated sender signatures and domains ### Message Components Every email can include: - **From**: Sender address (must be verified) - **To/Cc/Bcc**: Recipients (comma-separated for multiple) - **Subject**: Email subject line - **TextBody/HtmlBody**: Message content (plain text and/or HTML) - **MessageStream**: Target stream (transactional or broadcast) - **Tag**: Category for statistics (optional) - **Metadata**: Key-value pairs for internal tracking (optional) - **Headers**: Custom email headers (optional) - **Attachments**: Files and inline images (optional) - **TrackOpens/TrackLinks**: Enable tracking (optional) ## Sending Emails ### Single Email API Send individual transactional emails via HTTP POST to the `/email` endpoint. Full guide: [Send email with API](https://postmarkapp.com/developer/user-guide/send-email-with-api) **Key Features:** - Support for HTML, plain text, or multipart messages - Name formatting: `"John Doe "` - Custom headers and metadata support - Inline image embedding with ContentID - Maximum 50 recipients total (To, Cc, Bcc combined) - Tag emails for detailed statistics (one tag per message, max 1000 chars) - Override sender name while keeping verified email address **Message Format:** ```json { "From": "sender@example.com", "To": "receiver@example.com", "Cc": "copied@example.com", "Bcc": "blind-copied@example.com", "Subject": "Test", "Tag": "Invitation", "HtmlBody": "Hello ", "TextBody": "Hello", "ReplyTo": "reply@example.com", "Metadata": { "color": "blue", "customer-id": "12345" }, "Headers": [ {"Name": "CUSTOM-HEADER", "Value": "value"} ], "TrackOpens": true, "TrackLinks": "HtmlOnly", "MessageStream": "outbound", "Attachments": [ { "Name": "document.pdf", "Content": "base64-encoded-content", "ContentType": "application/pdf" }, { "Name": "image.jpg", "ContentID": "cid:image.jpg", "Content": "base64-encoded-image", "ContentType": "image/jpeg" } ] } ``` **Response Format:** ```json { "ErrorCode": 0, "Message": "OK", "MessageID": "b7bc2f4a-e38e-4336-af7d-e6c392c2f817", "SubmittedAt": "2010-11-26T12:01:05.1794748-05:00", "To": "receiver@example.com" } ``` Use the `MessageID` for tracking bounces via webhooks or the bounce API. ### Batch Email API Send up to 500 emails in a single API call to `/email/batch`. Ideal for high-volume transactional sends with better performance than individual calls. **Batch Limitations:** - Maximum 500 messages per API call - Maximum 50 MB total payload size (including attachments) - Each message independently validated and sent - Mixed success/failure responses possible **Batch Format:** ```json [ { "From": "sender@example.com", "To": "receiver1@example.com", "Subject": "Welcome!", "TextBody": "Welcome to our service.", "HtmlBody": "

Welcome!

AltStyle によって変換されたページ (->オリジナル) /

", "MessageStream": "outbound", "Tag": "welcome-email" }, { "From": "sender@example.com", "To": "receiver2@example.com", "Subject": "Your order confirmation", "TextBody": "Order #12345 confirmed.", "HtmlBody": "Order confirmed", "MessageStream": "outbound", "Tag": "order-confirmation", "Attachments": [ { "Name": "invoice.pdf", "Content": "base64-content", "ContentType": "application/pdf" } ] } ] ``` **Batch Response:** Returns an array with individual results for each message: ```json [ { "ErrorCode": 0, "Message": "OK", "MessageID": "b7bc2f4a-e38e-4336-af7d-e6c392c2f817", "SubmittedAt": "2010-11-26T12:01:05.1794748-05:00", "To": "receiver1@example.com" }, { "ErrorCode": 406, "Message": "Inactive recipient" } ] ``` ## Code Examples ### Send a Single Email Basic example with text and HTML: ```bash curl "https://api.postmarkapp.com/email" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '{ "From": "sender@example.com", "To": "receiver@example.com", "Subject": "Hello from Postmark", "TextBody": "Hello dear Postmark user.", "HtmlBody": "Hello dear Postmark user.", "MessageStream": "outbound" }' ``` Advanced example with all features: ```bash curl "https://api.postmarkapp.com/email" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '{ "From": "John Sender ", "To": "Jane Receiver ", "Cc": "manager@example.com", "Subject": "Project Update", "Tag": "project-updates", "HtmlBody": "

Project Status

See attached report.

", "TextBody": "Project Status\n\nSee attached report.", "ReplyTo": "projects@example.com", "TrackOpens": true, "TrackLinks": "HtmlAndText", "MessageStream": "outbound", "Metadata": { "project_id": "ABC123", "client": "Acme Corp" }, "Headers": [ {"Name": "X-Priority", "Value": "High"} ], "Attachments": [ { "Name": "report.pdf", "Content": "JVBERi0xLjMKJeLjz9M...", "ContentType": "application/pdf" }, { "Name": "chart.png", "ContentID": "cid:chart123", "Content": "iVBORw0KGgoAAAANSU...", "ContentType": "image/png" } ] }' ``` ### Send Batch Emails Send multiple personalized emails efficiently: ```bash curl "https://api.postmarkapp.com/email/batch" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '[ { "From": "sender@example.com", "To": "receiver1@example.com", "Subject": "Test #1", "TextBody": "Hello user 1", "MessageStream": "outbound" }, { "From": "sender@example.com", "To": "receiver2@example.com", "Subject": "Test #2", "TextBody": "Hello user 2", "MessageStream": "outbound" } ]' ``` ### Send with Template Use `TemplateAlias` to reference templates by name — this is the recommended path for all production transactional email. Templates keep your email layouts separate from your application code and return a `MessageID` for webhook correlation. ```bash curl "https://api.postmarkapp.com/email/withTemplate" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '{ "From": "billing@acme.example", "To": "receiver@example.com", "TemplateAlias": "receipt", "TemplateModel": { "receipt_id": "rcpt_123", "amount": "49ドル.00", "dashboard_url": "https://acme.example/dashboard" }, "MessageStream": "outbound" }' ``` For TypeScript SDK users, see the [TypeScript transactional email recipe](https://postmarkapp.com/developer/integration/official-libraries#typescript) for a complete implementation with typed `TemplateModel`, batch sending, webhook verification, and a repair guide. ### Send Bulk Marketing Email ```bash curl "https://api.postmarkapp.com/email/bulk" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '{ "From": "sender@example.com", "Subject": "Newsletter for {{FirstName}}", "HtmlBody": "Hi, {{FirstName}}", "TextBody": "Hi, {{FirstName}}", "MessageStream": "broadcast", "Messages": [ { "To": "user1@example.com", "TemplateModel": {"FirstName": "Alice"} }, { "To": "user2@example.com", "TemplateModel": {"FirstName": "Bob"} } ] }' ``` ## Email Features ### Attachments Include attachments by adding Base64-encoded content. Postmark disallows certain file types to prevent viruses/spyware. ```json { "Attachments": [ { "Name": "document.pdf", "Content": "base64-encoded-content-here", "ContentType": "application/pdf" } ] } ``` **Attachment Limits:** - Individual TextBody and HtmlBody: 5 MB each - Total message size with attachments: 10 MB - Base64 encoding increases size ~33%, but Postmark calculates size after encoding - Attachments not retrievable via UI, API, or webhooks after sending ### Inline Images Embed images directly in HTML using Content-ID: ```json { "HtmlBody": "", "Attachments": [ { "Name": "logo.png", "Content": "base64-encoded-image", "ContentType": "image/png", "ContentID": "cid:logo123" } ] } ``` Note: Reference the same image multiple times without duplicating the attachment. ### Tracking Enable open and click tracking per email or server-wide: ```json { "TrackOpens": true, "TrackLinks": "HtmlAndText" } ``` **TrackLinks Options:** - `"None"`: No link tracking - `"HtmlAndText"`: Track links in both HTML and text - `"HtmlOnly"`: Track links in HTML only - `"TextOnly"`: Track links in text only ### Custom Headers and Metadata Add custom headers for email routing and metadata for internal tracking: ```json { "Headers": [ {"Name": "X-Custom-Header", "Value": "custom-value"}, {"Name": "Message-ID", "Value": ""} ], "Metadata": { "customer_id": "12345", "order_id": "67890", "campaign": "welcome-series" } } ``` Metadata helps track emails internally without affecting delivery. ### Tags Categorize emails for detailed statistics and reporting (one tag per message): ```json { "Tag": "password-reset" } ``` Maximum tag length: 1000 characters. Use consistent naming for better analytics. ## Tracking Opens Open tracking uses an invisible pixel to detect when recipients view your emails. This provides insights into engagement rates, user activity, and email client usage. **Documentation:** - [Tracking opens overview](https://postmarkapp.com/developer/user-guide/tracking-opens) - [Tracking opens per message stream](https://postmarkapp.com/developer/user-guide/tracking-opens/tracking-opens-per-message-stream) - [Tracking opens per email](https://postmarkapp.com/developer/user-guide/tracking-opens/tracking-opens-per-email) - [Message opens API](https://postmarkapp.com/developer/user-guide/tracking-opens/message-opens-api) ### How Open Tracking Works 1. **Pixel Insertion**: Invisible 1x1 pixel added to HTML emails 2. **Detection**: Pixel loads when email is viewed 3. **Data Collection**: Client info, location, and timestamp recorded 4. **Analytics**: Data aggregated by tag, message, and account ### Enabling Open Tracking #### Method 1: Per Message Stream Configure default tracking for all emails in a stream. Guide: [Tracking opens per message stream](https://postmarkapp.com/developer/user-guide/tracking-opens/tracking-opens-per-message-stream) ```bash curl "https://api.postmarkapp.com/servers/:serverid" \ -X PUT \ -H "Accept: application/json" \ -H "X-Postmark-Account-Token: account-token" \ -d '{ "TrackOpens": true }' ``` When enabled at the server level, all HTML emails automatically include tracking. #### Method 2: Per Email (API) Enable tracking for individual emails. Guide: [Tracking opens per email](https://postmarkapp.com/developer/user-guide/tracking-opens/tracking-opens-per-email) ```json { "From": "sender@example.com", "To": "receiver@example.com", "Subject": "Your Order", "HtmlBody": "...", "TrackOpens": true } ``` **Note**: Server-level setting overrides per-email settings. You cannot disable tracking per-email if enabled at server level. #### Method 3: Per Email (SMTP) Add SMTP header for individual email tracking: ``` X-PM-TrackOpens: true ``` ### Open Tracking Data #### Information Collected - **Timestamp**: When the email was opened - **Client**: Email client name and version - **Platform**: Desktop, WebMail, or Mobile - **Operating System**: OS name and version - **Geographic Location**: Country, region, city (when available) - **IP Address**: Recipient's IP (when available) - **User Agent**: Browser/client details #### Sample Open Event Data ```json { "RecordType": "Open", "MessageStream": "outbound", "FirstOpen": true, "MessageID": "883953f4-6105-42a2-a16a-77a8eac79483", "Recipient": "john@example.com", "ReceivedAt": "2024-11-14T18:24:47Z", "Tag": "welcome-email", "Client": { "Name": "Chrome 119.0", "Company": "Google", "Family": "Chrome" }, "OS": { "Name": "Windows 11", "Company": "Microsoft", "Family": "Windows" }, "Platform": "Desktop", "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...", "Geo": { "CountryISOCode": "US", "Country": "United States", "RegionISOCode": "CA", "Region": "California", "City": "San Francisco", "Zip": "94102", "Coords": "37.7749,-122.4194", "IP": "192.0.2.1" }, "Metadata": { "customer_id": "12345", "campaign": "onboarding" } } ``` ### Message Opens API Query and retrieve open tracking data programmatically. Full guide: [Message opens API](https://postmarkapp.com/developer/user-guide/tracking-opens/message-opens-api) #### Search All Opens ```bash curl "https://api.postmarkapp.com/messages/outbound/opens?count=25&offset=0" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` #### Filter Opens ```bash curl "https://api.postmarkapp.com/messages/outbound/opens?\ recipient=john@example.com&\ tag=welcome-email&\ count=25&offset=0" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` #### Opens for Specific Message ```bash curl "https://api.postmarkapp.com/messages/outbound/opens/{messageid}" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` **Query Parameters:** - `recipient`: Filter by recipient email - `tag`: Filter by message tag - `client_name`: Filter by email client - `client_company`: Filter by client company - `client_family`: Filter by client family - `os_name`: Filter by operating system - `os_company`: Filter by OS company - `os_family`: Filter by OS family - `platform`: Filter by platform (Desktop, WebMail, Mobile) - `country`: Filter by country - `region`: Filter by region - `city`: Filter by city ### Open Tracking Webhook Receive real-time notifications when emails are opened. #### Configuration ```bash curl "https://api.postmarkapp.com/webhooks" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '{ "Url": "https://yourapp.com/open-webhook", "MessageStream": "outbound", "HttpAuth": { "Username": "username", "Password": "password" }, "Triggers": { "Open": { "Enabled": true, "PostFirstOpenOnly": false } } }' ``` **Options:** - `PostFirstOpenOnly`: If `true`, only first open is sent. If `false`, every open triggers webhook. ### Limitations and Considerations #### Technical Limitations - **HTML Only**: Plain text emails cannot include tracking pixels - **Image Blocking**: Recipients who block images won't trigger opens - **Ad Blockers**: May prevent tracking pixel from loading - **Multiple Opens**: Only first open saved in UI/API unless webhook configured otherwise #### Privacy Considerations - **Apple Mail Privacy Protection**: iOS 15+ may pre-fetch images causing false positives - **Gmail Proxy**: Gmail serves images through proxy, limiting geographic and OS detection - **Corporate Firewalls**: May block or cache tracking pixels #### Best Practices 1. **Respect Privacy**: Include unsubscribe options and honor opt-outs 2. **Combine Metrics**: Use opens with clicks for better engagement picture 3. **Test Thoroughly**: Verify tracking works with your email templates 4. **Monitor Trends**: Focus on trends rather than individual opens 5. **Handle False Positives**: Account for privacy protection features ### Open Rate Calculation ``` Open Rate = (Unique Opens / Delivered Emails) ×ばつ 100 ``` **Considerations:** - Use unique opens (first open only) for accuracy - Exclude bounced emails from delivered count - Account for image blocking (typically 20-30% underreporting) - Compare rates within similar campaign types ### Use Cases 1. **Engagement Analysis**: Identify most engaged subscribers 2. **Re-engagement Campaigns**: Target users who haven't opened recently 3. **A/B Testing**: Compare subject line effectiveness 4. **Send Time Optimization**: Analyze when users open emails 5. **Client Analytics**: Understand email client distribution 6. **Geographic Insights**: Identify regional engagement patterns ## Tracking Links Link tracking replaces URLs in your emails with tracking URLs that route through Postmark servers, recording click data before redirecting to the original destination. This provides insights into user engagement and content effectiveness. **Documentation:** [Tracking links](https://postmarkapp.com/developer/user-guide/tracking-links) ### How Link Tracking Works 1. **Link Replacement**: Original URLs replaced with tracking URLs (`click.pstmrk.it`) 2. **Click Detection**: User clicks tracked link 3. **Data Recording**: Browser, location, timestamp captured 4. **Instant Redirect**: User redirected to original URL 5. **Data Storage**: Click information saved for analytics **Key Features:** - Works in both HTML and plain text emails - Links never expire (work indefinitely) - HTTPS/TLS encryption for all tracked links - Globally distributed infrastructure for fast redirects - No dependency on image loading (unlike open tracking) ### Enabling Link Tracking #### Method 1: Server/Stream Level Configure default tracking for all emails: ```bash curl "https://api.postmarkapp.com/servers/:serverid" \ -X PUT \ -H "Accept: application/json" \ -H "X-Postmark-Account-Token: account-token" \ -d '{ "TrackLinks": "HtmlAndText" }' ``` #### Method 2: Per Email (API) Enable tracking for individual emails: ```json { "From": "sender@example.com", "To": "receiver@example.com", "Subject": "Check out our new features", "HtmlBody": "View Features", "TextBody": "View features at https://example.com/features", "TrackLinks": "HtmlAndText" } ``` #### Method 3: Per Email (SMTP) Add SMTP header for link tracking: ``` X-PM-TrackLinks: HtmlAndText ``` ### Tracking Options - **`"None"`**: No link tracking (default) - **`"HtmlAndText"`**: Track links in both HTML and text bodies - **`"HtmlOnly"`**: Track only HTML links (preserves clean text URLs) - **`"TextOnly"`**: Track only plain text links **Important Notes:** - Identical links in HTML and text count as one unique click - Each unique link clicked by a recipient triggers a new click event - Multiple clicks on same link by same recipient = one unique click ### Link Click Data #### Information Collected - **Timestamp**: When the link was clicked - **Original Link**: The destination URL - **Click Location**: HTML or Text body - **Platform**: Desktop, WebMail, or Mobile - **Client Details**: Browser name and version - **Operating System**: OS information - **Geographic Data**: Country, region, city (when available) - **IP Address**: User's IP address - **Metadata**: Custom metadata from original email #### Sample Click Event Data ```json { "RecordType": "Click", "MessageStream": "outbound", "MessageID": "883953f4-6105-42a2-a16a-77a8eac79483", "ReceivedAt": "2024-11-14T18:30:45Z", "Recipient": "john@example.com", "Tag": "product-announcement", "OriginalLink": "https://example.com/features", "ClickLocation": "HTML", "Client": { "Name": "Chrome 119.0", "Company": "Google", "Family": "Chrome" }, "OS": { "Name": "Windows 11", "Company": "Microsoft", "Family": "Windows" }, "Platform": "Desktop", "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...", "Geo": { "CountryISOCode": "US", "Country": "United States", "RegionISOCode": "NY", "Region": "New York", "City": "New York", "Zip": "10001", "Coords": "40.7128,-74.0060", "IP": "192.0.2.1" }, "Metadata": { "customer_id": "12345", "campaign": "feature-launch" } } ``` ### Message Clicks API Query click data programmatically for analytics and reporting. #### Search All Clicks ```bash curl "https://api.postmarkapp.com/messages/outbound/clicks?count=25&offset=0" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` #### Filter Clicks ```bash curl "https://api.postmarkapp.com/messages/outbound/clicks?\ recipient=john@example.com&\ tag=product-announcement&\ count=25&offset=0" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` #### Clicks for Specific Message ```bash curl "https://api.postmarkapp.com/messages/outbound/clicks/{messageid}" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` **Query Parameters:** - `recipient`: Filter by recipient email - `tag`: Filter by message tag - `client_name`: Filter by browser/client - `client_company`: Filter by client company - `client_family`: Filter by client family - `os_name`: Filter by operating system - `os_company`: Filter by OS company - `os_family`: Filter by OS family - `platform`: Filter by platform (Desktop, WebMail, Mobile) - `country`: Filter by country - `region`: Filter by region - `city`: Filter by city ### Click Tracking Webhook Receive real-time notifications when links are clicked. #### Configuration ```bash curl "https://api.postmarkapp.com/webhooks" \ -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "X-Postmark-Server-Token: server-token" \ -d '{ "Url": "https://yourapp.com/click-webhook", "MessageStream": "outbound", "HttpAuth": { "Username": "username", "Password": "password" }, "Triggers": { "Click": { "Enabled": true } } }' ``` #### Webhook Behavior - One POST per unique click (first click only by default) - Multiple links = multiple webhook calls - Clicks older than retention period not tracked - Data pushed immediately when click occurs ### Custom Link Tracking Domain (Enterprise) For enterprise customers, Postmark supports custom tracking domains instead of `click.pstmrk.it`: ``` Example: click.yourdomain.com ``` Benefits: - Brand consistency in URLs - Improved deliverability - Greater user trust ### Link Tracking Statistics #### Click Rate Calculation ``` Click Rate = (Unique Clicks / Delivered Emails) ×ばつ 100 Click-to-Open Rate = (Unique Clicks / Unique Opens) ×ばつ 100 ``` #### Aggregate Statistics API ```bash curl "https://api.postmarkapp.com/stats/outbound/clicks?\ tag=welcome-email&\ fromdate=2024年11月01日&\ todate=2024年11月30日" \ -X GET \ -H "Accept: application/json" \ -H "X-Postmark-Server-Token: server-token" ``` Response includes: - Total clicks - Unique clicks - Click rates by platform - Browser statistics - Geographic distribution ### Best Practices 1. **URL Shortening**: Consider original URL length as tracking adds characters 2. **Testing**: Verify tracked links work before sending campaigns 3. **Analytics Tags**: Use consistent tags for better reporting 4. **Privacy Compliance**: Disclose link tracking in privacy policy