Event signal:plan.upgradedplan.downgraded| Destination:Salesforce| Use case:Churn Prevention Event Routing| Typical setup:~15 minutes
Workflow outcome
The workflow starts when a plan changes in your product and ends with Salesforce reflecting the current plan state and revenue context the account team needs.
The practical outcome is simple: the moment a user changes plans, Salesforce reflects it quickly enough for downstream workflow logic, handoffs, or prioritization to react.
Why teams care
Plan changes are some of the clearest expansion or contraction signals in a SaaS product, but they often stay trapped inside billing systems until a later sync catches up.
If Salesforce is the system the team actually works from, waiting for exports or one-off sync jobs means the best follow-up window is already slipping away.
The technical trap is treating plan changes like a reporting problem. They are really delivery problems across systems, with retries, field selection, and auditability all needing to hold up when the signal matters.
What it depends on
These pages stay focused on the workflow outcome, but the setup still needs the right workspace, destination connection, and event path underneath.
You need a workspace and publishable key so your product can emit plan change events.
Read moreAuthorize Salesforce in Meshes and confirm the connected user can update the contact fields you want to use.
Read moreDecide which Salesforce contact field or fields should represent current plan state, upgrade, or downgrade context.
Your application should emit plan.upgraded or plan.downgraded with the revenue context the CRM needs.
The source event
For Salesforce, the important part is not sending every billing detail. It is projecting the plan-change context into the contact fields your team actually uses to drive follow-up or reporting.
Event payload
plan.upgradedplan.downgraded{
"customer_id": "cus_5501",
"email": "sam@bluebird.app",
"old_plan": "starter",
"new_plan": "growth",
"effective_at": "2026-03-21T14:18:00Z",
"mrr_delta": 150
}What matters most
Used to identify the Salesforce contact that should receive the update.
old_plan
Provides the before-state so account teams can see what changed.
new_plan
Defines the current plan state the Salesforce record should reflect.
effective_at
Adds timing context when teams need to know exactly when the plan changed.
mrr_delta
Useful for flagging whether the event represents expansion or downgrade impact.
Field mapping view
| Event field | Destination target | Why it matters |
|---|---|---|
| Salesforce Contact email | Acts as the lookup key for the contact that should be updated. | |
| new_plan | Current plan field | Reflects the latest plan state for the account inside Salesforce. |
| old_plan | Previous plan field | Helps CS or RevOps see which direction the change moved. |
| mrr_delta | Expansion or downgrade indicator | Useful when the CRM workflow needs to distinguish growth from risk. |
| effective_at | Plan change timestamp field | Adds the timeline context the follow-up team often needs. |
The destination connection
In your Meshes workspace, create the Salesforce connection that should receive plan.upgraded and plan.downgraded. Before you build the rules, confirm the connected user can update the fields that reflect current plan state and revenue movement.
Where Meshes matters
Most teams do not need another destination. They need the destination to stay in sync without embedding its delivery quirks, retries, and mapping logic into the product code path.
In Meshes, create one or more Salesforce Update Property rules keyed off plan.upgraded and plan.downgraded, using email as the contact identifier and mapping the plan-change context into the fields your CRM workflow already expects.
A sample event
This is the part teams like: the source event stays readable and product-shaped while Meshes owns the destination-facing complexity.
TypeScript example
import MeshesEventsClient from '@mesheshq/events';
const events = new MeshesEventsClient(process.env.WORKSPACE_PUBLISHABLE_KEY!);
await events.emit({
event: 'plan.upgraded',
payload: {
customer_id: 'cus_5501',
email: 'sam@bluebird.app',
old_plan: 'starter',
new_plan: 'growth',
effective_at: '2026-03-21T14:18:00Z',
mrr_delta: 150,
},
});Destination outcome
Use Send Test Event in Meshes or send either a plan.upgraded or plan.downgraded event, then confirm the Salesforce contact updates the fields your CS or RevOps workflow uses.
Operational visibility
The difference between a nice demo and a usable product workflow is whether you can see what happened when the destination is slow, misconfigured, or unavailable.
In Meshes
Why teams buy Meshes
What's next
Use Case
See another lifecycle signal pushed into Salesforce for customer success and revenue follow-up.
Open linkIntegration
Review the Salesforce connection flow, supported actions, and contact-matching behavior.
Open linkDocs
Use the Meshes rule model and mappings docs to keep the Salesforce projection explicit.
Open linkCompare
Compare routed CRM updates with maintaining plan-change sync workers and retries yourself.
Open linkGuide
See the adjacent revenue-alert workflow where the same billing layer feeds Slack instead of Salesforce.
Open linkGuide
See another conversion-window workflow where delivery timing matters as much as the destination update itself.
Open link