Skip to content

Changelog

All notable changes to the Synapse Customer Communications Platform API are documented here.


Upcoming

Note

This release has been verified and is rolling out. The changes below are documented ahead of the release date and become generally available when the release ships.

Optional stored subject on templates, and subject/preheader for Inspect

Added

  • Optional subject on templates -- POST /v1/templates and PUT /v1/templates/{slug} now accept an optional subject (max 255 characters). Template responses (GET /v1/templates/{slug} and list) now include subject (a string, or null when no subject is stored). On update, omitting subject leaves the stored value unchanged; sending "subject": null clears it. Templates remain content-only otherwise — sender_name, from_email, reply_to, bcc, content_type, and status are still rejected with 422. See the Templates API.
  • subject and preheader on POST /v1/inspect -- the email-channel inspect run accepts optional subject and preheader. Supplying subject suppresses the "subject missing" finding (SJ001); supplying preheader suppresses "preheader missing" (SJ007). Because content-only template bodies have no <title> or hidden preheader element, these let Inspect evaluate the complete email instead of flagging findings a fragment can never satisfy. Ignored on push / in_app channels. See the Inspect API.

Changed

  • Send-time subject resolution -- when an email uses a template, the subject now resolves as: send-request override → flow step → campaign → template's stored subject → empty. A stored template subject is the last-resort default; any closer source still wins when set. Templates with no stored subject behave exactly as before. See Subject resolution.

2026-09-01

Go live on the shared domain — a custom domain is now optional

Every workspace, on every plan including Free, can now go live and send real email from Synapse's shared pyrx.tech domain with no domain setup. Verifying your own sending domain is now an optional upgrade for better deliverability and branding — it is no longer required to send in live mode.

Changed

  • Live sending on the shared domain -- Live email that sends from Synapse's shared, already-verified pyrx.tech domain (either the default [email protected] address or an explicit @pyrx.tech "From") now goes out normally. Previously such sends were blocked; they are no longer.
  • Custom sender domain is optional, not a prerequisite -- Adding and verifying your own domain remains available on any plan and is recommended for production, but it is no longer a requirement to go live. You can go live on the shared domain first and add a custom domain later with no changes to your integration.
  • Go-live checklist -- Verifying a custom sender domain is now shown as an informational, recommended step rather than a blocking requirement. Going live still requires a verified account email, complete company information, and at least one API key.

Unchanged

  • Anti-spoofing protections -- A live send from a custom domain that you have not verified still cannot go out on that domain — it is automatically downgraded to the shared pyrx.tech address instead. A send with a malformed or empty "From" address is still rejected.
  • Test mode -- Test-mode email continues to deliver from the isolated test.pyrx.tech sandbox domain, exactly as before.

v1.4.0 (2026-07-19)

Commercial email now automatically carries a compliant footer and a working one-click unsubscribe, satisfying CAN-SPAM and the bulk-sender requirements at Gmail, Yahoo, and Apple Mail.

Added

  • Automatic CAN-SPAM footer -- Every commercial send (campaigns, promotional flow steps, and promotional direct sends) now appends your workspace's physical mailing address and an unsubscribe link. You don't template any of it. Transactional email is exempt.
  • One-click unsubscribe (RFC 8058) -- Commercial email now includes List-Unsubscribe and List-Unsubscribe-Post headers, enabling the inbox "Unsubscribe" control in Gmail, Yahoo, and Apple Mail.
  • Public unsubscribe endpoint -- GET and POST /v1/public/unsubscribe?token=… (unauthenticated; the signed token in the link is the authorization). GET renders a confirmation page and does not change anything; POST unsubscribes the contact (idempotent) and serves one-click. See the Unsubscribe API.

Changed

  • POST /v1/send now acts on content_type -- Previously accepted but ignored, content_type is now live. promotional is treated as commercial and gets the footer; transactional or an omitted value stays exempt (any other value is rejected with 422). A commercial send from a workspace with no complete company address is suppressed (response status: "suppressed", no email sent) rather than sent non-compliant. See Direct Send API.
  • POST /v1/email-logs/{id}/resend re-applies the footer -- Resending a commercial email now re-attaches the footer and one-click headers. A resend from a workspace with no complete company address is suppressed (success: false).

Action required

  • Complete your company name and physical mailing address in Settings → General before sending commercial email. Commercial sends from a workspace without a complete address are blocked (fail-closed). This is the same company information required to go live. Transactional email is unaffected.

v1.3.0 (2026-05-06)

Synapse Inspect -- Email Quality Pipeline

