Webhooks
Webhooks
Webhooks let you receive real-time event callbacks whenever data changes in your Coastline workspace. Register a target URL with a trigger, and Coastline will POST a JSON payload to that URL each time the event fires. Use webhooks to push data into Zapier, Make, n8n, your own backend, or any HTTP endpoint you control.
How it works
- Create an API key in Settings → API Keys.
- Subscribe to a trigger by sending a
POST /v1/subscriptionswith atrigger_idand yourtarget_url. - Coastline POSTs a signed JSON payload to your URL each time the event fires.
- Respond with an HTTP
2xxwithin 15 seconds to acknowledge delivery.
See the subscriptions reference for the full create / list / revoke API.
Available triggers
The trigger_id field on a subscription must match one of the values below.
| trigger_id | Label | Description |
|---|---|---|
| opportunity.created | New Opportunity | Fires when a new opportunity (lead) is created. |
| opportunity.project.stage.updated | Opportunity Stage Changed | Fires whenever an opportunity or project moves to a new pipeline stage. |
| opportunity.project.approved | Project Approved | Fires when an opportunity is approved and converted into a project. |
| opportunity.estimate_sent | Estimate Sent | Fires when an estimate is sent to a customer. |
| opportunity.estimate_approved | Estimate Approved | Fires when a customer approves an estimate. |
| opportunity.estimate_cancelled | Estimate Cancelled | Fires when an estimate is cancelled. |
| opportunity.d4d.spotted | New Lead Spotted (D4D) | Fires when a new lead is captured via Driving for Dollars. |
| envelope.signed | Document Signed | Fires when a recipient signs a document. |
| envelope.completed | Document Fully Signed | Fires when every recipient has signed a document. |
Payload shape
Every webhook delivery is a JSON object with the same envelope. The data field contains the full record that triggered the event (e.g. the opportunity row for an opportunity event).
| Field | Type | Description |
|---|---|---|
| id | string | Unique event id. Use this to deduplicate. |
| trigger | string | The trigger_id this event matches (e.g. opportunity.created). |
| entity_type | string | The entity that emitted the event (opportunity, contact, task, contractor, envelope). |
| entity_id | string | UUID of the entity record. |
| occurred_at | string | ISO 8601 timestamp of when the event happened. |
| performed_by | string | null | UUID of the workspace user who took the action, or null for system events. |
| metadata | object | Trigger-specific context (e.g. previous_stage_id, new_stage_id for stage changes). |
| data | object | null | The full record that triggered the event. Same shape returned by the resource endpoints. |
Signature verification
Every request includes an X-Coastline-Signature header of the form sha256=<hex>. The signature is an HMAC-SHA256 of the raw request body, keyed by the signing_secret returned when you created the subscription. Verify the signature on every request, never trust an unsigned payload.
You will also receive these headers on each delivery:
| Header | Description |
|---|---|
| X-Coastline-Signature | sha256=<hex> HMAC of the request body. |
| X-Coastline-Event | The trigger_id of the event (e.g. opportunity.created). |
| X-Coastline-Event-Id | Unique event id, same as the id field in the payload. Use to deduplicate. |
| User-Agent | CoastlineCRM-Webhooks/1.0 |
Retries and delivery
- Coastline expects a
2xxresponse within 15 seconds. - Failed deliveries are retried with exponential backoff at 1, 5, 15, 60, and 240 minutes (6 attempts total).
- Permanent
4xxresponses (other than 408 / 429) are not retried. - Respond with HTTP
410 Goneto permanently revoke a subscription from the receiver side. - Deliveries are at-least-once. Use the
idfield to deduplicate.
Sample payloads
Fetch up to three of your most recent real events for any trigger via GET /v1/triggers/{trigger_id}/sample. If your workspace has not yet emitted that trigger, a synthetic payload is returned so you can map fields ahead of time.