Migration from Legacy
Migrate your contact data into Benchmark Email using the API. This guide walks through the complete end-to-end workflow: reviewing your contact structure, creating lists, importing contacts, and verifying the results.Goal
By the end of this guide you will have migrated your contact data into Benchmark Email by adding custom fields to your contact structure, creating lists, creating contacts with all their field values, assigning contacts to lists, and verifying the migration was successful.Prerequisites
- An API key with
contacts:writescope (includes read access) - Your API base URL (found on the Settings > API Keys page)
- Your source data (contacts, field definitions, list assignments) exported from your legacy system
- Familiarity with API authentication
Overview
The migration follows this order:Steps
Step 1: Review and update your contact structure
First, retrieve your existing contact structure to see what fields are already defined.PUT to update the structure. For example, to add Company, Phone, City, State, and Signup Source fields:
- The contact structure
_id(e.g.,64a1b2c3d4e5f6a7b8c9d0e1) - Each field’s
_idto map your data to the correct fields - Each tag’s
_idif you plan to assign tags
Step 2: Create lists
Create lists that match your legacy system’s segmentation. You will need the contact structure ID from Step 1._id from the responses. You will need these when creating contacts.
See Manage Lists for details.
Step 3: Create contacts
Now create contacts one at a time, mapping your legacy data to the field IDs from your contact structure and assigning list memberships.Step 4: Handle errors and retries
Bulk migrations will encounter transient errors. Implement retry logic with exponential backoff. Rate limit handling: The API allows 3,600 requests per hour (~1 request/second sustained). For large migrations, pace your requests accordingly.Step 5: Verify the migration
After all contacts are created, verify the migration by checking counts and spot-checking individual contacts. Check total contact count:totalRecords value in the response against your expected count.
Check list membership counts:
totalContacts count.
Spot-check a specific contact:
Migration Checklist
- Export all contacts from your legacy system
- Map legacy fields to Benchmark field types
- Update the contact structure with all required fields
- Record the field ID mapping (legacy field name to Benchmark
_id) - Create all lists and record their IDs
- Run a small test batch (10-50 contacts) to validate the mapping
- Run the full migration with retry logic
- Verify total contact count matches expectations
- Verify list membership counts
- Spot-check 5-10 individual contacts for field accuracy
Tips for Large Migrations
- Pace your requests. The API rate limit is 3,600 requests/hour. For 10,000 contacts, expect the migration to take approximately 3 hours.
- Log everything. Keep a log of each contact created (email, status code, contact ID) so you can identify and retry failures.
-
Use dedup checks sparingly. Each dedup search counts against your rate limit. If you are confident your source data has no duplicates, skip the dedup step and handle duplicate errors (
400 DuplicateFieldError) instead. - Batch your field mapping once. Fetch the contact structure once at the start, build your field map, and reuse it for every contact. Do not fetch the structure for each contact.
-
Monitor your monthly quota. Each API request counts toward your monthly quota (
contactLimit x 10). Check remaining quota via theX-Monthly-Remainingresponse header.
Common Errors
| Status | Error | Cause | Fix |
|---|---|---|---|
401 | UnauthorizedError | Invalid or inactive API key | Verify your key in Settings > API Keys |
403 | ForbiddenError | Key lacks contacts:write scope | Migration requires contacts:write |
400 | ValidationError | Missing key or contactStructureId, or invalid field ID | Verify your field mapping matches the contact structure |
400 | DuplicateFieldError | Contact with this email already exists | Use search to dedup, or update the existing contact instead |
429 | TooManyRequestsError | Rate limit or monthly quota exceeded | Implement backoff and respect the Retry-After header. See Rate Limits |
Next Steps
- Search Contacts — verify imported contacts and run quality checks
- Manage Lists — refine list organization post-migration
- Manage Campaigns — start creating campaigns for your migrated contacts
- View Reports — track campaign performance