Skip to content

Webhooks reference

Oxrion Desktop can notify your own system whenever you create a license — for example to store it in a customer portal and make it downloadable. You set up webhooks in Email & Hooks.

Oxrion Desktop sends an HTTP POST with a JSON body to your webhook URL:

POST /oxrion/webhook HTTP/1.1
Content-Type: application/json
User-Agent: Oxrion-Desktop
X-Oxrion-Event: license.created
X-Oxrion-Delivery: 5c1d0a3f9e2b4c7d8a6f1e0b2c3d4e5f
X-Oxrion-Timestamp: 1760000000
X-Oxrion-Signature: sha256=5a5a97fab1a6e646fff8630422bc96efaaeb16fbf411ef5903bbe6f5d29f80a9
HeaderMeaning
X-Oxrion-EventThe event. Currently always license.created.
X-Oxrion-DeliveryA random ID, different for every attempt. Useful in your logs.
X-Oxrion-TimestampWhen the request was sent, in Unix seconds.
X-Oxrion-Signaturesha256= and the HMAC-SHA256 of the timestamp and the body. Only sent when the webhook has a signing secret.
{
"event": "license.created",
"test": false,
"id": "a1b2c3d4e5f60718293a4b5c",
"host": "shop.example.com",
"expiry": "2027-10-01T12:00:00+03:00",
"duration": "1 year",
"issued_at": "2026-10-01T09:30:00Z",
"customer": "Acme Ltd.",
"email": "billing@acme.example",
"note": "Invoice 1042",
"group": "MyProject",
"fingerprint": "95867194943b3037ab0863e400e74686",
"filename": "4dd390c7e80bd49479aa883814db249106596746.lic",
"license": "# Host: shop.example.com\n# Expiry: 2027-10-01 12:00 (UTC+3)\n\n…"
}
FieldMeaning
eventlicense.created
testtrue for Send test webhook — sample data, not a real license.
idA stable ID for this license. It stays the same when the same license is sent again, so you can ignore duplicates.
hostThe license’s host.
expiryWhen the license expires, as an RFC 3339 time in the time zone it was issued in (for example 2027-10-01T12:00:00+03:00), or an empty string if it never expires. Any RFC 3339 parser reads it as an exact moment.
durationThe period used to set the expiry, for example 1 year. Left out when the date was picked directly.
issued_atWhen the license was created (UTC).
customer, email, noteFrom the license record. Left out when empty.
groupThe group’s name, if it has one.
fingerprintIdentifies the license key that signed the license (the group).
filenameThe .lic file name. Save the file under exactly this name.
licenseThe complete .lic file content. Left out if the webhook doesn’t include the license.

Answer with any 2xx status within 15 seconds. Anything else counts as a failure:

  • Other status codes, timeouts and connection errors fail the delivery.
  • Redirects are not followed. Use the final URL.
  • Failed deliveries are not retried automatically. The license is still created; its row in License History shows Hook not sent, and you can send it again from there.

With a signing secret, check every request before trusting it:

  1. Take the raw request body, exactly as received.
  2. Compute HMAC-SHA256(secret, timestamp + "." + body) as hex and put sha256= in front.
  3. Compare it with X-Oxrion-Signature using a constant-time comparison.
  4. Reject requests whose timestamp is more than a few minutes old, so a captured request can’t be replayed.

Use the secret exactly as it is shown in the Vault — the text itself.

<?php
$secret = getenv('OXRION_WEBHOOK_SECRET');
$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_OXRION_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_OXRION_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $body, $secret);
if (!hash_equals($expected, $signature) || abs(time() - (int) $timestamp) > 300) {
http_response_code(401);
exit;
}
$event = json_decode($body, true);
if ($event['test']) {
http_response_code(204); // test delivery: nothing to store
exit;
}
// Store each license once, even if it is sent again.
// save_license($event['id'], $event['host'], $event['filename'], $event['license'] ?? null);
http_response_code(204);
  • Duplicates happen. A license can be sent more than once (for example when you press Send webhook again). Use id to store it only once.
  • The license file is ready to use. If you offer it for download, serve license under the name in filename so it works without renaming.
  • Customer data is in the body. Keep your endpoint on HTTPS and don’t log bodies you don’t need.