PushMail.dev

API Reference

Complete reference for every PushMail API endpoint. Base URL https://pushmail.dev/api/v1

All requests require authentication via Authorization: Bearer pm_live_... header or session cookie.

Authentication

POST
/auth/signup

Create account (org + user + session)

POST
/auth/login

Login and receive session cookie

POST
/auth/logout

Destroy session

GET
/auth/me

Get current user and organization

POST
/auth/forgot-password

Send password reset email

POST
/auth/reset-password

Reset password with token

API Keys

GET
/api-keys

List all API keys for your org

POST
/api-keys

Create a new API key

DELETE
/api-keys/:id

Revoke an API key

Sites

GET
/sites

List all sites

POST
/sites

Create a new site

GET
/sites/:id

Get site details

PUT
/sites/:id

Update a site (name, domain, autoBcc, sendFrequencyCapDays, companyName, physicalAddress)

DELETE
/sites/:id

Delete a site (fails if site has sends)

Contacts

GET
/contacts?siteId=X

List contacts with search, filter, pagination

POST
/contacts

Create a contact (with optional tags and lists)

GET
/contacts/:id

Get contact details

PUT
/contacts/:id

Update contact fields

DELETE
/contacts/:id

Delete a contact

POST
/contacts/bulk

Bulk create/update up to 100 contacts (note: uses siteId not siteId in body)

GET
/contacts/export?siteId=X

Export contacts as CSV or JSON (filter by list, tag, status, or segment)

Lists

GET
/lists?siteId=X

List all lists for a site

POST
/lists

Create a list

GET
/lists/:id

Get list details

PUT
/lists/:id

Update a list

DELETE
/lists/:id

Delete a list

GET
/lists/:id/contacts

Search contacts to add to a list (requires ?q= param)

POST
/lists/:id/contacts

Add a contact to a list

DELETE
/lists/:id/contacts

Remove a contact from a list

Tags

GET
/tags?siteId=X

List all tags for a site

POST
/tags

Create a tag

DELETE
/tags/:id

Delete a tag

Segments

GET
/segments?siteId=X

List all segments for a site

POST
/segments

Create a segment with rules

GET
/segments/:id

Get segment details with live contact count

PUT
/segments/:id

Update segment name, description, or rules

DELETE
/segments/:id

Delete a segment

GET
/segments/:id/contacts

List contacts matching segment rules (paginated)

POST
/segments/:id/count

Preview contact count for rules

POST
/segments/preview-count

Preview contact count without creating a segment

Template Folders

GET
/template-folders

List all template folders

POST
/template-folders

Create a folder (name)

PUT
/template-folders/:id

Rename a folder (name)

DELETE
/template-folders/:id

Delete a folder (templates moved to unfiled)

Templates

GET
/templates

List all templates (includes folderId)

POST
/templates

Create a template (optional folderId)

GET
/templates/:id

Get template details

PUT
/templates/:id

Update a template (name, subject, html, designJson, folderId)

DELETE
/templates/:id

Delete a template

POST
/templates/:id/render

Preview rendered HTML with sample variables

Sequences

GET
/sequences?siteId=X

List sequences

POST
/sequences

Create a sequence. Optional sendingConfigId to use a specific sending config for all emails in the sequence.

GET
/sequences/:id

Get sequence details

PUT
/sequences/:id

Update a sequence (name, status, triggerType, sendingConfigId, autoBcc)

DELETE
/sequences/:id

Delete a sequence

GET
/sequences/:id/detail

Get sequence with steps, enrollments, and stats

POST
/sequences/:id/enroll

Enroll contacts into the sequence. Optional startAtStep to begin at a specific step position.

GET
/sequences/:id/enrollments

List enrollments for a sequence

POST
/sequences/:id/enrollments

Create an enrollment

DELETE
/sequences/:id/enrollments

Cancel an enrollment

Sequence Steps

GET
/sequences/:id/steps

List steps in a sequence

POST
/sequences/:id/steps

Add steps to a sequence. Supports email, delay, and condition types. Condition steps accept conditionConfig (JSON), trueBranchStepOrder, and falseBranchStepOrder for workflow branching.

