Webhooks & Events
Configure real-time notifications for asset uploads, download status changes, and community interactions on your SoundScape projects.
Event Types
SoundScape fires webhook events whenever a configured activity occurs in your studio workspace. Each event delivers a structured JSON payload to the endpoint URL you register in your project settings.
New Asset Uploaded
Triggered when a sound file is successfully ingested into your library. Includes file metadata, audio fingerprint hash, and upload timestamp. Fires once per asset — retries are not sent for duplicate uploads of the same file.
Download Status Update
Sent when a licensed download transitions between states: queued → processing → ready or failed. Useful for tracking batch-export pipelines or notifying your CI/CD when assets are ready for consumption.
Community Like
Fired when another SoundScape user likes a sound in your public collection. The payload includes the liker's public profile slug and the liked asset ID. Rate-limited to 60 events per minute per webhook endpoint.
Community Comment
Triggered when a user posts a comment on one of your sounds. Contains the comment body, author slug, and a moderation flag. Comments flagged for review include "moderation": true in the payload.
License Purchase
Sent after a third-party buyer completes a license transaction for your asset. Includes the license tier (Standard, Extended, or Source), buyer organization slug, and transaction reference. Always delivered within 5 seconds of payment confirmation.
Project Export Complete
Fires when a multi-track project export finishes rendering. The payload lists all rendered stems, their formats (WAV, OGG, MP3), and a short-lived download URL valid for 24 hours. Ideal for automating asset handoff to your game engine.
Payload Examples
Every webhook request uses POST with Content-Type: application/json. The body follows a consistent envelope structure: event, timestamp, webhook_id, and data.
asset.uploaded
{
"event": "asset.uploaded",
"timestamp": "2025-06-12T14:32:07Z",
"webhook_id": "whk_8f3n2m9x1v",
"data": {
"asset_id": "snd_7d4k2p9q",
"filename": "metal_impact_heavy_01.wav",
"duration_sec": 1.84,
"sample_rate_hz": 48000,
"bit_depth": 24,
"channels": 2,
"fingerprint_hash": "sha256:a3f8c91e7b2d4f06",
"upload_by": "user_marcus_renner",
"project_id": "prj_soundscape_indie_rpg"
}
}
asset.status_changed
{
"event": "asset.status_changed",
"timestamp": "2025-06-12T14:35:41Z",
"webhook_id": "whk_8f3n2m9x1v",
"data": {
"asset_id": "snd_7d4k2p9q",
"previous_status": "processing",
"current_status": "ready",
"format": "wav",
"file_size_bytes": 1728000,
"download_url": "https://cdn.soundscape.dev/dl/snd_7d4k2p9q?token=eyJhbG...",
"expires_at": "2025-06-13T14:35:41Z"
}
}
community.comment_posted
{
"event": "community.comment_posted",
"timestamp": "2025-06-12T18:11:22Z",
"webhook_id": "whk_8f3n2m9x1v",
"data": {
"comment_id": "cmt_2x7w4n1k",
"asset_id": "snd_9r1m5t8j",
"author_slug": "elara_audio_design",
"body": "Perfect for the boss fight cue — the low-end rumble sits really well under dialogue.",
"moderation": false,
"project_id": "prj_soundscape_indie_rpg"
}
}
license.purchase_completed
{
"event": "license.purchase_completed",
"timestamp": "2025-06-13T09:47:55Z",
"webhook_id": "whk_8f3n2m9x1v",
"data": {
"transaction_ref": "txn_4p8h2v6b",
"asset_id": "snd_3k9c7w1n",
"license_tier": "Extended",
"buyer_slug": "studio_nocturn_games",
"buyer_org_id": "org_nocturn_2024",
"amount_cents": 4900,
"currency": "USD",
"project_id": "prj_soundscape_indie_rpg"
}
}
Verification
Every webhook request includes an X-SoundScape-Signature header so you can verify the payload originated from SoundScape and has not been tampered with.
The signature is an HMAC-SHA256 digest of the raw request body, computed with your webhook secret. The secret is visible in your project settings under Integrations → Webhooks → Show Secret. Treat it like an API key — never commit it to public repositories.
Header format:
X-SoundScape-Signature: t=1718210527,v1=a8f3c2d1e9b7406f5a3c8d2e1b9f7a4c6d8e2f0a1b3c5d7e9f1a3b5c7d9e1f3
The header contains a timestamp (t) and the hex-encoded signature (v1). Reject requests where the timestamp is more than 5 minutes older than your server clock to prevent replay attacks.
Verification steps:
1. Read the raw request body as a string.
2. Extract the timestamp from X-SoundScape-Signature.
3. Reject if |now - timestamp| > 300 seconds.
4. Compute HMAC-SHA256(raw_body, webhook_secret).
5. Compare your computed digest with the v1 value using constant-time comparison.
6. Return HTTP 200 within 3 seconds to acknowledge receipt.
Python example:
import hashlib
import hmac
import time
def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
# Parse timestamp and signature
parts = dict(item.split("=") for item in signature_header.split(","))
ts = int(parts["t"])
sig = parts["v1"]
# Timestamp check: reject if older than 5 minutes
if abs(time.time() - ts) > 300:
return False
# Compute HMAC-SHA256
computed = hmac.new(
secret.encode("utf-8"),
raw_body,
hashlib.sha256
).hexdigest()
# Constant-time comparison
return hmac.compare_digest(computed, sig)
If verification fails, respond with HTTP 401. SoundScape will retry delivery up to 3 times with exponential backoff (1 minute, 5 minutes, 15 minutes). After all retries are exhausted, the webhook is disabled and you receive an email alert at the project lead's address.
For local development, use ngrok or localtunnel to expose a temporary HTTPS endpoint. SoundScape only accepts https:// webhook URLs — http:// endpoints are rejected at registration time.