io.tt SDK Docs
GuidesCRM

CRM Integration

Routing Experience Registration Data to Your CRM

When a consumer completes a registration in any io.tt experience, the platform automatically routes their data to the brand's configured CRM. You do not need to write any CRM-specific code — collect the data in your form, pass it to the SDK signup method, and the platform handles the rest.


How It Works

The SDK is CRM-agnostic. The flow is always the same regardless of which CRM the brand uses:

  1. Consumer fills in the registration form
  2. You call the SDK signup method (signupForCompetition, signupForBasicExperience, etc.)
  3. io.tt receives the registration data over HTTPS
  4. io.tt applies the experience's field transformer server-side
  5. io.tt writes the data to the configured CRM — creating or updating a record

CRM configuration is managed by io.tt on behalf of the brand. You do not configure the CRM target in code.


Standard Fields

These fields are available on all signup methods and are supported by all native CRM integrations. The Type column reflects what the SDK expects from your code.

FieldTypeFormat / ConstraintsNotes
uidstringAny unique identifier — typically the user's email addressRequired on all signup methods. You provide this value — it is not generated by io.tt. io.tt uses it internally to detect whether this person has already registered for this experience. When email is used as the uid (the most common pattern), pass the same value for both uid and email.
emailstringValid email address. Max 80 charsThe actual email address — mapped to the email field in your CRM. Required for Klaviyo. Used as the primary key when deduplicating CRM records across all integrations. If you are already passing email as uid, pass it here too.
firstNamestringMax 40 chars
lastNamestringMax 80 chars
titlestringe.g. Mr., Ms., Dr.Mapped to a salutation/title field where supported
phoneNumber{ countryCode: number; number: string }e.g. { countryCode: 44, number: "7700900000" }Normalised to E.164 format server-side
dateOfBirthstringISO 8601 date: YYYY-MM-DDNot available on all CRM object types (e.g. Salesforce Lead)
addressLine1stringMax 255 chars
addressLine2stringMax 255 chars
localitystringCity / town. Max 40 chars
administrativeDivisionstringState / county / region. Max 80 chars
postalCodestringMax 20 chars
countrystringISO 3166-1 alpha-2 recommended (e.g. "GB"). Max 80 chars
marketingConsentbooleantrue or falseControls list subscription and opt-out flags — always pass explicitly if your form collects it
profilingConsentbooleantrue or falsePassed through to integrations that support it

All fields except uid are optional. Only collect what your experience requires.


The extra Field

All signup methods accept an extra object for any custom data your form collects beyond the standard fields. Pass it in your call and the platform routes it to the CRM:

await sdk.signupForCompetition(EXPERIENCE_ID, {
  uid: userEmail,
  email: userEmail,
  firstName: "Jane",
  lastName: "Smith",
  marketingConsent: true,
  extra: {
    ageRange: "25-34",
    productPreference: "single-malt",
    retailer: "harrods-london",
  },
});

How extra is handled depends on the integration:

IntegrationHow extra is handled
SalesforceEach key maps to a custom field named io_tt_extra_{key}__c — must be pre-created by the Salesforce admin
KlaviyoEach key is spread directly as a custom profile property — no pre-creation needed
Custom webhookThe full extra object is included in the payload as-is

extra values must be strings or primitives. Nested objects are not supported for CRM field mapping.


Integration Types

Native integrations are direct API connections where io.tt writes data to the CRM on the brand's behalf. No additional endpoint is required on your side. io.tt applies a per-experience transformer server-side that maps io.tt fields to the target CRM's field names and formats automatically.

IntegrationWhat it doesGuide
SalesforceCreates or updates Leads and Contacts via the Salesforce REST APIDeveloper · Setup
KlaviyoCreates profiles and subscribes opted-in participants to a configured listDeveloper · Setup

Custom Webhook (fallback)

A webhook sends an HTTP POST to a URL you control each time a consumer registers. The payload is sent in io.tt's participant data structure (with fields nested under participant.personalInfo.* and participant.address.*). A custom transform function can optionally be configured per webhook in the io.tt dashboard — this runs server-side and can reformat the payload before it is sent to your endpoint. Without a transform function, your endpoint receives the raw io.tt structure and is responsible for mapping it into your destination CRM. This is a fallback option for platforms that do not have a native io.tt integration.


The marketingConsent field is respected by all integrations, but the behaviour differs:

IntegrationBehaviour
SalesforcemarketingConsent: trueHasOptedOutOfEmail: false. Inverted to match Salesforce's opt-out model
KlaviyomarketingConsent: true → profile subscribed to list. false or omitted → profile created but not subscribed
Custom webhookmarketingConsent value included in payload as-is — your endpoint is responsible for acting on it

Always pass marketingConsent explicitly if your form collects it. Omitting it is treated the same as false by all integrations.


Notes

  • CRM configuration is managed by io.tt staff — you do not configure the CRM target in SDK code.
  • All field mapping and transformation is applied server-side. Treat SDK responses as the source of truth.
  • The SDK does not validate field values against CRM-specific constraints before submission.

On this page