Skip to content

Webhooks ​

DeepCrate can send HTTP webhooks when key events occur, letting you integrate with external services like Discord, Slack, Home Assistant, or custom automation pipelines.

Supported Events ​

EventFired When
download_completedAn album or track finishes downloading via slskd
queue_approvedA queue item is approved (moved to wishlist)
queue_rejectedA queue item is rejected
wishlist_removedA wishlist item is removed because it already exists in your library (during a library sync)

Configuration ​

Add a webhooks array to your config.yaml:

yaml
webhooks:
  - name: "discord"
    enabled: true
    url: "https://discord.com/api/webhooks/..."
    secret: "my-signing-secret"     # optional
    events:
      - download_completed
      - queue_approved
    timeout_ms: 10000               # default: 10000 (10s), max: 30000
    retry: 2                        # default: 0, max: 5

Configuration Reference ​

KeyTypeRequiredDefaultDescription
namestringYes-Display name for logging
enabledboolNotrueEnable/disable this webhook
urlstringYes-HTTP(S) endpoint to POST to
secretstringNo-HMAC-SHA256 signing secret
eventsstring[]Yes-Events to subscribe to (at least one)
timeout_msnumberNo10000Request timeout in milliseconds (max 30000)
retrynumberNo0Number of retry attempts on failure (max 5)

Payload Format ​

Every webhook POST sends a JSON body with this structure:

json
{
  "event": "download_completed",
  "timestamp": "2026-03-18T12:00:00.000Z",
  "data": {
    "artist": "Boards of Canada",
    "album": "Music Has the Right to Children",
    "download_path": "/music/Boards of Canada/Music Has the Right to Children",
    "mbid": "a1b2c3d4-e5f6-..."
  }
}

The data fields are optional and vary by event:

FieldEvents
artistAll
albumAll
download_pathdownload_completed
mbidAll (when available)

Signature Verification ​

When a secret is configured, DeepCrate includes an X-Webhook-Signature header containing an HMAC-SHA256 hex digest of the raw JSON body.

To verify the signature on your receiving end:

javascript
import crypto from 'crypto';

function verifySignature(body, secret, signature) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}

// In your request handler:
const raw = JSON.stringify(req.body);
const sig = req.headers['x-webhook-signature'];

if (!verifySignature(raw, 'my-signing-secret', sig)) {
  return res.status(401).send('Invalid signature');
}

Retry Behavior ​

When a webhook delivery fails (network error or non-2xx response), DeepCrate retries using exponential backoff:

AttemptDelay
1st retry2 seconds
2nd retry4 seconds
3rd retry8 seconds
4th retry16 seconds
5th retry32 seconds

Set retry: 0 to disable retries entirely.

Testing ​

From the UI ​

The webhooks settings page includes Test and Dry Run buttons for each configured webhook:

  • Test: sends a sample download_completed payload to the URL and reports the result
  • Dry Run: returns the payload that would be sent, without making an HTTP call

From the API ​

bash
# Live test
curl -X POST http://localhost:8080/api/v1/webhooks/test \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhook",
    "secret": "my-secret",
    "timeout_ms": 5000,
    "dry_run": false
  }'

# Dry run
curl -X POST http://localhost:8080/api/v1/webhooks/test \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhook",
    "dry_run": true
  }'

See the API Reference for full endpoint documentation.