Webhooks
Opt-in push notifications. Submit with a webhook_url and webhook_secret, and we’ll POST the result to your endpoint when it’s ready. No polling needed.
How it works
Section titled “How it works”- You submit code with
webhook_urlandwebhook_secret - Your code executes in the sandbox
- We POST the result to your URL with HMAC-SHA256 signature headers
- You verify the signature and process the result
Signature verification
Section titled “Signature verification”We follow the Standard Webhooks specification - the same pattern used by OpenAI, Stripe, and Svix.
Headers
Section titled “Headers”| Header | Value |
|---|---|
webhook-id | Unique message ID (the submission UUID) |
webhook-timestamp | Unix timestamp (seconds) |
webhook-signature | v1,<base64-encoded-hmac> |
Signed content
Section titled “Signed content”The HMAC-SHA256 is computed over:
{webhook-id}.{webhook-timestamp}.{body}Verification example (Python)
Section titled “Verification example (Python)”import hmac, hashlib, base64
def verify_webhook(body: bytes, headers: dict, secret: str) -> bool: msg_id = headers["webhook-id"] timestamp = headers["webhook-timestamp"] signature = headers["webhook-signature"]
signed_content = f"{msg_id}.{timestamp}.".encode() + body expected = hmac.new( secret.encode(), signed_content, hashlib.sha256 ).digest() expected_b64 = "v1," + base64.b64encode(expected).decode()
return hmac.compare_digest(signature, expected_b64)Important behaviour
Section titled “Important behaviour”- Webhooks are opt-in. No URL, no webhook.
- Secret is mandatory when URL is provided. We don’t deliver unsigned webhooks.
- HTTPS required in production. Set
RUSTBOX_ALLOW_LOCALHOST_WEBHOOKS=truefor local dev. - Non-blocking delivery. Webhook failures don’t affect the submission result.
- No retries. Single attempt with 5s timeout. Poll as fallback.
SSRF protection
Section titled “SSRF protection”Webhook URLs are validated:
- Must use HTTPS (unless localhost mode is enabled)
- Private IPs blocked:
10.x,172.16-31.x,192.168.x,169.254.x - Loopback blocked:
127.0.0.1,::1,localhost