Skip to content

Events

During normal operation, DAM emits certain kinds of events that are used internally to perform a range of operations but can also be used externally to build a tight integration. The way these events can be consumed is through web hooks.

In order to receive events, API users first need to subscribe to the event types they want to listen to, and then DAM will forward event information when the events are produced. When API users are no longer interested in receiving events, they can unsubscribe from them by providing the subscription ID that was given at subscription time.

Types of events

When the target endpoint in your system is called, the request will be sent with different methods and payloads depending on the event being notified. Below you can find a list with the events currently supported and more information about the method and the payload you can expect from each one:

  • AfterFileCreated: POST

    Payload:

    1
    2
    3
    4
    5
    {
        "FileIdsOfCreated": [
            "uuid"
        ]
    }
    
  • AfterFileDeleted: POST

    Payload:

    1
    2
    3
    4
    5
    {
        "FileIdsOfDeleted": [
            "uuid"
        ]
    }
    
  • AfterFileMasterDataUpdated: POST

    Payload:

    1
    2
    3
    4
    5
    {
        "FileIdsOfUpdated": [
            "uuid"
        ]
    }
    
  • AfterFileUpdated: POST

    Payload:

    1
    2
    3
    4
    5
    {
        "FileIdsOfUpdated": [
            "uuid"
        ]
    }
    

Subscribing

There is an endpoint designed to subscribe to events. There is another endpoint to unsubscribe from events. This endpoint requires the subscription ID that was given at subscription time. See the API reference for more information about the web hook endpoints.

Using the subscription endpoint, API users can create a subscription to an event type. The body of the request needs to contain a valid URI for the target. This target represents the endpoint in your system that will be called when the event takes place in DAM. It is not required that the target uses HTTPS.

Generated secret

When subscribing, DAM will generate a symmetric secret for you, which will be returned as a base64 string and not stored or logged. There is no way to retrieve or change this secret afterwards. The secret is used for two purposes:

  • To generate a JWT token that the HTTP call to your system will be authenticated with.
  • To add a signature to the message, so that your systen can check that the contents are correct.

Request signatures

As an additional layer of security, we guarantee that all webhook requests from DAM include a digital signature of their bodies. You can use this signature to ensure that a request is genuine, as well as to protect against replay attacks. We strongly recommend that you always verify the signature on webhook requests.

Verifying request signatures

When DAM sends a webhook request to your system, the request will always contain the following headers:

  • X-Bizzkit-Signature: The request signature as a series of key-value pairs algo1=<signature1>,...,algoN=<signatureN> specifying signature algorithms and base64 encoded signatures respectively.
  • X-Bizzkit-Signature-Timestamp: The UNIX timestamp specifying when the webhook request was initiated by DAM.

The signature header must be treated as a series of comma-separated key-value pairs, despite only a single key-value pair being present for now. This is to support the rotation of algorithms in the future, should the current algorithm become insufficient. Signature algorithms are deprecated in due time before removal. You cannot assume any ordering of algorithms in the signature header, but should instead search for and extract the signatures for those algorithms your customer solution supports.

DAM currently only uses an SHA-256 HMAC signature with base64 encoding to sign its requests. The secret is also treated as base64, whereas the request body and timestamp are treated as UTF-8 encoded strings. Your system needs to reproduce this signature to verify the authenticity of the request. To further provide protection against replay attacks, the signature is calculated from both the request body and timestamp as such:

ToBase64(HMACSHA256(FromBase64(secret), FromUTF8(Timestamp + Body)))

Note

The signature is generated from the raw request body, and not a prettified representation with indentation and newlines, as many frameworks will generate.

Example

Sample signature verification
private static bool VerifySignature(string secret, string body, string xBizzkitSignature, string xBizzkitTimestamp)
{
  var signature = CreateSignature(Convert.FromBase64String(secret),
    Encoding.UTF8.GetBytes(xBizzkitTimestamp + body));
  var expectedBizzkitSignature = $"sha256={signature}";

  // Consider using a constant time comparison to avoid timing attacks
  return expectedBizzkitSignature == xBizzkitSignature;
}

private static string CreateSignature(byte[] key, byte[] payload)
{
  var hash = HashHmacSha256(key, payload);
  return Convert.ToBase64String(hash);
}

private static byte[] HashHmacSha256(byte[] key, byte[] payload)
{
  using var hmac = new HMACSHA256(key);
  return hmac.ComputeHash(payload);
}

Reliability

DAM will keep trying to deliver the events to your system until it succeeds in doing so. The following conditions are considered an error when trying to deliver the event:

  • Your system responds with an HTTP response code other than 200 (OK).
  • DAM cannot reach your system.
  • Your system does not respond within 10 seconds.