Outbound webhooks

Language Icon 1 month ago · 8 min read
Cloud Server v4+
Contribute Go to Code

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.

Introduction

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:

  1. In the CircleCI web app select your organization.

  2. Select Projects in the sidebar.

  3. Find your project in the list, select the ellipsis more icon, and select Project Settings.

  4. In the sidebar select Webhooks

  5. Select Add Webhook

  6. Fill out the webhook form (the table below describes the fields and their intent)

  7. 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

content-type

application/json

user-agent

A string indicating that the sender was CircleCI (CircleCI-Webhook/1.0).

circleci-event-type

The type of event, (workflow-completed, job-completed, etc)

circleci-signature

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

hello world

secret

734cc62f32841568f45715aeb9f4d7891324e6d948e4c6c60c0621cdac48623a

lalala

another-secret

daa220016c8f29a8b214fbfc3671aeec2145cfb1e6790184ffb38b6d0425fa00

an-important-request-payload

hunter123

9be2242094a9a8c00c64306f382a7f9d691de910b4a266f67bd314ef18ac49fa

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 status 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