Skip to content

Migration Tooling

Synapse provides built-in migration tooling to import contacts from MoEngage, Customer.io, Iterable, Mailchimp, Braze, Klaviyo, or any platform via CSV/JSON file upload. Migrations run as background jobs with real-time progress, checkpoint-based resumability, and encrypted credential storage.

Note

Migrations require a Starter plan or higher and an owner or admin role. For the full API reference, see Migrations API.


Supported Platforms

PlatformHow It WorksEstimated Time
MoEngageFetches contacts via Data API (20 per request, 1,000 req/min)~10 min per 100K contacts
Customer.ioCreates bulk export via App API, downloads JSON lines5-15 min (depends on export generation)
IterableTriggers CSV export, downloads when ready10-20 min (Iterable exports can be slow)
MailchimpPaginated member fetch via Marketing API~1 min per 10K members
BrazeTriggers an async segment export, downloads when ready5-20 min (Braze export prep can be slow)
KlaviyoCursor-paginated fetch of all profiles via the Profiles API~2-10 min per 100K profiles
CSV / JSONUpload a file directly (CSV, JSON array, or NDJSON)Seconds to minutes

Quick Start

1. Get your source platform credentials

PlatformWhat you needWhere to find it
MoEngageWorkspace ID + Data API Key + Data CenterSettings > General + Settings > APIs > Data
Customer.ioApp API KeySettings > App API
IterableStandard API KeySettings > API Keys
MailchimpAPI Key (with -usNN datacenter suffix)Account > Extras > API keys
BrazeREST API Key + REST endpoint + Segment IDSettings > APIs and Identifiers (key + endpoint); Segments (segment ID)
KlaviyoPrivate API Key (starts with pk_, profile read access)Settings > API keys
CSV/JSONNo credentials neededExport from your platform's dashboard

2. Start the migration

Via Dashboard: Navigate to Settings > Migrations > New Migration, select your platform, enter credentials, and configure field mapping.

Via API:

bash
curl -X POST https://synapse-api.pyrx.tech/v1/migrations \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"platform": "moengage",
"credentials": {
"app_id": "YOUR_WORKSPACE_ID",
"api_key": "YOUR_DATA_API_KEY",
"extra": {"data_center": "DC4"}
},
"config": {
"tags": ["imported-from-moengage"]
}
}'

3. Monitor progress

Poll GET /v1/migrations/{id} or watch the progress bar in the dashboard:

json
{
"status": "running",
"progress": {
"imported": 2100,
"failed": 12,
"total": 4500,
"percent_complete": 48.0
}
}

4. Resume on failure

If the migration fails (network timeout, rate limit, etc.), resume from the last checkpoint:

bash
curl -X POST https://synapse-api.pyrx.tech/v1/migrations/{id}/resume \
-H "Authorization: Bearer <jwt>"

What Gets Migrated

DataMigrated?Notes
Contacts (email, name, phone)YesUpserted by external_id -- duplicates are merged
Custom propertiesYesStored in properties JSONB
Subscription statusYesOpt-out flags mapped to unsubscribed
TagsYesAdd import tags via config.tags
Event historyNoEvents are forward-only -- send new events via the Events API
TemplatesNoConvert Jinja2 templates with the NLT converter
Flows / campaignsNoRecreate in the dashboard or via the Flows API

Field Mapping

Use config.field_mapping to map source field names to Synapse contact fields. Fields not mapped to a standard field are stored in properties automatically.

json
{
"config": {
"field_mapping": {
"First Name": "first_name",
"Last Name": "last_name",
"Phone Number": "phone",
"Plan Type": "product_type"
}
}
}

Standard target fields

email, first_name, last_name, phone, product_type, subscription_status, timezone, locale


CSV / JSON File Upload

For platforms without a direct adapter, export your data and upload it to Synapse.

Supported formats

  • CSV (.csv) -- comma-separated with header row
  • JSON (.json) -- JSON array of objects
  • NDJSON (.ndjson, .jsonl) -- newline-delimited JSON

CSV example

csv
external_id,email,first_name,last_name,plan,company
user_001,[email protected],Alice,Smith,starter,Acme Corp
user_002,[email protected],Bob,Jones,growth,Beta Inc

Standard column names (external_id, email, first_name, last_name, phone) are mapped automatically. All other columns go into properties.

Tip

Synapse auto-detects file format from extension and content. It handles UTF-8 BOM and falls back to Latin-1 encoding if UTF-8 fails.


Security

  • Credentials are encrypted at rest (AES-128-CBC + HMAC-SHA256) and decrypted only during active processing.
  • Credentials are deleted when the migration completes, fails, or is cancelled.
  • Migration records are tenant-scoped -- one workspace cannot see another's migrations.
  • No plaintext storage -- credentials never appear in logs, error messages, or API responses.

Template Migration

If your existing platform uses Jinja2 templates (MoEngage, Customer.io), use the NLT Jinja2 Migration tool to convert them:

Jinja2NLT
{{UserAttribute['First Name']}}{the user's First Name}
{{attr|default('MOE_NOT_SEND')}}{the attr from the trigger event, required}
{% if UserAttribute['Plan'] == 'premium' %}{if the user's Plan is premium}
{% for item in UserAttribute['Orders'] %}{for item in the user's Orders}

Full Migration Checklist

  1. Export templates from your legacy platform and convert to NLT syntax
  2. Map event names to Synapse snake_case convention
  3. Run the contact migration (API or file upload)
  4. Verify imported contacts in the dashboard
  5. Create email templates in Synapse
  6. Recreate flows with the correct triggers and conditions
  7. Run in shadow mode to validate output against your legacy platform
  8. Cut over to Synapse and deactivate legacy flows
Warning

Run both systems in parallel during migration. Use shadow mode to verify Synapse produces the correct output before switching over completely.


GDPR Data Portability

Synapse's migration tooling supports GDPR Article 20 data portability rights:

  • Import: From any supported platform or via file upload
  • Export: Via POST /v1/contacts/export (CSV or JSON) at any time
  • Deletion: Via DELETE /v1/contacts/{external_id} (soft delete with audit trail)