Webhooks are the HTTP/HTTPS callbacks triggered by the events of the API requests, such as POST, PUT, and DELETE. The SSL verification is set when configuring webhooks.

The DocSpace administrator can create webhooks, subscribe to them, and configure webhooks so that events on the portal trigger actions on external services. This approach can be useful for synchronizing and tracking certain events.

The instructions on how to create and configure webhooks can be found here.

The API methods for working with webhooks can be found in this section.

The Accept and Content-Type webhook headers must be used. Custom headers are not available.

The API request is signed with the secret key which is generated when creating the webhook:

private string GetSecretHash(string secretKey, string body)
    var secretBytes = Encoding.UTF8.GetBytes(secretKey);
    using var hasher = new HMACSHA256(secretBytes);
    var data = Encoding.UTF8.GetBytes(body);
    var hash = hasher.ComputeHash(data);
    return Convert.ToHexString(hash);

The secret key is sent in the x-docspace-signature-256 header:

    "Accept": ["*/*"],
    "x-docspace-signature-256": [

The webhook request body contains the original request body.

The request timeout is 5 minutes:

var lifeTime = TimeSpan.FromMinutes(5);

Func<IServiceProvider, HttpRequestMessage, IAsyncPolicy<HttpResponseMessage>> policyHandler = (s, _) =>
    var settings = s.GetRequiredService<Settings>();

    return HttpPolicyExtensions
        .OrResult(msg => msg.StatusCode == HttpStatusCode.NotFound)
        .WaitAndRetryAsync(settings.RepeatCount ?? 5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));


.ConfigurePrimaryHttpMessageHandler(_ =>
    return new HttpClientHandler
        ServerCertificateCustomValidationCallback = (_, _, _, _) => true

If the response contains the 5xx, 408, or 404 statuses, the request can be repeated. There are 5 requests available with an interval of 2 to the power of the attempt number, measured in seconds.

There are no restrictions for the response body, except for the database limit on the text size. The response does not need to be signed. It must contain any successful status.

Each webhook is added to the queue and then sequentially retrieved from there. But webhooks are sent in parallel. Therefore, webhooks may not be in the same sequence as simulating events.

The pending webhooks in the queue are checked every 5 seconds, and up to 10 threads are started to send unprocessed webhooks.