Gareth Wilson Gareth Wilson

Guide to Cyberimpact Webhooks: Features and Best Practices

Published


Cyberimpact webhooks let your email marketing automation trigger work in other systems. When a contact subscribes through a form, joins a group, clicks a link or reaches a date in a scenario, Cyberimpact can send that contact's details to your CRM, your database or a notification channel as the scenario runs.

This guide covers how the Send a webhook action works, what it sends, how to authenticate it with a header you add, how Cyberimpact retries, and the practices that make a Cyberimpact receiver dependable.

What are Cyberimpact webhooks?

Cyberimpact sends webhooks from one place: the Send a webhook action in a marketing automation scenario. You place the action after the scenario's trigger, or later in the path, and "the webhook will be sent as soon as a contact reaches this step". To use it, marketing automation must be included in your plan.

Each request is a JSON POST to the URL you enter. You choose which contact data to include, can add your own key/value pairs to the data, and can add key/value pairs to the request headers. Cyberimpact doesn't sign webhooks. Its documentation suggests the headers for "including API keys or authentication tokens to secure the requests sent", so a secret header is how you authenticate them.

Cyberimpact webhook features

FeatureDetails
Where it's configuredThe Send a webhook action in a marketing automation scenario
PlanMarketing automation must be included
When it firesWhen a contact reaches the action's step
Method and formatPOST with a JSON body
Event identifierevent, which is automation.webhook.send in the documented test request
DataContact fields, consent information and statistics you select, plus Additional information key/value pairs
AuthenticationA header you add. Header keys cannot contain spaces or special characters. No signature
RetriesOver the next 12 hours, then the request is marked Failed
TestA Test button that expects a 200
Source IPsNot published

Common events

The scenario's trigger decides when the webhook fires. Cyberimpact lists these as examples:

  • A subscriber registers through a subscription form.
  • A contact is added to a group.
  • An email is opened or a link is clicked.
  • A subscriber meets advanced search criteria (segmentation triggers or conditions).
  • A subscriber responds to a survey.
  • A contact's date is reached.
  • A contact is updated through an update profile form.
  • A contact's consent expires or is about to.

The trigger isn't named in the request. When you press Test, Cyberimpact sends test data like this:

{
  "id": "test_evt_GppedVq2CWTWxUUxrm26bic0C",
  "event": "automation.webhook.send",
  "timestamp": "2024-05-28T12:56:40Z",
  "idClient": 3,
  "data": {
    "type": "member",
    "id": 54321,
    "email": "john.doe@example.org",
    "firstname": "John",
    "lastname": "Doe"
  }
}

data holds the contact. In a live run it carries the fields you selected under Data to be transmitted, which can include contact details, consent information (type, source, dates, proof and IP address) and personal statistics such as mailing counts and open and click rates, plus any Additional information pairs. The documentation shows only the test request, so record a real delivery before you depend on the exact keys.

Because the same event value arrives for every scenario, add an Additional information pair that names the scenario, such as scenario = newsletter-signup, to route on.

Setting up Cyberimpact webhooks

  1. Generate a long random secret, for example with openssl rand -hex 32.
  2. Create a scenario, or open an existing one, and press + at the point in the path where the webhook should fire.
  3. Select the Send a webhook action and enter your full HTTPS endpoint URL.
  4. Press Test next to the URL. A green check means your endpoint accepted the request with a 200.
  5. Under Data to be transmitted, select the contact information to send.
  6. Add an Additional information pair naming the scenario, and a header pair for your secret: a key such as Authorization and a value such as Bearer <secret>.
  7. Click Add, then activate the scenario.

Use a simple header key without spaces or special characters. Cyberimpact doesn't accept them in header keys, and it doesn't say whether a hyphen counts, so Authorization is the safe choice.

The Test step comes before the header step in Cyberimpact's instructions, and the documentation doesn't say whether the test request carries your headers. If your receiver rejects the test with a 401, don't read that as a broken URL. Test the full configuration by activating the scenario with a contact that meets its criteria. Cyberimpact suggests adding a segmentation condition such as "Email is equal to" your test address so other contacts can't enter it.

In Hookdeck. Create a source with the Cyberimpact type, enter the header key in API Key Header and the exact value in API Key, including any Bearer prefix, and use the source URL in the action. Hookdeck answers with a 200, so the Test button shows a green check whether or not the test request carries your header. The source accepts POST.

For local development, hookdeck listen 3000 cyberimpact --path /webhooks/cyberimpact with the Hookdeck CLI gives you a public HTTPS URL, with no account required.

Securing Cyberimpact webhooks

Read your header, compare the whole value with the secret in constant time, and only then parse the body.

const crypto = require('crypto');
const express = require('express');

const app = express();

