Staying in sync
There are three ways to find out what changed in a brokerage. They work best together: webhooks
tell you when to look, the change feed tells you what changed, and updated_since covers the
lists the feed does not.
| Tool | What it gives you | Can it miss a change? |
|---|---|---|
GET /v1/changes | Every change, in order, with deletes and merges | No, within 30 days |
| Webhooks | A signed POST to your server, seconds after a change | Yes. Treat it as a hint |
updated_since | The rows of one list that changed since a time | No, but it cannot see deletes |
For a working sync loop with code, follow the Sync your book guide.
The change feed
GET /v1/changes is the source of truth for a sync. It returns every change to the contacts,
leads, deals, tasks, intakes, documents, appointments, and communications your key can read, in
the order the changes took effect. BrokerPlus writes each entry in the same database transaction as
the change itself, whether the change came from the app, an import, an automation, or the API. A
checkpoint never skips an entry.
Code
Code
What each action asks you to do:
action | Do this |
|---|---|
created, updated | Read the record again by record_id, and upsert it. |
archived | Read it again. It left the active book, but you can still read it. |
deleted | Remove it from your copy. |
merged | Point your references at merged_into_id, then remove it. |
The rules that matter:
- Start with
after=now. It returns a checkpoint and no entries. Take it before you copy the lists, so a change made during your copy is still in the feed. - Save
next_checkpointafter you apply the page, not before. - Follow
has_more, not the page size. A page can be short, or even empty, whilehas_moreistrue. Call again at once. When it isfalse, wait and poll again. - A checkpoint belongs to its
types. Keep one checkpoint pertypesvalue you use. You can read it with the sametypesor fewer. Reading more types from it would skip their entries, so that returns400 INVALID_CHECKPOINT. A checkpoint fromafter=nowbelongs to thetypesyou sent with it, or to every type when you sent none. - Entries are kept for 30 days. An older checkpoint returns
410 CHECKPOINT_EXPIRED. Take a new one withafter=now, copy the lists again, and carry on from there. - The feed covers the fields of the record itself. Rows that hang off a record, such as addresses, notes, or the mortgage application, are not in it. Read them when their parent changes.
Webhooks
A webhook is a signed POST that BrokerPlus sends to your server when something happens, such as
lead.created or deal.stage_changed. It arrives in seconds, so it is the fastest signal you get.
A webhook is a hint, not a record of truth. A delivery can arrive late, arrive twice, or, after an outage longer than its retry window, not arrive at all. So on each delivery, read the change feed from your checkpoint, or read the record by its id. Never build your copy from the webhook bodies alone.
How to register an endpoint, verify a signature, and read the delivery log is on the Webhooks page.
updated_since on a list
The main record lists accept updated_since: contacts, leads, deals, tasks, intakes, appointments,
submissions, communications, opportunities, and campaigns. The API reference shows it
on each list that has it.
With updated_since, a list returns the rows that changed at or after that time, oldest change
first, with ties broken by id. To read on from the last row you saved, send its updated_at as
updated_since and its id as after_id, and keep page at 1:
Code
Don't sync with page numbers. A row that changes while you read moves to the end of the order, every
later row shifts up one place, and the next page skips a row. The updated_at and id pair does
not move, so nothing is skipped.
A value of updated_since that is not a date returns 400 VALIDATION_ERROR, and so does after_id
without updated_since.
Records that leave a list
A list cannot tell you that a record is gone. It just stops returning it.
| Record | Leaves the list when |
|---|---|
| Contact | It is deleted, archived, or merged into another contact. |
| Deal | It is deleted, or BrokerPlus marks it as a test. |
| Lead | It is deleted. An archived lead stays, with archived_at set. |
The change feed reports all of these. For a list the feed does not cover, run a reconcile now and then: read the full list, and remove from your copy each id that is no longer in it.
Small lists
Users, teams, pipelines, tags, lenders, and the other setup lists are small and change rarely. Read them in full on each run.