Integration · Revenue operations
How to build a sales engagement to CRM sync
A rep sequences a contact at an account another rep is negotiating with, and the CRM timeline has four thousand automated emails on it. Here is the model behind a sync that avoids both, the prompts that build it, and what it takes to run in production.
Built with Tray Headless
- System Salesforce
- Step Build the enrolment view
- Step Suppression check
- Step Enrol
- System Outreach
Suppression runs before every send rather than once at enrolment, because the reason not to send usually appears afterwards.
The short answer
What is a sales engagement to CRM sync?
Done well, a sales engagement to CRM sync is four things: activity logged at a level people can read instead of every automated send, suppression rules that stop sequences reaching accounts they must not touch, one definition of engagement shared by both systems, and enrolment driven from CRM state rather than from a list somebody exported. Most of these come apart on logging everything. A timeline with four thousand automated emails on it is a timeline nobody scrolls, and the two calls that mattered are lost in it.
What matters here
- Do not log every automated send. Summarise the sequence and log the replies, opens on high intent, and anything a human did.
- Suppression is the reason to build this. An open opportunity, an active support escalation or a legal hold must stop a sequence.
- Define engagement once. If the CRM and the engagement tool disagree about what engaged means, every report built on either is wrong.
- Drive enrolment from CRM state, not an exported list. A list is stale the moment it is downloaded.
- Never let a sequence reach somebody who unsubscribed, regardless of which system holds the record.
Who this is for
You run revenue operations or sales operations. Reps work in the engagement tool, managers report from the CRM, and the two disagree about what happened and to whom.
How it works in practice
What happens between a rep enrolling somebody and the CRM reflecting it usefully.
- 1
Enrolment is driven from CRM state
A saved view, not an exported list, so somebody who converted this morning is not sequenced this afternoon.
- 2
Suppression runs before every send
Open opportunity, active escalation, legal hold, unsubscribed, already in another sequence. Checked at send time instead of at enrolment.
- 3
Activity is logged at a readable level
The sequence as one record, plus replies, meetings and anything a human did individually.
- 4
Engagement is computed once
One definition, applied in one place, written to both systems rather than calculated twice with different answers.
- 5
A reply pulls the person out of automation
Immediately, and notifies the owner. Nothing is worse than a sequence continuing after somebody answered.
- 6
The CRM stays the reporting surface
Managers report from one place, and it agrees with what the reps see.
What the sync is made of
Two tools with overlapping jobs. Four parts, and the second one prevents the incident.
Readable activity logging
The sequence summarised, the replies and meetings logged individually. A timeline of every automated send is a timeline nobody reads.
Suppression rules
Checked at send time, not at enrolment. Open opportunities, escalations, legal holds and unsubscribes all stop a sequence.
One engagement definition
Computed once and written to both, because two definitions produce two dashboards and an argument about which is right.
Enrolment from CRM state
A live view rather than an exported list, so state changes between download and send cannot cause the wrong email.
The Tray Headless prompts
Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.
Once per project, run
/tray-workflows:set-workspace
to pick the workspace these build in. Point it at a sandbox first.
- 1
Set up and find where suppression state actually lives
The reasons not to send are scattered across several systems.
Headless skills
build-workflowUse build-workflow. The systems in play are Salesforce and Outreach, or whatever we run in those seats. I need the Outreach prospect and sequence model including how enrolment and finishing work, and from Salesforce the Lead, Contact, Opportunity and Case objects plus any opt-out field. Specifically map where each of these lives: an open opportunity, an active support escalation, a legal or compliance hold, and an unsubscribe. Those four are the reasons not to send, and they are in different places.
- 2
Suppress at send time, not at enrolment
Because state changes between enrolling somebody and emailing them.
Headless skills
build-workflowUse build-workflow. Before every send, not once at enrolment, check: An open opportunity on the account owned by somebody else An active support escalation above a severity A legal or compliance hold on the account An unsubscribe, in either system, treated as authoritative The person already active in another sequence The account in a do-not-contact list Any hit pauses the sequence for that person and tells the enroller why. Do this at send time. A prospect enrolled on Monday whose account opened an escalation on Tuesday must not receive Wednesday’s email, and an enrolment-time check will not catch that.
This is the step that prevents the incident everybody remembers: an automated nudge landing while an account is escalated or in negotiation.
- 3
Log at a level somebody will read
A timeline of four thousand automated emails is a timeline nobody scrolls.
Log to the CRM selectively: The sequence enrolment as one activity record, with the sequence name and the enroller, updated as it progresses rather than appended to Every reply, logged individually with its content Every meeting booked Calls and manually sent one-to-one emails Sequence completion or exit, with the reason Do not log every automated send, every open and every click as separate activities. Roll those into counts on the sequence record. Then update Last Activity Date from meaningful interactions only. If an automated open refreshes it, every hygiene rule that depends on activity becomes meaningless, and pipeline hygiene is usually built on exactly that field.
- 4
Define engagement once
Two definitions produce two dashboards and a standing argument.
Headless skills
tray-gotchasUse tray-gotchas, then compute engagement in one place and write the result to both systems. A workable definition: a reply, a meeting booked, or a click on a high-intent link. Opens do not count, because open tracking is now unreliable enough that including it makes the metric noise. Write an engagement score and a last-engaged timestamp to both. Never let each system compute its own, because they will diverge within a week and every report built on either becomes indefensible. Also pull somebody out of automation the moment they reply, and notify the owner within minutes. A sequence that continues after a human answered is the fastest way to lose a deal you had.
- 5
Enrol from live CRM state
An exported list is stale the moment it is downloaded.
Drive enrolment from a saved CRM view evaluated at run time, not from a list somebody exported. Re-evaluate membership before each send. Somebody who converted, became a customer or opened an opportunity since enrolment leaves the sequence automatically instead of continuing to receive prospecting email. Then report weekly: sends suppressed and by which rule, replies and meetings by sequence, sequences continuing after a reply, which should be zero, and any send that reached a suppressed account, which should also be zero. Those two zeros are the health of this integration. Everything else is volume.
- 6
Validate, then hand the rules over
Because suppression rules are commercial policy.
Run the per-step schema checks and the whole-workflow audit before this touches production. Then open the same workflow in Tray Build so sales operations can add a suppression rule or change the engagement definition in the visual canvas. Those rules change after every incident, and the change should take an afternoon rather than a sprint.
What it connects to
The engagement tool sends, the CRM decides who may be sent to.
Outreach
Read sequence state, replies and meetings. Write enrolment, and pause a sequence when suppression fires.
Reads and writes
Salesforce
Read the suppression state and the enrolment view. Write summarised activity and the shared engagement score.
Reads and writes
Zendesk
Read active escalations, because an automated nudge during a severity one is the incident people remember.
Reads
Gong
Read call outcomes, so a conversation that happened outside the engagement tool still counts as engagement.
Reads
Slack
Tell the owner within minutes of a reply, and tell the enroller when suppression stopped a send.
Writes
Snowflake
Land suppression and engagement history, so sequence effectiveness is measurable by segment.
Writes
Same build, other stacks
The design does not change if you run something else in one of these seats. The same prompts build it against Microsoft Dynamics 365, Google BigQuery, Microsoft Teams, Jira, HubSpot or Databricks.
Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.
Running it in production
This sends email to customers and prospects on the company's behalf. The suppression path is a control.
It runs on the platform, not on somebody's machine
Send-time suppression checks run against every send at whatever volume the team generates, on the same engine, with a record of each decision.
Every suppression is recorded
Which rule fired, for whom, and when. When somebody asks why a prospect was not contacted, that is the answer.
No credential ever lands in the workflow itself
The engagement tool credential can send email as your company. It lives in your workspace, scoped and revocable, never beside the logic.
Sales operations own the rules
Suppression rules and the engagement definition open in Tray Build, changed by the team that owns outbound policy.
Two numbers should always be zero
Sequences continuing after a reply, and sends that reached a suppressed account. Alert on both instead of reporting them monthly.
Questions people ask
Why not log every automated send to the CRM?
Because a timeline with four thousand automated emails on it is one nobody scrolls, and the two calls that mattered are buried. Summarise the sequence and log replies, meetings and anything a human did.
Why check suppression at send time rather than enrolment?
Because state changes in between. A prospect enrolled on Monday whose account escalates on Tuesday must not receive Wednesday’s email, and an enrolment-time check cannot catch that.
Why compute engagement in one place?
Because if both systems calculate it, they diverge within a week and every report built on either becomes indefensible. Compute once, write to both.
Should opens count as engagement?
No. Open tracking is unreliable enough now that including it turns the metric into noise. A reply, a booked meeting or a high-intent click are real signals.
What should the automation never do?
Continue a sequence after somebody replied, and reach an account under suppression. Both should be zero and both should alert, not appear in a monthly report.
Related guides
Revenue operations
How to build lead routing that assigns in seconds
Match the lead to an account first, evaluate rules in a fixed order, catch what they miss, and time it from arrival. The Headless prompts that build it.
Revenue operations
How to build pipeline hygiene automation
Detect the staleness that matters, nudge the owner rather than the report, escalate on the deals that count, and measure whether it worked. The prompts that build it.
Revenue operations
How to build a conversation intelligence to CRM sync
Write the few fields a rep will act on, keep every claim linked to its moment in the call, and never let a model set a close date. The prompts that build it.
Last reviewed September 2026.