Content · Web Development · PHP

Implementing Outgoing Webhooks

Deliver signed event notifications to configured subscriber.

1 views Published Oct 17, 2026 Updated Oct 17, 2026 admin

Deliver signed event notifications to configured subscriber endpoints. The examples separate the essential operation from the conditions a production implementation must enforce.

What It Does


Deliver signed event notifications to configured subscriber endpoints.

Prerequisites


Use a dedicated development environment with test accounts and records. Separate authorization, validation and error handling from response formatting; never copy demonstration-only secrets into production.

Example 1: Core Behavior


The first example isolates the core operation so its result is easy to understand.

<?php
$body=json_encode(['event'=>'item.created','id'=>37],JSON_THROW_ON_ERROR);
$key=getenv('WEBHOOK_SIGNING_KEY')?:'demo-only';
$signature=hash_hmac('sha256',$body,$key);
echo 'Signature length: '.strlen($signature);

Example 2: Alternative or Failure Case


The second example demonstrates an alternative outcome, rule or failure condition.

<?php
$event=['id'=>'evt_44','type'=>'item.updated'];
$payload=json_encode($event,JSON_THROW_ON_ERROR);
echo json_encode(['eventId'=>$event['id'],'bytes'=>strlen($payload)]);

Practical Example: Applying the Rule


This practical workflow performs the relevant operation, with strict error checks. Configure the required transport or database driver before running it.

<?php
$secret = getenv('WEBHOOK_SIGNING_KEY');
if (!$secret) throw new RuntimeException('Missing webhook signing key');
$payload = json_encode(['id' => 'evt_42', 'type' => 'item.created'], JSON_THROW_ON_ERROR);
$signature = hash_hmac('sha256', $payload, $secret);
$ch = curl_init('https://hooks.example.test/receive');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-Signature: sha256=' . $signature, 'X-Event-ID: evt_42'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, CURLOPT_FOLLOWLOCATION => false]);
$result = curl_exec($ch);
if ($result === false) throw new RuntimeException('Webhook delivery transport failed');
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status < 200 || $status >= 300) throw new RuntimeException('Queue retry for webhook delivery');
echo 'Delivery accepted';

Important Behavior and Edge Cases


Queue and retry deliveries with backoff, validate destinations to prevent SSRF, and include stable event IDs.

Comparison with Related Functions or Patterns


ApproachWhen it differs
Implementing Outgoing WebhooksDeliver signed event notifications to configured subscriber endpoints.
Related API or patternA webhook receiver validates signatures and de-duplicates incoming events.

Common Beginner Mistakes


MistakeCorrect approach
Delivering to an arbitrary callback URL supplied by an untrusted userQueue and retry deliveries with backoff, validate destinations to prevent SSRF, and include stable event IDs.
Substituting a related API without checking its semanticsA webhook receiver validates signatures and de-duplicates incoming events.

Key Takeaways


  • Deliver signed event notifications to configured subscriber endpoints.
  • Queue and retry deliveries with backoff, validate destinations to prevent SSRF, and include stable event IDs.
  • A webhook receiver validates signatures and de-duplicates incoming events.

Select this API or pattern based on its documented behavior and the trust boundaries in your own application, and test all external integrations against their actual deployments.

Share this resourceSend this page to someone who may find it useful.