Skip to content

Webhooks

Configure webhook endpoints to receive real-time notifications for Spark CRM events.

Webhooks allow you to receive real-time HTTP notifications when events occur in Spark CRM.

Navigation: Settings > Webhooks

screenshot of Webhooks settings page


Overview

When a configured event occurs, Spark CRM calls your endpoint using the HTTP method selected on the webhook (MethodPOST or GET; the create form opens with GET preselected). POST deliveries carry a JSON body; GET deliveries send no body at all, so any data must be passed through {token} placeholders in the Endpoint URL.


Creating a Webhook

Prerequisites

Webhooks are available on Account-type teams only. You also need the relevant webhook permissions: webhooks:view_any to see the list, webhooks:create to add one, webhooks:update to edit, webhooks:delete to remove, and webhooks:view_logs for logs and statistics. Account owners and administrators have them all.

Without view permission the panel shows an Access Restricted card; without both update and delete permission the row menu shows only a disabled View Only item.

Step 1: Navigate to Webhooks

  1. Go to Settings in the sidebar
  2. Click Webhooks in the left menu

Step 2: Add Webhook

  1. Click Add Webhook button
  2. Configure the webhook settings:

screenshot of add webhook form

Field Description
Webhook Name * A label for the webhook; shown in the list and in the logs flyout
Method * POST or GET. Defaults to GET. POST sends a JSON body; GET sends none
Endpoint URL * The destination URL, e.g. https://example.com/webhook. Supports {token} placeholders — click the braces button beside the field to browse and copy available tokens. HTTPS is strongly recommended, since the signature header and any configured authentication credentials travel as request headers, but http:// URLs are accepted and not rejected by validation
Authentication How Spark CRM authenticates to your endpoint: No Authentication (default), Bearer Token (Authorization: Bearer …), API Key (X-API-Key: …), Custom Header (you supply the header name), or Basic Authentication (Authorization: Basic …, base64-encoded). Any option other than No Authentication requires a credential value; Custom Header also requires a Header Name. Basic Authentication expects user:password and is masked in the form
Secret Optional shared secret for verification
Events * Searchable multi-select. Choose at least one trigger; the webhook fires on any selected event, subject to the campaign scoping below
Select All Campaigns Fire for every campaign, including campaigns created later
Campaigns Shown when Select All Campaigns is unchecked. Restrict this webhook to the selected campaigns — events from other campaigns are not delivered. Leaving it empty applies no campaign filter. Customer-level events have no campaign and are never filtered
JSON Payload Parameters POST only. Custom key/value pairs (token placeholders supported) that replace the default payload
Delay (minutes) Hold the delivery for this many minutes after the event fires (0 = send immediately; maximum 10,080 = 7 days). Ignored for Cart Abandoned, which is already scheduled. Delayed deliveries re-check the record’s state when they are finally sent and are skipped if it no longer matches the event
Active Enable or disable this webhook (checked by default)
Verify SSL Validate the endpoint’s TLS certificate (checked by default)

Fields marked * are required.

Step 3: Select Events

Choose which events should trigger the webhook. The Events field is a single searchable multi-select containing every trigger in one flat list — the groupings below are a documentation aid only, so type to filter rather than looking for headings. At least one event is required.

Transaction Events:

  • Transaction Approved
  • Transaction Declined

Order Events:

  • Order Created
  • Order Updated
  • Order Complete
  • Order Canceled
  • Order Declined
  • Refund Created

There is no transaction-level refund trigger — refunds are covered by Refund Created, whose payload names the refund transaction, the original charge and the refunded products.

Subscription Events:

  • Subscription Created
  • Subscription Updated
  • Subscription Canceled
  • Subscription Process Reminder
  • Subscription Past Due
  • Subscription Expired
  • Trial Started
  • Trial Ended
  • Subscription Rebill Complete
  • Subscription Rebill Declined

Customer Events:

  • Customer Created
  • Customer Updated
  • New Customer Added
  • Customer Blacklisted

Cart Events:

  • Cart Abandoned

Fulfillment Events:

  • Fulfillment Created
  • Tracking Updated
  • Out for Delivery (requires Enhanced Shipping Notifications)
  • Delivered (requires Enhanced Shipping Notifications)

Dispute Events:

  • Dispute Opened
  • Dispute Won
  • Dispute Lost

Out for Delivery and Delivered require the Enhanced Shipping Notifications add-on. Without it, both appear in the Events list greyed out and labelled “(Requires Enhanced Shipping Notifications)” and cannot be selected. Fulfillment Created and Tracking Updated are always available.

