Using ZIS inbound webhooks
In this tutorial, you'll use an event from a ZIS inbound webhook to kick off a ZIS flow. You can use an inbound webhook to send custom events to ZIS from a third-party system.
What you'll need
To complete this tutorial, you'll need the following:
-
Familiarity with ZIS. Before you start, complete the Building your first ZIS integration tutorial.
-
A registered ZIS integration. You can use the same integration you created in Building your first ZIS integration or register a new one. To register a new integration, see Registering the integration name.
-
A ZIS OAuth token for the integration. See Obtaining a ZIS OAuth token.
Creating the integration
The ZIS integration you create listens for user creation events from a third-party system named Acme. Acme sends the events to ZIS using an inbound webhook. When it detects the event, the integration uses the event's data to create a user profile in Zendesk.
-
Create an OAuth connection named "zendesk". You'll use the connection to authenticate Zendesk API requests in the integration's ZIS flow.
In a typical setup, an admin uses a private Zendesk app to create OAuth connections. For this tutorial, you'll create a "zendesk" connection without an app.
To create the connection, follow the steps in Creating an OAuth connection for Zendesk. Then return here.
-
Create a JSON file named my_zis_bundle.json.
-
Add the following bundle skeleton to my_zis_bundle.json:
{"name": "Example integration with a ZIS inbound webhook","description": "Create Zendesk user for new Acme system user","zis_template_version": "2019-10-14","resources": {"AddZendeskUser": {"_placeholder_": "ZIS custom action definition goes here"},"NewAcmeUserFlow": {"_placeholder_": "ZIS flow goes here"},"NewAcmeUserJobSpec": {"_placeholder_": "ZIS job spec goes here"}}}You'll define the custom action, ZIS flow, and job spec in the next steps.
-
In my_zis_bundle.json, replace the
AddZendeskUserplaceholder with the following custom action definition."AddZendeskUser": {"type": "ZIS::Action::Http","properties": {"name": "AddZendeskUser","definition": {"method": "POST","path": "/api/v2/users","connectionName": "zendesk","headers": [{"key": "Content-Type","value": "application/json"}],"requestBody": {"user": {"name.$": "$.user_name","email.$": "$.email","role.$": "$.role"}}}}},When called, the action sends a POST request to the Zendesk API's Create User endpoint. The request body contains the user's name, email address, and role.
-
Replace the
NewAcmeUserFlowplaceholder with the following ZIS flow definition. In the definition, replace "INTEGRATION" with your integration key."NewAcmeUserFlow": {"type": "ZIS::Flow","properties": {"name": "NewAcmeUserFlow","definition": {"StartAt": "AddZendeskUser","States": {"AddZendeskUser": {"Type": "Action","ActionName": "zis:INTEGRATION:action:AddZendeskUser","Parameters": {"user_name.$": "$.input.user.name","email.$": "$.input.user.email","role": "agent"},"End": true}}}}},The flow contains a single Action state. The state calls the custom action you defined in the previous step. The state requires
user.nameanduser.emailvalues from the event. -
Replace the
NewAcmeUserSpecplaceholder with the following job spec definition. In the definition, replace "INTEGRATION" with your integration key."NewAcmeUserSpec": {"type": "ZIS::JobSpec","properties": {"name": "NewAcmeUserSpec","event_source": "acme_system","event_type": "user_created","flow_name": "zis:INTEGRATION:flow:NewAcmeUserFlow"}}The job spec tells ZIS to run the ZIS flow when it detects an event with an
event_sourceof "acme_system" and anevent_typeof "user_created". -
Save my_zis_bundle.json. The file should now look like this:
{"name": "Example integration with a ZIS inbound webhook","description": "Create Zendesk user for new Acme system user","zis_template_version": "2019-10-14","resources": {"AddZendeskUser": {"type": "ZIS::Action::Http","properties": {"name": "AddZendeskUser","definition": {"method": "POST","path": "/api/v2/users","connectionName": "zendesk","headers": [{"key": "Content-Type","value": "application/json"}],"requestBody": {"user": {"name.$": "$.user_name","email.$": "$.email","role.$": "$.role"}}}}},"NewAcmeUserFlow": {"type": "ZIS::Flow","properties": {"name": "NewAcmeUserFlow","definition": {"StartAt": "AddZendeskUser","States": {"AddZendeskUser": {"Type": "Action","ActionName": "zis:INTEGRATION:action:AddZendeskUser","Parameters": {"user_name.$": "$.input.user.name","email.$": "$.input.user.email","role": "agent"},"End": true}}}}},"NewAcmeUserSpec": {"type": "ZIS::JobSpec","properties": {"name": "NewAcmeUserSpec","event_source": "acme_system","event_type": "user_created","flow_name": "zis:INTEGRATION:flow:NewAcmeUserFlow"}}}} -
Upload the bundle to ZIS.
curl -X POST https://{subdomain}.zendesk.com/api/services/zis/registry/{integration}/bundles \-u {email}/token:{api_token} \-H "Content-Type: application/json" \-d @my_zis_bundle.json -
Install the job spec to enable the integration.
curl -X POST "https://{subdomain}.zendesk.com/api/services/zis/registry/job_specs/install?job_spec_name=zis:{integration}:job_spec:NewAcmeUserSpec" \-u {email}/token:{api_token}
Creating the ZIS inbound webhook
Next, create a ZIS inbound webhook. The following request creates a webhook with
a source_system of "acme_system" and an event_type of "user_created". This
matches the source_type and event_type of the integration's job spec.
curl -X POST https://{subdomain}.zendesk.com/api/services/zis/inbound_webhooks/generic/{integration} \-H "Authorization: Bearer {access_token}" \-H "content-type: application/json" \-d '{"source_system": "acme_system","event_type": "user_created"}'
Save the response in a safe place. Later, you'll use the response's path,
username, and password to send event data to the webhook's ingest
URL.
{"event_type": "user_created","id": "01FDXQXBGQRZ3XN28WKX559PR2","integration": "INTEGRATION","password": "***password***","path": "/api/services/zis/inbound_webhooks/generic/ingest/xyz","source_system": "acme_system","username": "***username***","uuid": "d339ba7f-4a42-40fc-ae75-0e93315d3d0f","zendesk_account_id": 1}
Testing the integration
To test the integration, send event data for a test user to the webhook's ingest URL. Then verify the integration created a related Zendesk user profile.
-
Make a POST request to the webhook's ingest URL. In a typical setup, a developer configures the third-party system to make these requests in response to events in the system. For this tutorial, you'll make the request using the following curl command.
In the command, replace "{path}", "{username}", and "{password}" with values you saved when creating the webhook. The request body contains the event data as JSON.
Important: Escape any reserved URI characters in the "{username}" or "{password}" with a leading backslash (\). For example, you'd escape "myp@s$word" as "myp\@s\$word".
curl -X POST https://{subdomain}.zendesk.com{path} \-u {username}:{password} \-H "content-type: application/json" \-i -d '{"user": {"name": "John Doe","email": "[email protected]"}}'If successful, the request returns a 200 HTTP status code.
-
Search for the test user's Zendesk profile using the
user.emailaddress from step 1.curl https://{subdomain}.zendesk.com/api/v2/users/search.json \-u {email}:{password} \-G --data-urlencode "query=email:[email protected]"The response contains the test user's id, name, email address, and role. You'll use the id in the next step.
{"users": [{"id": 12345,"url": "https://SUBDOMAIN.zendesk.com/api/v2/users/12345.json","name": "John Doe","email": "[email protected]",..."role": "agent",...}],"next_page": null,"previous_page": null,"count": 1}You also can verify the test user exists using the Zendesk Admin Center.

-
To clean up, delete the test user's profile. Replace "{user_id}" with the id from the previous step.
curl -X DELETE https://{subdomain}.zendesk.com/api/v2/users/{user_id}.json \-u {email_address}:{password}To permanently delete the test user, run the following request afterward.
curl -X DELETE https://{subdomain}.zendesk.com/api/v2/deleted_users/{user_id}.json \-u {email_address}:{password}