PUT
/sequences/:id/steps/:stepId

Update a step (type, templateId, delayMinutes, conditionConfig, trueBranchStepOrder, falseBranchStepOrder)

DELETE
/sequences/:id/steps/:stepId

Remove a step

Sequence Playbooks

GET
/sequences/playbooks

List pre-built sequence playbooks (no auth required)

POST
/sequences/playbooks/:playbookId/create

Create a sequence from a playbook template (creates sequence + templates + steps)

Holiday Emails

GET
/holidays?siteId=X

List holiday emails for a site

POST
/holidays

Schedule a holiday email injection into active sequences

GET
/holidays/:id

Get holiday details and send stats

PUT
/holidays/:id

Update a holiday (name, date, templateId, status). Set status to 'cancelled' to stop sending.

DELETE
/holidays/:id

Delete a holiday and its send records

Campaigns

GET
/campaigns?siteId=X

List campaigns

POST
/campaigns

Create a campaign. Optional sendingConfigId to use a specific sending config.

GET
/campaigns/:id

Get campaign details, stats, and sendingConfigLabel

PUT
/campaigns/:id

Update a campaign (name, templateId, listId, tagId, sendingConfigId, A/B test settings). Only draft or scheduled campaigns can be updated.

DELETE
/campaigns/:id

Delete a campaign

POST
/campaigns/:id/schedule

Schedule a campaign for future delivery

POST
/campaigns/:id/send

Send a campaign immediately. Requires sendingConfigId on the campaign. Supports A/B test variant splitting.

Campaign A/B Testing

GET
/campaigns/:id/variants

List all variants for a campaign

POST
/campaigns/:id/variants

Create a variant (subject, template, or HTML override)

GET
/campaigns/:id/variants/:variantId

Get variant details with open/click rates

PUT
/campaigns/:id/variants/:variantId

Update a variant

DELETE
/campaigns/:id/variants/:variantId

Delete a variant (deleting all disables A/B testing)

Forms

GET
/forms?siteId=X

List all forms (optionally filter by siteId)

POST
/forms

Create a form (siteId, name, designJson, sequenceId, listId, tags, doubleOptIn)

GET
/forms/:id

Get form details

PUT
/forms/:id

Update a form (name, designJson, status, sequenceId, listId, tags, doubleOptIn)

DELETE
/forms/:id

Delete a form (cascades to submissions)

GET
/forms/:id/submissions

List form submissions (paginated)

POST
/forms/:id/submit

Public form submission endpoint (no auth, rate limited by IP, CORS enabled)

Lead Scoring

GET
/scoring/rules

List scoring rules (optionally filter by siteId)

POST
/scoring/rules

Create a scoring rule

GET
/scoring/rules/:id

Get scoring rule details

PUT
/scoring/rules/:id

Update a scoring rule

DELETE
/scoring/rules/:id

Delete a scoring rule

GET
/contacts/:id/score

Get a contact's lead score and scoring log

POST
/contacts/:id/score

Manually adjust a contact's lead score

Sends & Events

GET
/sends?siteId=X

List sent emails with status and cost

GET
/sends/:id

Get a single send by ID, including its full event history (delivered, open, click, bounce, etc.)

GET
/events?siteId=X

List email events (delivered, open, click, bounce, etc.)

Custom Events

POST
/events/custom

Record a custom event for a contact

GET
/events/custom

List custom events (filterable by contactId, eventName)

GET
/events/custom/names

List all distinct custom event names in your org

Transactional Email

POST
/send

Send a single transactional email. Pass fromEmail/fromName directly or use sendingConfigId. Requires templateId or html+subject. Pass secure: true for encrypted delivery.

POST
/send/batch

Send up to 1000 emails in one call. Supports fromEmail/fromName or sendingConfigId, with per-recipient variables and tracking.

POST
/validate

Validate an email address (syntax, MX, disposable check)

Suppressions

GET
/suppressions

List suppressions (paginated, filterable by reason)

POST
/suppressions

Add a manual suppression

DELETE
/suppressions/:email

Remove an email from the suppression list

GET
/suppressions/check/:email

Check if an email is suppressed

