URL: /code/integrations/your-crm · Id: `page:/code/integrations/your-crm`

# The CRM you already use

> Keep the CRM you know: your agents keep its contacts, companies and deals in step with your records, in the direction you choose.

Keep the CRM you know: your agents keep its contacts, companies and deals in step with your records, in the direction you choose.

```text title="Run it · Ask"
Show me what one sync with my CRM would change, with my records leading.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Integration.sync({ integration: 'integrations/crm-mirror' })
```

```json title="Run it · Response"
{
  "$type": "Integration",
  "mode": "try",
  "stored": false,
  "system": "crm",
  "direction": "mirror",
  "wouldChange": {
    "contacts": {
      "create": 41,
      "update": 12
    },
    "organizations": {
      "create": 18,
      "update": 3
    },
    "deals": {
      "create": 5,
      "update": 2
    }
  },
  "conflicts": [
    {
      "record": "contacts/rosa-northgate",
      "field": "title",
      "ours": "Owner",
      "theirs": "Property Manager",
      "wins": "ours"
    }
  ]
}
```

- **Connect:** Sign in once, 4 grants
- **Runs through:** [Your account](/code/integrations#three-ways)
- **First run:** See what one sync would change, record by record, free on your account
- **Sites:** None, it holds your records

## Connect once
1. Call `Integration.connect` with `system: 'crm'` and the `mode` you want, then open the `connectUrl` it returns and sign in to your CRM as an admin.
2. Choose the direction. `mirror` writes your records out, so your team sees every Contact, deal and Meeting in the CRM; `import` turns each edit made in the CRM into a Change here.
3. Pick the pipeline and the fields to keep in step; a field you leave out stays where it is.

| Grant | What it unlocks | Scope |
| --- | --- | --- |
| Contacts | People, read and written in the direction you chose | `contacts: read, write` |
| Companies | The Organizations they work at | `companies: read, write` |
| Deals | Deals and their stages in one pipeline | `deals: read, write` |
| Activity | Each Message and Meeting logged on the record’s timeline | `activities: write` |

| To | Do this |
| --- | --- |
| Pause | `Integration.pause` stops every sync at once and keeps the cursor; `Integration.resume` picks up the changes made meanwhile, once each. |
| Reconnect | `Integration.reconnect` returns a fresh `connectUrl` that lasts one hour, and keeps the Integration’s id and cursor, so nothing imports twice. |
| Disconnect | `Integration.revoke` revokes the token with your CRM; every record stays on both sides, and nothing is deleted from either. |

## What your agents do
| Ask | Verb | Runs through | Price |
| --- | --- | --- | --- |
| Keep my contacts, companies and deals in step with the CRM, my records leading. | [`Integration.sync`](https://startupbuilder.dev/business/nouns/integration/sync) | Your account | Free |
| Bring my existing CRM records in once, then keep them in step. | [`Integration.connect`](/code/integrations/calls/connect) | Your account | Free |
| Qualify this lead and open its deal in both places. | [`Lead.qualify`](/code/apps/crm/qualify) | Your account | Free |
| Move the Northgate deal to proposal, and show it in the CRM. | [`Deal.advance`](https://startupbuilder.dev/business/nouns/deal/advance) | Your account | Free |

Calls on your own account are free.

## What it holds
| Noun | The account’s object | When | Which side leads |
| --- | --- | --- | --- |
| [Contact](https://startupbuilder.dev/business/nouns/contact) | `contact or person` | In `mirror`: your agents write it out | Your records |
| [Contact](https://startupbuilder.dev/business/nouns/contact) | `contact or person` | In `import`: your team edits it in the CRM, and the edit arrives as a Change | The account |
| [Organization](https://startupbuilder.dev/business/nouns/organization) | `company or account` | In the direction you chose | Your records |
| [Deal](https://startupbuilder.dev/business/nouns/deal) | `deal or opportunity` | In the direction you chose | Your records |
| [Meeting](https://startupbuilder.dev/business/nouns/meeting) | `activity` | A Meeting is booked or held | Your records |
| [Message](https://startupbuilder.dev/business/nouns/message) | `activity` | A Message is sent or received | Your records |

## Events and webhooks
| Direction | Event |
| --- | --- |
| Emits | `Integration.synced`, `Lead.qualified`, `Deal.advanced` |
| Hears `record created or changed` | Becomes `Integration.synced` |

Any Event can wake a Workflow, and a Watch delivers it to your endpoint, signed ([Events and webhooks](/code/events)).

## Limits
| What | Limit | Call |
| --- | --- | --- |
| Direction | One per Integration. Your records stay the record in both modes, and the side you declared leads every conflict | Every call |
| The first sync | Reads every record once; each later run reads only what changed since the cursor, so a run takes seconds | [`Integration.sync`](https://startupbuilder.dev/business/nouns/integration/sync) |
| Stages | Map one to one onto the pipeline you picked; a stage with no match refuses with `venue-rejected` and names it | [`Lead.qualify`](/code/apps/crm/qualify) |

## Field map
| Our field | The CRM you already use’s field | Notes | Calls |
| --- | --- | --- | --- |
| `Lead.status` | `lead status or lifecycle stage` | Whichever your CRM keeps | [`Lead.qualify`](/code/apps/crm/qualify) |
| `Lead.fit` | `fit` | A field the platform adds: `strong`, `partial` or `none` | [`Lead.qualify`](/code/apps/crm/qualify) |
| `Lead.owner` | `owner` | None. | [`Lead.qualify`](/code/apps/crm/qualify) |

## What try does here
Reads your CRM and returns what one sync would change on each side, record by record; nothing is written to either.

## How long a connection lasts
A connection lasts until you revoke it in your CRM’s settings; the platform refreshes the token before it lapses.

The platform asks you to reconnect 7 days before it runs out; until you do, a call that needs it refuses with [`needs-reauth`](/code/refusals#needs-reauth).

## Plays and strategies
| Kind | Where |
| --- | --- |
| Plays | [Closer handoff](/plays/closer-handoff), [Buying committee](/plays/buying-committee), [lead nurture](/plays/lead-nurture), [lead reactivation](/plays/lead-reactivation) |
| Strategies | [Hands-on](/strategy/hands-on) |

## Used by
- **Workflows:** [Ad test setup](/capabilities/run-ads/ad-test-setup)
- **Services:** [Sales closing](/capabilities/convert-visitors/sales-closing)

## Reference

| Call | Path | Price |
| --- | --- | --- |
| [`Integration.sync`](https://startupbuilder.dev/business/nouns/integration/sync) | `POST /integrations/sync` | Free |
| [`Integration.connect`](/code/integrations/calls/connect) | `POST /integrations/connect` | Free |
| [`Lead.qualify`](/code/apps/crm/qualify) | `POST /leads/qualify` | Free |
| [`Deal.advance`](https://startupbuilder.dev/business/nouns/deal/advance) | `POST /deals/advance` | Free |