Start Building for Free

Webhooks overview

4 months ago3 min read
Server v4.x
Server v3.x
On This Page

Use webhooks to:


A webhook allows you to connect a platform you manage (either an API you create yourself, or a third party service) to a stream of future events.

Setting up a webhook on CircleCI enables you 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.


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. Visit a specific project you have set up on CircleCI
  2. Click on Project Settings
  3. In the sidebar of your Project Settings, click on Webhooks
  4. Click Add Webhook
  5. Fill out the webhook form (the table below describes the fields and their intent)
  6. Provided your receiving API or third party service is set up, click Test Ping Event to dispatch a test event. Note that the test ping event has an abbreviated payload for ease of testing. See full examples of workflow-completed and job-completed events below.
Webhook nameYThe name of your webhook
URLYThe URL the webhook will make POST requests to
Certificate ValidationYEnsure the receiving host has a valid SSL certificate before sending an event 1
Secret tokenNUsed by your API/platform to validate incoming data is from CircleCI
Select an eventYYou must select at least one event that will trigger a webhook

1Only leave this unchecked for testing purposes.

Communication protocol with webhooks

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 5 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, please get get in touch with our team.

Webhook headers

A number of HTTP headers are set on webhooks, as detailed in the table below.

Header NameValue
user-agentA string indicating that the sender was CircleCI (CircleCI-Webhook/1.0).
circleci-event-typeThe type of event, (workflow-completed, job-completed, etc)
circleci-signatureWhen present, this signature can be used to verify that the sender of the webhook has access to the secret token.

Validate webhooks

You should validate incoming webhooks 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:

BodySecret KeySignature
hello worldsecret734cc62f32841568f45715aeb9f4d7891324e6d948e4c6c60c0621cdac48623a

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(',')

    # Run HMAC-SHA256 on the request body using the configured signing secret
    valid_signature =, '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`
        'circleci-signature': 'v1=773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4'

# the following will return `False`
        'circleci-signature': 'v1=not-a-valid-signature'

Event specifications of webhooks

CircleCI currently offers webhooks for the following events:

Event typeDescriptionPotential statusesIncluded sub-entities
workflow-completedA workflow has reached a terminal state“success”, “failed”, “error”, “canceled”, “unauthorized”project, organization, workflow, pipeline
job-completedA job has reached a terminal state“success”, “failed”, “canceled”, “unauthorized”project, organization, workflow, pipeline, job

Next steps

Help make this document better

This guide, as well as the rest of our docs, are open source and available on GitHub. We welcome your contributions.

Need support?

Our support engineers are available to help with service issues, billing, or account related questions, and can help troubleshoot build configurations. Contact our support engineers by opening a ticket.

You can also visit our support site to find support articles, community forums, and training resources.