Migrating from Your Legacy CEP
This guide maps legacy CEP concepts, APIs, and template syntax to their Synapse equivalents. If you are migrating existing flows and templates, use this as your reference.
Concept Mapping
| Legacy CEP | Synapse | Notes |
|---|---|---|
| User | Contact | Identified by external_id (your user ID) |
| UserAttribute | Contact properties | properties JSONB field on contact record |
| EventAttribute | Event attributes | attributes JSON object in event payload |
| Smart Campaign / Flow | Flow | Event-triggered multi-step journey |
| Template (Jinja2) | Template (NLT) | Human-readable syntax replaces Jinja2 |
| Segment | Segment | Filter DSL with all/any grouping |
| Campaign Stats | Analytics | Delivery, open, click, bounce tracking |
| MOE_NOT_SEND | required modifier | Suppresses email if value is null |
default('fallback') | or "fallback" | Provides a fallback value |
Template Syntax Migration
Variables
| Legacy CEP (Jinja2) | Synapse (NLT) |
|---|---|
{{UserAttribute['First Name']}} | {the user's First Name} |
{{UserAttribute['First Name']|default('Guest')}} | {the user's First Name, or "Guest"} |
{{EventAttribute['wics_open.Reference Number']}} | {the Reference Number from the trigger event} |
{{EventAttribute['wics_open.Reference Number']|default('MOE_NOT_SEND')}} | {the Reference Number from the trigger event, required} |
Conditionals
| Legacy CEP (Jinja2) | Synapse (NLT) |
|---|---|
{% if UserAttribute['Plan'] == 'premium' %} | {if the user's Plan is premium} |
{% elif UserAttribute['Plan'] == 'starter' %} | {else if the user's Plan is starter} |
{% else %} | {else} |
{% endif %} | {end if} |
Loops
| Legacy CEP (Jinja2) | Synapse (NLT) |
|---|---|
{% for item in UserAttribute['Orders'] %} | {for item in the user's Orders} |
{{ item['Name'] }} | {item.Name} |
{% endfor %} | {end for} |
Formatting
| Legacy CEP (Jinja2) | Synapse (NLT) |
|---|---|
{{ amount | int }} | {the Amount, as "number"} |
| Custom Jinja filter for currency | {the Amount, as "currency"} |
| Custom date formatting | {the Date, as "long date"} |
MOE_NOT_SEND to Required
In the legacy platform, |default('MOE_NOT_SEND') prevents an email from being sent when a critical attribute is missing. Synapse uses the required modifier:
When required resolves to null, the entire email is suppressed. The email_logs record is created with status: "suppressed" and the suppressed_reason field explains which attribute was missing.
Use the NLT Jinja2 migration tool to automatically convert existing Jinja2 templates to NLT syntax. The converter handles default('MOE_NOT_SEND') to required mapping automatically.
API Migration
Event Ingestion
Legacy API:
Synapse:
Key Differences
| Concern | Legacy CEP | Synapse |
|---|---|---|
| Authentication | MOE-APPKEY header | X-WORKSPACE-ID + X-API-KEY headers |
| User ID field | customer_id | external_id |
| Event format | Nested actions array | Flat event object |
| Attribute keys | Title Case | snake_case (NLT resolves both) |
| Idempotency | Not built-in | idempotency_key field with 7-day TTL |
| Response | Sync (200 OK) | Async (202 Accepted) |
Flow Migration
Legacy Flow Structure
Synapse Flow Configuration
Migration Checklist
- Export legacy templates -- Download all active template HTML and note the Jinja2 expressions used
- Convert Jinja2 to NLT -- Use the converter tool or manually translate using the syntax mapping above
- Map event names -- Align your legacy event names with the Synapse
snake_caseconvention - Map user attributes -- Ensure contact
propertiesin Synapse include all attributes your templates reference - Create templates -- Import converted HTML into Synapse via
POST /v1/templates - Create flows -- Recreate each legacy flow as a Synapse flow with the appropriate trigger, conditions, and steps
- Shadow mode -- Enable shadow mode (
PYRXCRM_SHADOW_MODE=true) to log emails without sending, while your legacy platform continues as the primary sender - Validate -- Compare Synapse email logs against legacy platform delivery for a sample period
- Cutover -- Disable legacy flows and activate Synapse flows
Run both systems in parallel during migration. Use shadow mode to verify Synapse produces the same output as your legacy platform before switching over.