What is a webhook?
A webhook is an HTTP callback: instead of your system constantly asking pixx.io "Has anything changed?" (polling), pixx.io reaches out to you on its own as soon as a defined event occurs (push).
| Polling | Webhook | |
|---|---|---|
| Principle | Regular request to the API | pixx.io actively sends an HTTP request |
| Timeliness | Depends on the polling interval | Near real time |
| Resources | Many unnecessary requests | Only on an actual change |
| Implementation | Requires a scheduled API client | Requires a publicly reachable endpoint |
To put it visually: polling is like checking your front door every five minutes to see whether the mail has arrived. A webhook is the doorbell — it lets you know the moment it's there.
How it works in pixx.io
Technically, anything can sit behind the target URL — pixx.io only takes care of delivering the event; what happens next is entirely up to you.
Setting up a webhook in pixx.io
- Open the Settings (gear icon, bottom left) → Administration → Webhooks.
- Click New webhook.
- Fill in the "Edit webhook" form (see the table below).
- In the Webhook Events section, select the events you want. Events are grouped into categories (e.g. file, collection, comment). Each category can be expanded; a filled minus symbol on the category checkbox indicates a partial selection.
- Save — the webhook is active immediately.
| Field | Description |
|---|---|
| Name | A descriptive name, e.g. "AI processing" |
| URL * | Publicly reachable HTTPS endpoint that pixx.io sends the request to |
| Secret | Secret key for signature verification (strongly recommended, see chapter 05) |
| Description | Internal documentation of what the webhook is for |
Event categories at a glance
Events are grouped by object type. In total, 781 events across 55 categories are available (as of the current export). The largest categories:
| Category | Events | Applies to |
|---|---|---|
| portal | 100 | Press portals / external portals |
| permissionGroup | 61 | Permission groups |
| space | 55 | Mediaspace configuration |
| file | 55 | Files — see detail table below |
| settings | 51 | Branding, SMTP, watermarks and more |
| generalSettings | 40 | General system settings |
| externalShare | 28 | External shares |
| uploadLink | 26 | Upload links |
| spaceNavigation | 24 | Navigation (header/footer) |
| user | 21 | User accounts |
The file category in detail
A clear naming scheme covers both the lifecycle of a file and every individual metadata change at a granular level.
| Event | Description |
|---|---|
| fileCreated | A new file was uploaded |
| fileDeleted | A file was deleted |
| fileDeletedDuplicate | A file was deleted as a duplicate |
| fileDownloaded | A file was downloaded |
fileModified* events (selection) — there's a dedicated, granular event for practically every field:
| Event | Description |
|---|---|
| fileModifiedFileName | File name changed |
| fileModifiedDescription | Description changed |
| fileModifiedCreator | Author/photographer changed |
| fileModifiedCreateDate | Creation date changed |
| fileModifiedUserID | Responsible user changed |
| fileModifiedRating | Rating (stars) changed |
| fileModifiedRotation | File rotated |
| fileModifiedSubject | Subject/topic changed |
| fileModifiedFileStateID | File status changed (e.g. in the approval workflow) |
| fileModifiedDirectoryIDPath | File moved to another folder |
| fileModifiedKeywordsAdded / …Deleted | Keywords added / removed |
| fileModifiedKeywordsRecognitionAdded / …Deleted | AI-recognized keywords added / removed |
| fileModifiedRecognizedText | Text recognition (OCR) updated |
| fileModifiedFaces | Face recognition updated |
| fileModifiedLocation | Location metadata changed |
| fileModifiedLanguageCodesAdded / …Removed | Language code added / removed |
| fileModifiedCollectionIDsAdded / …Removed | File added to / removed from a collection |
| fileModifiedExternalShareIDsAdded / …Removed | External share added / removed |
| fileModifiedLicenseFilesAdded / …Deleted | License file added / deleted |
| fileModifiedModelFilesAdded / …Deleted | Model release file added / deleted |
| fileModifiedPropertyFilesAdded / …Deleted | Property release file added / deleted |
| fileModifiedMarkedUserIDsAdded / …Removed | Marker set for / removed from a user |
| fileModifiedIsCheckedOut | Checkout status changed |
| fileModifiedIsDownloadLocked | Download lock changed |
| fileModifiedMainVersionFileID | Main version of a file changed |
| fileModifiedVariantStack | Assignment to a variant stack changed |
| fileModifiedUploadDate / …UploadLink | Upload date or the upload link used changed |
| fileModifiedMetadataField… | Change to a custom metadata field: date, text, truncated text, single/multi selection, language, location, orientation, focal point |
| fileReplaced | File replaced with a new version |
| fileReplacedPreviewFile / fileRestoredPreviewFile | Preview image replaced / restored |
Security: the secret & signature verification
Without signature verification, in principle anyone who knows the URL can send forged requests to your endpoint. With a secret, you make sure that an incoming request actually comes from pixx.io.
The common, recommended approach (as used by GitHub, Stripe & co.):
- pixx.io computes an HMAC-SHA256 signature over the request body using your secret.
- The signature is sent along as an additional header.
- Your endpoint recomputes the signature over the raw body it received and compares it in constant time (
hash_equals()in PHP,crypto.timingSafeEqual()in Node.js). - Only on a match is the payload processed as trustworthy.
X-Pixxio-Signature as a placeholder.Payload structure (example)
Every webhook call delivers a JSON payload with information about the event:
{
"event": "fileModifiedKeywordsAdded",
"timestamp": "2026-08-19T10:42:00Z",
"webhookId": "wh_12345",
"fileId": 987654,
"changes": {
"keywordsAdded": ["Summer", "Campaign2026"]
},
"triggeredBy": {
"userId": 42,
"userName": "c.trautbeck"
}
}
Best practices for the receiver
- Use HTTPS — plain-text HTTP endpoints are a security risk.
- Verify the signature first, before the payload is processed at all.
- Respond quickly: acknowledge receipt promptly with 2xx, offload processing asynchronously (queue, background job).
- Process idempotently: events can, in theory, be delivered more than once — unique IDs help with duplicate detection.
- Subscribe granularly: prefer targeted fileModified* events over the entire file category.
- Logging & monitoring: log incoming events and error rates.
- Plan for bulk operations: a bulk upload can trigger a large number of events in a short time — use a queue rather than synchronous processing.
Use cases
AI-assisted post-processing
fileCreated → an external AI service generates alt text/keywords → written back via the API into custom metadata or keywords.
Notifications
New file, new comment or new external share → message in Slack/Microsoft Teams.
PIM/shop/CMS sync
fileModifiedFileName / …MetadataField… → update the asset reference in Storyblok, Shopware and the like.
Compliance & rights
fileModifiedLicenseFilesAdded / …Deleted → check expiry dates, automatic reminder before a license ends.
Archiving & backup
fileDeleted → automatic copy to external storage before the trash is emptied.
Approval processes
externalShare* → kick off an approval workflow, e.g. four-eyes principle before publishing.
Combining with automation platforms
For many use cases you don't need a server of your own at all — automation platforms handle receiving, logic and the callback:
- Make (formerly Integromat): pixx.io offers a dedicated Make app with ready-made modules. Alternatively, you can also enter Make's generic "Custom Webhook" trigger directly as the webhook URL in pixx.io.
- Zapier / n8n: both offer a generic webhook trigger with a unique URL. You enter this URL verbatim into the URL field of the pixx.io webhook — after that you can build the logic you want with filters, routers and HTTP modules, including a callback to the pixx.io API.
The advantage: filtering by event type, data transformation and error handling can all be configured visually, without any code of your own.
Custom script receiver (PHP)
<?php
// webhook-receiver.php
$secret = getenv('PIXXIO_WEBHOOK_SECRET');
$payload = file_get_contents('php://input');
$signatureHeader = $_SERVER['HTTP_X_PIXXIO_SIGNATURE'] ?? '';
$expectedSignature = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expectedSignature, $signatureHeader)) {
http_response_code(401);
exit('Invalid signature');
}
// Acknowledge the payload immediately, offload processing asynchronously
http_response_code(200);
$data = json_decode($payload, true);
switch ($data['event'] ?? '') {
case 'fileCreated':
// e.g. queue a job: kick off AI processing
break;
case 'fileModifiedKeywordsAdded':
// e.g. update your own search index
break;
}
Closing the loop: writing back via the API
A webhook alone only delivers information — the real automation only emerges in combination with the pixx.io REST API. A typical flow, using automatic alt-text generation as an example:
- Trigger: fileCreated fires after an upload.
- Fetch context: the script loads further file information via the API if needed.
- Processing: an external AI service generates alt text or keywords.
- Write back: the script updates the file in pixx.io via the API — a custom metadata field, keywords or a comment.
For writing back, dedicated API endpoints are available depending on the object (files, collections, keywords, custom metadata, external shares and much more) — you'll find the complete, up-to-date reference including authentication in the API documentation.
Checklist before going live
- Endpoint is publicly reachable over HTTPS
- Secret is set, signature verification is implemented
- Only the events actually needed are subscribed
- Response is fast (2xx), processing runs asynchronously
- Duplicates/retries are handled idempotently
- Logging and monitoring are active
- Tested with a single test event before rollout
Further links
Appendix: complete event list
All 781 events across 55 categories — searchable and filterable.
| Category | Event | Action |
|---|