Salesloft

Salesloft is a sales engagement platform. This integration lets Datafly Signal create or update a Person in Salesloft whenever a visitor identifies or converts on your site, so inbound web leads land in your sales workflow server-side, without a browser-side script and without losing leads to ad-blockers or consent gates.

Signal delivers to the Salesloft Person Upsert API: one server-to-server POST per qualifying event. The upsert is keyed on email address, so resubmitting the same lead updates the existing Person instead of creating a duplicate.

Prerequisites

  • A Salesloft account with permission to create and update People.
  • A Salesloft API key with the People scope. In Salesloft, go to Your Applications > API Keys > Create New, give it a descriptive name, select the People scope, and copy the key (shown only once).
  • A Datafly Signal pipeline already collecting events from your site via Datafly.js.

Configuration

FieldRequiredDescription
API KeyYesYour Salesloft API key with the People scope, from Your Applications > API Keys. Stored encrypted; sent as the Authorization: Bearer header on every request.

Configure in Signal

  1. In the Management UI, open your pipeline and choose Add integration > Salesloft.
  2. Paste your API Key.
  3. Select the Lead Capture preset. It maps Lead Generated, Signed Up, and Identified events to a Salesloft Person upsert; all other events are dropped.
  4. Save. Signal validates the credential on the first qualifying event; a 200 with a Person id in the response confirms the integration is live.

API Endpoint

POST https://api.salesloft.com/v2/person_upserts
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

A successful upsert returns 200 with the created or updated Person:

{ "data": { "id": 1234, "email_address": "jane.doe@example.com" } }

Identity Signals

Salesloft is a first-party CRM that you own and use to contact leads, so contact details are stored as plaintext (unlike advertising integrations, which hash PII). Signal sends:

Signal sourceSalesloft fieldNotes
traits.emailemail_addressTrimmed and lower-cased. Used as the upsert_key, so it also matches existing People.
traits.first_namefirst_name
traits.last_namelast_name
traits.phonephoneNormalised to E.164.
traits.titletitleJob title.
traits.companyperson_company_name

Consent is honoured: when the visitor’s canonical marketing consent is granted, Signal sends do_not_contact: false; when consent is denied or absent it sends do_not_contact: true, so leads who haven’t opted in are flagged not-to-contact in Salesloft.

Campaign attribution is written to custom_fields (utm_source, utm_medium, utm_campaign, signal_landing_page) and the event’s lead source is added to tags. Salesloft rejects custom_fields keys that don’t already exist as Person custom fields, so create those custom fields in your tenant first (or remove the mappings if you don’t need them).

Event Mapping

Datafly.js eventSalesloft action
Lead GeneratedUpsert Person (adds lead_source to tags)
Signed UpUpsert Person (records signup method)
IdentifiedUpsert Person
(everything else)Dropped

Example

When a visitor submits a contact form, fire a Lead Generated event with identity traits:

datafly.track("Lead Generated", {
  lead_source: "Website Contact Form"
}, {
  traits: {
    first_name: "Jane",
    last_name:  "Doe",
    email:      "Jane.Doe@Example.com ",
    phone:      "07700 900123",
    title:      "Head of Marketing",
    company:    "Example Ltd"
  }
});

Signal transforms and delivers this to Salesloft as:

{
  "upsert_key": "email_address",
  "email_address": "jane.doe@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "phone": "+447700900123",
  "title": "Head of Marketing",
  "person_company_name": "Example Ltd",
  "do_not_contact": false,
  "tags": ["Website Contact Form"],
  "custom_fields": {
    "utm_source": "google",
    "utm_medium": "cpc",
    "utm_campaign": "brand"
  }
}

Note the email was trimmed and lower-cased and the phone normalised to E.164 before delivery, and do_not_contact is false because marketing consent was granted.

Testing

  1. Submit a test form on your site (or fire datafly.track("Lead Generated", ...) from the browser console) with a real name and email.
  2. In Salesloft, open People and confirm the new Person appears with the correct email, phone and company.
  3. Resubmit the same email with a changed field (e.g. a new title) and confirm Salesloft updates the existing Person rather than creating a duplicate.
  4. In the Signal Event Debugger, confirm the event delivered with a 200 and a Person id in the response body.

Troubleshooting

SymptomLikely causeFix
401 UnauthorizedInvalid or revoked API keyRe-create the key in Your Applications > API Keys and update the integration.
403 ForbiddenAPI key missing the People scopeRe-create the key with the People scope selected.
400 / 422 referencing a custom fieldA custom_fields key doesn’t exist in your tenantCreate the matching Person custom field in Salesloft, or remove that mapping from the preset.
400 Bad Request missing emailEvent has no traits.emailPass traits.email in the event’s identity context; it’s required as the upsert key.
Duplicate People createdupsert_key not sent, or different email casingThe preset sends upsert_key: email_address and lower-cases email; confirm you haven’t overridden these.
429 Too Many RequestsTeam-level rate limit hitSalesloft rate-limits per team across all integrations; Signal retries automatically, but reduce volume or stagger if persistent.