Skip to main content
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:write scope (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:
Each step depends on the previous one: contacts reference field IDs from the structure, and list IDs for assignments. Plan your migration before writing code.

Steps

Step 1: Review and update your contact structure

First, retrieve your existing contact structure to see what fields are already defined.
Your account has a default contact structure. If you need to add custom fields to match your legacy data, use PUT to update the structure. For example, to add Company, Phone, City, State, and Signup Source fields:
Save the response. You will need:
  • The contact structure _id (e.g., 64a1b2c3d4e5f6a7b8c9d0e1)
  • Each field’s _id to map your data to the correct fields
  • Each tag’s _id if you plan to assign tags
See Manage Custom Fields for details.

Step 2: Create lists

Create lists that match your legacy system’s segmentation. You will need the contact structure ID from Step 1.
Save each list’s _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.
Bulk migration script pattern (pseudocode):

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.
Dedup before creating: To avoid duplicate errors for contacts that already exist, search before creating:
See Search Contacts for more search patterns.

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:
Check the totalRecords value in the response against your expected count. Check list membership counts:
Each list in the response includes a totalContacts count. Spot-check a specific contact:
Verify that the returned fields, tags, and list assignments match your source data.

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

  1. Pace your requests. The API rate limit is 3,600 requests/hour. For 10,000 contacts, expect the migration to take approximately 3 hours.
  2. Log everything. Keep a log of each contact created (email, status code, contact ID) so you can identify and retry failures.
  3. 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.
  4. 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.
  5. Monitor your monthly quota. Each API request counts toward your monthly quota (contactLimit x 10 on free plans, contactLimit x 100 on paid plans). Check remaining quota via the X-Monthly-Remaining response header.

Common Errors

Next Steps