Skip to main content

Webhooks

What are Webhooks​

Identity can notify your application in real-time when user profile data changes by sending HTTP POST requests to a URL you specify. Webhooks are currently available for first-party apps only — that is, apps created by Eurofurence staff.

Enabling Webhooks​

Navigate to the developer portal, open your app, and go to the Webhooks section. Set your webhook URL, select which fields you want to subscribe to, and save. A signing secret is generated automatically on first save and is displayed once — store it securely.

Events​

Only one event type is currently supported:

EventDescription
user.updatedTriggered when a user changes their email address or username

Subscribing to Fields​

You can subscribe to either or both of the following fields:

FieldDescription
emailThe user's email address
usernameThe user's username

Your webhook will only fire when a field you have subscribed to actually changes. If a user updates a field you are not subscribed to, no delivery is made.

Payload Schema​

Each delivery sends a JSON body with the following structure:

{
"event": "user.updated",
"id": "01HXJ...",
"occurred_at": "2026-04-06T12:34:56Z",
"subject": "42",
"changed": {
"email": {
"old": "old@example.com",
"new": "new@example.com"
}
}
}
FieldDescription
eventThe event name (user.updated)
idUnique delivery ID (ULID)
occurred_atISO 8601 timestamp of when the change occurred
subjectThe user's numeric ID
changedObject containing only the subscribed fields that actually changed, each with old and new values

Headers​

Every delivery includes the following HTTP headers:

HeaderExampleDescription
Content-Typeapplication/jsonAlways JSON
User-AgentEF-Identity-Webhooks/1.0Identifies the sender
X-EF-Eventuser.updatedThe event type
X-EF-Delivery01HXJ...Unique delivery ID
X-EF-Timestamp1712412896Unix timestamp of dispatch
X-EF-Signaturev1,abc123...HMAC signature for verification

Verifying Signatures​

Each delivery is signed with HMAC-SHA-256. The signature is computed over "<timestamp>.<raw_body>" using your app's signing secret, and prefixed with v1,.

Always verify signatures before processing a delivery. Use the raw request body — not a parsed or re-serialized version — for the HMAC computation.

PHP:

$timestamp = $request->header('X-EF-Timestamp');
$signature = $request->header('X-EF-Signature');
$body = $request->getContent();

$expected = 'v1,' . hash_hmac('sha256', $timestamp . '.' . $body, $secret);

if (! hash_equals($expected, $signature)) {
abort(401, 'Invalid signature');
}

if (abs(time() - (int) $timestamp) > 300) {
abort(401, 'Timestamp too old — possible replay');
}

Node.js:

const crypto = require('crypto');

function verifyWebhook(secret, timestamp, body, signature) {
const expected = 'v1,' + crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${body}`)
.digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
throw new Error('Invalid signature');
}

if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
throw new Error('Timestamp too old');
}
}
tip

The 300-second tolerance guards against replay attacks. Reject deliveries whose timestamp is more than 5 minutes old.

Retries​

If your endpoint returns a non-2xx status or times out, Identity retries delivery with exponential backoff:

AttemptDelay
110 seconds
21 minute
35 minutes
430 minutes
52 hours
66 hours

After 6 failed attempts, the delivery is marked as failed. Each attempt is recorded individually in your delivery history.

Delivery History​

All deliveries are stored for 7 days. In your app's Webhooks section you can view:

  • The full request payload
  • The HTTP response code returned by your endpoint
  • Any error details
  • Retry status

You can redeliver any past delivery directly from the UI.

Testing​

Click Send test delivery in the Webhooks section to dispatch a synthetic user.updated event using your own account as the subject. The test flows through the same signing and delivery pipeline and appears in your delivery history.

Troubleshooting​

  • 4xx from your endpoint: Check that your URL is publicly reachable and that the endpoint accepts POST requests.
  • Signature verification fails: Ensure you are using the raw request body (not parsed JSON) as input to the HMAC computation.
  • Deliveries stop arriving: Check that your app still has first-party status and that the webhook URL is saved.
  • Old deliveries have disappeared: Delivery history has a 7-day retention window.