Cookbook
Keep your CRM, and put an agent beside it
You are not leaving Salesforce this year, or HubSpot, or the system your recruiters live in. This is the job that lets an agent work anyway, without a migration and without your nightly sync undoing it.
The situation
Your CRM has seven years of history, a managed package, and reports the board reads. Nobody is replacing it. But it was built for people typing into forms, and the thing you now want is an agent that reads a call, updates the account, and tells you what changed. Handing an agent write access to the system of record is how you find out what an agent will do at three in the morning.
So do not. Keep the incumbent as the system of record, put Indraft beside it as the layer the agent writes to, and move what is worth moving between them.
What must be true when you are done
- Your CRM is still the system of record and nothing about it changed.
- Your agent writes freely, and every value it writes says so.
- The nightly import cannot undo what the agent learned yesterday.
- What flows back is only what the agent learned, never what you imported.
- You can tell, per field, which system said it.
Decide who owns which field, before anything else
This is the whole recipe and the rest is plumbing. Two systems holding the same field is fine; two systems believing they decide it is not. Write the split down before you wire anything.
- The incumbent owns identity and money. Account names, owners, amounts, close dates, anything a report or a commission plan is built on. These flow one way, in.
- Indraft owns what was said. Call summaries, what a person committed to, the risk somebody named, the reading of a thread. These are the things your CRM has no field for and your agent produces constantly.
- A small contested middle. Industry, lifecycle, job titles. Pick one owner per field. The next two sections are what happens when you get this wrong, which you will.
Mark what came from the incumbent
The import says where each value came from. One field, and it is what everything below depends on.
Agent
Key it on the incumbent's own record id and the job is safe to re-run. The second night finds the same record rather than making another:
Agent
The agent writes what it learned
Now the part your CRM cannot do. The agent records the call and updates what it now believes, and what it writes is marked as something it observed rather than something it was handed.
You
Ask which system said what, and you get an answer per field:
Agent
The night the import tries to undo it
This is where every "put a tool beside your CRM" plan dies. Tonight's export still says Industrial software, and it runs at two in the morning with nobody watching. In most setups it wins, silently, and the agent's work is gone by Tuesday.
Here it does not win, and it says so:
Agent
Something a person or an agent observed outranks something an import carried. The import is not rejected and not applied quietly: the response names the field, both values, and the standing of each, so your workflow can report it. A disagreement between your two systems is now a line in a log rather than a value that changed while you slept.
That is also your answer for the contested middle above. Get the ownership split wrong and you find out from a held-fields report rather than from a customer.
Push back only what the agent learned
The other direction is where people build a loop: they push everything back, the incumbent exports it again, and the two systems trade the same value forever. The change feed carries the assertion kind, so the filter that prevents it is one condition.
Agent
Send back the observed rows. Never send back the imported ones: those came from the incumbent in the first place, and echoing them is how a sync becomes a fight. Everything else about the wiring is the scheduling recipe: a trigger, an HTTP call, retries, and somewhere the failures go.
Verify it
- Run the import twice. One record, not two. If you get two, the incumbent's record id is not reaching the idempotency key.
- Have the agent change a field, then run the import again. The agent's value must survive and the response must name it as held. This is the test that decides whether the whole arrangement works.
- Read the held-fields report after a week. Every entry is a field two systems disagree about. A long list means the ownership split needs a decision, not that the product is fighting you.
- Check nothing imported flowed back. Look at what your workflow sent and confirm every row was observed. One imported row in there is a loop waiting for a quiet week.
Run it again
Nightly for the import, and whenever the agent works for the other direction. Revisit the ownership split once a quarter using the held report: the fields that keep appearing are the ones where you never actually decided, and deciding is cheaper than the argument you are currently having twice a month.