Listening to webhook events

When creating an integration you must specify a webhook url. The webhook url is used for notifying you once some asynchronous task, like a library track analysis, has finished or failed. Your webhook address must be facing the public internet.

Your webhook handler must return the status code 200, otherwise, the call will be treated as unsuccessful (and retried at a later point in time). Furthermore, there should be no redirects happening (30X status codes). All requests to your webhook will be aborted if the duration exceeds three seconds.

Delay the heavy lifting

We recommend not doing any heavy and time intensive tasks inside your webhook handler in order to not exceed the maximum invocation limit of three seconds. A better approach would be to delay the tasks until after the webhook response was sent, e.g. by writing the webhook payload to a worker queue, which is processed independently.

The webhook does (in contrast to the GraphQL API), for security reasons, only include the necessary data. In most cases, this means only the id of the processed entity.

Furthermore, the Signature header of the request includes a HMAC based on the Webhook secret set during the integration creation process. You should use this signature in order to verify that the request sent to your webhook originates from will send a POST method HTTP request with Content-Type: application/json to your specified webhook url.

Verifying the Request Signature#

Example implementation of verifying the request signature in Node.js.

import crypto from "crypto";
function verifySignature(
secret /* Secret specified on */,
signature /* Signature sent via the Signature header */,
body /* raw request body */
) {
const hmac = crypto.createHmac("sha512", secret);
const compareSignature ="hex");
if (signature !== compareSignature) {
throw new Error("Invalid signature");

Webhook Event Types#

New Webhook Format

When enqueuing a library track with the Mutation.libraryTrackCreate or Mutation.libraryTrackEnqueue fields on our API will automatically result in the new Webhook V2 payload.

Any usage of Mutation.inDepthAnalysisCreate or Mutation.inDepthAnalysisEnqueueAnalysis should be migrated and the webhook should be adjusted to accept the new webhook payload.

All library tracks that are enqueued using the Mutation.libraryTrackCreate or Mutation.libraryTrackEnqueue fields will result in the Webhook version 2 payload.

"version": "2",
"resource": {
"type": "LibraryTrack",
"id": "999"
"event": {
"AudioAnalysisV6" |
"FastMusicalAnalysis" |
"FullScaleMusicalAnalysis" |
"status": "finished" | "failed"

The resource property indicates the resource that is affected. Currently, in the example payload above that is the LibraryTrack with the ID 999.

The event property describes the status change of one of our four analysis types. The type property of the event can either be AudioAnalysisV6, FastMusicalAnalysis, FullScaleMusicalAnalysis or InDepthAnalysis. The naming is consistent with the corresponding GraphQL object/union type. The status property can be either finished or failed.

The analysis result/error can then be fetched via the GraphQL API.

Webhook Event Types (Old)#

All library tracks that are enqueued using the Mutation.inDepthAnalysisCreate or the Mutation.inDepthAnalysisEnqueueAnalysis fields will result in the following webhook events.

Event TypeExample Body
TEST{ "type": "TEST", "data": null }
IN_DEPTH_ANALYSIS_FAILED{ "type": "IN_DEPTH_ANALYSIS_FAILED", "data": {"inDepthAnalysisId": "86"} }
IN_DEPTH_ANALYSIS_FINISHED{ "type": "IN_DEPTH_ANALYSIS_FINISHED", "data": {"inDepthAnalysisId": "86"} }
SPOTIFY_TRACK_ANALYSIS_FINISHED{ "type": "SPOTIFY_TRACK_ANALYSIS_FINISHED", "data": {"spotifyTrackId": "5n8Aro6j1bEGIy7Tpo7FV7"} }
IN_DEPTH_ANALYSIS{ "type": "IN_DEPTH_ANALYSIS", "id": 9999, "event": {"type": "FAST_MUSICAL_ANALYSIS", status: "FINISHED"}}

You can find an example webhook integration here: Cyanite Integration Example on Github

InDepthAnalysis and SpotifyTrackAnalysis#

For a finished or failed analysis of a library or spotify track the API sends the IN_DEPTH_ANALYSIS_FAILED, IN_DEPTH_ANALYSIS_FINISHED, SPOTIFY_TRACK_ANALYSIS_FAILED and SPOTIFY_TRACK_ANALYSIS_FINISHED events.

FastMusicalAnalysis and FullScaleAnalysis#

The FastMusicalAnalysis and FullScaleAnalysis use the new webhook event payload schema. Instead of using the event type as an identifier for the resource and the status it utilizes a more flexible nested structure that is more resource oriented.

Both the FastMusicalAnalysis and the FullScaleAnalysis are enqueued for spotify tracks and library tracks (InDepthAnalysis records). The status of those analyses is reported with a webhook containing the following payload:

"type": "IN_DEPTH_ANALYSIS", // resource type
"id": "9999", // id of the resource
"event": {
"type": "FULL_SCALE_MUSICAL_ANALYSIS", // analysis type
"status": "FINISHED" // status of the analysis "FINISHED" or "FAILED"