Echo Labs Docs
Search the docs
Find a guide, an endpoint or a section

Webhooks

Receive and verify job completion events.

Receiving events

Set webhook_url on job creation to receive job.completed and job.cancelled events. Each event’s data contains the job; see the payload reference.

Use a public HTTPS URL. Verify the event, queue it for processing, and return any 2xx within ten seconds. Redirects count as failures.

Verifying signatures

Verify Echo-Signature (t=<unix time>,v1=<hex HMAC>) using the submitting key’s signing secret from Billing → API.

Signatures use HMAC-SHA256 over <timestamp>.<raw body>. Use the original request bytes, compare in constant time, and reject timestamps more than five minutes away:

python
import hashlib, hmac, time

def verify(raw_body: bytes, signature: str, secret: str, tolerance: int = 300) -> bool:
    """signature is the Echo-Signature header: t=<unix time>,v1=<hex HMAC>."""
    parts = dict(item.split("=", 1) for item in signature.split(","))
    timestamp = parts["t"]
    expected = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body,
                        hashlib.sha256).hexdigest()
    fresh = abs(time.time() - int(timestamp)) < tolerance
    return fresh and hmac.compare_digest(expected, parts["v1"])

Retries and duplicates

Failed deliveries retry after 1 minute, 5 minutes, 15 minutes, 1 hour, 3 hours, 6 hours, and 12 hours: eight attempts total. After exhaustion, fetch the job with GET /jobs/{id}.

Deduplicate using the event id (also in Echo-Event-Id), which stays the same across attempts. Delivery can repeat and is not guaranteed after retries run out.