A new multi-stage email quality analysis pipeline that detects rendering issues, spam triggers, accessibility violations, and dark-mode problems before you send a campaign or activate a flow.

  • 5-stage pipeline -- Static analysis (HTML/CSS/a11y/dark-mode), external resource validation (broken links, image checks, CDN), spam scoring (internal heuristics + SpamAssassin/mail-tester), vendor client rendering (multi-client screenshots), and cross-client visual diff detection.
  • 110+ finding codes across 10 categories (html, css, images, links, spam, accessibility, rendering, dark_mode, subject, tracking). Each code is a stable identifier that never changes.
  • Three severity levels -- critical (blocks send), warning (should fix), info (advisory).
  • Pre-send blocking -- Campaigns and flows with critical findings are blocked until fixed or explicitly overridden. Override requires a typed reason and creates an audit log entry. Configurable per workspace (advisory mode available).
  • Credit system -- Quick Check (Stages 1-3) is always free. Full Inspect costs 1 credit per unique template version. Monthly credits by plan: Free (5), Starter (25), Growth (100), Enterprise (unlimited).
  • Auto-fixers -- 8 dark-mode auto-fix transformers that modify the template AST with reversible patches.
  • Finding management -- Snooze findings (1-365 days), mark as fixed, or mark as false positive.
  • Workspace configuration -- GET/PUT /v1/inspect/config to set default render clients, auto-run on save, blocking behavior, spam provider, and globally snoozed codes.

API Endpoints

MethodPathDescription
POST/v1/inspectTrigger an inspect run
GET/v1/inspect/{job_id}Get job status and summary
GET/v1/inspect/{job_id}/findingsList findings (paginated, filterable)
POST/v1/inspect/findings/{id}/snoozeSnooze a finding
POST/v1/inspect/findings/{id}/mark-fixedMark as fixed
POST/v1/inspect/findings/{id}/mark-false-positiveMark as false positive
GET/v1/inspect/creditsGet credit balance and ledger
POST/v1/inspect/overrideCreate override token
POST/v1/inspect/pre-send-checkCheck if template can be sent
GET/v1/inspect/configGet workspace inspect config
PUT/v1/inspect/configUpdate workspace inspect config

New Permissions

  • inspect:read and inspect:write scopes added to Owner, Admin, Developer, and Marketing roles.

v1.2.0 (2026-05-06)

Template Editor V2

The visual email editor has been rebuilt with an AST-first architecture. Templates are now stored as structured JSON documents (body_ast) alongside the compiled HTML, enabling richer editing and safer migrations.

  • AST-first data model -- New body_ast (JSONB), body_text (plain text), ast_schema_version, and renderer_used fields on all template responses. Fully backward-compatible -- body_html continues to work for templates created via the API.
  • 20 block types -- paragraph, text, title, list, blockquote, code, image, video, gif, sticker, icons, columns, spacer, divider, table, button, link, menu, social, and raw HTML. Each block type is extensible via the Block Registry.
  • HTML import -- Paste or upload existing HTML emails. An 8-step importer pipeline converts HTML to editable blocks with confidence scoring. Unrecognized HTML is preserved verbatim as raw HTML blocks -- nothing is lost.
  • Bidirectional editing -- Switch between the drag-and-drop block canvas and a Monaco HTML code editor. Changes in either view sync to the other in real time.
  • Preflight checks (POST /v1/templates/{slug}/preflight) -- Server-side pre-send validation covering content quality, link health, image hosting, sender domain verification, and NLT syntax. Inline browser-side checks run as you edit.
  • Plain-text rendering -- Every template now has a body_text field with a plain-text version for email clients that don't render HTML.
  • Version tracking -- Template versions now include AST patches for precise diffing.

