GoodFit Docs
  • 👋GoodFit
  • 🔬Product
    • Scoring Fields
    • Scoring Analysis
    • Page
    • Segments
      • Creating Segments
      • Dynamic Segments
      • Personas and Contacts
      • Contact Credits
      • Syncing Segments
    • Tags
    • Integrations
      • Salesforce
        • Common Salesforce Errors
      • HubSpot
      • CSV Export
      • Webhooks
  • 📓Guides
    • Prioritisation
      • How to build your first Score?
    • Segmentation
      • Segments Introduction
      • Personas Introduction
      • Programmatic Outreach
      • Distribution
      • Tiering
      • LinkedIn Ads
      • Maximising Contact Coverage
    • Distribution
      • Getting Started
      • Key Concepts / Prerequistes
Powered by GitBook
On this page
  • Overview
  • Accounts & Contacts
  • Payloads
  • Authentication
  1. Product
  2. Integrations

Webhooks

GoodFit supports syncing company and contact records to your systems via Webhook. This guide will outline the steps to take in order to fully set it up as well as best practices.

PreviousCSV ExportNextPrioritisation

Last updated 3 months ago

Overview

Accounts & Contacts

The Webhook connector supports both syncing into Accounts & Contacts if Contacts are enabled on your GoodFit account. GoodFit will send a webhook request for each new and modifed record in your dataset.

You can specify a webhook URL to send the events to, separately for companies and contacts. If you dont wish to recieve events for contacts, you can leave 'Webhook contacts URL' blank.

Payloads

Records are sent as JSON payloads to your webhook endpoints. The exact schema of these messages depends on the configuration of your GoodFit account. You can see an exact example of payloads for each record type in the webook settings panel.

Webhook Batch Size

You're able to specify whether you want records to be sent individually or in batches. The value can be set in Webhook Batch Size field. The maximum batch size supported is 200 records in a single call.

Authentication

GoodFit supports 2 optional methods for securing the webhook integration, depending on the nature of the platform you are sending data to:

  • HTTP headers. This allows you to add additional HTTP headers that are included in the HTTP webhook request we send to your endpoints. For example you can include an API key or similar in the Authoriziation header.

  • HMAC signature. This allows the webhook message to be cryptographically signed with a shared key, known only to the sender (GoodFit) and your application. The secret is never transferred in the message and cannot be intercepted.

HMAC Authentication

Before the source app sends an HTTP request via the webhook, it hashes the payload (request body) with HMAC using the shared secret key. The resulting hash is then bundled into the HTTP request as a header, and the entire request (header and body) is sent to the webhook endpoint.

Upon receiving the HTTP request, the destination app hashes the body with the secret key and then compares the result to the hash provided in the header. If the values match, the destination app knows the data is legit and processes it. If the values do not match, the destination app rejects the data.

If someone tries to spoof the payload without knowing the shared key, they won't be able to generate a valid hash.

In enabled, by pasting the shared key into the webhook settings panel, GoodFit will sign the JSON payload as a string, using the shared secret key and include the SHA256 hash into the x-goodfit-hmac-sha256 header.

The exact implementation of this is left to your system, however an example may be:

const signatureHeader = 'x-goodfit-hmac-sha256'
const signatureAlgorithm = 'sha256'
const encodeFormat = 'hex'
const hmacSecret = process.env.WEBHOOK_SECRET

app.post('/webhook', (req, res) => {
  // Create digest with payload + hmac secret
  const hashPayload = req.rawBody
  const hmac = crypto.createHmac(signatureAlgorithm, hmacSecret)
  const digest = Buffer.from(signatureAlgorithm + '=' + hmac.update(hashPayload).digest(encodeFormat), 'utf8')
  
  // Get hash sent by the provider
  const providerSig = Buffer.from(req.get(signatureHeader) || '', 'utf8')


  // Compare digest signature with signature sent by provider
  if (providerSig.length !== digest.length || !crypto.timingSafeEqual(digest, providerSig)) {
    res.status(401).send('Unauthorized')
  }else{
    // Webhook Authenticated 
    // process and respond...
    res.json({ message: "Success" })
  }
})
🔬
Webhook Settings Pannel