Freshdesk
Datafly Signal delivers identified events to Freshdesk server-to-server using the Freshdesk REST API v2. Signal turns identified website and product activity into Freshdesk contacts, keeping your support CRM in step with the people using your site — no client-side form integration required.
Prerequisites
Before configuring Freshdesk in Signal you need a Freshdesk account, your Freshdesk subdomain, and an API key belonging to an agent allowed to manage contacts.
Find your Freshdesk domain
Your Freshdesk domain is the part before .freshdesk.com in your portal URL. For example, if you sign in at https://acme.freshdesk.com, your domain is acme.
Get your API key
- Sign in to Freshdesk as an agent with permission to create and update contacts.
- Click your profile picture (top right) and choose Profile Settings.
- Your API key is shown on the right-hand side of the profile page. Copy it.
The API key inherits the permissions of the agent it belongs to. If that agent can’t manage contacts, neither can the API call. Use a key from an agent (or a dedicated service agent) with contact-write permission.
Configuration
| Field | Required | Description |
|---|---|---|
| Freshdesk Domain | Yes | Your Freshdesk subdomain — the part before .freshdesk.com (e.g. acme). |
| API Key | Yes | The API key from your Freshdesk agent profile. |
Configure in Signal
Add the Freshdesk integration
In the Signal management UI, open your pipeline, go to Integrations, and add Freshdesk.
Enter your credentials
Paste your Freshdesk Domain and API Key into the configuration fields and save.
Choose the blueprint preset
Select the Default preset. It maps identified Signal events onto Freshdesk contact fields and drops anonymous traffic.
Save and deploy
Save the pipeline. Identified events will begin syncing to Freshdesk as contacts.
API Endpoint
Signal sends each identified event as an HTTP POST to your Freshdesk contacts API:
POST https://<your-domain>.freshdesk.com/api/v2/contactsAuthentication is HTTP Basic Auth, where your API key is the username and any non-empty string is the password (Freshdesk’s own examples use apikey:X). Signal handles this for you using the API key you supplied.
A successful create returns 201 Created with the new contact object.
Freshdesk’s create-contact endpoint is not an upsert. If an event carries an email that already belongs to a Freshdesk contact, Freshdesk returns 409 Conflict. Signal treats this as a final (non-retried) response — the event is acknowledged and not resent — which is the expected behaviour for a contact-sync pipeline. If you want each contact created exactly once, scope the pipeline to first-touch events such as Signed Up.
Identity Signals
Freshdesk is a support CRM, so the contact record must hold real, readable identity — email, phone, and name are sent in the clear and are not hashed. (A hashed email would be useless to a support agent.) Signal maps:
| Signal trait | Freshdesk field |
|---|---|
name (falls back to email) | name (required) |
email (trimmed, lower-cased) | email |
phone (normalised to E.164) | phone |
user_id | unique_external_id |
title | job_title |
company_id | company_id |
unique_external_id carries your canonical Signal user id so you can join Freshdesk contacts back to your own systems.
Consent
The Freshdesk contact API has no per-event marketing-consent field — mailability is managed on the contact inside Freshdesk. The blueprint instead gates delivery on the visitor’s marketing consent and, when consent is granted, adds a marketing-consent tag to the contact so your team can segment consenting contacts.
Event Mapping
Only identified events reach Freshdesk. Anonymous and page-view events are dropped, because the contacts endpoint requires a name and an identifier.
| Signal event | Freshdesk action |
|---|---|
Signed Up | Create contact (with signup_method custom field) |
Identified | Create / update contact |
Example: Signed Up
A Datafly.js call:
datafly.track('Signed Up', {
method: 'email'
}, {
traits: {
name: 'John Doe',
email: 'John.Doe@example.com',
phone: '07700 900123',
title: 'Head of Growth'
}
});Produces the following request body to POST /api/v2/contacts:
{
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+447700900123",
"unique_external_id": "usr_123",
"job_title": "Head of Growth",
"tags": ["marketing-consent"],
"custom_fields": {
"signup_method": "email"
}
}custom_fields keys must already exist in your Freshdesk contact field schema. Create the signup_method field in Admin → Contact Fields (or remove the mapping) before going live, or Freshdesk will reject the request.
Testing
- Trigger an identified event (e.g. complete a real sign-up that fires
Signed Up). - In the Signal Event Debugger, confirm the event was delivered to Freshdesk and returned
201. - In Freshdesk, go to Contacts and confirm the new contact appears with the expected name, email, and tags.
You can also verify your credentials directly:
curl -u YOUR_API_KEY:X \
-H "Content-Type: application/json" \
-X POST "https://YOUR_DOMAIN.freshdesk.com/api/v2/contacts" \
-d '{"name":"Test Contact","email":"test+signal@example.com"}'A 201 Created response confirms the domain and key are correct.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized | Wrong or missing API key | Re-copy the key from Profile Settings; check it has no trailing spaces. |
403 Forbidden | The agent’s role can’t manage contacts | Use a key from an agent with contact-write permission. |
404 Not Found | Wrong Freshdesk domain | Enter only the subdomain (e.g. acme, not the full URL). |
409 Conflict | Email already belongs to a contact | Expected for re-identified users; scope to first-touch events (e.g. Signed Up) if you only want one create per contact. |
400 Bad Request | Missing name/identifier, or unknown custom_fields key | Ensure events carry a name and email; create referenced custom fields in Freshdesk first. |
429 Too Many Requests | Plan rate limit exceeded | Signal retries automatically; if persistent, check your Freshdesk plan’s API limit. |