> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Salesforce to Orbit: reconnect, or run both

> Move your messaging and contact-data workflows off Salesforce (or onto it next to Salesforce) — decision matrix for replace-all vs side-by-side, the contact-object map, and a seven-step relink runbook.

# Migrate from Salesforce to Orbit

A Salesforce migration differs from a platform-messaging migration (Twilio, Vonage, …) in one fundamental way: the source is a *system of record*, not a sending pipe. When a team says "migrate off Salesforce," they usually mean one of three different things. Pick the row that matches what you actually need before you touch a connector:

| What you mean                                                                                     | The move                                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Send Orbit campaigns driven by Salesforce segments or reports                                     | Don't migrate — keep Salesforce live as the source, connect it so it *selects* audiences at send time. [Connect HubSpot & Salesforce](/guides/hubspot-salesforce-integration). |
| Surface Salesforce Accounts/Opportunities next to Orbit conversations                             | Don't migrate — connect so the inbox and customer 360 show your CRM context. Same guide.                                                                                       |
| Consolidate: stop using Salesforce as the daily CRM and run customer engagement entirely in Orbit | **This guide.** Salesforce is either retired or shrunk to a compliance record while Orbit takes over contact, messaging, and routing.                                          |

The connector is identical either way — OAuth via Nango, `integration_id: "salesforce"`. What changes is what you do *after* the connection is live. The sections below are ordered for a consolidation, but sections 1–4 are identical to a parallel-run setup (parallel Salesforce and Orbit for a season is fine), so they apply regardless.

## 1. What's exported from Salesforce — know before you start

Export these from Salesforce before you change anything, while the org still has full data:

