Salesforce Sales Cloud
Datafly Signal creates Salesforce Sales Cloud records server-to-server using the REST API Create-a-Record resource. Lead-capture events from your site — sign-ups, form submissions, demo requests — become Salesforce Lead records, with no client-side script and no data leaving your infrastructure unhashed where hashing applies.
Prerequisites
You need a Salesforce org with API access and an External Client App (or Connected App) configured for the OAuth 2.0 Client Credentials flow. This is the recommended server-to-server authentication method — it requires no interactive login and no refresh tokens.
Create an External Client App
- In Salesforce Setup, search for External Client App Manager (or App Manager for a classic Connected App).
- Create a new app and enable OAuth Settings.
- Enable the Client Credentials Flow.
- Select the OAuth scopes your integration needs (at minimum Manage user data via APIs /
api). - Save and note the Consumer Key (client ID) and Consumer Secret (client secret).
Assign a Run As integration user
The Client Credentials flow runs as a specific user. Assign a dedicated integration user that has Create permission on the target object (e.g. Lead). This keeps the integration’s permissions tightly scoped and auditable.
Note your hosts
- Login host —
login.salesforce.comfor production,test.salesforce.comfor a sandbox, or your My Domain login URL. Tokens are minted here. - Instance URL — your org host, e.g.
acme.my.salesforce.com. API calls go here. It is returned asinstance_urlin the token response.
Configuration
| Field | Required | Description |
|---|---|---|
instance_url | Yes | Your org host with no scheme, e.g. acme.my.salesforce.com. |
login_host | Yes | OAuth token host: login.salesforce.com (production) or test.salesforce.com (sandbox). |
client_id | Yes | Consumer Key of the External Client App. |
client_secret | Yes | Consumer Secret of the External Client App. |
sobject_type | Yes | Object to create, e.g. Lead or Contact. Default Lead. |
Configure in Signal
- Go to Integrations > Add Integration > Salesforce Sales Cloud.
- Choose the Default (Lead Capture) preset.
- Enter your
instance_url,login_host,client_id,client_secret, andsobject_type. - Select the consent categories that apply (typically
marketing). - Click Save.
The integration’s Field Mappings can be edited in the Management UI to map additional Lead fields.
API Endpoint
Signal first obtains an access token via the Client Credentials grant:
POST https://{login_host}/services/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}The token response returns access_token and instance_url. Signal then creates the record:
POST https://{instance_url}/services/data/v60.0/sobjects/Lead
Authorization: Bearer {access_token}
Content-Type: application/jsonA successful create returns HTTP 201 with the new record ID:
{ "id": "00Q5g00000ABCDeEAF", "success": true, "errors": [] }Identity Signals
Salesforce Sales Cloud is a system of record, not a probabilistic match service. Records are keyed by their natural fields — for Leads, the Email field is the de-facto identifier. Signal maps the identity traits you provide via datafly.identify() to standard Salesforce field API names:
| Signal trait | Salesforce field |
|---|---|
email | Email |
firstName | FirstName |
lastName | LastName (required) |
company | Company (required) |
phone | Phone |
title | Title |
city / state / country | City / State / Country |
Salesforce requires LastName and Company on every Lead. If an event arrives without them, Salesforce returns a 400 REQUIRED_FIELD_MISSING error and Signal marks the delivery as a permanent failure. Make sure your lead-capture forms collect these fields.
The marketing consent signal maps to the Lead’s HasOptedOutOfEmail flag: when canonical marketing consent is true, the Lead is opted in (HasOptedOutOfEmail = false); otherwise it is opted out.
Event Mapping
Default (Lead Capture) preset
| Signal event | Salesforce action |
|---|---|
Signed Up | Create Lead |
Lead Generated | Create Lead |
Form Submitted | Create Lead |
Demo Requested | Create Lead |
Anonymous page views (page) and other events are dropped — only lead-capture events create records.
Example: Lead Generated
Datafly.js call:
datafly.identify("lead-001", {
email: "jane.doe@example.com",
firstName: "Jane",
lastName: "Doe",
company: "Acme Corp",
phone: "+44 7700 900123",
title: "Head of Growth"
});
datafly.track("Lead Generated", {
description: "Requested whitepaper: Server-Side Tagging",
industry: "Technology",
num_employees: 250
});Salesforce REST payload sent by Signal:
{
"Email": "jane.doe@example.com",
"FirstName": "Jane",
"LastName": "Doe",
"Company": "Acme Corp",
"Phone": "+44 7700 900123",
"Title": "Head of Growth",
"LeadSource": "google",
"Description": "Requested whitepaper: Server-Side Tagging",
"Industry": "Technology",
"NumberOfEmployees": 250,
"HasOptedOutOfEmail": false
}Testing
- Configure the integration against a sandbox first (
login_host = test.salesforce.com). - Submit a lead-capture form on a page running Datafly.js.
- In Salesforce, open the Leads tab and confirm the new record appears with the mapped fields.
- Use Signal’s Event Debugger to inspect the exact REST payload sent and the
201response containing the new record ID.
Troubleshooting
| Problem | Solution |
|---|---|
400 REQUIRED_FIELD_MISSING | The event lacked LastName or Company. Ensure your form collects both, or add static defaults in Field Mappings. |
400 DUPLICATES_DETECTED | A Salesforce duplicate rule blocked the create. Adjust the rule, or switch to an upsert flow on an external ID. |
401 Unauthorized | The access token expired or the External Client App credentials are wrong. Signal refreshes automatically; if it persists, re-check client_id / client_secret. |
403 Forbidden | The Run As integration user lacks Create permission on the object, or you hit the org’s API request limit. |
404 Not Found | Wrong instance_url, an unknown sobject_type, or an unsupported API version. Confirm the object name and your instance host. |
| No records appearing | Confirm the event name matches one in the preset (Signed Up, Lead Generated, Form Submitted, Demo Requested) — other events are dropped by design. |
Rate Limits
Salesforce enforces a daily API request limit per org (varies by edition and license count). The integration creates one record per matching event; for high-volume sign-up flows, monitor your org’s API Usage in Setup and consider gating which events create Leads.