# Connecting Salesforce

Connect a Salesforce org to Wire and pick which objects flow into which containers. Accounts, contacts, opportunities, custom objects — each record becomes an entry your agents can search and read, and the relationships between records (a contact's account, an opportunity's company, the tasks on a deal) become a navigable graph. Salesforce stays the source of truth; Wire mirrors the slice of it you want available to your agents.

Unlike file connectors, Salesforce syncs **records, not files**: each record is an entry, and CRM relationships come straight from your Salesforce schema rather than being inferred.

## Before you start

- **Edition:** API access is required. It's included in Enterprise, Unlimited, Performance, and Developer editions. Professional edition needs Salesforce's paid API add-on; Starter and Pro Suite don't qualify.
- **Who connects:** whoever clicks Connect authorizes Wire as the Salesforce user they're logged in as. If that person is a Salesforce administrator, no Salesforce-side setup is needed at all — approval happens right on the consent screen. If they're not an admin, a Salesforce admin may need to approve the Wire app first (Salesforce blocks unapproved apps by default).

## How it's organized

Wire splits the connection in two, the same way as every connector:

1. **Connector** is the authorization. Lives at the **organization** level. An owner or admin connects a Salesforce org once; anyone with permission can then attach objects from it to their containers.
2. **Source** is a set of objects (e.g. Account + Contact + Opportunity) that flows into a specific container. One connected org can feed many containers, each with its own object selection.

## Permissions

| Action | Who can do it |
|---|---|
| Connect / disconnect a Salesforce org at the org level | **Owner**, **Admin** |
| View the connectors list | All members |
| Attach objects to a container | Anyone with **edit** access to that container |
| Detach a source / sync a source | Anyone with **edit** access to that container |

Separately, **what Wire can see inside Salesforce** is decided entirely by the Salesforce user who connected: Wire reads exactly the objects, fields, and records that user's profile and sharing rules expose, and nothing more.

## Step 1. Connect at the org level

1. Open **Organization → Connectors** in the Wire dashboard.
2. Click **Add connector** and pick **Salesforce**.
3. Click **Continue to Salesforce**. You'll be sent to Salesforce to sign in (if you aren't already) and approve read access for Wire.
4. Approve, and you land back on the Connectors page with the org connected.

Wire asks Salesforce for read access via the API: it can query records and schema, and nothing else. Wire never creates, modifies, or deletes anything in the connected org.

### Recommended for production: a dedicated integration user

Connecting as yourself works and is the fastest way to try things out. For a durable production setup we recommend connecting as a **dedicated integration user** instead, because a personal connection stops syncing when that person changes their password, is deactivated, or leaves the company.

The recipe (done by your Salesforce admin, ~10 minutes):

1. Create a user with the **Minimum Access – API Only Integrations** profile. Enterprise edition and above include **5 free Integration User licenses**, so this costs nothing.
2. Grant it **read** permission (via permission sets) on exactly the objects you want Wire to sync. This doubles as your scoping mechanism: Wire can never see more than this user can.
3. Log in to Salesforce as that user and click Connect in Wire.

Reconnecting as a different user later is just running Connect again while logged in as them — it appears as its own connector row, and you can move container sources over at your own pace. The connector row always shows which login it's connected as, so you can tell at a glance whether you're on a personal login or the integration user.

## Step 2. Attach objects to a container

1. Open the container you want to feed.
2. Go to the **Sources** tab.
3. In the **Salesforce** row, click **Setup** (or **Edit** if you already have a source attached).
4. Click **Add objects** and pick which objects to sync. The list is your org's real schema — standard and custom objects both — with the core CRM set (Account, Contact, Opportunity, Content Note) pre-selected. Use the filter box if your org has hundreds of objects.
5. Click **Attach**. Wire kicks off a backfill of the selected objects.

The source row shows its state with a pill:

| Pill | Meaning |
|---|---|
| **Pending** | Queued, backfill hasn't started yet |
| **Syncing** | Backfill is running, records are landing |
| **Synced** | Caught up with Salesforce |
| **Error** | Something went wrong, hover the row for details |

