Documentation Index
Fetch the complete documentation index at: https://docs.streamkap.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Zendesk Webhook source receives events from your Zendesk account at a dedicated HTTPS endpoint and routes each event to a Kafka topic based on its event type (tickets, users, organizations, articles, messaging, etc.).
You point Zendesk at the Streamkap-generated webhook URL, configure which event subscriptions to send, and Streamkap takes care of parsing, key extraction, schema inference, and routing.
This connector is in Beta. Behaviors and defaults may change before general availability.
Prerequisites
- A Zendesk account with Admin permissions (required to create webhooks and event subscriptions).
- A Streamkap workspace with permission to create source connectors.
- A clear list of the Zendesk objects you want to capture (tickets, users, organizations, etc.).
How It Works
- Endpoint provisioning — When you create the source, Streamkap generates a unique HTTPS webhook URL and an API key.
- Zendesk subscription — In Zendesk, you create a webhook target pointing at that URL and subscribe it to the event types you care about.
- Event routing — Each incoming event carries a
type field (for example zen:event-type:ticket.created). The Zendesk payload router maps the event domain to a topic — ticket.* events go to ticket_events, user.* events go to user_events, and so on.
- Key extraction — The router pulls a stable identifier from the payload (typically
detail.id) and uses it as the Kafka message key, enabling upsert-style consumption downstream.
- Optional flattening / fan-out — Nested
detail fields can be promoted to top level, and array fields (such as ticket tags or custom fields) can be fanned out into their own topics.
Streamkap Setup
1. Create the Source
- Navigate to Sources and choose Zendesk Webhook.
- Give the source a memorable Name (for example,
zendesk-prod).
2. Connection Settings (Auth tab)
These fields are populated automatically once you save the source — you do not enter them manually.
| Field | Description |
|---|
| Webhook URL | Read-only. The HTTPS endpoint that Zendesk posts events to. Generated on save. |
| API Key | Read-only and encrypted. Sent by Zendesk in the X-API-Key header to authenticate each request. Generated on save. |
3. Schema (Zendesk Models)
In the Schema tab, the topics are pre-populated with the nine built-in Zendesk event models. Leave them all enabled, or remove any you do not want to ingest.
| Topic | Domain |
|---|
ticket_events | Tickets |
user_events | Users |
organization_events | Organizations |
article_events | Help Center articles |
community_post_events | Community posts |
messaging_events | Messaging tickets / conversations |
agent_events | Agent availability and status |
omnichannel_config_events | Omnichannel configuration |
messaging_metrics_events | Messaging live metrics |
Any fan-out topics you configure (see below) are added to this list automatically.
4. Settings
| Field | Default | Description |
|---|
| Unknown Event Behavior | DEFAULT_TOPIC | What to do when an event type is not recognised. DEFAULT_TOPIC routes it to a fallback topic, SKIP drops it silently, FAIL halts the connector. |
| Unknown Event Default Topic | unknown | Topic name used when behavior is DEFAULT_TOPIC. Only shown when the option above is set to DEFAULT_TOPIC. |
| Flatten Detail Fields | false | Promote nested detail.* fields to top level. Recommended for destinations that do not support nested objects (most data warehouses). |
| Flatten Detail Prefix | detail_ | Prefix added to flattened fields (for example detail.id becomes detail_id). Only shown when flattening is enabled. |
| Include Event Field | true | Keep the raw event field in the output record. Enable for audit-log style ingestion (append mode); disable for state-table style (upsert mode) where only the entity matters. |
| Fan-out Fields (advanced) | (empty) | Comma-separated list of domain.field pairs to fan out into their own topics — for example ticket.tags,ticket.custom_fields,organization.tags. See Fan-out below. |
| Enable Dead Letter Queue (advanced) | false | Failed records are written to a DLQ topic instead of crashing the connector. |
5. Save and Copy the Endpoint
Save the source. Copy the Webhook URL and API Key — you will need them in the next section to configure Zendesk.
Zendesk Setup
You configure Zendesk to send events to the Streamkap endpoint in two pieces: a webhook target and one or more event subscriptions.
1. Create the Webhook in Zendesk
- In Zendesk, go to Admin Center → Apps and integrations → Webhooks → Webhooks.
- Click Create webhook.
- Choose Trigger or automation (or Zendesk events — see step 2 below).
- Configure the webhook:
- Name —
Streamkap (or anything memorable).
- Endpoint URL — paste the Webhook URL from Streamkap.
- Request method —
POST.
- Request format —
JSON.
- Authentication — choose API key:
- Header name —
X-API-Key
- Value — paste the API Key from Streamkap.
- Click Test webhook to confirm Zendesk can reach the endpoint, then Create webhook.
2. Subscribe to Event Types
To stream object-level events (ticket created, user updated, organization deleted, …), connect the webhook to Zendesk’s Events subscription system:
- In Admin Center, go to Apps and integrations → Webhooks → Connections.
- Click Create connection, pick the webhook you just created, and select the event types you want to forward.
- Use event types from the families that match the topics you enabled in Streamkap:
zen:event-type:ticket.*
zen:event-type:user.*
zen:event-type:organization.*
zen:event-type:article.*
zen:event-type:community_post.*
zen:event-type:messaging_ticket.*
zen:event-type:agent.*
zen:event-type:omnichannel_config.*
zen:event-type:messaging_live_metrics.*
- Save the connection. Zendesk now begins POSTing events to Streamkap.
For triggers and automations (instead of native event subscriptions), set the request body to forward the relevant fields — including a type value such as zen:event-type:ticket.updated — so the payload router can identify the event family.
Event Routing Reference
The payload router inspects the type field on each incoming event and maps it to a topic.
| Event type prefix | Topic | Default key |
|---|
zen:event-type:ticket.* | ticket_events | { "detail_id": <ticket_id> } |
zen:event-type:user.* | user_events | { "detail_id": <user_id> } |
zen:event-type:organization.* | organization_events | { "detail_id": <organization_id> } |
zen:event-type:article.* | article_events | { "detail_id": <article_id> } |
zen:event-type:community_post.* | community_post_events | { "detail_id": <post_id> } |
zen:event-type:messaging_ticket.* | messaging_events | { "detail_id": <message_id> } |
zen:event-type:agent.* | agent_events | { "detail_agent_id": <agent_id> } |
zen:event-type:omnichannel_config.* | omnichannel_config_events | { "account_id": <account_id> } |
zen:event-type:messaging_live_metrics.* | messaging_metrics_events | { "account_id": <account_id> } |
Event types ending in .deleted or .removed (but not .soft_deleted or .undeleted) automatically set __deleted: true on the output record so downstream sinks can issue tombstones.
Fan-out
When Flatten Detail Fields is on, scalar fields are promoted to the top level — but arrays and lists of objects (tags, custom fields, comments, …) cannot be flattened cleanly. Fan-out solves this by emitting one record per array element to a dedicated topic.
Set Fan-out Fields to a comma-separated list of domain.field pairs:
ticket.tags,ticket.custom_fields,ticket.comments,ticket.collaborators,ticket.followers,organization.tags
| Fan-out entry | Generated topic | Key shape |
|---|
ticket.tags | ticket_tags | { detail_id, value } |
ticket.custom_fields | ticket_custom_fields | { detail_id, id } |
ticket.comments | ticket_comments | { id } |
ticket.collaborators | ticket_collaborators | { detail_id, id } |
ticket.followers | ticket_followers | { detail_id, id } |
organization.tags | organization_tags | { detail_id, value } |
The fan-out topics are added to the Schema list automatically, so you do not need to register them manually.
Each fan-out record contains the array element’s own fields plus:
detail_id — parent entity ID (matches the key field name).
_ctx_event_id — the originating webhook event UUID, useful for correlating fan-out records back to the parent event.
Example fan-out tag record:
{
"value": "urgent",
"detail_id": 987654,
"_ctx_event_id": "01HF6...-event-uuid"
}
Fan-out topics do not emit tombstone records when array items are removed (for example when a tag is removed from a ticket). To handle deletions, either configure the downstream sink for delete-and-reinsert mode on each parent event, or treat each ticket event as the source of truth and full-replace the child rows.
Example Payload
A typical event sent by Zendesk:
{
"type": "zen:event-type:ticket.created",
"id": "01HF6...-event-uuid",
"account_id": 123456,
"time": "2026-01-24T15:30:00Z",
"subject": "zen:ticket:987654",
"detail": {
"id": 987654,
"subject": "Cannot login",
"status": "new",
"tags": ["urgent", "billing"],
"custom_fields": [{ "id": 123, "value": "tier1" }]
},
"event": {
"comment": { "id": 555, "body": "We are looking into it" }
}
}
With Flatten Detail Fields enabled and Include Event Field disabled, the record written to ticket_events looks like:
{
"type": "zen:event-type:ticket.created",
"account_id": 123456,
"time": "2026-01-24T15:30:00Z",
"subject": "zen:ticket:987654",
"detail_id": 987654,
"detail_subject": "Cannot login",
"detail_status": "new",
"__deleted": false
}
The arrays (tags, custom_fields) are emitted to ticket_tags and ticket_custom_fields if those entries are listed in Fan-out Fields.
Common Patterns
State table (upsert) ingestion
Use this when you want one row per Zendesk entity in your warehouse, mirroring the live state.
- Flatten Detail Fields —
true
- Include Event Field —
false
- Fan-out Fields — list any nested arrays you want as separate tables (typically
ticket.tags, ticket.custom_fields)
Downstream sinks upsert by the detail_id key. .deleted events flip __deleted: true, which most sinks treat as a tombstone.
Audit log ingestion
Use this when you want every event preserved as a separate row.
- Flatten Detail Fields —
false
- Include Event Field —
true
- Fan-out Fields — empty
Each event becomes a record. Downstream consumers see the full context of every change.
Troubleshooting
Zendesk’s webhook test returns 401 — Check that the X-API-Key header name is exactly X-API-Key and the value matches the API Key shown in the Streamkap UI. Regenerate the source if the key was lost.
Events arrive in the unknown topic instead of the expected one — The event type did not match any known prefix. Verify the event family is one of those listed in Event Routing Reference. If you are using a Zendesk trigger (rather than an event subscription), make sure the request body includes a valid type value.
No data is flowing — Confirm in Zendesk that the webhook is Active and connected to at least one event subscription. Use the Activity view on the Zendesk webhook to see recent delivery attempts and response codes.
Records are nested when I expected flat fields — Toggle Flatten Detail Fields on and re-deploy the source. Existing records already in Kafka will not be retroactively flattened.
My destination cannot handle the array fields — Add the relevant entries to Fan-out Fields so each array element becomes its own record in a dedicated topic.
Limitations
- The Zendesk Webhook source is currently Beta.
- The connector accepts only
POST requests; do not configure Zendesk to use a different HTTP method.
- Maximum payload size is 50 MB and maximum header size is 64 KB. Zendesk events fit comfortably within these limits.
- Each request is treated as a single Kafka record. Zendesk does not batch events into one request.
- The connector runs as a single task; horizontal scaling requires multiple source instances.
See Also
- Webhook Source — generic webhook source for any HTTP-capable producer.