Transfercompleted
Sent when a transfer completes successfully (any direction: company→user, user→company, user→user).
Verifying Signatures
Every webhook includes x-sideshift-signature and x-sideshift-timestamp headers. Your webhook secret is provided when you configure webhooks in Settings → Connect.
Compute the expected signature as HMAC-SHA256(secret, timestamp.rawPayload) and compare using a constant-time comparison.
const crypto = require("crypto");
function verify(payload, timestamp, signature, secret) {
// Reject old webhooks to prevent replay attacks
if (Math.floor(Date.now() / 1000) - parseInt(timestamp) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${payload}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Python:
import hmac, hashlib, time
def verify(payload, timestamp, signature, secret):
if int(time.time()) - int(timestamp) > 300:
return False
expected = hmac.new(secret.encode(), f"{timestamp}.{payload}".encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
Reliability
- Return a
200within 5 seconds to acknowledge receipt. Do heavy processing asynchronously. - Non-2xx responses are retried with exponential backoff (up to 5 retries over ~8 hours).
- Webhooks may be delivered more than once — deduplicate by event ID.
- Sandbox mode delivers webhooks identically to production.
WEBHOOK
Authorizations
Your SideShift Connect API key (sk_live_* or sk_test_*). Generate from Settings → Connect.
Body
application/json
Response
200
Webhook acknowledged