Changelog
All notable changes to the Synapse Customer Communications Platform API are documented here.
Upcoming
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
subjecton templates --POST /v1/templatesandPUT /v1/templates/{slug}now accept an optionalsubject(max 255 characters). Template responses (GET /v1/templates/{slug}and list) now includesubject(a string, ornullwhen no subject is stored). On update, omittingsubjectleaves the stored value unchanged; sending"subject": nullclears it. Templates remain content-only otherwise —sender_name,from_email,reply_to,bcc,content_type, andstatusare still rejected with422. See the Templates API. subjectandpreheaderonPOST /v1/inspect-- the email-channel inspect run accepts optionalsubjectandpreheader. Supplyingsubjectsuppresses the "subject missing" finding (SJ001); supplyingpreheadersuppresses "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 onpush/in_appchannels. 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.techdomain (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.techaddress 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.techsandbox domain, exactly as before.
v1.4.0 (2026-07-19)
CAN-SPAM Footer & One-Click Unsubscribe
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-UnsubscribeandList-Unsubscribe-Postheaders, enabling the inbox "Unsubscribe" control in Gmail, Yahoo, and Apple Mail. - Public unsubscribe endpoint --
GETandPOST /v1/public/unsubscribe?token=…(unauthenticated; the signed token in the link is the authorization).GETrenders a confirmation page and does not change anything;POSTunsubscribes the contact (idempotent) and serves one-click. See the Unsubscribe API.
Changed
POST /v1/sendnow acts oncontent_type-- Previously accepted but ignored,content_typeis now live.promotionalis treated as commercial and gets the footer;transactionalor an omitted value stays exempt (any other value is rejected with422). A commercial send from a workspace with no complete company address is suppressed (responsestatus: "suppressed", no email sent) rather than sent non-compliant. See Direct Send API.POST /v1/email-logs/{id}/resendre-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/configto set default render clients, auto-run on save, blocking behavior, spam provider, and globally snoozed codes.
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/inspect | Trigger an inspect run |
GET | /v1/inspect/{job_id} | Get job status and summary |
GET | /v1/inspect/{job_id}/findings | List findings (paginated, filterable) |
POST | /v1/inspect/findings/{id}/snooze | Snooze a finding |
POST | /v1/inspect/findings/{id}/mark-fixed | Mark as fixed |
POST | /v1/inspect/findings/{id}/mark-false-positive | Mark as false positive |
GET | /v1/inspect/credits | Get credit balance and ledger |
POST | /v1/inspect/override | Create override token |
POST | /v1/inspect/pre-send-check | Check if template can be sent |
GET | /v1/inspect/config | Get workspace inspect config |
PUT | /v1/inspect/config | Update workspace inspect config |
New Permissions
inspect:readandinspect:writescopes 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, andrenderer_usedfields on all template responses. Fully backward-compatible --body_htmlcontinues 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_textfield 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-migrationwith 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 byexternal_id. Returnscreatedboolean andupdated_fieldslist. No more409 Conflicton duplicateexternal_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 tonullto remove it. - Soft delete (
DELETE /v1/contacts/{external_id}) -- Setssubscription_statusto"deleted"instead of hard-deleting. Contact record and email logs are retained for audit. - Bulk import improvements (
POST /v1/contacts/bulk) -- Newon_conflictvalue"merge"(replaces"update"). Added"replace"strategy. Response now includestotalcount and per-itemerrors[]for partial success.
Enhanced Event Ingestion
contactfield -- Renamed fromcontact_override/contact_overrides. Supports all new contact fields includingtimezone,locale,properties(shallow-merged),tags,$add_tags, and$remove_tags.external_idpreferred --external_idis now the primary identifier in all documentation and examples.user_idis still accepted as a deprecated alias.
New Contact Fields
tags(string[]) -- Categorize contacts for segmentation and filteringtimezone(string) -- IANA timezone for send-time optimizationlocale(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-- Useexternal_idinsteadcontact_overrides/contact_override-- Usecontactinsteadon_conflict: "update"(bulk import) -- Useon_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
requiredmodifier 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 Resendwait-- Delay with configurable durationcondition-- Branch based on event or contact dataupdate_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-KEYheaders- Key format:
psk_{env}_{hex32} - 4 scopes:
data,reporting,management,full liveandtestenvironments
- Key format:
- 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_idon 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
| Plan | Price | Monthly Emails | Contacts | Events | Retention |
|---|---|---|---|---|---|
| Free | $0 | 1,000 | 1,000 | 10,000 | 30 days |
| Starter | $49/mo | 10,000 | 10,000 | 100,000 | 90 days |
| Growth | $299/mo | 100,000 | 100,000 | 1,000,000 | 365 days |
| Enterprise | Custom | Unlimited | Unlimited | Unlimited | Unlimited |
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.
Subscribe to the Synapse status page and developer newsletter for advance notice of API changes, deprecations, and new features.