Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vobiz.ai/llms.txt

Use this file to discover all available pages before exploring further.

Every callback Vobiz sends to your endpoint includes HMAC signatures in the request headers. Validating these signatures proves the request came from Vobiz and was not tampered with in transit.
Your auth token is the signing key. Vobiz uses your account’s auth token (visible in the Vobiz Console) to sign each callback. Keep it secret — anyone who has it can forge valid signatures.

Signature headers

Vobiz sends the following headers with every callback:
HeaderDescription
X-Vobiz-SignatureV1 — HMAC-SHA1, base64-encoded (legacy, included for backwards compatibility)
X-Vobiz-Signature-V2V2 — HMAC-SHA256, base64-encoded
X-Vobiz-Signature-V2-NonceRandom 20-digit nonce used to produce the V2 signature
X-Vobiz-Signature-MA-V2V2 signed with the parent (main) account auth token — present for sub-account callbacks
X-Vobiz-Signature-V3V3 — HMAC-SHA256, base64-encoded
X-Vobiz-Signature-V3-NonceRandom 20-digit nonce used to produce the V3 signature
X-Vobiz-Signature-MA-V3V3 signed with the parent (main) account auth token — present for sub-account callbacks
Recommended: Validate X-Vobiz-Signature-V2 or X-Vobiz-Signature-V3. Both use HMAC-SHA256 and are the actively maintained signature schemes. V1 (HMAC-SHA1) is provided only for legacy compatibility.

How signatures are computed

V2 signature

  1. Take your callback URL and strip all query parameters to get the base URL (e.g. https://your-domain.com/webhook).
  2. Concatenate: baseURL + nonce (where nonce is the value of X-Vobiz-Signature-V2-Nonce).
  3. Compute HMAC-SHA256 of that string using your auth token as the key.
  4. Base64-encode the result.
X-Vobiz-Signature-V2 = base64( HMAC-SHA256( key=authToken, msg=baseURL + nonce ) )

V3 signature

Identical to V2 except the nonce is joined to the base URL with a . separator:
X-Vobiz-Signature-V3 = base64( HMAC-SHA256( key=authToken, msg=baseURL + "." + nonce ) )

Multi-account (MA) variants

For callbacks on sub-accounts, Vobiz additionally signs with the parent account’s auth token and sends the result in X-Vobiz-Signature-MA-V2 / X-Vobiz-Signature-MA-V3. The algorithm is identical — only the key differs. This lets you verify callbacks using either the sub-account or the main account auth token.

Validation examples

import hmac
import hashlib
import base64
from urllib.parse import urlparse, urlunparse

def get_base_url(url: str) -> str:
    parsed = urlparse(url)
    return urlunparse((parsed.scheme, parsed.netloc, parsed.path, "", "", ""))

def validate_v2(callback_url: str, auth_token: str, request_headers: dict) -> bool:
    signature = request_headers.get("X-Vobiz-Signature-V2", "")
    nonce     = request_headers.get("X-Vobiz-Signature-V2-Nonce", "")

    base_url = get_base_url(callback_url)
    msg      = (base_url + nonce).encode()
    key      = auth_token.encode()

    expected = base64.b64encode(hmac.new(key, msg, hashlib.sha256).digest()).decode()
    return hmac.compare_digest(signature, expected)

def validate_v3(callback_url: str, auth_token: str, request_headers: dict) -> bool:
    signature = request_headers.get("X-Vobiz-Signature-V3", "")
    nonce     = request_headers.get("X-Vobiz-Signature-V3-Nonce", "")

    base_url = get_base_url(callback_url)
    msg      = (base_url + "." + nonce).encode()
    key      = auth_token.encode()

    expected = base64.b64encode(hmac.new(key, msg, hashlib.sha256).digest()).decode()
    return hmac.compare_digest(signature, expected)

# Usage (e.g. Flask)
from flask import request, abort

AUTH_TOKEN = "your_auth_token_here"

@app.route("/webhook", methods=["POST"])
def webhook():
    url = request.url
    if not validate_v2(url, AUTH_TOKEN, request.headers):
        abort(403, "Invalid signature")
    # ... handle event

Sub-account callbacks

If your Vobiz account uses sub-accounts, callback requests include both the sub-account signature and the parent (main) account signature. You can validate using either auth token.
HeaderSigned with
X-Vobiz-Signature-V2Sub-account auth token
X-Vobiz-Signature-MA-V2Parent account auth token
X-Vobiz-Signature-V3Sub-account auth token
X-Vobiz-Signature-MA-V3Parent account auth token
The algorithm for MA variants is identical — only the key differs. Use the same validation code, substituting your parent account auth token as the key.

Best practices

Always use constant-time comparison when comparing signatures. Standard string equality (==) is vulnerable to timing attacks. Use hmac.compare_digest (Python), crypto.timingSafeEqual (Node.js), or hmac.Equal (Go).
  • Validate on every request. Reject any callback missing the signature headers with HTTP 403.
  • Use HTTPS. Plaintext HTTP exposes the nonce and signature, which an attacker could replay before you process the request.
  • Check the nonce is fresh (optional but recommended). Nonces are randomly generated per request, not time-based, so replay protection requires you to store and check seen nonces for a short window (e.g. 5 minutes).
  • Prefer V2 or V3 over V1. V1 uses HMAC-SHA1, which is weaker than SHA-256.
  • Rotate your auth token if compromised. Rotating your auth token immediately invalidates all signatures computed with the old key.

Callbacks overview

Understand how Vobiz delivers callbacks and what parameters to expect.

Callback configurations

Configure callback URLs, methods, and retry behaviour for your applications.