POST
/suppressions/import

Bulk import suppressions from CSV or JSON

GET
/suppressions/export

Export suppressions as CSV or JSON

Secure Messages

GET
/secure-messages

List all secure messages for your org (with pagination)

GET
/secure-messages/:id

Get secure message details (status, view count, expiry)

POST
/secure-messages/:id/revoke

Revoke a secure message (deletes encrypted blob, marks as revoked)

Reports

GET
/reports/multi-sequence?siteId=X

List contacts actively enrolled in multiple sequences for a site

GET
/reports/stalled-enrollments?siteId=X

List active enrollments that haven't progressed in 24+ hours

GET
/reports/sequence-funnel?siteId=X

Enrollment status breakdown per sequence (active, completed, cancelled, failed)

GET
/reports/unengaged-contacts?siteId=X

Subscribed contacts with 5+ sends who never opened or clicked

GET
/reports/no-sequences?siteId=X

Subscribed contacts not enrolled in any active sequence

GET
/reports/schedules

List all scheduled reports for your org

POST
/reports/schedules

Create a scheduled report (daily, weekly, or monthly email delivery)

GET
/reports/schedules/:id

Get a scheduled report

PUT
/reports/schedules/:id

Update a scheduled report (frequency, recipient, active)

DELETE
/reports/schedules/:id

Delete a scheduled report

Imports

POST
/imports/upload

Upload CSV and start import

GET
/imports

List imports

GET
/imports/:id

Get import progress and stats

Providers

GET
/providers

List available email providers with their display names, capabilities (supportsWebhooks, supportsBatch), and config fields

Sending Config

GET
/sending-configs

List sending configurations (returns provider, fromEmail, fromName, isByok, verified)

POST
/sending-configs

Add a sending config. Pass provider (sendgrid, ses, postmark, mailgun, sparkpost, brevo, mailjet, mandrill, resend, elastic-email) and credentials object with provider-specific fields (e.g. apiKey, region, domain). Defaults to sendgrid. Legacy apiKey field still accepted.

PUT
/sending-configs/:id

Update a sending config

DELETE
/sending-configs/:id

Remove a sending config

POST
/sending-configs/:id/verify

Verify the config by sending a test email

Domains

GET
/domains

List all verified and pending domains

POST
/domains

Add a domain and start verification

GET
/domains/:id

Get domain details and DNS records

DELETE
/domains/:id

Remove a domain

Settings

GET
/settings

Get current user settings and org info

PUT
/settings/password

Change your password

PUT
/settings/org

Update organization name

MFA

GET
/mfa/status

Get MFA status (TOTP and email OTP)

POST
/mfa/totp/setup

Generate TOTP secret and QR code URI

POST
/mfa/totp/verify-setup

Verify TOTP code to complete setup

POST
/mfa/totp/disable

Disable TOTP authentication

POST
/mfa/email-otp/enable

Enable email-based OTP

POST
/mfa/email-otp/disable

Disable email-based OTP

POST
/mfa/challenge

Request an MFA challenge (sends email OTP)

POST
/mfa/verify

Verify MFA code to complete login

Dashboard & Analytics

GET
/dashboard/overview

Dashboard stats (contacts, sends, open rate)

GET
/analytics/overview

Analytics data for charts and trends

Deliverability Analytics

GET
/analytics/deliverability?period=30d

Get deliverability metrics. Query param period accepts 7d, 30d, or 90d (default 30d). Returns funnel (sent, delivered, opened, clicked, bounced, failed), bounceBreakdown (hard, soft, block, topReasons), complaintRate, dailyTrends (per-day sent/delivered/opened/clicked/bounced with rates), ispBreakdown (top 20 recipient domains with delivery and open rates), configPerformance (per sending config stats), and reputation (score: excellent/good/fair/poor, bounceRate, complaintRate, factors).

Plans

GET
/plans

List all available plans with features and pricing

GET
/plans/current

Get your org's current plan, usage, and billing period

POST
/plans/change

Preview or confirm a plan upgrade/downgrade with proration

POST
/plans/cancel

Cancel subscription (remains active until period end)

GET
/plans/usage