Migration (Internal)

  • Background migration job converts V1 templates to V2 format nightly with byte-identity validation. Existing templates continue to work unchanged.
  • Admin migration dashboard at /admin/template-migration with progress tracking, diff history, and per-template rollback controls.
  • Admin API at /v1/admin/template-migration/* for programmatic migration management.

Backward Compatibility

All existing API contracts are preserved. The body_ast, body_text, ast_schema_version, and renderer_used fields are additive -- existing integrations that only use body_html are unaffected. Templates created via the API without body_ast continue to work; the visual editor will import them into V2 format when opened.


v1.1.0 (2026-04-14)

Contacts API

  • Upsert endpoint (POST /v1/contacts) -- Creates a new contact or merges with an existing one by external_id. Returns created boolean and updated_fields list. No more 409 Conflict on duplicate external_id.
  • Partial update (PATCH /v1/contacts/{external_id}) -- Update specific fields with tag operators ($add_tags, $remove_tags). Properties are shallow-merged; set a key to null to remove it.
  • Soft delete (DELETE /v1/contacts/{external_id}) -- Sets subscription_status to "deleted" instead of hard-deleting. Contact record and email logs are retained for audit.
  • Bulk import improvements (POST /v1/contacts/bulk) -- New on_conflict value "merge" (replaces "update"). Added "replace" strategy. Response now includes total count and per-item errors[] for partial success.

Enhanced Event Ingestion

  • contact field -- Renamed from contact_override/contact_overrides. Supports all new contact fields including timezone, locale, properties (shallow-merged), tags, $add_tags, and $remove_tags.
  • external_id preferred -- external_id is now the primary identifier in all documentation and examples. user_id is still accepted as a deprecated alias.

New Contact Fields

  • tags (string[]) -- Categorize contacts for segmentation and filtering
  • timezone (string) -- IANA timezone for send-time optimization
  • locale (string) -- Locale code for localized content

Backward Compatibility

The following deprecated aliases are still accepted but will be removed in a future version:

  • user_id -- Use external_id instead
  • contact_overrides / contact_override -- Use contact instead
  • on_conflict: "update" (bulk import) -- Use on_conflict: "merge" instead

v1.0.0 (2026-04-07)

Initial Release

Core API

  • Event Ingestion (POST /v1/events) -- Async event ingestion with contact upsert, idempotency keys, and RabbitMQ routing
  • Direct Send (POST /v1/send) -- Send transactional emails immediately without a flow
  • Flows (/v1/flows) -- Full CRUD with activate, pause, and flow stats endpoints
  • Templates (/v1/templates) -- Full CRUD with preview rendering endpoint
  • Segments (/v1/segments) -- Full CRUD with evaluate and contact list endpoints
  • Contacts (/v1/contacts) -- Full CRUD with search, bulk import, and custom properties
  • Analytics (/v1/analytics) -- Dashboard summary, per-flow stats, email logs, and CSV export

Template Engine

  • NLT (Natural Language Template) Engine -- Human-readable template syntax replacing Jinja2
    • 3 data sources: contact, trigger event, named events
    • 19 comparison operators for conditionals
    • 19 chainable filters
    • For loops with item access and loop variables
    • 17 currency formats, 6 date formats
    • Math operators and aggregates
    • Variable assignment and ternary expressions
    • required modifier for send suppression
    • XSS prevention via HTML escaping

Flow Engine

  • Event-triggered multi-step flows with 4 step types:
    • send_email -- Render and send via Resend
    • wait -- Delay with configurable duration
    • condition -- Branch based on event or contact data
    • update_contact -- Modify contact properties
  • Priority queue routing (critical, high, normal, low)
  • Dead letter queue with two-tier visibility (infrastructure vs tenant errors)

Authentication

  • API Key Authentication -- X-WORKSPACE-ID + X-API-KEY headers
    • Key format: psk_{env}_{hex32}
    • 4 scopes: data, reporting, management, full
    • live and test environments
  • JWT Authentication -- ES256 tokens from pyrx.auth with JWKS verification (6-hour cache)
  • Multi-workspace support -- Users can belong to multiple workspaces

Security

  • RBAC -- 6 roles (owner, admin, developer, marketing, operations, viewer) with granular permissions
  • Multi-tenancy -- PostgreSQL Row-Level Security on all business tables
  • Tenant isolation -- tenant_id on every table with defense-in-depth (application + database)

Webhooks

  • Resend Events -- email.sent, email.delivered, email.opened, email.clicked, email.bounced, email.complained
  • Lemon Squeezy Events -- subscription_created, subscription_updated, subscription_cancelled, subscription_expired, subscription_payment_failed
  • pyrx.payment Events (deprecated) -- subscription.activated, subscription.renewed, payment.failed, subscription.past_due, subscription.cancelled, subscription.paused
  • Signature Verification -- Svix (Resend), HMAC-SHA256 (Lemon Squeezy), shared secret with rotation (pyrx.payment)

Plans

PlanPriceMonthly EmailsContactsEventsRetention
Free$01,0001,00010,00030 days
Starter$49/mo10,00010,000100,00090 days
Growth$299/mo100,000100,0001,000,000365 days
EnterpriseCustomUnlimitedUnlimitedUnlimitedUnlimited

SDKs

  • Python SDK (synapse-crm) -- Sync and async clients with retry logic
  • JavaScript SDK (@pyrx-crm/sdk) -- Lightweight client-side tracking SDK for browsers and bundlers

API Versioning

The Synapse API is versioned under the /v1/ prefix. No breaking changes will be introduced within a version. When breaking changes are necessary, a new version (/v2/) will be introduced with a migration guide and overlap period.

Note

Subscribe to the Synapse status page and developer newsletter for advance notice of API changes, deprecations, and new features.