Webhooks
Get a signed HTTPS request at your own endpoint each time a candidate applies, and verify it, test it, and handle retries.
Overview
Section titled “Overview”Webhooks send an HTTPS request from Dover to a URL you choose when something happens. Today there is one event, Candidate applied, which fires each time someone applies to one of your jobs. Use it to update your own systems, post to a chat tool, or start a workflow, without checking Dover for new applicants. Adding and managing endpoints needs the Integrations company permission.
Add an endpoint
Section titled “Add an endpoint”- Click Settings → Integrations.
- Open Webhooks.
- Under Add new endpoint, enter your Endpoint URL. It must be public and use HTTPS.
- Choose the Event, Candidate applied.
- Click Add endpoint.
- In Save your signing secret, click Copy signing secret and store it somewhere safe.
Manage your endpoints
Section titled “Manage your endpoints”Active endpoints lists each endpoint with its Event and Status.
- Pause or resume: use the switch to set an endpoint Active or Paused. A paused endpoint gets nothing, and requests waiting to be sent to it are cancelled.
- Test: click Test to send a sample event to an active endpoint. Dover shows Test event queued.
- Delete: click the delete icon and confirm.
What Dover sends
Section titled “What Dover sends”Each request is a POST with a JSON body. The event type is candidate.application.created.
{ "id": "6f1f6c2e-...", "type": "candidate.application.created", "api_version": "2026-07-23", "created_at": "2026-11-02T15:04:05+00:00", "data": { "client": { "id": "..." }, "job": { "id": "...", "title": "Senior Software Engineer" }, "application": { "id": "...", "applied_at": "2026-11-02T15:03:58+00:00", "external_application_id": null, "source": { "id": "...", "label": "Dover careers page" }, "candidate": { "first_name": "Alice", "last_name": "Johnson", "full_name": "Alice Johnson", "linkedin_public_id": null }, "application_questions": [{ "question": "Why this role?", "answer": "..." }] } }}A test event has the type webhook.test and only the company’s ID in data.
Every request has these headers:
| Header | What it holds |
|---|---|
Dover-Webhook-Id |
The event’s ID. The same event has the same ID on every retry. |
Dover-Webhook-Delivery-Id |
The ID of this delivery. |
Dover-Webhook-Timestamp |
When Dover signed the request, in Unix seconds. |
Dover-Webhook-Version |
The payload version, such as 2026-07-23. |
Dover-Webhook-Signature |
The signature, as v1= followed by a hex value. |
Idempotency-Key |
The event’s ID, so you can ignore repeats. |
Verify a request
Section titled “Verify a request”Check the signature before you trust a request.
- Read the raw request body, exactly as received.
- Join the
Dover-Webhook-Timestampvalue, a period, and the raw body. - Compute an HMAC-SHA256 of that text, using your signing secret as the key, and write it as hex.
- Compare it to the value after
v1=inDover-Webhook-Signature, using a constant-time comparison.
import hashlib, hmac
def is_valid(secret: str, timestamp: str, body: bytes, header: str) -> bool: signed = timestamp.encode() + b"." + body expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() return hmac.compare_digest(f"v1={expected}", header)Reject requests with an old timestamp to block replays. Use Dover-Webhook-Id to ignore an event you already handled.
Delivery and retries
Section titled “Delivery and retries”Respond with a 2xx status within 10 seconds. If Dover gets a timeout, a network error, a 408, 425, 429, or any 5xx, it tries again about 5 minutes later, up to 10 attempts in total. Other responses, such as 400 or 404, aren’t retried. Dover doesn’t follow redirects.
Frequently asked questions
Section titled “Frequently asked questions”Why can’t I add my URL?
Section titled “Why can’t I add my URL?”Dover accepts only public HTTPS addresses. It rejects localhost, private network addresses, URLs with a username or password, and hosts it can’t resolve.
I lost my signing secret. What do I do?
Section titled “I lost my signing secret. What do I do?”Delete the endpoint and add it again. The new endpoint gets a new secret, shown once.
Why did I get the same event twice?
Section titled “Why did I get the same event twice?”Dover retries when it doesn’t get a 2xx answer in time. Use Dover-Webhook-Id or Idempotency-Key to ignore an event you already handled.
Why is the Test button turned off?
Section titled “Why is the Test button turned off?”You can only test an Active endpoint. Switch it on first.
Which events can I get?
Section titled “Which events can I get?”Only Candidate applied for now.