Get current period usage vs plan limits

Billing

GET
/billing/usage

Get current month usage and credit balance

GET
/billing/subscription

Get current plan, subscription details, and invoices

POST
/billing/checkout

Create Stripe Checkout session for plan subscription

GET
/billing/credits

List available credit packages

POST
/billing/credits

Create Stripe Checkout session for credit purchase

POST
/billing/portal

Create Stripe Customer Portal session

POST
/billing/webhooks

Stripe webhook handler (called by Stripe, not by your app)

Organization Health

GET
/org/health

Get sending health, trust level, and rate limits

Rate Limits

GET
/rate-limit

Get current rate limit usage for your org (general and send buckets)

Branding

GET
/org/branding

Get branding discount status

PUT
/org/branding

Enable or disable branding footer (15% discount)

CAN-SPAM Compliance

GET
/compliance

Get compliance settings (physical address, unsubscribe URL, enabled)

PUT
/compliance

Update compliance settings

POST
/unsubscribe?token=TOKEN

RFC 8058 one-click unsubscribe (called by email clients)

GET
/unsubscribe/:token

Browser-based unsubscribe confirmation page

POST
/unsubscribe/:token

Process browser-based unsubscribe

Stock Photos

GET
/stock-photos?q=&page=&per_page=&orientation=

Search Pexels stock photos

POST
/stock-photos/save

Download a photo to R2 storage

Website Tracking (Public)

GET
/tracking/script?siteId=X

Serve the JavaScript tracking snippet (Content-Type: application/javascript)

POST
/tracking/event

Record a page view or custom event (public, no auth)

POST
/tracking/identify

Link an anonymous visitor to a known contact (public, no auth)

Webhooks

GET
/webhooks

List outgoing webhook endpoints

POST
/webhooks

Create an outgoing webhook endpoint

GET
/webhooks/:id

Get webhook endpoint details

PUT
/webhooks/:id

Update a webhook endpoint

DELETE
/webhooks/:id

Delete a webhook endpoint

POST
/webhooks/sendgrid

Receive SendGrid event webhooks (inbound)

Inbound Provider Webhooks

POST
/webhooks/sendgrid

SendGrid inbound events. Verifies ECDSA signature via x-twilio-email-event-webhook-signature header. Supports ?config_id= for per-config secrets.

POST
/webhooks/ses

Amazon SES inbound events via SNS. Auto-confirms SNS subscriptions. Supports ?config_id=&secret= query params for verification.

POST
/webhooks/postmark

Postmark inbound events. Supports ?config_id=&secret= query params for verification.

POST
/webhooks/mailgun

Mailgun inbound events. Verifies HMAC-SHA256 signature. Supports ?config_id= for per-config secrets.

POST
/webhooks/sparkpost

SparkPost inbound events. Supports ?config_id= for per-config secrets.

POST
/webhooks/brevo

Brevo (Sendinblue) inbound events. Supports ?config_id=&secret= query params for verification.

POST
/webhooks/mailjet

Mailjet inbound events. Supports ?config_id=&secret= query params for verification.

POST
/webhooks/mandrill

Mandrill (Mailchimp Transactional) inbound events. Verifies webhook signature. Supports ?config_id= for per-config secrets.

POST
/webhooks/resend

Resend inbound events. Supports ?config_id=&secret= query params for verification.

POST
/webhooks/elastic-email

Elastic Email inbound events. Supports ?config_id=&secret= query params for verification.

Batch size limits

Endpoints that accept arrays enforce maximum sizes to prevent abuse and ensure reliable processing.

EndpointFieldMax items
POST /v1/contacts/bulkcontacts100
POST /v1/send/batchrecipients1,000
POST /v1/sequences/:id/stepssteps200
POST /v1/sequences/:id/enrollcontactIds100

Requests exceeding these limits are rejected with a 400 error.

Response format

All responses follow a consistent format:

Success
{ "data": { ... } }
Error
{ "error": "Human-readable error message" }

Rate limit headers

Every authenticated API response includes rate limit headers. See Rate Limits for details.

HeaderDescription
X-RateLimit-LimitMax requests per window
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when window resets

On this page