> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pivotal.app/llms.txt.
> For full documentation content, see https://docs.pivotal.app/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pivotal.app/_mcp/server.

# Webhooks

Webhooks let Pivotal push events to your own systems the moment something happens. A customer flips to at-risk, your warehouse loads a row. A task is completed, your QBR tool updates the slide. Pivotal handles the delivery, signing, retries, and replay; you handle what to do with the payload.

This page covers the **end-user setup** of an endpoint inside Pivotal. For the developer spec (event catalog, payload shapes, signature verification), open the [Webhooks overview](/webhooks/overview).

## Where to add an endpoint

Endpoints live at **Admin > Developer > Webhooks**. The page is split into **Live** and **Test** so you can wire a staging URL alongside production without crossing them.

Click **Add endpoint**, paste your URL, pick the events to subscribe to, and save. Pivotal sends a `webhook.ping` event right away so you can confirm it arrived before anything real flows through.

## Pick events you need

Pivotal fires around twenty event types across four objects: customer, contact, onboarding, task. Subscribing to all of them is the wrong default. Pick by use case:

* **Warehouse ETL**: `customer.updated`, `onboarding.updated`, `task.updated`. The `updated` events fire on any change, so you snapshot the latest state.
* **Slack-adjacent alerting**: `customer.at_risk`, `customer.churned`, `onboarding.delayed`. State flips only, low volume.
* **Bidirectional CRM sync**: `customer.created`, `customer.updated`, scoped to the fields you care about (set the field filter in the endpoint config).
* **In-app analytics**: `task.completed`, `phase.changed`. Drive funnel charts off these.

The full event list with example payloads is in the [Webhooks overview](/webhooks/overview).

## What a delivery looks like

Every delivery is a `POST` with three Pivotal-specific headers:

```
POST https://your-app.com/webhooks/pivotal
content-type: application/json
pivotal-event: customer.at_risk
pivotal-delivery-id: msg_2m3kJ8Hf9aB1cD2eF3gH4iJ5kL
pivotal-signature: v1,t=1716566400,sig=base64(hmac-sha256(secret, t + "." + body))
```

The body is JSON: `{ id, type, created_at, data }`. The `data` object is the full record at the time of the event. Pivotal signs the payload with the endpoint secret shown on the endpoint page; verify it in your handler before trusting the body.

## The replay button

Every endpoint has a **Deliveries** tab listing the last 90 days of attempts. Each row shows the status code, response time, and payload. If a delivery failed (or you broke your handler and want to re-send the last hour), select the rows and click **Replay** in the action bar. Pivotal re-POSTs each one to the same endpoint, with the same body and a new delivery id.

Retries are automatic for the first 24 hours after a delivery fails (5xx or timeout) with exponential backoff. After 24 hours, the delivery is marked permanently failed and you replay manually.

## Gotcha: changing the endpoint URL does not replay

Updating the URL on an existing endpoint affects new deliveries only. To re-send the historical events to the new URL, open **Deliveries**, filter to the window you care about, select all, and click **Replay**.

## Related

* [Webhooks overview](/webhooks/overview) (developer spec)
* [Data export](/product/integrations/data-export)
* [API quickstart](/api/welcome/quickstart)

Email **[help@pivotal.app](mailto:help@pivotal.app)** with a screenshot of where you got stuck and the customer or onboarding id from the URL.