Skip to main content

Listening to webhook events

Because of the asynchronous nature of our analysis process, we use webhooks to notify you whenever an event occurs. It's a convenient way to let you know that for example analysis is finished and your data is already waiting for you.

When you create a new integration, you are also asked to specify a publicly available URL that our systems can call whenever some event regarding your Cyanite library occurs. This can be for example a finished analysis.

The URL is assigned to the integration and will be used only to notify you about actions concerning this specific integration. This means that you can have multiple integrations and their webhooks will be separate from each other.

tip

You won't receive any webhooks for actions performed through the Cyanite App as by design it's not connected to any integration.

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 Cyanite.ai.

Cyanite.ai 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 Cyanite.ai */,
signature /* Signature sent via the Signature header */,
body /* raw request body */
) {
const hmac = crypto.createHmac("sha512", secret);
hmac.write(body);
hmac.end();
const compareSignature = hmac.read().toString("hex");
if (signature !== compareSignature) {
throw new Error("Invalid signature");
}
}
Test events

Note that the test event that you can trigger in the web-app does not contain the signature header.

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": {
"type":
"AudioAnalysisV6" |
"InDepthAnalysis",
"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 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 Cyanite.ai GraphQL API.