* **Contacts and Leads** — a CSV per object, with the fields your campaigns reference (Email, Phone, MobilePhone, custom fields). Include `OwnerId`, `AccountId`, and your own record-type and consent fields.
* **Accounts** — the company dimension. Orbit maps Accounts to the CDP `accounts` entity for [linked audiences](/guides/linked-audiences); export account name, tier, ARR/MRR if you segment on it.
* **Opportunities** — for history and audience modeling, not for the daily workflow in Orbit.
* **Tasks / Events** — Salesforce activity history. Orbit's [CRM activity logger](/guides/hubspot-salesforce-integration#provider-differences) writes new communications as Tasks *into* Salesforce going forward, but it does not backfill history. Export history if you need it; otherwise move forward without it.
* **Reports and list views** — the segments your campaigns reference. These do not export as CSVs you can act on; you will rebuild them in Orbit as a [CDP segment](/guides/cdp-segments), or point an Orbit campaign at the Salesforce report as a live audience source (see [choose the recipient list](#3-recreate-your-audiences-in-orbit)).

Keep the exported CSVs — they are the audit spine if a row doesn't reconcile after the relink.

## 2. Connect Salesforce to Orbit (OAuth, admin-only)

The connection is the standard Nango OAuth integration. Only **owner/admin** roles can run it — it touches provider credentials.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/integrations/connect \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "integration_id": "salesforce" }'
```

The response returns an `auth_url`; redirect the browser to it and complete the OAuth consent. Orbit polls the org for *Contact, Lead, Account, Opportunity, Ticket* changes and receives real-time updates if you wire a webhook (that is optional — the poller alone works).

Verify the connection landed:

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/integrations \
  -H "X-API-Key: dv_live_sk_your_key_here"
# Expect a row for provider: 'salesforce' with connected: true
```

Inbound syncs then populate Orbit contacts: FirstName, LastName, Email, Phone, MobilePhone, Account fields, and the `salesforce:`-namespaced attributes for org-specific fields. The identifier link is written on each contact as `attributes.salesforce_id`. Once a link exists, outbound write-back is HubSpot-only today — Salesforce is poller-only (the [Provider differences](/guides/hubspot-salesforce-integration#provider-differences) table names which paths are live).

## 3. Recreate your audiences in Orbit

A Salesforce *segment* (a report, a saved list view, a report filter) is not a portable object — moving it means either recreating it natively on Orbit's contact data, or pointing an Orbit campaign directly at the source while Salesforce is still live. Both are supported:

| Salesforce object                                                                                                        | Orbit destination                                                                                                                              | When to use it                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Report (a filtered Contact/Lead report)                                                                                  | Point the campaign at the live report — audience\_source: `salesforce_report`, `ref`: the report id                                            | You still own the report in Salesforce and trust it as the source of truth. Orbit resolves the members at send time.         |
| List view (a saved filter over Contacts or Leads)                                                                        | Point the campaign at the view — audience\_source: `salesforce_list_view`, `ref`: the view id, `sobject`: `Contact` or `Lead`                  | A short-lived filter you don't want to rebuild. Orbit passes the `sobject` hint so the resolver reads from the right object. |
| List of fixed emails/phones (or any segment you intend to keep in Orbit)                                                 | [CSV import](/guides/import-contacts) into Orbit's contact book, then build a native [CDP segment](/guides/cdp-segments) over it.              | Day-zero data consolidation; the Salesforce report is retired.                                                               |
| A segment that traverses Accounts → Opportunities (e.g. "profiles on accounts with at least one closed-won Opportunity") | [Linked audiences](/guides/linked-audiences) over the CDP data graph — declare the entity once, then compose relational audiences with no SQL. | Your targeting is genuinely relational, not just a flat filter over one object.                                              |

Recreate audiences before you retire the SalesForce report — a campaign that points at a Salesforce report works only while the connection is live.

## 4. Mirror ongoing activity back to Salesforce (optional)

If Salesforce stays live for a period (compliance desk, finance, an org not yet decommissioned), Orbit can write each new message and call back into the contact's engagement timeline so a Salesforce user opens a Contact and sees Orbit SMS/WhatsApp/voice/email mixed chronologically — without a poll.

This runs once you enable activity logging; dispatch is fail-open per [CRM activity logger](/guides/hubspot-salesforce-integration#step-5---failure-modes-and-monitoring) (a Salesforce outage never blocks an Orbit send; failed fanouts are logged as audit + PostHog events, never retried on the critical path). The provider mapping is:

| Orbit channel   | Salesforce engagement             |
| --------------- | --------------------------------- |
| SMS / RCS / MMS | Task with `Subject: 'SMS'`        |
| WhatsApp        | Task with `Subject: 'WhatsApp'`   |
| Voice           | Task with `Subject: 'Voice Call'` |
| Email           | Task with `Subject: 'Email'`      |

Enable only when you are keeping the connection alive for a season — if you plan to cut the org in under a month, skip this step.

## 5. Rebuild the daily workflow in Orbit

This is the consolidation step — the daily engagement, messaging, and ticketing work that lived in Salesforce moves to Orbit's own surfaces:

| Salesforce surface                | Orbit equivalent                                                                                                         |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Sales/Service Cloud inbox         | [Unified inbox](/guides/inbox-setup) — SMS, WhatsApp, email, voice, social in one thread                                 |
| Sales/Service ticket / Case       | [Inbox tickets](/guides/inbox-tickets-workflow) — assign, link to conversations, macro, defer                            |
| Sales cadences / Sequences        | [Campaigns](/guides/campaign-end-to-end) with multi-channel steps                                                        |
| Einstein / AI replies             | [AI agent assistant](/guides/agent-assist-whisper-coaching) or [Orby, the operator assistant](/guides/orby-in-dashboard) |
| Process builder / Flow automation | [Flows (visual builder)](/guides/build-first-flow)                                                                       |
| Reports over engagement           | [Analytics](/guides/ask-your-data-insights) — delivery, response time, agent performance                                 |

The rebuild is gradual — leave Salesforce live while you move one workflow over at a time and harden each. The [seven-step cutover runbook](/guides/migration-playbook-hub#4-runbook-for-cutover--the-canonical-seven-steps) applies unchanged; the only provider-specific detail is which Salesforce objects step 3 (audiences) and step 6 (mirror write-back) close out.

## 6. Reconcile, then cut over

The generic seven-step cutover in [Migration playbook hub](/guides/migration-playbook-hub#4-runbook-for-cutover--the-canonical-seven-steps) works as-is; these are the Salesforce-specific verification checkpoints to hang off it:

1. **Freeze sends on Salesforce** — Marketing Cloud / Account Engagement / Service Cloud outbound; whatever you have that sends. Verify your outbound queue reads empty while Orbit keeps flowing on the split traffic.
2. **Redirect webhooks** — if you wired a webhook for real-time Salesforce updates into Orbit, leave it running until cutover. On Orbit, the verification is the same `X-Orbit-Signature` HMAC — replay a `message.delivered` against your receiver before you cut over.
3. **Swap API keys** — cut your own integration (if any) onto an Orbit key; the OAuth connection to Salesforce itself stays until decommission.
4. **Flip sender identity** — the route-by step is traffic-side, not Salesforce-side; the destination sender moves to Orbit's numbers.
5. **Watch the first-hour parity window** — delivery-rate parity on the split class before decommissioning.
6. **Hold the fallback warm** — keep the Salesforce org connected (sync still running) for one full billing cycle as a compliance record if needed. The OAuth connection can be revoked separately from closing the org.
7. **Decommission** — verify: the org shows no live sends, `GET /api/v1/integrations` shows the `salesforce` row revoked, and your exported CSVs reconcile row-for-row with the contacts Orbit reports imported. Then close the org.

## 7. Operate after the migration

Once cut over, the ongoing surfaces that keep a migration honest:

* **Settings → Migrations** — the job history for every import run lives here, with status and rollback. [Monitor, cancel, and roll back platform migrations](/guides/migration-jobs-operations).
* **Audit ledger** — every relink, rollback, and export lands in the tenant audit log; when a contact lost its Account mapping, the ledger is the timeline that says which step introduced it.
* **Suppression and consent state** — Salesforce opt-outs must exist in Orbit's per-channel suppression before decommission, or a compliance defect follows. [Opt-out lists](/guides/opt-out-lists) covers how Orbit enforces it.
* **Sync health** — if you left Salesforce connected as a record, `GET /api/v1/integrations/{id}/status` reports the per-sync `last_sync` timestamp, and **Settings → Integrations → Salesforce → Status** surfaces the same.

<Tip>
  Consolidating off Salesforce entirely, or running both for a season? The solutions team works Salesforce offloads regularly — [migrate@devotel.io](mailto:migrate@devotel.io) with your org shape and traffic mix gets you the same dual-run plan the sections above assume.
</Tip>
