Webhook integration
On This Page
- Custom webhooks
- Quickstart
- Example: Trigger one pipeline from another
- 1. Set up a custom webhook for Project B
- 2. Configure Project A to trigger Project B
- Example: Extract custom webhook payload data
- Outbound webhooks
- Quickstart
- Communication protocol for outbound webhooks
- Outbound webhook headers
- Validate outbound webhooks
- Outbound webhook event specifications
- Next steps
A webhook allows you to connect a platform (for example, CircleCI, an API you create yourself, or a third party service) to a stream of future events.
Setting up an outbound webhook on CircleCI enables your third party service to receive information (referred to as events) from CircleCI, as they happen. This can help you avoid polling the API or manually checking the CircleCI web application for desired information.
Setting up an inbound webhook (as a custom webhook trigger) on CircleCI enables a third party service to trigger a CircleCI pipeline. Any service that can send a webhook or make a curl
request can trigger a CircleCI pipeline.
Selecting a custom webhook as a pipeline trigger is generally available for orgs that integrate with CircleCI’s GitHub App, and is available in "Preview" for orgs that integrate with GitHub via the CircleCI GitHub OAuth App. To find out which GitHub account type you have, see the GitHub App integration page. |
Custom webhooks
Use custom webhooks to trigger a pipeline from anywhere that can emit a webhook or run a curl command.
Custom webhooks are inbound to CircleCI and are used to trigger pipelines from other services. If you are looking for a way to have a CircleCI pipeline trigger a service, use an outbound webhook. |
This section presents some use cases for CircleCI custom webhooks.
Quickstart
Follow these steps to set up and test a custom webhook trigger. Trigger from anywhere that can emit a webhook or run a curl command:
-
In the CircleCI web app select Projects in the sidebar.
-
Find your project in the list, select the ellipsis (), select Project Settings, and select Pipelines in the sidebar.
-
If there is already a pipeline set up and it uses the desired YAML configuration file, proceed to the Triggers step below (step 5). If not, select Set up pipeline. If there is a Connect button, select it and follow the steps to install the CircleCI GitHub App into your GitHub organization.
-
Name the new pipeline and select the repository where the CircleCI YAML configuration file is stored. Enter the file path (including the
.circleci
directory). The file path can be different than.circleci/config.yml
(for example,.circleci/webhook.yml
). Save the pipeline. -
Select Triggers in the sidebar.
-
Select Add Trigger.
-
Select Custom Webhook from the dropdown menu.
-
Select Next.
-
Complete the form fields and options:
-
Enter a descriptive name for the trigger. For example, if you are setting up a custom webhook to run pipelines on events from Datadog, enter "Datadog" here.
-
(Optional) Add a description.
-
In the field "Pipeline to run", at the bottom of the page, select the pipeline that you created in the step above.
-
Enter the branch to use to fetch your config file when a Custom Webhook is received.
-
Enter the branch to use to check out your code when using the checkout step in config. If your config is stored in the same repository as your code, then your Config branch and your Checkout branch should be the same.
-
-
Select Save.
-
You will see a webhook endpoint URL and secret. You can use these to set up your webhook trigger from your external source. Copy the Webhook URL and use it in your trigger source appended with the secret.
The secret will not be shown again so be sure to copy the URL before clicking Done. -
You can now test your custom webhook trigger with
curl
. To trigger your pipeline, copy and paste the following sample request and replace<your-URL>
and<your-secret>
with the URL and secret that you generated in the previous step:When triggering via curl
, you must use aPOST
request withcontent-type: application/json
.curl -X POST -H "content-type: application/json" 'https://internal.circleci.com/private/soc/e/<your-URL>?secret=<your-secret>'
See our community forum for more details or how to use this functionality with a 3rd party service like DockerHub.
Custom webhooks will not work with security group restrictions. Additionally, the configuration file that is used for pipelines triggered by a custom webhook will only be visible in the CircleCI web app if the configuration file path is .circleci/config.yml . |
Example: Trigger one pipeline from another
Use a custom webhook to configure one pipeline to trigger a second pipeline. For example, you might need to run a set of integration tests on a repository after you have made a change to a separate repository.
For this example, assume you have two projects in separate repositories:
You can also use this method to trigger one pipeline from another within the same project. |
-
Project A
-
Project B
When a change is made to Project A, we want the full Project A configuration to be run, and then the Project B pipeline should be triggered. To achieve this, follow these steps:
1. Set up a custom webhook for Project B
Navigate to Project B in the CircleCI web app and set up a custom webhook by following these steps:
-
In the CircleCI web app select Projects in the sidebar.
-
Find your project in the list, select the ellipsis (), select Project Settings, and select Pipelines in the sidebar.
-
If there is already a pipeline set up and it uses the desired YAML configuration file, proceed to the Triggers step below (step 5). If not, select Set up pipeline. If there is a Connect button, select it and follow the steps to install the CircleCI GitHub App into your GitHub organization.
-
Name the new pipeline and select the repository where the CircleCI YAML configuration file is stored. Enter the file path (including the
.circleci
directory). The file path can be different than.circleci/config.yml
(for example,.circleci/webhook.yml
). Save the pipeline. -
Select Triggers in the sidebar.
-
Select Add Trigger.
-
Select Custom Webhook from the dropdown menu.
-
Select Next.
-
Complete the form fields and options:
-
Enter a descriptive name for the trigger. For example, if you are setting up a custom webhook to run pipelines on events from Datadog, enter "Datadog" here.
-
(Optional) Add a description.
-
In the field "Pipeline to run", at the bottom of the page, select the pipeline that you created in the step above.
-
Enter the branch to use to fetch your config file when a Custom Webhook is received.
-
Enter the branch to use to check out your code when using the checkout step in config. If your config is stored in the same repository as your code, then your Config branch and your Checkout branch should be the same.
-
-
Select Save.
-
You will see a webhook endpoint URL and secret. You can use these to set up your webhook trigger from your external source. Copy the Webhook URL and use it in your trigger source appended with the secret.
The secret will not be shown again so be sure to copy the URL before clicking Done.
2. Configure Project A to trigger Project B
Navigate to Project A in the CircleCI web app and set up an environment variable. The value of the environment variable will be the secret from the custom webhook you just set up for Project B.
-
In the CircleCI web app select your organization.
-
Select Projects in the sidebar.
-
Find your project in the list, select the ellipsis (), and select Project Settings.
-
Select Environment Variables from the sidebar.
-
Select Add Environment Variable.
-
Give your environment variable a name, for example,
WEBHOOK_SECRET
. -
Update your Project A configuration file with a step that will trigger a pipeline for Project B, for example (lines 13-16):
version: 2.1 jobs: say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: example command: echo "one step" - run: name: Kick off new pipeline command: | curl -X POST -H "content-type: application/json" "https://internal.circleci.com/private/soc/e/6ccfca1c-5ed6-4dcf-96ca-374969d6edcb?secret=${WEBHOOK_SECRET}" workflows: say-hello-workflow: jobs: - say-hello
Example: Extract custom webhook payload data
The custom webhook body is available by using the pipeline.trigger_parameters.webhook.body
pipeline value.
The following example shows how you can use jq
to extract values from the webhook payload into environment variables when you want to use them in your configuration.
In this example the webhook body contains a property called branch
. jq
is installed and used to extract the branch
value into an environment variable named WEBHOOK_BRANCH
, which is then used in a GitHub clone command.
commands:
shallow_clone:
description: Shallow Git Clone
steps:
- gh/setup:
token: "GITHUB_TOKEN"
- jq/install
- run:
name: Shallow Clone
environment:
WEBHOOK_BRANCH: << pipeline.trigger_parameters.webhook.body >> | jq .branch
command: gh repo clone << pipeline.trigger_parameters.github_app.repo_url >> . -- --depth 10 --branch "$WEBHOOK_BRANCH"
Outbound webhooks
Use outbound webhooks to integrate your CircleCI builds with external services.
For example, you could use Outbound webhooks to:
-
Build a custom dashboard to visualize or analyze workflow/job events.
-
Send data to incident management tools (such as PagerDuty).
-
Use tools like Airtable to capture data and visualize it.
-
Alert when a workflow is cancelled, then use the API to rerun the workflow.
-
Trigger notification systems to alert people when workflows/jobs complete.
-
Build your own automation plugins and tools.
The following sections detail CircleCI outbound webhook structure and protocols.
Quickstart
Projects are limited to 5 outbound webhooks. |
Webhooks are set up on a per-project basis, either within the CircleCI app or via API.
To configure webhooks via API see our documentation for Webhooks Public API.
To configure webhooks within the CircleCI app:
-
In the CircleCI web app select your organization.
-
Select Projects in the sidebar.
-
Find your project in the list, select the ellipsis (), and select Project Settings.
-
In the sidebar select Webhooks
-
Select Add Webhook
-
Fill out the webhook form (the table below describes the fields and their intent)
-
If your receiving API or third party service is set up, select Test Ping Event to send a test event.
The test ping event has an abbreviated payload for ease of testing. See full examples for sample webhook payloads section of the webhooks reference.
Field | Required? | Intent |
---|---|---|
Webhook name | Y | The name of your webhook |
URL | Y | The URL the webhook will make POST requests to |
Certificate Validation | Y | Ensure the receiving host has a valid SSL certificate before sending an event. You should only leave this unchecked for testing purposes. |
Secret token | N | Used by your API/platform to validate incoming data is from CircleCI |
Select an event | Y | You must select at least one event that will trigger a webhook |
Communication protocol for outbound webhooks
Once set up, a webhook is sent whenever an event occurs on the CircleCI platform.
A webhook is sent using an HTTP POST to the URL that was registered when the webhook was created, with a body encoded using JSON.
CircleCI expects the server that responds to a webhook will return a 2xx response code. If a non-2xx response is received, CircleCI will retry at a later time. If CircleCI does not receive a response to the webhook within a short period of time, CircleCI will assume that delivery has failed, and will retry at a later time. The timeout period is currently 10 seconds.
Webhook requests may be duplicated. To deduplicate (prevent requests from being duplicated for a specific event), use the id
property in the webhook payload for identification.
If you have feedback about timeouts and retries, get in touch with our team.
Outbound webhook headers
A number of HTTP headers are set on webhooks, as detailed in the table below.
Header name | Value |
---|---|
|
|
| A string indicating that the sender was CircleCI ( |
| The type of event, ( |
| When present, this signature can be used to verify that the sender of the webhook has access to the secret token. |
Validate outbound webhooks
You should validate webhooks as they come in to third party services to verify that they are coming from CircleCI. To support this, when creating a webhook, you can optionally provide a secret token. Each outgoing HTTP request to your service will contain a circleci-signature
header. This header will consist of a comma-separated list of versioned signatures.
POST /uri HTTP/1.1
Host: your-webhook-host
circleci-signature: v1=4fcc06915b43d8a49aff193441e9e18654e6a27c2c428b02e8fcc41ccc2299f9,v2=...,v3=...
Currently, the latest (and only) signature version is v1. You should only check the latest signature type to prevent downgrade attacks.
The v1 signature is the HMAC-SHA256 digest of the request body, using the configured signing secret as the secret key.
Here are some example signatures for given request bodies:
Body | Secret Key | Signature |
---|---|---|
|
|
|
|
|
|
|
|
|
The following is an example of how you might validate signatures in Python:
import hmac
def verify_signature(secret, headers, body):
# get the v1 signature from the `circleci-signature` header
signature_from_header = {
k: v for k, v in [
pair.split('=') for pair in headers['circleci-signature'].split(',')
]
}['v1']
# Run HMAC-SHA256 on the request body using the configured signing secret
valid_signature = hmac.new(bytes(secret, 'utf-8'), bytes(body, 'utf-8'), 'sha256').hexdigest()
# use constant time string comparison to prevent timing attacks
return hmac.compare_digest(valid_signature, signature_from_header)
# the following will return `True`
verify_signature(
'secret',
{
'circleci-signature': 'v1=773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4'
},
'foo',
)
# the following will return `False`
verify_signature(
'secret',
{
'circleci-signature': 'v1=not-a-valid-signature'
},
'foo',
)
Outbound webhook event specifications
CircleCI currently offers outbound webhooks for the following events:
Event type | Description | Potential statuses | Included sub-entities |
---|---|---|---|
workflow-completed | A workflow has reached a terminal state | "success", "failed", "error", "canceled", "unauthorized" | project, organization, workflow, pipeline |
job-completed | A job has reached a terminal state | "success", "failed", "canceled", "unauthorized" | project, organization, workflow, pipeline, job |
Next steps
-
See the Webhooks reference page for key definitions and sample payloads.
-
Follow the Using webhooks with third party tools tutorial.