Connect a custom CRM
Receive contact and opportunity updates from any CRM, then optionally send CJM scores back.
Use Custom CRM when your CRM does not have a CJM connection. It gives you two independent flows:
- Inbound Webhooks: your CRM or automation sends contacts and opportunities to CJM.
- Sync Out: CJM sends a contact's score and label back to your CRM.
You can use either flow on its own. A Viewer can see this setup; an Administrator is required to enable it, create webhooks, change mappings, rotate tokens, or configure Sync Out.
Receive data from your CRM
This flow is CRM → CJM. Create one webhook for each type of update you want to receive:
- Contact created, updated, or deleted.
- Opportunity created.
- Opportunity stage changed.
- Opportunity value changed.
Each webhook has its own URL, so send only the matching event type to it.
Set up an inbound webhook
- Open Pipeline → Connections, find Custom CRM, and select Enable.
- In Inbound Webhooks, select Create webhook.
- Give it a recognizable name, select its Event type, then select Create webhook.
- Copy the Webhook URL and add it to the corresponding webhook or automation in your CRM.
- Send one realistic test event from the CRM.
- Return to CJM. When the captured sample appears, map its fields and select Save mapping.
The URL contains a secret token. Treat it like a password: store it only in your CRM or secret manager and do not publish it. CJM shows the complete URL when it is created; if you need a replacement later, use Rotate token.
What happens to the first event
Before a mapping exists, CJM captures the JSON you send as a sample. It does not process that first event as a contact or opportunity. This lets you select the actual fields sent by your CRM before data enters the pipeline.
The webhook status tells you what to do next:
| Status | Meaning | Next action |
|---|---|---|
awaiting sample | CJM has not received a sample yet. | Check the URL and send a test event. |
ready to map | A sample is available. | Map the fields and save. |
active | The mapping is saved and future matching events are processed. | Monitor your CRM and edit the mapping if its payload changes. |
disabled | CJM ignores events sent to this URL. | Re-enable it when you are ready; the saved mapping remains available. |
Map the fields
For each CJM field, choose From sample field to use a value in the captured JSON, or Static value when the value is always the same.
CRM Contact ID is required for every event. Map the same stable contact identifier your CRM uses for that person. Email, phone, name, company, opportunity ID, stage, pipeline, value, and currency are optional, but mapping them improves profile matching and reporting.
For opportunity events, saving the field mapping is only the first half of setup. Create a manual CJM pipeline, add its stages, and use Link external stage ID to connect the exact captured crmStageId to the right stage. Follow Map pipeline stages. The raw pipeline ID and name are optional reference values; CJM does not infer a stage from its display name.
You can edit an active mapping without pausing the webhook. CJM keeps the most recent sample, so send another representative event if your CRM changes its field names or nesting.
Security and lifecycle
The inbound endpoint accepts any JSON object. It does not expect an HMAC signature header: the secret token in the URL authorizes the request. Do not add the token to logs, documentation, or client-side code.
- Rotate token stops the old URL immediately. Update the CRM with the new URL before sending more events.
- Turning the webhook off makes CJM ignore events without asking the sender to retry.
- Delete permanently removes the webhook and makes its URL stop accepting events. Create a new webhook if you need it again.
Send CJM data back to your CRM
Sync Out is the reverse flow: CJM → your endpoint. It is useful when your CRM or automation should react to a contact's CJM score or pipeline state.
Configure Sync Out
- Open Pipeline → Connections, select Manage webhooks on Custom CRM, then open Sync Out.
- Enter a public endpoint that accepts a JSON
POST, such as a Zapier or Make catch hook, or an endpoint you manage. - Select Save.
- Copy the displayed Signing secret immediately and store it safely.
CJM sends this JSON body when the contact's score or stage changes:
{
"crmContactId": "the-contact-id-from-your-CRM",
"score": 75,
"label": "WARM",
"syncedAt": "2026-09-07T10:00:00.000Z"
}Every request includes X-CJM-Signature, formatted as sha256=<hex digest>. Verify it with HMAC-SHA256 using the signing secret and the exact raw JSON body. Saving a Sync Out URL creates a new secret, so update the receiving endpoint after each save.
Verify and troubleshoot
Trigger a real score or stage change, then check both the receiving endpoint and the fields under the Sync Out URL:
- Last attempt: when CJM last tried to send data.
- Last status: whether that attempt succeeded or failed.
- Last error: the latest error CJM received.
The receiving endpoint must respond within 10 seconds. Failed Sync Out requests are not retried automatically, so fix the URL, availability, or signature verification and trigger a new score or stage change to test again.
Common problems
- Still waiting for a sample: ensure your CRM is posting JSON to the complete current URL. A rotated or deleted URL no longer works.
- Mapping cannot be saved: set CRM Contact ID. It is required even for opportunity updates.
- A stage has no expected effect: map its raw
crmStageIdin a manual pipeline as described in Map pipeline stages. - Sync Out fails: check that the endpoint is public, responds in under 10 seconds, and calculates the signature from the unmodified raw body.