Selecting an event is not the only condition for delivery — campaign scoping applies as well. See Select All Campaigns and Campaigns in the field table above.

GET https://api.sparkcrm.io/v1/webhooks/events returns every trigger with its label and available tokens if you need the authoritative list.

Step 4: Save

Click Create Webhook to save the new webhook (on the edit flow the same button reads Update Webhook).

A Webhook Created (or Webhook Updated) confirmation appears and the panel closes. Saving replaces the webhook’s entire event subscription set — any event you deselect is removed. The signing secret is generated when the webhook is first created and is not regenerated by later edits.


Webhook Payload

What is sent depends on the webhook’s Method:

  • GET — no body. Only the Endpoint URL is sent, with any {token} placeholders substituted.
  • POST with no JSON Payload Parameters — a flat JSON object containing every available field for that event (null fields omitted).
  • POST with JSON Payload Parameters defined — a JSON object containing exactly the parameters you defined, with {token} placeholders substituted. The same parameter set applies to every event selected on the webhook.

Default POST body

{
  "event_type": "order_created",
  "timestamp": "2026-02-02T12:00:00Z",
  "order_number": "ORD-260202-00001",
  "order_uuid": "9f8c1d2e-3a4b-4c6d-8e8f-9a0b1c2d3e4f",
  "status": "processing",
  "total_amount": 99.99,
  "subtotal": 89.99,
  "tax": 5.00,
  "shipping": 5.00,
  "currency": "USD",
  "customer_number": "CUST-260202-00001",
  "customer_email": "jane@example.com",
  "items": []
}

There is no envelope — every field is top level, and fields with no value are omitted entirely.

Event values are always the snake_case trigger key (transaction_approved, subscription_rebill_complete, refund_created, and so on), matching the values returned by GET https://api.sparkcrm.io/v1/webhooks/events. There is no event key and no dot notation.

Order payload fields

order_number, order_uuid, status, total_amount, subtotal, tax, shipping, currency, customer_number, customer_email, customer_first_name, customer_last_name, phone and items[] (each item annotated with is_subscription and billing_interval), plus the shipping_* and billing_* address fields and the attribution fields affiliate_id, sub1-sub5, utm_source, utm_medium and utm_campaign. utm_term and utm_content appear on transaction payloads only.

Customer details are flat fields, not a nested customer object, and the line-item array is items[] — a products[] array appears on transaction, subscription and fulfillment payloads, not on order payloads.

URL tokens

The Endpoint URL supports {token} placeholders, e.g. https://example.com/hook?order={order_number}&email={customer_email}. Values are URL-encoded when the webhook is sent; tokens that have no value for that event are left in the URL as-is. Click the braces button beside the Endpoint URL field to browse and copy the available tokens.


Verifying Webhooks

If you configure a webhook secret, Spark CRM includes a signature header for verification:

X-Webhook-Signature: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

The value is the raw lowercase hex HMAC-SHA256 digest — there is no sha256= prefix.

Verification process:

  1. Compute HMAC-SHA256 of the raw request body using your secret
  2. Compare with the value in X-Webhook-Signature
  3. If they match, the webhook is authentic

Example (PHP):

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, $your_secret);

if (hash_equals($expected, $signature)) {
    // Webhook is verified
}

Managing Webhooks

Webhook List

The list shows your team’s webhooks, newest first, 10 per page:

Column Description
Name Webhook name; shows a CS badge when created by a Customer Service provider, and an Nmin delay subtitle when a delay is configured
URL Endpoint URL (truncated, monospace)
Events Badges naming the first two subscribed events, plus a +N more badge when there are others
Method GET or POST
Status Active / Inactive
Created By Team or CS
(actions) The row’s menu: Edit, Test Webhook, View Logs, View Statistics, Delete

Last-delivery information is not shown in the list — open the row’s menu and choose View Logs for per-delivery history, or View Statistics for the last successful and failed call and the success rate.

Webhooks created for you by a Customer Service provider also appear here, marked with a CS badge beside the name and shown as CS in the Created By column. An information callout appears above the table when any are present; these webhooks may have different access permissions than ones your team created.

Editing a Webhook

  1. Open the menu at the end of the webhook’s row and choose Edit (the item appears only if you have webhook update permission; when you have neither update nor delete permission the menu shows only a disabled View Only item)
  2. Modify settings
  3. Click Update Webhook

Deleting a Webhook

  1. Open the menu at the end of the webhook’s row and choose Delete (shown only if you have webhook delete permission)
  2. Confirm deletion in the Delete Webhook dialog