Large objects backfill in batches across several sync cycles, so a big org fills in progressively rather than all at once.

## What lands in the container

- **One entry per record**, titled by the record's name, with its fields laid out as readable text. Formula fields are excluded (they can change without the record itself changing, so they'd go stale).
- **Relationships as graph edges.** Lookup and master-detail fields — a Contact's Account, an Opportunity's Account, a Task's related records — become explicit relationships agents can traverse with `wire_navigate`. These come from your schema, not from inference, so they're exact.
- **Stable identity.** When a record changes in Salesforce, its entry is updated in place. Agents' references and the graph stay intact across updates.
- **Notes, with their full content.** Salesforce notes (Enhanced Notes) are often the highest-value context in a CRM — meeting summaries, call notes, the "why" behind a deal. Sync the **Content Note** object (pre-selected in the picker) and each note lands with its complete body, linked in the graph to the records it's attached to. Legacy notes (the older Notes feature) sync through their own **Note** object.

## Keeping things in sync

After the initial backfill, Wire polls for changed records on a regular cadence — creates and updates flow in continuously. Deletions and merges are reconciled on a daily pass:

- **Deleted records** are removed from the container.
- **Merged records** (e.g. two duplicate contacts merged in Salesforce) resolve to the surviving record; the duplicate's entry is removed and references redirect to the winner.

If you've just made a change and want it reflected immediately, hit **Sync now** on the source row.

### API usage

Syncing spends API calls from your Salesforce org's daily allocation, which is shared across all your integrations. Wire is deliberately conservative: it self-throttles to a small daily budget, and it stops syncing entirely for the day if your org approaches its overall API limit — Wire will never be the reason another integration hits the wall. A skipped sync resumes automatically once the allocation resets.

## Detaching a source

Go back to the **Sources** tab, hit **Edit**, then the trash icon on the source row. Wire archives the source, then removes every record it synced from the container in the background — entries, relationships, and embeddings. **Your Salesforce org is never touched.** Detaching only removes Wire's mirror.

## Disconnecting

At the org level (**Organization → Connectors → Disconnect**), disconnecting cascades through every container the org fed, removing synced records in the background.

You can also revoke Wire from the Salesforce side (**Setup → Connected Apps OAuth Usage**). Wire notices on the next sync and marks the connector as needing re-authorization; reconnecting from the Connectors page restores it, and attached sources resume where they left off.

## Limits and notes

- Up to 20 objects per source. Attach additional sources if you need more.
- Very long text fields (e.g. a huge note body) are truncated in the entry with an explicit marker; the full text stays in Salesforce.
- Records sync at up to a few thousand per cycle, so very large objects take multiple cycles to backfill completely.
- A sync paused for more than 30 days can miss deletions that happened in the gap (Salesforce's deletion log only goes back 30 days). Detach and re-attach to fully reconcile.

## Privacy and security

- Wire's access is read-only API access; it can never write to your org.
- Wire sees only what the connected Salesforce user's profile and sharing rules allow.
- Authorization tokens are encrypted at rest with a key Wire never exposes to its own application code, and every read of them is logged.
- Revoking access from either side stops syncing immediately; nothing keeps working in the background.

## Troubleshooting

**The connector shows "needs re-authorization"**
Access was revoked on the Salesforce side — commonly because the connecting user's password changed, their session policy expired the grant, or an admin revoked the app. Click **Connect** on the Connectors page and approve again; the same connector row is restored and sources resume. If this recurs, switch to a dedicated integration user (see above).

**Connecting fails with an approval error**
Your Salesforce org blocks apps that an admin hasn't approved. Ask a Salesforce admin to run the Connect flow once (their approval registers the app), or to approve the Wire app under **Setup → Connected Apps OAuth Usage** — after that, non-admin users can connect.

**An object I expect isn't in the picker**
The picker shows objects the connected user can query. Check that user's profile/permission sets in Salesforce.

**Sync says it's skipped for API limits**
Your org is near its daily API allocation (or Wire's own conservative budget is spent). Syncing resumes automatically after the daily reset. If you need a higher budget for Wire, contact support.