Table of contents
1. Introduction to FUGA webhooks
Summary
A webhook (also known as an ‘HTTP push API’) i s a way for an application to actively deliver, or ‘push’, notifications to another application about changes in data. A webhook delivers data (often referred to as ‘events’) to other applications as i t happens , meaning you get this data referencing any changes almost immediately. This is unlike typical (REST) APIs where you would need to actively make requests for data in a very high frequency in order to get data on changes in real-time. This makes webhooks much more efficient for both your organization as well as for FUGA.
Webhooks can be delivered to an HTTP(S) endpoint of your choosing, which can subsequently trigger another application for automation purposes.
FUGA offers webhook notifications for events in 3 categories:
- Product state changes:
- Notifying about changes to a product’s state from ‘Pending’ (or ‘ Draft’) to ‘Published’ (or ‘Approved’)
- Product metadata changes:
- Including the information about which exact entity/field was changed
- Product deliveries:
- Including information on the delivery attempt (successful, cancelled, rejected), the product that was delivered and to what DSP it was delivered
The FUGA Product ID, present in the Product state changes and Product metadata changes event payload, can be used to subsequently call the FUGA API and, for example, query further product details, make updates to a product and/or its assets, or send delivery instructions.
In the Product delivery event payloads, FUGA will send the FUGA Product ID for subsequent API requests, as well as the product’s UPC and the DSP name + ID to which a product insert, update or takedown was sent.
Why use webhooks?
In current applications, FUGA clients use webhooks to keep two systems in sync. For example, when you rely on your own catalog database in conjunction with your FUGA catalog, it is important to be able to sync any changes. Changes from your catalog database to FUGA are managed by sending an update through the UI, XML/DDEX or the REST API. Changes that are made in your FUGA catalog, can be synced back to your catalog database using these webhooks that notify you of the aforementioned changes.
Product state changes & Product metadata changes
Successful implementations we have seen of the Product state changes and Product metadata changes webhooks include:
- Internal alignment between teams. A digital operations team might make changes to the release date of a product of which the marketing team should be notified. Using FUGA Product metadata changes webhooks it is easy to trigger an internal messaging system that would subsequently request the product information through FUGA’s API, and inform the relevant teams of the updated release date.
- A product’s information that has been ‘published’ (or ‘approved’) , and therefore can be considered ‘final’ as the tracklist has now been locked, can be exported into a label copy system for registration purposes. The Product state changes events can be used to execute such a script.
- In a White Label setup, a distributor can get notifications of products that have been submitted by its label’s sub-organizations to the FUGA master organization for review. Any rejections can also trigger an application that would notify the labels of such rejections.
- Product information can be ingested into an ERP upon finalization, so to further be used for accounting to vendors. Once the Product state changes webhook notifies an application of a finished product (a product is ‘published’ or ‘approved’) , its label information and UPC can act as identifiers for this purpose.
Of course you can use these webhooks for many other implementations that require notification of a product status or metadata change. Please do note that in order to successfully retrieve a product’s information using the FUGA Product ID in the event payload, requires access to the FUGA API. Please reach out to your business development representative, or through sales@fuga.com for more information about obtaining such access.
Product deliveries
The Product deliveries webhooks can notify you of delivery events. There are three types of delivery events:
- Successful deliveries
- Cancelled deliveries
- Rejected deliveries
If a product is delivered to 50 DSPs, this will result in 50 webhook events, detailing the individual DSPs the product was delivered to.
This latest addition to the FUGA Webhooks functionality have seen several successful implementations, that include:
- Marketing team notifications, whereby a client-managed application notifies the marketing team of a successful delivery to, for example, Spotify, prompting promotion related activities.
- The automatic generation of a neighbouring rights registration form, the moment a product has an actual street date and is delivered to all relevant DSPs.
- The tracking of product delivery statuses for high volume delivery clients. Clients no longer have to search for delivery statuses in the FUGA UI, by querying release schedules through the FUGA API. Instead, FUGA actively informs clients of successful deliveries, which are being persisted in a client-managed dashboard, where the absence of a delivery confirmation to particular DSPs will trigger a warning.
As you can see, FUGA Webhooks can be used for a variety of applications, and we would be happy to discuss practical implementations and use-cases.
2. Message Header
The message header for all webhooks messages contains the following parameters:
- Source message id (fuga-webhooks-in-message-id)
- Outgoing message id (fuga-webhooks-out-message-id)
- Message signature (fuga-signature)
The source message id is unique per message.
The outgoing message id is unique per message and endpoint and can be used for detecting when duplicate messages are received by an endpoint. If you have multiple endpoints then it is possible that more than one endpoint may receive a message with the same source message id, however, the same outgoing message id should never be received by more than one endpoint.
The message signature can be used to verify that the message received matches what was sent by FUGA. Any other header parameters present should not be relied upon as they may be removed without notice at any point in time.
Verifying the message signature
As an added security measure, webhooks messages have an encrypted signature in the header that can be used to verify that the message received matches what was sent by FUGA. To verify the signature, follow these steps:
- Get the message signature (fuga-signature) from the header by retrieving the HTTP header value by name.
- Get the HTTP body content (JSON webhook event)
- Concatenate the salt value provided to you by FUGA to the JSON webhook event string. Ensure that the concatenated value does not contain any whitespace prior to hashing.
- Use the SHA3-256 hashing algorithm and the concatenated value from step #3 to generate the hash signature.
- Compare the generated hash signature from step #4 with the signature (fuga-signature) from step #1.
If the two values match then the message received matches the message sent. If the two values do not match, please contact FUGA Support at support@fuga.com.
The salt value is different per organization. The default value for the salt will be the organization id. This value can be changed at the customer’s request or at FUGA’s discretion (in which case, you will be notified of the new salt value).
Example code:
// Provided by FUGA Support
var salt = ...
// The value of "fuga-signature" HTTP header
var fugaSignature = ...
// The body of the HTTP request
var requestBody = ...
// Salting is done by appending the salt value to the body of the request
var saltedBody = requestBody.concat(salt);
// Take the SHA3-256 digest of the body combined with salt
var generatedSignature = new
org.apache.commons.codec.digest.DigestUtils("SHA3-256").digestAsHex(saltedBody);
if (generatedSignature.equals(fugaSignature)) {
// Valid signature, accept this message
} else {
// Not valid signature, discard this message, contact FUGA support
}
3. Payload structure
All three types of event payloads contain the following data:
- An event timestamp , containing date, time and timezone
- An event type , detailing the kind of event:
- For the Product state changes webhooks, this is "type" : "product_state"
- For the Product metadata changes webhooks, this is: "type" : "product_change"
- For the Product delivery, this is "type" : "delivery_completed", "delivery_cancelled", "delivery_rejected"
- The organization_id, detailing to which FUGA organization the product belongs
- The data, which contains more detailed information such as an identifier of the product, what triggered the event, to what DSP a product was delivered, etc.
Product state changes
The Product state change event payload is the simplest one to read and process. It merely informs your application of the fact that a product’s state has been changed.
{
"timestamp" : "2017-09-25T10:29:07.321+0000",
"type" : "product_state",
"organization_id" : 1274049923 ,
"data" : {
"product_id" : 1305137102
}
}
Using the "product_id" , one could perform a GET request to the /products/{id} endpoint (FUGA API plan access required), and retrieve the "upc", "name", "catalog_number", "state", or any other key/value from the returned object.
Product metadata changes
The Product metadata changes event payload is a more extensive message, depending on the amount of changes that have been made to a product. FUGA combines the trigger events per every 5 - 10 minutes, so as to not overload your endpoint with too many webhook events when a product is being changed.
In the example below, a product’s release date and Parental Advisory have been changed. One of the track’s main genres and ISRC code have been changed as well.
{
"timestamp" : "2020-11-11T15:56:22.349+00:00",
"type" : "product_change",
"organization_id" : 1247418730,
"data" : {
"product_id" : 3303398852 ,
"triggers" : [{
"type" : "update",
"entity_id" : 3303398886,
"entity_class" : "com.iip.fuga.model.ReleaseSchedule",
"user" : "admin-user-testing",
"field_names" : ["releaseDate"]
}, {
"type" : "update",
"entity_id" : 3294089843,
"entity_class" : "com.iip.fuga.model.Track",
"user" : "admin-user-testing",
"field_names" : ["mainGenre", "isrcCode"]
}, {
"type" : "update",
"entity_id" : 3303398852 ,
"entity_class" : "com.iip.fuga.model.AudioProduct",
"user" : "admin-user-testing",
"field_names" : ["parentalAdvisory"]
}]
}
}
In order to make sure these changes are synched back to your system, you could perform a GET request with the "product_id" to the /products/{id} endpoint, as well as a GET request with the (in this example) data["triggers"][1]["entity_id"] for the asset/track to the /products/{id}/assets/{assetid} or /assets/{id} endpoint.
Another example of a Product metadata changes event payload is the example below, which is send when a new product is created in your catalog.
{
"timestamp" : "2020-11-11T15:58:32.915+00:00",
"type" : "product_change",
"organization_id" : 1247418730,
"data" : {
"product_id" : 3303586380,
"triggers" : [{
"type" : "create",
"entity_id" : 3303586380,
"entity_class" : "com.iip.fuga.model.AudioProduct",
"user" : "admin-user-testing",
"field_names" : []
}]
}
}
As you can see, the "type" in the "triggers" states "create" , indicating that this product has just been created in your catalog. If you are using FUGA’s DDEX or FUGA XML ingestion interface, this webhook allows you to confirm successful ingestion by performing a GET request with the "product_id" to the /products/{id} endpoint, and verifying the the "upc", "name" and/or "catalog_number" from the returned object.
Please note the presence of the "user" key in the "triggers" , detailing which exact user in your FUGA organization has made the change.
Product deliveries
Product deliveries webhooks can notify your application of delivery events. The event payload is somewhat more versatile and does not necessarily require any subsequent API requests, as the message already includes the product’s "upc" as well as the DSP "name". The following example details a successful initial (new product) delivery, or "INSERT" , to the DSP called "Deezer". You can subsequently persist the "product"‘s "upc" in your application/system, or perform a GET request with the "product_id" to the /products/{id} endpoint to obtain additional product information.
{
"timestamp" : "2020-09-30T19:21:30.216+00:00",
"type" : "delivery_completed",
"organization_id" : 1247418730,
"data" : {
"action" : "INSERT",
"status" : "DELIVERED",
"product" : {
"id" : 3140007706,
"upc" : "8720205125385"
},
"dsp" : {
"id" : 2100357,
"name" : "Deezer"
}
}
}
Another example would be the below event, which details a successful "METADATA_ONLY" delivery of a product to the DSP called "Mixcloud".
{
"timestamp" : "2020-10-01T11:05:32.745+00:00",
"type" : "delivery_completed",
"organization_id" : 1247418730,
"data" : {
"action" : "METADATA_ONLY",
"status" : "DELIVERED",
"product" : {
"id" : 3140007706,
"upc" : "8720205125385"
},
"dsp" : {
"id" : 1684139985,
"name" : "Mixcloud"
}
}
}
The below example details a cancelled "METADATA_ONLY" delivery attempt of a product to "Mixcloud", including the reason for cancellation. This product receives a cancellation based on validation in delivery.
{ "timestamp" : "2020-10-01T11:05:32.745+00:00",
"type" : "delivery_cancelled",
"organization_id" : 1247418730,
"data" : {
"action" : "METADATA_ONLY",
"status" : "CANCELLED",
"reason" : "Neither the release nor any of its tracks have applicable usage rights for this DSP. Update the usage rights, or enable Available Separately on track level.",
"product" : {
"id" : 3140007706,
"upc" : "8720205125385"
},
"dsp" : {
"id" : 1684139985,
"name" : "Mixcloud"
}
}
}
The final example below details a rejected "INSERT" delivery attempt of a product to "Apple Music". This product has been rejected during QC for this QC DSP. For more information on QC and QC DSPs, please be referred to the Content Operations section of FUGA's Knowledge Base or, if anything remains unclear, reach out to content@fuga.com.
{
"timestamp" : "2020-10-01T11:05:32.745+00:00",
"type" : "delivery_rejected",
"organization_id" : 1247418730,
"data" : {
"action" : "INSERT",
"status" : "REJECTED",
"product" : {
"id" : 3140007706,
"upc" : "8720205125385"
},
"dsp" : {
"id" : 1330598,
"name" : "Apple Music"
}
}
}
Using delivery webhooks is preferred to querying FUGA’s API for a product’s delivery status per DSP. Please note that:
- A separate webhook event is sent for every delivery event. This means that for 1 product that has had a delivery attempt to 50 DSPs, FUGA will send you 50 webhook notifications.
- Delivery attempts with a Rejected status are only applicable to specific aggregation feeds FUGA does QC for. For more information on QC and QC DSPs, please be referred to the Content Operations section of FUGA's Knowledge Base or, if anything remains unclear, reach out to content@fuga.com.
4. Configuration
Information needed to enable webhooks
In order to successfully enable the webhooks feature, FUGA would require the following information:
- Endpoint URL(s) to receive the webhooks + an endpoint name > We recommend setting up separate URLs for your own testing, and live environments.
- A username, and password which FUGA can use as credentials to access your endpoint URL(s) for basic authentication.
- An email address that can be used to send alert messages to, in case the delivery of webhooks would fail (optional)
Feature activation
When your agreement with FUGA includes the use of webhooks, your FUGA onboarding manager or account manager will activate the service for you. If you would like to get access to the webhooks feature and do not have this included in your agreement, please reach out to your business development representative, or contact sales@fuga.com.
Setup
Once the webhooks feature has been activated, you can configure your endpoints in the Webhooks settings menu by logging in to your FUGA account on https://fugamusic.com, and selecting Settings > Webhook settings.
Here, you will be able to add a new endpoint by clicking Add Event Endpoint.
In the Add endpoint menu, please fill in the required fields:
- Endpoint URL
- Endpoint Name
- Endpoint username
- Endpoint password
- The event you would like to receive:
- Product state changes
- Product metadata changes
- Product deliveries
- Alert email - optional, for notification of message delivery failures
Once a new endpoint is configured, it will display as ‘Pending’. It can take up to 5 minutes for an endpoint to be activated, and displayed as ‘Active’. You can use the Refresh button to see i f the status has been updated.
5. FAQ
Q: In which format does FUGA send webhooks?
A: FUGA webhooks are sent in JSON
Q: Are the events sent as PUT or POST?
A: FUGA Webhook events are sent as POST
Q: Are there any message examples available?
A: Yes, please see the Product state changes , Product metadata changes and Product delivery messages above
Q: Should my application confirm receipt of a Webhook event?
A: Yes, please send a confirmation within 3 seconds, with status code 200. When FUGA doesn't receive a 200 code within 3 seconds, the delivery attempt is considered unsuccessful, and we will retry at a later time.
Q: Do I need access to the FUGA API to be able to use webhooks?
A: For the Product state changes and Product metadata changes webhooks to be useful, you would need to have access to the FUGA API in order to query product information by using the Product ID. For the Product delivery, depending on your use case, access to the FUGA API is not necessary per se, as the event payload includes the product’s UPC and DSP name.
Q: Are the username and password sent in plain text?
A: The username and password will be sent in the standard Basic Authorization header format, which contains the username and password in a Base64 encoded string e.g.
Authorization: Basic {{BASE_64_ENCODED_VALUE}}
Please note: Although the username and password are encoded, they are not encrypted . More information about Basic Authorization can be found at: https://www.loginradius.com/blog/engineering/everything-you-want-to-know-about-authorizati on-headers/#1-basic-auth
Q: Is the endpoint we have on file still accessible?
A: If you have recently changed the location or name of your endpoint, check that your endpoint configurations have been updated accordingly.
Q: Are the endpoint credentials we have on file still up-to-date?
A: If you have recently updated your passwords or reset your credentials, check that your endpoint configurations have been updated accordingly.
Q: Has your SSL certificate expired?
A: If your SSL certificate has expired, you will need to obtain a new one and upload it to the server where your endpoint is hosted.
6. Changelog
v.4 - 2024-09-12
- Added Product delivery events: Cancelled and Rejected
v.3 - 2022-07-13
- Added message header information
- Added instructions for verifying the message signature
v.2 - 2020-11-11
- Added description on Product deliveries / Successful deliveries webhooks
- Updated Setup documentation
- Included more use cases
v.1 - 2020-02-25
- Initial version of documentation, including Product state changes and Product metadata changes webhooks