Testing a Webhook

Open the menu and choose Test Webhook, then Send Test. The configured endpoint is called with dummy data substituted for any tokens, and the result modal shows the status code, final URL, payload, response body and response headers.

Viewing Delivery Logs

Open the menu and choose View Logs for the per-delivery history: search, a status filter (Completed / Failed / Pending / Skipped), a per-page selector, View Details and Resend on each row, and Resend Selected for bulk redelivery.

Viewing Statistics

Open the menu and choose View Statistics for the success rate, total, successful and failed call counts, average processing time, last successful and failed call, trigger distribution and the most common failure reasons.

View Logs and View Statistics require webhook log-viewing permission.


Delivery & Retries

Successful Delivery

  • Your endpoint returns HTTP 200-299
  • The delivery is recorded in the webhook’s logs with status Completed, along with the response code, response body and processing time

Log statuses are Pending, Completed, Failed and Skipped.

Failed Delivery

  • Your endpoint is unreachable or times out
  • The delivery is retried up to 3 attempts in total, waiting 30 seconds and then 60 seconds
  • Retries apply only to connection-level failures. If your endpoint answers with an error status (4xx/5xx), the delivery is marked Failed immediately and is not retried — redeliver it manually from > View Logs > Resend
  • A webhook is switched off automatically only once it has been failing continuously for at least 3 hours and has accumulated at least 10 consecutive failures with no successful delivery in between
  • When that happens its Status flips to Inactive, you are notified, and it stops firing until you edit it and re-check Active — re-enabling resets the failure streak
  • Any single successful delivery resets the counter

Skipped Delivery

A queued delivery is skipped — logged with status Skipped and a reason — when the record it describes has changed state before it was sent. This is most likely on webhooks with a Delay configured, or on a retry. Examples: an order that recovered from Declined, a cart that is no longer abandoned, a reactivated subscription, an un-blacklisted customer, or a fulfillment whose delivery status changed.

Deliveries are also dropped entirely, with no log entry, if the webhook is deactivated or deleted while its jobs are still queued.

Timeout

  • Your endpoint has 10 seconds to accept the connection and 20 seconds in total to respond
  • Slower than that and the delivery is recorded as failed (and retried, since a timeout counts as a connection-level failure)
  • Manual Test Webhook sends allow 30 seconds
  • Return 2xx immediately and process data asynchronously if needed

Best Practices

Endpoint Design

  • Respond quickly: Return 200 immediately, process async
  • Idempotent handling: Same event may arrive multiple times
  • Secure endpoints: use HTTPS and verify signatures. Verify SSL is enabled by default and validates your endpoint’s TLS certificate on every delivery — leave it on. Turning it off (for example for a self-signed staging certificate) means deliveries, including the signature header and any configured authentication credentials, are sent without certificate validation
  • Log payloads: Store for debugging

Reliability

  • Handle retries: every delivery carries an X-Webhook-ID header containing a UUID. Automatic retries of the same delivery reuse the same value, so store it and ignore IDs you have already processed. The same value appears as the Event column in > View Logs
  • Monitor failures: Alert on repeated delivery failures
  • Keep endpoints healthy: 100% uptime ideal

Security

  • Use HTTPS only: http:// endpoints are accepted by validation but never expose one — the signature header and any configured authentication credentials would travel in cleartext
  • Verify signatures: Always check webhook authenticity
  • Restrict IP: Allowlist Spark CRM IPs if possible

Troubleshooting

Webhooks Not Arriving

Check:

  • Webhook is Active, and was not auto-disabled after a failure streak
  • Endpoint URL is correct
  • Events are selected
  • The event’s campaign is in scope — either Select All Campaigns is checked or the campaign is in the Campaigns list
  • A Delay is not still holding the delivery
  • Firewall allows incoming requests
  • Endpoint returns 2xx status
  • The delivery was not logged as Skipped — check > View Logs

Invalid Signature

Check:

  • Secret matches exactly
  • Using raw request body (not parsed JSON)
  • HMAC algorithm is SHA256
  • Comparing against the bare lowercase hex digest — the header carries no sha256= prefix

Duplicate Events

This is expected: implement idempotent handling keyed on the X-Webhook-ID header. Automatic retries reuse the same ID, so ID-based dedupe suppresses them. A manual Resend from the logs is issued with a new X-Webhook-ID and will look like a new event to your handler — dedupe on your own business key if that matters.


Navigation

Type to search…

↑↓ navigate↵ selectEsc close