URL-verification handshakes
Some providers verify that they own a callback URL with a one-time challenge/validation handshake instead of signing every request. Emithook answers these handshakes synchronously at the edge for you — you paste the URL, the provider's validation passes on the first try, and every real event afterwards is acked in <100 ms and fanned out to your destinations.
This guide covers the handshake-only providers — Zoom, Dropbox, eBay, and Microsoft Graph. They ship no signature preset (they verify as none); the handshake is the whole verification story. The setup scaffolding is the same for all four, so it's shown once below, then each provider's handshake is described in its own section.
1. Create the endpoint
Pick the matching preset when you create the endpoint — that's what tells the edge which handshake to auto-answer. Swap preset for zoom, dropbox, ebay, or msgraph:
curl -X POST https://api.emithook.com/v1/endpoints \
-H "Authorization: Bearer $EK_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://wh.emhk.in/acme/zoom-app/events",
"preset": "zoom",
"destinations": ["dst_acme_https", "dst_acme_sqs"]
}'// → 201 Created
{
"id": "ep_01JX9...",
"url": "https://<ingest-domain>/zoom-app/events",
"verification": "none",
"status": "active"
}TIP
The URL is live immediately on the shared ingest domain (<ingest-domain>, config-driven) — no DNS. Paste it into the provider's webhook/notification settings (see each section below).
Some handshakes need a shared token to compute their response. Where a section calls for one, set it the same way as any secret:
curl -X PUT https://api.emithook.com/v1/endpoints/ep_01JX9.../secret \
-H "Authorization: Bearer $EK_KEY" \
-d '{ "secret": "your-provider-token" }'2. Per-provider handshakes
Zoom — endpoint.url_validation (CRC)
Zoom POSTs { "event": "endpoint.url_validation", "payload": { "plainToken": "<token>" } } and expects a JSON body echoing plainToken plus an encryptedToken — an HMAC-SHA256 (hex) of the plainToken under your Secret Token. Set that token as the endpoint secret (above); the Zoom preset computes the CRC response and answers synchronously, so validation passes on the first click of Validate in the Zoom Marketplace app's Event Subscriptions.
Dropbox — challenge echo
Dropbox verifies with a GET carrying a ?challenge=<value> query parameter and expects that exact value echoed back as the response body. The Dropbox preset returns the challenge verbatim, so the webhook URI verifies immediately in the Dropbox App Console under Webhooks. No secret is needed for the handshake itself.
eBay — marketplace account deletion
eBay verifies its Marketplace Account Deletion / Closure notification URL with a GET carrying a challenge_code query parameter. eBay expects back a JSON body whose challengeResponse is the SHA-256 hash of challengeCode + verificationToken + endpoint. Set your chosen verification token as the endpoint secret (above); the eBay preset hashes the three values and answers synchronously, so the URL validates when you save it in the eBay Developer alerts/notifications settings.
Microsoft Graph — validationToken
Microsoft Graph validates a subscription's notificationUrl with a POST carrying a ?validationToken=<token> query parameter, and expects that token echoed back as text/plain within 10 seconds. The Microsoft Graph preset returns the validationToken verbatim so POST /subscriptions succeeds on the first attempt. The clientState you set on the subscription is delivered on later notifications for your own comparison.
3. Confirm delivery
Once the handshake passes, real events flow through exactly like any other endpoint — acked in <100 ms, then fanned out to each destination independently:
emithook logs tail --endpoint /zoom-app/events12:04:31 evt_01JX… meeting.started → dst_acme_https 200 142ms ✓
12:04:31 evt_01JX… meeting.started → dst_acme_sqs enqueued ✓If api.acme.in is down, Emithook retries with backoff and parks events behind the circuit breaker — when it recovers, they drain automatically. Nothing is lost.
4. Replay if needed
# replay everything that dead-lettered for this endpoint
emithook replay --dlq --endpoint /zoom-app/events