Leads and contacts are still the currency of many Sitecore projects. Even when I am the only engineer on an XM Cloud build, I have to make sure form submissions and engagement events reach Salesforce reliably or marketing and sales teams will not see the value.
Historically, teams wired Sitecore XP directly to Salesforce with custom APIs or legacy connectors. In the XM Cloud and composable era, Sitecore Connect becomes the primary integration hub:
- XM Cloud and your headless apps emit forms and events,
- Sitecore Connect picks them up,
- transforms them into a canonical schema,
- and pushes them into Salesforce and downstream systems.
This post walks through the pattern I use in that situation—a pragmatic design that:
- streams form submissions and key events into Salesforce,
- handles retries and idempotency,
- respects personal data (personally identifiable information, PII) and regional constraints,
- and leaves room to fan out to customer data platforms (CDP), warehouses, or other tools later.
At a glance, the flow looks like this:
How I model a canonical lead and event schema
Before wiring any connectors, I want to be clear on what I send to Salesforce.
Define a canonical lead/contact schema
I work with marketing and sales to define:
- lead/contact fields that matter (email, name, company, role, phone),
- lead source and campaign attribution fields,
- consent and subscription flags (legal requirements),
- any custom Salesforce fields (for example product interest, region, vertical).
I document this schema in docs/integrations/xm_to_salesforce_schema.md and treat it as a contract.
Map XM Cloud forms to the canonical schema
For each XM Cloud form I:
- identify which fields map to canonical lead/contact fields,
- decide how to handle optional or multi-value fields,
- capture additional context:
- page or route where the form was submitted,
- Experience Edge site and language,
- personalization or experiment IDs if available.
This mapping can live:
- in YAML/JSON configuration files that Sitecore Connect reads,
- or directly in Connect recipes (but still documented in git).
How I capture forms and events from XM Cloud
I need a reliable way to get submissions and events out of XM Cloud and into Connect.
Form submissions
Depending on the architecture:
- forms may post directly to a headless API you own,
- or to a Sitecore-provided endpoint,
- or to a serverless handler in Azure.
The pattern I use most often:
- The front end submits to a server-side endpoint (Next.js route handler or Azure Function).
- This endpoint:
- validates the payload,
- logs it (for example in Application Insights),
- writes a record into a queue or topic (for example Azure Service Bus),
- optionally triggers a Sitecore Connect webhook or connector.
Engagement events
Likewise, key engagement events (page views, call-to-action clicks, downloads) can be:
- captured client-side and batched to your backend,
- enriched with session or CDP identifiers,
- forwarded to a queue or event hub.
I rarely send every event to Salesforce; instead I:
- define a subset of conversion or intent events that matter (for example “demo request started,” “pricing page viewed 3+ times”),
- route those events into Connect for customer relationship management (CRM) updates,
- send the full stream to a customer data platform, analytics, or a warehouse.
How I use Sitecore Connect as the integration hub
With submissions and events landing in a queue or via webhooks, Sitecore Connect becomes the orchestrator.
Connect to sources and Salesforce
In Sitecore Connect I:
- configure connections to:
- your queue/event source (for example Azure Service Bus or HTTP webhook),
- Salesforce (using the official connector),
- any additional sinks (for example CDP or data warehouse endpoints).
I make sure:
- secrets are stored in Connect’s vault or underlying secret store,
- least privilege is applied (Salesforce user with necessary but not excessive permissions).
Implement flows for forms and events
Typical flows:
-
Form submission flow
- Trigger: new message on queue or webhook event.
- Steps:
- parse payload,
- map fields to canonical schema (using your mapping config),
- look up existing lead/contact in Salesforce by email or other keys,
- upsert lead/contact and create activity or task,
- set source and campaign fields.
-
Event flow
- Trigger: event representing meaningful engagement.
- Steps:
- enrich with contact info if available,
- create or update a Salesforce Campaign Member, Task, or custom object,
- optionally send a copy to CDP or analytics.
I keep flows small and composable and reuse mappings where possible.
How I handle retries, idempotency, and errors
Integrations fail. Networks glitch. APIs throttle. I try to design for this from day one.
Idempotency keys
I use idempotency keys to prevent duplicates:
- for form submissions: a hash of
(email, form_id, submission_timestamp_rounded)or a submission ID if I generate one, - for events: a unique event ID or a combination of
(session_id, event_type, timestamp).
I store these keys:
- in the queue message,
- and in Salesforce (for example in a custom field or an integration log object) to detect duplicates.
Retry policies and dead letters
I configure Connect and the queue to:
- retry transient failures with backoff (for example Salesforce timeouts),
- send poison messages (consistently failing payloads) to a dead-letter queue,
- notify an operations channel (email, Slack, or Teams) when thresholds are exceeded.
I try to include enough context in logs:
- payload excerpts (redacted as needed),
- error messages from Salesforce and intermediate steps,
- correlation IDs for tracing.
How I think about security, personal data, and regions
These flows handle personal data and sometimes sensitive marketing data.
Data minimization
I only send to Salesforce what is needed:
- I avoid including full free-text comments if they may contain sensitive information,
- if I must send them, I consider running a redaction step first (for example with an AI classifier that masks personal data),
- I avoid logging sensitive fields in Connect or queues.
Regionality and residency
If a project operates in multiple regions, I:
- ensure XM Cloud, queues, and Connect instances respect data residency policies,
- route European data through European-resident services where required,
- avoid moving personal data across regions unless explicitly allowed.
I document these choices for compliance teams.
How I fan out to CDP, data warehouse, and beyond
Once forms and key events are flowing reliably, I usually:
- send full event streams to Sitecore CDP or another customer data platform,
- push subsets or aggregates to a data warehouse (for example Azure Synapse, Snowflake),
- trigger downstream workflows (for example marketing nurture campaigns).
Patterns that work well:
- use Connect to branch flows: one branch to Salesforce, another to a customer data platform or warehouse,
- or have an Azure Function subscribe to the same queue and send copies where needed.
I try to keep:
- mapping logic centralized where possible,
- documentation updated when new destinations are added.
How I handle observability and stakeholder reporting
Integrations succeed when stakeholders can see what is happening.
I track and report:
- total form submissions and events processed,
- success versus failure rates by form and region,
- time from submission to Salesforce visibility,
- volume by campaign or channel.
I use:
- dashboards (for example Power BI or other BI tools),
- alerts for sustained error rates,
- regular reviews with marketing and sales to refine mapping and logic.
With this foundation, XM Cloud no longer sits as an island; it becomes a first-class source of truth for Salesforce and the rest of the go-to-market stack.
Useful links
- Sitecore Connect documentation — https://doc.sitecore.com/xmc/en/developers/sitecore-connect/sitecore-connect.html
- Sitecore XM Cloud documentation — https://doc.sitecore.com/xmc/en/home.html
- XM Cloud forms and data capture — https://doc.sitecore.com/xmc/en/users/xm-cloud/forms.html
- Salesforce developer documentation — https://developer.salesforce.com/docs