At a Glance — Zendesk to Salesforce Sync with n8n
- Flow direction: Zendesk webhook → n8n → Salesforce (real-time); Salesforce → Zendesk runs on a schedule (every 5–15 min) for status sync back
- Contact lookup: Query Salesforce Contact by requester email → get AccountId for Case creation; branch on Contact found / not found / no Account
- Deduplication: Create
Zendesk_Ticket_ID__cas a Text(18) field on the Salesforce Case object before go-live — this is your idempotency key - VIP routing: Check Account
Priority_Tier__c— Enterprise/Strategic tier triggers a Slack alert to the account manager at ticket creation - n8n advantage: Zendesk's native Salesforce integration has a fixed schema; n8n gives you custom routing, custom field mapping, and full control over error handling
- Salesforce setup required: Create the custom field in Salesforce Setup before running the workflow — queries against a non-existent field silently return empty
Why sync Zendesk and Salesforce?
Zendesk and Salesforce serve different audiences in most B2B companies. Support handles reactive communication in Zendesk; sales and customer success track relationships and revenue in Salesforce. The gap between them creates real problems:
- Account managers don't know a key account has had 5 support tickets this month until renewal time
- Support agents can't see that a requester is on an at-risk account flagged by CS
- Reporting across support volume and account health requires manual data exports
Zendesk does have a native Salesforce integration, but it's a fixed-schema sync focused on contact matching. If you need custom logic — routing tickets differently based on Salesforce account tier, creating Cases in specific record types, or syncing custom fields — you'll quickly hit its limits. n8n gives you full control over the mapping, routing, and error handling.
The workflow overview
The core flow runs in one direction: Zendesk events → n8n → Salesforce. A lighter reverse flow (Salesforce → Zendesk) runs on a schedule for status sync. Here's the sequence for new ticket creation:
- Zendesk fires a webhook when a ticket is created
- n8n receives the event and extracts the requester email and ticket ID
- n8n queries Salesforce for a Contact matching the email
- If found: check the Account's tier/priority field and route accordingly
- Create a Salesforce Case linked to the Account, storing the Zendesk ticket ID
- Optionally: add a note to the Zendesk ticket with the Salesforce Case number
Step 1 — Set up the Zendesk webhook trigger
In your n8n workflow, add a Webhook trigger node and copy the URL. Zendesk's webhook system lives in two places: Webhooks (Admin → Apps and integrations → Webhooks) and Triggers (Admin → Objects and rules → Triggers).
Create a Zendesk Webhook pointing at your n8n URL. Then create a Trigger that fires the webhook on your chosen conditions. For a new ticket sync, set the trigger condition to Ticket is Created. For escalation sync, add conditions like Ticket Priority is Urgent or Ticket Status changed to Escalated.
In the webhook payload, include at minimum:
ticket.id— Zendesk ticket ID (your deduplication key)ticket.requester.email— for Salesforce Contact lookupticket.subjectandticket.description— for Case creationticket.priorityandticket.statusticket.created_at
Zendesk lets you customize the JSON payload using its Liquid-style templating. Expose whatever custom fields you'll need for routing — account IDs stored in Zendesk organization custom fields, SLA tier, product area, etc.
Step 2 — Look up the Salesforce Contact and Account
With the requester email from the Zendesk payload, query Salesforce using the Salesforce node (SOQL query operation):
SELECT Id, AccountId, Account.Name, Account.Type, Account.Priority_Tier__c FROM Contact WHERE Email = '{{requester_email}}' LIMIT 1
Three outcomes to handle:
- Contact found with Account — proceed to Case creation using the AccountId
- Contact found without Account — create the Case without an account, or route to a catch-all queue
- No Contact found — either create a new Lead in Salesforce, or log for manual follow-up. Do not fail silently.
Use an If node to branch on whether the SOQL query returned a result. This is where you also implement priority routing: if the Account's Priority_Tier__c field is "Enterprise" or "Strategic", flag the Case as high priority and add an additional Slack notification to the account manager.
Step 3 — Deduplicate before creating the Case
Zendesk triggers can fire more than once for the same ticket event — particularly if you've set up multiple triggers or if there's a trigger configuration error. Before creating a Salesforce Case, query for an existing one using the Zendesk ticket ID stored in a custom field:
SELECT Id FROM Case WHERE Zendesk_Ticket_ID__c = '{{ticket_id}}' LIMIT 1
You'll need to create the custom field Zendesk_Ticket_ID__c in Salesforce (a Text field on Case, 18 chars is sufficient) before running this query. If a Case already exists with this ticket ID, update it rather than creating a second one.
Field setup required: Create Zendesk_Ticket_ID__c as a Text(18) field on the Case object in Salesforce Setup before going live. This is your idempotency key for the sync — without it, every Zendesk trigger fire creates a duplicate Case.
Step 4 — Create the Salesforce Case
With the Contact's AccountId and the deduplication check passed, create the Salesforce Case using the Salesforce node (Create operation, Case object):
- Subject: Zendesk ticket subject
- Description: Zendesk ticket description (first comment body)
- AccountId: from the Contact lookup
- ContactId: from the Contact lookup
- Zendesk_Ticket_ID__c: the Zendesk ticket ID (deduplication key)
- Priority: map Zendesk priority (low/normal/high/urgent) to Salesforce (Low/Medium/High)
- Origin: "Zendesk" — useful for reporting
- Status: "New"
After creating the Case, optionally write back to the Zendesk ticket: use the Zendesk node to add an internal note on the ticket with the Salesforce Case number and a link. This gives support agents visibility into the CRM record without leaving Zendesk.
Step 5 — Sync status updates back to Zendesk (scheduled)
The reverse direction — Salesforce Case status changes updating the Zendesk ticket — is harder to make event-driven because Salesforce's Outbound Messages require SOAP configuration. A simpler approach is a scheduled n8n workflow:
- Every 10–15 minutes, query Salesforce for Cases modified in the last 20 minutes:
SELECT Id, Status, Zendesk_Ticket_ID__c FROM Case WHERE LastModifiedDate > LAST_N_MINUTES:20 AND Zendesk_Ticket_ID__c != null - For each Case, map the Salesforce Status to the corresponding Zendesk status
- Update the Zendesk ticket using the Zendesk node (Update Ticket operation)
This introduces up to 15 minutes of lag on Salesforce-side changes, which is usually acceptable. If you need real-time Salesforce → Zendesk updates, use Salesforce Platform Events with n8n's HTTP Request node polling the Streaming API — more complex but fully event-driven.
Error handling and monitoring
Both Zendesk and Salesforce have API rate limits. The Zendesk webhook fires are typically low volume (ticket events don't happen thousands of times per minute), but Salesforce's API limits depend on your edition. Monitor for 429 (rate limited) and 503 responses and implement exponential backoff in your retry logic.
Set up an n8n Error Trigger workflow to catch failed executions and notify via Slack. Include the Zendesk ticket ID, the error code, and a direct Zendesk link so support can manually escalate if the automation failed. A missed Case creation during a critical account escalation is a recoverable problem — a silent failure you discover in a post-mortem is not.
If you need this implemented and maintained rather than built in-house, Entech Solutions delivers n8n Zendesk integrations and Salesforce automations — fully documented, production-ready, with error handling included. Most Zendesk-CRM sync projects go live in 2–3 weeks.