Email SupportCall Us Go to Close

Webhooks


Webhooks allow a subscription URL to be configured that we will POST event data to as it is added to the Event Log. Each subscription is configured to trigger when an event matches a set of object types and actions.

Here is an example of the Webhook data for an opportunity that was won. This would be sent to the URL you provide using a POST request:

{
  "event": {
    "date_created": "2019-01-15T12:48:23.395000",
    "meta": {
      "request_method": "PUT",
      "request_path": "/api/v1/opportunity/oppo_7H4sjNso7FyBFaeR3RXi5PMJbilfo0c6UPCxsJtEhCO/"
    },
    "id": "ev_2sYKRjcrA79yKxi3S4Crd7",
    "action": "updated",
    "date_updated": "2019-01-15T12:48:23.395000",
    "changed_fields": [
      "confidence",
      "date_updated",
      "status_id",
      "status_label",
      "status_type"
    ],
    "previous_data": {
      "status_type": "active",
      "confidence": 70,
      "date_updated": "2019-01-15T12:47:39.873000+00:00",
      "status_id": "stat_3FD9DnGUCJzccBKTh8LiiKoyVPpMJsOkJdcGoA5AYKH",
      "status_label": "Active"
    },
    "organization_id": "orga_XbVPx5fFbKlYTz9PW5Ih1XDhViV10YihIaEgMEb6fVW",
    "data": {
      "contact_name": "Mr. Jones",
      "user_name": "Joe Kemp",
      "value_period": "one_time",
      "updated_by_name": "Joe Kemp",
      "date_created": "2019-01-15T12:41:24.496000+00:00",
      "user_id": "user_lAm7YqrzZj00t1GLK5eTOaRgdkNChswxydbhUhGRbcM",
      "updated_by": "user_lAm7YqrzZj00t1GLK5eTOaRgdkNChswxydbhUhGRbcM",
      "value_currency": "USD",
      "organization_id": "orga_XbVPx5fFbKlYTz9PW5Ih1XDhViV10YihIaEgMEb6fVW",
      "status_label": "Won",
      "contact_id": "cont_BwlwYQkIP6AooiXP1CMvc6Zbb5gGh2gPu4dqIDlDrII",
      "status_type": "won",
      "created_by_name": "Joe Kemp",
      "id": "oppo_8H4sjNso7FyBFaeR3RXi5PMJbilfo0c6UPCxsJtEhCO",
      "lead_name": "KLine",
      "date_lost": null,
      "note": "",
      "date_updated": "2019-01-15T12:48:23.392000+00:00",
      "status_id": "stat_wMS9M6HC2O3CSEOzF5g2vEGt6RM5R3RfhIQixdnmjf2",
      "value": 100000,
      "created_by": "user_lAm7YqrzZj00t1GLK5eTOaRgdkNChswxydbhUhGRbcM",
      "value_formatted": "$1,000",
      "date_won": "2019-01-15",
      "lead_id": "lead_zwqYhEFwzPyfCErS8uQ77is2wFLvr9BgVi6cTfbFM68",
      "confidence": 100
    },
    "request_id": "req_4S2L8JTBAA1OUS74SVmfbN",
    "object_id": "oppo_7H4sjNso7FyBFaeR3RXi5PMJbilfo0c6UPCxsJtEhCO",
    "user_id": "user_lAm7YqrzZj00t1GLK5eTOaRgdkNChswxydbhUhGRbcM",
    "object_type": "opportunity",
    "lead_id": "lead_zwqYhEFwzPyfCErS8uQ77is2wFLvr9BgVi6cTfbFM68"
  },
  "subscription_id": "whsub_8AmjKCZYT3zI8eZoi4HhFC"
}

Webhook delivery

  • Failed deliveries are retried with a retry interval that exponentially backs off up to every 20 minutes. They will be retried up to 72 hours before being dropped.
  • Event ordering is not guaranteed due to event consolidation, delivery parallelism/retries and other factors.
  • A subscription will automatically be paused and its queue cleared when one of following happens:

    • Event queue reaches 100,000 backlogged events. Warning emails will be sent to admins when there is more than 80,000 backlogged events.
    • All event delivery fails for 3 days. Warning emails will be sent to admins before the subscription is paused.
  • Email notifications are sent to admins when a subscription is paused.
  • Paused subscriptions must be manually re-activated via the API before we will attempt to deliver events again.
  • We recommend processing Webhook events asynchronously meaning that you queue them locally before trying to process the payload. This will ensure we are always able to deliver the event and avoid the possibility of subscriptions getting paused because the max queue length is reached.
  • If your application needs to reprocess historical events, you can access them via the event log API for up to 30 days.
  • For updated or deleted actions the webhook will be called after the consolidation delay.
  • Event updates are written immediately to the event log during the consolidation period so if you query the event log directly you may see events that you haven't received a webhook notification for yet.

Data management

  • Users with the Admin role can manage subscriptions for all users in the organization. Non-admin users can only modify subscriptions created by them.
  • All data is delivered in the Webhook event even for non-admin users since they would have access to the same data via the application at delivery time.
  • We recommend using https to protect your data during delivery. SSL certificate validation is enabled by default but can be disabled via the verify_ssl field.

Webhook signatures

The subscription API's POST response includes a signature_key value that will be used to sign Webhooks for the subscription. The signature and signing timestamp is available in the following two headers of each POST request to your endpoint.

close-sig-hash: aa4fea8d4b74a0790e6b0dc2214db9d4d7651cb3e23f53caea499defd71ee431
close-sig-timestamp: 1544271440

The signature in the close-sig-hash header is the sha256 HMAC of the close-sig-timestamp and payload concatenated. The following Python 3 example code demonstrates how the signture can be verified.

key = '058bfb6a3d8cfdc4da7c3be5901b16ae11da982b46a25fb2cd7016e97a140a1c'
data = headers['close-sig-timestamp'] + payload
signature = hmac.new(bytearray.fromhex(key), data.encode('utf-8'), hashlib.sha256).hexdigest()
valid = hmac.compare_digest(headers['close-sig-hash'], signature)  # Will be True if sigs match

See the Subscription API documentation for the details of managing Webhook subscriptions.