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.
Migrations require a Starter plan or higher and an owner or admin role. For the full API reference, see Migrations API.
Supported Platforms
| Platform | How It Works | Estimated Time |
|---|---|---|
| MoEngage | Fetches contacts via Data API (20 per request, 1,000 req/min) | ~10 min per 100K contacts |
| Customer.io | Creates bulk export via App API, downloads JSON lines | 5-15 min (depends on export generation) |
| Iterable | Triggers CSV export, downloads when ready | 10-20 min (Iterable exports can be slow) |
| Mailchimp | Paginated member fetch via Marketing API | ~1 min per 10K members |
| Braze | Triggers an async segment export, downloads when ready | 5-20 min (Braze export prep can be slow) |
| Klaviyo | Cursor-paginated fetch of all profiles via the Profiles API | ~2-10 min per 100K profiles |
| CSV / JSON | Upload a file directly (CSV, JSON array, or NDJSON) | Seconds to minutes |
Quick Start
1. Get your source platform credentials
| Platform | What you need | Where to find it |
|---|---|---|
| MoEngage | Workspace ID + Data API Key + Data Center | Settings > General + Settings > APIs > Data |
| Customer.io | App API Key | Settings > App API |
| Iterable | Standard API Key | Settings > API Keys |
| Mailchimp | API Key (with -usNN datacenter suffix) | Account > Extras > API keys |
| Braze | REST API Key + REST endpoint + Segment ID | Settings > APIs and Identifiers (key + endpoint); Segments (segment ID) |
| Klaviyo | Private API Key (starts with pk_, profile read access) | Settings > API keys |
| CSV/JSON | No credentials needed | Export 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:
3. Monitor progress
Poll GET /v1/migrations/{id} or watch the progress bar in the dashboard:
4. Resume on failure
If the migration fails (network timeout, rate limit, etc.), resume from the last checkpoint:
What Gets Migrated
| Data | Migrated? | Notes |
|---|---|---|
| Contacts (email, name, phone) | Yes | Upserted by external_id -- duplicates are merged |
| Custom properties | Yes | Stored in properties JSONB |
| Subscription status | Yes | Opt-out flags mapped to unsubscribed |
| Tags | Yes | Add import tags via config.tags |
| Event history | No | Events are forward-only -- send new events via the Events API |
| Templates | No | Convert Jinja2 templates with the NLT converter |
| Flows / campaigns | No | Recreate 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.
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
Standard column names (external_id, email, first_name, last_name, phone) are mapped automatically. All other columns go into properties.
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:
| Jinja2 | NLT |
|---|---|
{{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
- Export templates from your legacy platform and convert to NLT syntax
- Map event names to Synapse
snake_caseconvention - Run the contact migration (API or file upload)
- Verify imported contacts in the dashboard
- Create email templates in Synapse
- Recreate flows with the correct triggers and conditions
- Run in shadow mode to validate output against your legacy platform
- Cut over to Synapse and deactivate legacy flows
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)