Zendesk stores who wrote in. It does not tell you their job title, their company size or whether they are a buyer. You add that with an enrichment step, and the route you pick decides how much of it you maintain.
TL;DR
- Six routes work. A small script against the Zendesk Users API ranks first for a technical buyer. A CSV import ranks last.
- The first 100 users take about 45 minutes and spend about 100 LeadOcean records. A lookup that finds nobody costs nothing.
- Everything lands in Zendesk user fields, so agents see it on the ticket.
Prerequisites
- A LeadOcean API key in
$LEADOCEAN_API_KEY(free plan works, 5 requests a second). - A Zendesk admin account and an API token or OAuth access token.
- Two custom user fields in Zendesk with keys
job_titleandcompany_size(Admin Center, People, Configuration, User fields). curlandjq, or an n8n instance if you pick route 3.
Step 1: Pick your route
Ranked for a technical buyer who wants control and a low bill. "Maintained by you" is the work you own after day one.
| Rank | Route | Maintained by you | Fits when |
|---|---|---|---|
| 1 | Script: LeadOcean enrich, then Zendesk users/create_or_update | A cron job | You want exact fields and no per-task fees |
| 2 | Zendesk webhook subscribed to user events, posting to your own endpoint that runs route 1 for one user | A small service | You want new users enriched as they arrive. Zendesk webhooks can subscribe to user activity events (Zendesk docs, October 2026) |
| 3 | n8n: HTTP Request to LeadOcean, then the built-in Zendesk node | A workflow | You want a visual flow. The n8n Zendesk node can create, get, search and update users (n8n docs, October 2026) |
| 4 | Zapier: webhook or code step, then a Zendesk action | A Zap | Zendesk is a Premium app on Zapier (Zapier, October 2026), so check your plan |
| 5 | An AI client with the LeadOcean MCP server | Nothing | An agent looks up one requester while you work a ticket. No write-back |
| 6 | CSV export, edit, bulk import | A person, monthly | One-off cleanup of a small list |
Route 1 wins because the Zendesk Users API takes custom field values in user_fields and creates or updates users matched by email or external ID (Zendesk developer docs, October 2026). The rest of this guide builds route 1. Routes 2 to 4 reuse the same two calls. Route 5 uses the hosted MCP server at https://api.leadocean.io/mcp (13 tools, OAuth sign-in).
Step 2: Enrich one user from their email
Zendesk already holds the email. Send it to LeadOcean as the one enrich input. Base URL https://api.leadocean.io, header x-api-key.
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "jane.doe@acme.com"}'Enrich takes exactly one of linkedin_url, email, phone or person_id. A person we hold nothing for returns 404 and costs nothing. A hit costs one record.
Step 3: Map the response to Zendesk user fields
The current role comes back in data.contact_data.contact_current_experiences[], and each entry carries job_title. Pull the first entry and build the Zendesk payload.
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
-H "x-api-key: $LEADOCEAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "jane.doe@acme.com"}' \
| jq '{user: {
email: "jane.doe@acme.com",
skip_verify_email: true,
user_fields: {
job_title: .data.contact_data.contact_current_experiences[0].job_title
}
}}' > user.jsonIf jq prints null, we hold no current role for that person. Leave the field empty rather than guess.
Step 4: Write it to Zendesk
create_or_update identifies the user by email, so existing end users are updated and strangers are created. The skip_verify_email flag in user.json stops Zendesk emailing new users.
curl https://YOURSUBDOMAIN.zendesk.com/api/v2/users/create_or_update \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ZENDESK_ACCESS_TOKEN" \
-X POST -d @user.jsonA 200 means the user existed and was updated. A 201 means it was created. Zendesk limits this endpoint to 5 requests a minute for each end user profile (Zendesk developer docs, October 2026).
Step 5: Run it for a batch
For more than a few users, collect the payloads and send them to create_or_update_many, which takes up to 100 users a call. Bulk user imports are off by default in Zendesk: an admin has to ask Zendesk support to enable them, or the call returns 403 (Zendesk developer docs, October 2026).
while read -r e; do
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
-H "x-api-key: $LEADOCEAN_API_KEY" -H "Content-Type: application/json" \
-d "{\"email\": \"$e\"}" \
| jq -c --arg e "$e" 'select(.data.contact_data.contact_current_experiences != null)
| {email: $e, user_fields: {job_title: .data.contact_data.contact_current_experiences[0].job_title}}'
sleep 0.25
done < emails.txt | jq -s '{users: .}' > batch.jsonsleep 0.25 keeps you under the 5 requests a second on Free. Misses return 404 and drop out of the file, so the batch only contains people we found. Post batch.json to /api/v2/users/create_or_update_many in chunks of 100. It returns a job status to poll, not the users.
Step 6: Check the result in Zendesk
Confirm the field landed before you schedule anything. Search for the user and read user_fields back.
curl -s "https://YOURSUBDOMAIN.zendesk.com/api/v2/users/search.json?query=jane.doe@acme.com" \
-H "Authorization: Bearer $ZENDESK_ACCESS_TOKEN" | jq '.users[0].user_fields'If the value is there, add a Zendesk trigger or view on job_title so agents can route and prioritise by role. Then put the loop on a cron job that only reads users created in the last day, so you never re-spend records on people you already enriched.
Two habits keep the bill flat. Store the LeadOcean person_id in a second user field and enrich by that ID on later runs. And skip role addresses and free-mail domains, since they rarely match a professional profile and add noise to the run.
What you get
A free leadocean_count_leads call shows the size of the next job: customer-service leaders at US companies running Zendesk. Run on 2026-10-21, filters technologies Zendesk, jobFunction Customer/Client Service, jobLevel Director or VP, country US.
{
"total": 1588,
"totalIsExact": true,
"totalAll": 2868,
"distinctCompanies": 745
}The 1,588 counts people with a verified or catch-all email (the tool's default). Without an email filter the same filters match 2,868. The count spent 0 records.
The enrich response shape from the API reference, with placeholder values and trimmed to the fields used above.
{
"success": true,
"data": {
"contact_data": {
"has_email": true,
"email_status": "verified",
"contact_current_experiences": [
{ "job_title": "Head of Support", "company_name": "Acme", "company_domain": "acme.com" }
]
},
"meta": { "source_ids": { "person_id": "1234567890" }, "fetched_at": "2026-10-01" }
}
}Since 2026-10-17 the same call also returns resume_data (past roles, education, certifications) when held. Past employers carry no company ID yet.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| 401 from LeadOcean | Missing or wrong x-api-key | Export $LEADOCEAN_API_KEY and resend |
| 404 from enrich | We hold nothing for that email | Skip the user. It costs nothing |
| 429 from LeadOcean | Above 5 requests a second on Free (200 on Agency) | Honour Retry-After, or raise the sleep |
| 402 from LeadOcean | The 1,000 free records are spent | Move to a paid plan on /pricing |
| 429 from Zendesk | More than 5 updates a minute for one user, or the account limit | Back off and retry that user later |
user_fields ignored | The field key does not exist in Zendesk | Create the field first and use its key, not its label |
FAQ
Does Zendesk enrich users out of the box?
No. Zendesk stores the fields you give it. Job title and company data have to arrive through the API, an automation tool or an app.
Which route is cheapest?
Route 1. You pay for LeadOcean records and nothing per task. Automation tools such as Zapier price by usage, so check their pricing pages for your volume.
Can I match by name and company instead of email?
Not in one call. There is no name plus domain lookup. Search by domain first, then enrich by person_id. See what company enrichment is.
What does 100 users cost?
At most 100 records, one per person found. Misses cost nothing. The free plan has 1,000 records for life. See pricing.
How do I know if enrichment helps support at all?
Test it on one queue and compare. For the sales side, see the SDR enrichment bake-off recipe and how to survey your own reps.
Put job titles on your Zendesk tickets this week
Free to start. No credit card. 1,000 records to spend whenever you like.
Get your free API key →