function safeEqual(received, expected) {
  const a = Buffer.from(received, 'utf8');
  const b = Buffer.from(expected, 'utf8');
  // timingSafeEqual throws on buffers of different lengths
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post('/webhooks/cyberimpact', express.raw({ type: '*/*' }), (req, res) => {
  const secret = process.env.CYBERIMPACT_WEBHOOK_SECRET; // e.g. "Bearer 5d2a..."
  if (!secret) return res.sendStatus(500); // fail closed when unconfigured

  const name = process.env.CYBERIMPACT_WEBHOOK_HEADER || 'Authorization';
  const received = req.get(name); // case-insensitive lookup
  if (typeof received !== 'string' || !safeEqual(received, secret)) {
    return res.sendStatus(401);
  }

  let payload;
  try {
    payload = JSON.parse(req.body.toString('utf8'));
  } catch {
    return res.sendStatus(400);
  }

  // Store payload.id, then queue payload.data for a worker.
  res.sendStatus(200);
});

The same check in Python:

import hmac
import os


def verify_cyberimpact_request(headers) -> bool:
    secret = os.environ.get("CYBERIMPACT_WEBHOOK_SECRET")
    if not secret:
        return False  # fail closed
    name = os.environ.get("CYBERIMPACT_WEBHOOK_HEADER", "Authorization")
    received = headers.get(name)  # case-insensitive in Starlette and Flask
    if not received:
        return False
    return hmac.compare_digest(received.encode("utf-8"), secret.encode("utf-8"))

A matching header proves the sender knows the secret, not that the contact data is unchanged, and a captured request can be replayed because there's no signature. The timestamp field isn't signed either, so treat it as information rather than proof of freshness. Use HTTPS and a long random secret, and change it in the action and your receiver together if it may have leaked.

Make Cyberimpact webhooks production-ready. Hookdeck Event Gateway checks your secret header on every Cyberimpact request, answers straight away so nothing sits in Pending, and keeps every contact event for replay.

Cyberimpact webhook limitations and pain points

Twelve hours, then the request is gone

The Problem: If your endpoint is down for longer than half a day, contacts that passed the step during the outage never reach your system.

Why It Happens: A request that isn't accepted immediately is marked Pending and retried "during the next 12 hours". After that, Cyberimpact stops and marks it Failed.

Workarounds:

  • Keep the endpoint available and respond with 200 quickly.
  • Check the webhook statistics for Pending and Failed requests after any incident.
  • Reconcile from Cyberimpact's data for contacts who passed the step while you were down.

How Hookdeck Can Help: Hookdeck accepts each request as it arrives, so Cyberimpact's 12-hour window stops being your recovery window. Hookdeck retries delivery to your service on your own schedule and lets you replay any event.

The scenario moves on regardless

The Problem: Later steps in a scenario run for a contact even when your system never received the webhook.

Why It Happens: "As soon as the first webhook request is sent, the contact can move on to the next step of your scenario, even if the request has not yet been accepted".

Workarounds:

  • Don't design scenarios that assume the webhook succeeded before the next step.
  • Make your receiver tolerant of contacts it hasn't seen before.

How Hookdeck Can Help: With Hookdeck in front, each request is accepted on arrival and queued, so delivery to your service no longer depends on your endpoint answering at the moment the contact passes the step.

One event name for every scenario

The Problem: Requests from different scenarios look the same.

Why It Happens: The documented event value is automation.webhook.send, and the trigger isn't included.

Workarounds:

  • Add an Additional information pair that names the scenario, and route on it.
  • Or give each scenario its own URL path.

How Hookdeck Can Help: Hookdeck filters can route on any body field or on the path, so one Cyberimpact source can feed different destinations per scenario.

A static header, not a signature

The Problem: Anyone who learns the header value can post fake contact events to your endpoint.

Why It Happens: The header is a fixed key/value pair. Nothing is computed over the body.

Workarounds:

  • Use a long random value over HTTPS only.
  • For sensitive changes, check the contact in Cyberimpact before acting.

How Hookdeck Can Help: Hookdeck's Cyberimpact source compares the header you name with the exact value you enter. Hookdeck answers Cyberimpact with a 200 either way, then records a request without the right header as failed verification, so it never reaches your destination.

Best practices

Deduplicate on id

Retries over 12 hours can deliver a request more than once. The test request carries an id; confirm live requests do too, and store it before processing. See our guide to webhook idempotency.

Send only what you need

Contact data includes consent proof and IP addresses. Select only the fields the receiving system uses, which keeps personal data out of logs that don't need it.

Keep header keys simple

Use Authorization or a single word. A key Cyberimpact rejects is easy to miss when you're setting up a scenario.

Acknowledge fast and process asynchronously

Verify, store, respond with 200, then do the work. See why to process webhooks asynchronously.

Conclusion

Cyberimpact sends a JSON POST from the Send a webhook action when a contact reaches that step, with a header you add as the only credential. Compare the header in constant time over HTTPS, name the scenario in the data, deduplicate on id, and respond quickly, because retries stop after 12 hours.

Hookdeck Event Gateway sits in front of your receiver, checks the header, accepts each request straight away and holds it until your service has processed it.

Get started with Hookdeck for free and handle Cyberimpact webhooks reliably in minutes.


Gareth Wilson

Gareth Wilson

Product Marketing

Multi-time founding marketer, Gareth is PMM at Hookdeck and author of the newsletter, Community Inc.