Skip to content
campaiDeveloper
campai.com

Migrate one workflow at a time, beginning with reads. Changing a URL prefix is insufficient: the CRM API has different contact shapes, permission scopes, and related objects. A request returning 200 does not establish that the new integration selects the same people or preserves the same business behavior.

Keep the existing integration available for comparison while you build a separate CRM reader. Avoid running both writers against the same fields during the transition.

What you’ll have at the end

A migration worksheet and a controlled cutover plan for the operations your integration actually uses.

  1. Inventory
  2. Map contracts
  3. Compare reads
  4. Switch one writer
Before you start
  • An inventory of existing requests and stored IDs
  • A current CRM API key
  • A comparison dataset and rollback owner
On this page

Record each existing request's environment, method, path, purpose, filters, fields consumed, and side effects. Include background workers, exports, webhook receivers, and website plugins. Identify which workflows create contacts, attach debtors, send messages, or issue financial documents.

Map each workflow to a current operation, such as List contacts, Get contact, Create contact, or Update contact. Read the actual request and response schemas; do not reuse an old payload merely because some property names still look familiar.

Save the production OpenAPI document using Track changes to the API contract. Record its source URL and download date for your comparison.

Make one row per business operation, rather than one row per old endpoint. Populate the values from your integration and the current API reference:

Field What to record
Business action For example, refresh one mapped member’s dates.
Existing call Method, path, input fields, response fields consumed.
Replacement Reviewed operation ID and exact new method/path.
Identity mapping How the existing local ID maps to the current CRM record.
Required access Key permissions and organization/mandate restrictions.
Comparison A known record, expected projection, and acceptable differences.
Cutover Which writer is stopped, who starts the new writer, and recovery criteria.

Ready to switch one read: its row has no unknown identity mapping, the new request succeeds, and the projected result agrees with the reviewed comparison. Keep unresolved rows on the existing implementation instead of guessing a replacement.

Use GET /apiKey/info to identify the key's organization and allowed scopes. Then discover the permitted mandates with List mandates. Follow the complete commands in Make your first API request and Find your organization and mandate IDs.

CRM member access uses the contact:member scope, alongside mandate access. An older broad contact permission is not evidence that every new contact-type operation is allowed. Key restrictions and field-level access can also change what is returned. Diagnose these using Resolve 403 errors and empty results.

Keep organization IDs, mandate IDs, contact IDs, member numbers, debtor account numbers, and application IDs in separate columns. Do not pass a visible member number where the endpoint requires a contact _id.

CRM field or object Migration consideration
Contact _id Persist the new record identity rather than assuming equality with a legacy ID.
oldContactId A nullable legacy reference on CRM records; use only when present and validated in your organization.
types A contact can have several types; do not model it as one exclusive old type.
member Membership fields have their own structure, including entry, exit, and termination dates.
mandates Scope and access can span mandates; one person need not become a duplicate local person per mandate.
debtor and debtor account Financial linkage is distinct from contact identity and requires its own permissions.
Application form and submission The admission workflow is separate from direct contact creation.

Use the exact read-only snapshot from Keep member data in sync to establish your CRM baseline. Compare aggregate counts and a reviewed set of synthetic or authorized records, including a contact with multiple types and one outside the key's mandate restriction.

The source contains a Sync from old contact operation, but it queues a mode-dependent legacy synchronization job. It is not a universal migration command or an ID-conversion lookup. Do not invoke it as a speculative fix for missing CRM records; determine the organization's migration state with its administrator first.

List contacts returns { contacts, count }; Get contact returns one record directly. Request returnCount: true when your workflow requires a matching count. Page through the complete list instead of treating the first response as all members.

Property filters use a JSON-encoded userFilter string. Supported paths and comparators come from the current endpoint's property model, not from arbitrary old database fields. Start with one known condition, compare the result, and then add the remaining predicates. Handling user filters explains the format.

Keep API values separate from UI labels and localization. Date-only values, timestamps, null fields, and arrays need explicit mappings. A missing field is not automatically a deletion instruction for the destination system.

Current CRM contact notifications use contacts.created, contacts.updated, and contacts.deleted, with the payload and HMAC rules in Build a webhook receiver. Do not send legacy events into the new parser without verifying their contract.

Run periodic reconciliation during and after the change. Webhooks are not a complete historical migration feed, and the current set does not cover bookings or events.

Define a cutover point, pause the old writer, complete a final reconciliation, and enable the new writer for a small reviewed scope. Keep a durable operation ledger so retries cannot recreate already migrated records.

Verify the resulting records and downstream effects before expanding. Preserve the previous configuration and mappings for operational recovery, but do not blindly replay old writes as a rollback. A software rollback cannot undo invoices, messages, or external actions already completed.

Check your result

Same business record
The reviewed identity mapping is stable.
Old filter versus new filter
Differences are explained before cutover.
Rollback
No two workers write the same operation concurrently.
Continue with Track changes to the API contract