Introduction to Webhooks

Webhooks provide a way for our system to send real-time notifications to your server when specific events occur. Instead of your system constantly polling our API to check for new work, we proactively "push" information to you as soon as it's available.

What are Webhooks?

A webhook is an HTTP callback: a structured message sent from our server to a URL you specify. When a relevant event occurs (such as a new fulfilment job being created), our system will make a POST request to your endpoint with a JSON payload containing the event details.

Benefits

  • Efficiency: Reduces the need for frequent, resource-intensive polling of our API.
  • Real-time Updates: Your system is notified immediately when new tasks are available, allowing for faster processing.
  • Reduced Latency: Enables near-instantaneous reactions to fulfilment requirements.
  • Scalability: Minimizes the load on both our API and your infrastructure by only communicating when necessary.

How to Use Them

  1. Set up an endpoint: Create a publicly accessible URL on your server capable of receiving POST requests with a JSON body.
  2. Register your webhook: For the moment, webhooks are set up on request. Please contact support to register your webhook url.
  3. Process the payload: Your endpoint should parse the incoming JSON, identify the event type, and take appropriate action based on the data provided.
  4. Acknowledge receipt: Always return a 200 OK or 204 No Content response to our server to indicate that you have successfully received and processed the webhook. If your server fails to respond with a success code, we will attempt to retry the delivery.

Duplication

You will need to take care to ensure your endpoint is idempotent, meaning that processing the same webhook multiple times will not result in duplication within your system. We send webhook payloads with a unique Idempotency-Key header to help you identify and handle duplicate deliveries. The key is generated using the format ffm_wh_<webhook_id>.

HMAC Signature Verification

Webhooks can optionally include an HMAC signature to verify the authenticity and integrity of the payload. When enabled, each request will contain an X-Webhook-Signature header.

How it Works

  1. A shared secret is configured for your webhook endpoint.
  2. Before sending the request, we compute an HMAC SHA-256 signature of the raw JSON body using your secret.
  3. The resulting signature is included in the X-Webhook-Signature header.
  4. Your endpoint recomputes the signature from the received body and compares it to the header value. If they match, the payload is verified.

Verifying the Signature

To verify the signature on your end, compute the HMAC SHA-256 of the raw request body using your shared secret and compare it against the X-Webhook-Signature header.

PHP example:

$secret = 'your-shared-secret';
$body = file_get_contents('php://input');
$expectedSignature = hash_hmac('sha256', $body, $secret);
$providedSignature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

if (!hash_equals($expectedSignature, $providedSignature)) {
    http_response_code(401);
    exit;
}

Use hash_equals() instead of === when comparing signatures to prevent timing attacks.

Node.js example:

const crypto = require('crypto');

function verifySignature(req, secret) {
  const signature = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(req.body))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(req.headers['x-webhook-signature'])
  );
}

Payload Schema

The webhook payload consists of an event string and a data object containing the job details.

Field Type Description
event string The name of the event.
data object An object containing the event details.