Migrate from another CRM
Move your records from another CRM into BrokerPlus through the API. This guide covers the order to import in, retries that never make duplicates, and how to stay inside the rate limit.
BrokerPlus also has an import in the app. Ask your account contact whether it reads your CRM's export. Reach for the API when you need to reshape the data on the way in, or when the app import doesn't read your CRM.
Before you start
- Contacts, leads, deals, and tasks have batch endpoints that write up to 100 records per request. Addresses, custom fields, and notes are one request per record.
- Every record a key creates belongs to the broker who created the key. To import each broker's book under their name, use a key each broker creates.
- Import 10 records first and look at them in BrokerPlus before you send the rest.
Pause your automations first
A record the API creates starts the same automations as one a broker adds by hand. A new contact
can start Contact Added automations, a new deal can start Deal Created, and a lead from
POST /v1/leads or POST /v1/leads/batch starts New Lead Created. Any of these can email or
text every person you import.
Turn off every automation on those three triggers before the import, and turn them back on after.
Don't import old leads as leads. POST /v1/leads is for someone asking for help right now. For an
old lead, create a contact with "types": ["lead"].
The order of the import
Each step uses ids from the one before it:
- Contacts:
POST /v1/contacts, orPOST /v1/contacts/batch. - Their addresses:
POST /v1/contacts/{id}/addresses. - Their custom fields:
PATCH /v1/contacts/{id}/custom-fields/{key}. - Deals, with the contacts on them:
POST /v1/deals, orPOST /v1/deals/batch. - Notes on contacts and deals:
POST /v1/contacts/{id}/notesandPOST /v1/deals/{id}/notes.
Keep a map from each old id to its new BrokerPlus id, in a file or a table. Every step needs it, and it lets you pick up where you left off after a failure. The batch endpoints can keep this map for you; see Send records in batches.
Use the old id in the idempotency key
Send an Idempotency-Key on every POST, built from the old system and the old id, for example
oldcrm-contact-48213. If the import stops and you run it again, a record that already went in
replays its first response instead of being created twice.
The API remembers a key for 24 hours, so use your id map to skip records from an earlier run, and the idempotency key for retries within one run. A retry must send the exact same body bytes: build each body once and reuse the string. See Idempotency and batch.
Check for people who are already in the book
Send "check_duplicates": true on each contact create. The API then refuses a contact with the
same email, or the same first and last name, as someone already in the book. You get
409 DUPLICATE_CONTACT with the matches in details.matches. Write the match into your id map
instead of creating the contact.
Code
A name match can be a different person with the same name. When matched_on is the name only,
check before you treat the two as one.
Your brokerage can also keep each person on one team only. Then a person who is already on another
team's book refuses the create with the same 409, whether or not you sent check_duplicates, and
details.matches can be empty because that record isn't yours to see. Log those people and ask
the other team.
Import a contact
Import a deal
POST /v1/deals takes the deal type, an optional pipeline and stage, a closing date, and the
contacts on the deal, using the BrokerPlus contact ids from your id map.
Then fill in the rest with PATCH requests: the loan terms with PATCH /v1/deals/{id}/application,
the property address with PATCH /v1/deals/{id}/property, and the deal's status with
PATCH /v1/deals/{id}. A PATCH takes no idempotency key and doesn't need one: sending the same
PATCH twice gives the same result.
Send records in batches
POST /v1/contacts/batch, POST /v1/leads/batch, POST /v1/deals/batch, and
POST /v1/tasks/batch write up to 100 records per request. Each item's data is the body you would
send to the single endpoint: a POST body for a new record, a PATCH body for one that exists.
Put your old id in external_id and the old system's name in namespace. The first batch creates
the record and remembers your id. A later batch with the same namespace and external_id updates
that record instead of creating another, so you can rerun the import after a failure, or a week
later to bring changes across, with no id map for these four types.
Code
The response is 200, with one result per item, in the order you sent them:
Code
A batch isn't one transaction: a failed item doesn't stop or undo the others. Check status on each
result, fix the failures, and resend only those. Each item also counts as one request against the
rate limit and runs the same checks and automations as the single endpoint. The full rules are on
Idempotency and batch.
Stay inside the rate limit
A key gets 600 requests a minute. A contact can take three or four requests (the contact, an address, custom fields, notes), so plan on about 150 contacts a minute per key.
- Send at a steady pace of no more than 10 requests a second. Use a fixed-rate queue, not bursts.
- Watch
RateLimit-Remainingand slow down when it gets low. - On
429, waitRetry-Afterseconds and send the same request again. - Each broker's key has its own limit, so you can import several brokers in parallel, one key each.
For example, 10,000 contacts at four requests each is 40,000 requests: a bit over an hour on one key. See Authentication.
After the import
Run the sync loop once and compare the contact and deal counts with the old CRM. Then give your brokers access. Don't keep taking new work in both systems: two places to write make two different books.