Webhooks

Webhooks allow your application to receive real-time notifications when events occur.
Our API sends an HTTP POST request to your configured endpoint whenever a subscribed event is triggered.
Currently, we support only envelope events. However, in the near future, we will support more.

Get started

First, you need to configure a webhook endpoint from the dashboard.

  • Log in to the Dashboard
  • Navigate to Settings -> Webhooks
  • Click Create in the specific API environment table (Production or Sandbox)
  • Complete the details and click Submit

See below how a webhook configuration looks.
In this example, we demonstrate a webhook endpoint that listens to the envelope.expired event. However, you can specify more events and listen to multiple events in the same webhook endpoint.

Webhooks

Code example:

See below a minimal JavaScript code example to verify your webhook works.

⚠️ This example does not verify webhook signatures. For production use, see the signature verification section below.

Test webhooks locally

We recommend testing your webhooks locally using the third-party tool ngrok.
First, copy the code snippet from the example above and run it. This will start your local server listening on port 3000.
Then, open a new terminal and start an ngrok tunnel with the following command:


Next, open the PDFGate dashboard and update your webhook URL host with the URL provided by ngrok.
It will look like:
https://e0c2-xxxx.ngrok-free.app
Your webhook URL should be updated like:
https://e0c2-xxxx.ngrok-free.app/{your_slug}

You should now start receiving webhook events on your local server.

Verify signature

Each webhook request includes an x-pdfgate-signature header.
Use this header to verify that the request was sent by PDFGate and that the payload was not modified in transit.

The signature header contains:
  • t: the Unix timestamp when the webhook was signed
  • v1: one or more values that are HMAC-SHA256 signatures.
Example:
x-pdfgate-signature: "t=1712345678,v1=abc123,v1=def456"

To verify the webhook:

1. Read the raw request body exactly as received
2. Extract the timestamp and v1 signatures from the x-pdfgate-signature header
3. Build the signed payload as: {timestamp}.{raw_body}
4. Compute the expected signature using HMAC-SHA256 and your webhook secret
5. Compare the expected signature against all v1 signatures in the header
6. Reject the request if:
  • the signature is missing
  • the timestamp is older than 5 minutes
  • none of the provided signatures match

We may include multiple signatures during secret rotation. Your code should consider the webhook valid if any of the v1 signatures matches the expected value.

Code example:

See below Javascript code example of signature verification. We are currently implementing this in our SDKs so you won’t need to implement it manually.

Event object

Each webhook delivers an Event type JSON payload:

Handle duplicate deliveries

Webhook deliveries may be retried and delivered out of order.
Before applying updates, we recommend retrieving the current state of the referenced resource from the API to ensure consistency.

Retry behavior

If your endpoint does not return a 2xx status code, delivery is retried. Retries are scheduled relative to the original event time and processed by a background job every 3 minutes. After the final attempt, the webhook is marked as failed.

AttemptDelay
Attempt #15 minutes
Attempt #215 minutes
Attempt #31 hour
Attempt #46 hours
Attempt #524 hours
Attempt #648 hours

Rotate signing secrets

If your signing secret is compromised, you can rotate it from the dashboard.

When rotation begins:
  • A new secret is generated.
  • A 24-hour grace period starts.
  • Webhooks are signed using both the previous and new secret.
  • The x-pdfgate-signature header will include multiple v1 values.
  • You should accept the request if any signature matches.
  • After 24 hours, the old secret becomes permanently invalid.
If rotation is canceled during the grace period:
  • The previous secret remains active.
  • The new secret is discarded.