Tinplate 42 Edge APIs

Security & Secrets Tier 2 Ready POST /v1/webhook-verify

Universal Webhook Signature Verification API — Stripe, GitHub, Slack & Shopify

Verify Stripe, GitHub, Slack, Shopify, and Svix HMAC webhook signatures and timestamps. Verify HMAC webhook signatures and replay timestamps for Stripe, GitHub, Slack, Shopify, Twilio, Svix/Standard Webhooks, and custom HMAC-SHA256.

Try It Live in Your Browser · No API Key Required

1. Interactive Sandbox & Sample JSON Output

200 OK · Ready

Editable Request JSON (POST /v1/webhook-verify)

Live 200 OK Response Envelope

{
  "ok": true,
  "data": {
    "valid": false,
    "provider": "github",
    "reason": "Signature mismatch",
    "matched_scheme": null,
    "timestamp_epoch": null,
    "timestamp_age_seconds": null,
    "timestamp_valid": null
  },
  "meta": {
    "request_id": "req_wh_01",
    "ms": 1
  }
}

2. Quickstart Code Examples

Full TypeScript & Python SDK →
curl -X POST "https://api.tinplate.dev/v1/webhook-verify" \
  -H "Content-Type: application/json" \
  -H "X-RapidAPI-Key: YOUR_RAPIDAPI_KEY" \
  -d '{"provider":"github","secret":"whsec_test_secret_key","raw_body":"{\"action\":\"opened\"}","headers":{"x-hub-signature-256":"sha256=e90f819b28a21b5c1a40b75c0b59c8788687c76724c5870769a28240a347047f"}}'
import { TinplateClient } from "@tinplate/sdk"; // npm install @tinplate/sdk

const tinplate = new TinplateClient({
  rapidApiKey: process.env.RAPIDAPI_KEY!,
});

const { data, meta } = await tinplate.call("/v1/webhook-verify", {
  "provider": "github",
  "secret": "whsec_test_secret_key",
  "raw_body": "{\"action\":\"opened\"}",
  "headers": {
    "x-hub-signature-256": "sha256=e90f819b28a21b5c1a40b75c0b59c8788687c76724c5870769a28240a347047f"
  }
});
console.log(`[${meta.ms} ms]`, data);
import requests

response = requests.post(
    "https://api.tinplate.dev/v1/webhook-verify",
    headers={
        "Content-Type": "application/json",
        "X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
    },
    json={
  "provider": "github",
  "secret": "whsec_test_secret_key",
  "raw_body": "{\"action\":\"opened\"}",
  "headers": {
    "x-hub-signature-256": "sha256=e90f819b28a21b5c1a40b75c0b59c8788687c76724c5870769a28240a347047f"
  }
}
)
print(response.json())
const response = await fetch("https://api.tinplate.dev/v1/webhook-verify", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
  },
  body: JSON.stringify({
  "provider": "github",
  "secret": "whsec_test_secret_key",
  "raw_body": "{\"action\":\"opened\"}",
  "headers": {
    "x-hub-signature-256": "sha256=e90f819b28a21b5c1a40b75c0b59c8788687c76724c5870769a28240a347047f"
  }
}),
});
const result = await response.json();
console.log(result);
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "tinplate_webhook_verify",
    "arguments": {
      "provider": "github",
      "secret": "whsec_test_secret_key",
      "raw_body": "{\"action\":\"opened\"}",
      "headers": {
        "x-hub-signature-256": "sha256=e90f819b28a21b5c1a40b75c0b59c8788687c76724c5870769a28240a347047f"
      }
    }
  }
}
OpenAPI 3.0.3 Schema Contract

Request Parameters & Response Schema Reference

Request Body Parameters (POST /v1/webhook-verify)

Parameter Type & Constraints Description
providerrequired "stripe" | "github" | "slack" | "shopify" | "svix" | "generic_hmac" Webhook provider signature scheme to verify.
raw_bodyrequired string
maxLen: 262144
Exact raw HTTP request body string (must not be re-serialized).
headersrequired object Incoming HTTP headers map (case-insensitive keys).
secretrequired string
minLen: 1, maxLen: 1024
Webhook signing secret (processed strictly in memory, never logged).
tolerance_secondsoptional integer
min: 0, max: 86400
Maximum allowed timestamp age in seconds for timestamped schemes (default 300; 0 disables).
now_epoch_secondsoptional integer
min: 0
Optional reference Unix timestamp in seconds (defaults to current time).
generic_optionsoptional object Options when provider is 'generic_hmac'.

Response data Object Fields (200 OK)

Field Type Description
valid boolean Field 'valid'
provider "stripe" | "github" | "slack" | "shopify" | "svix" | "generic_hmac" Webhook provider signature scheme to verify.
reason string | null Field 'reason'
matched_scheme string | null Field 'matched_scheme'
timestamp_epoch integer | null Field 'timestamp_epoch'
timestamp_age_seconds integer | null Field 'timestamp_age_seconds'
timestamp_valid boolean | null Field 'timestamp_valid'

3. What Webhook Signature Verifier API Detects & Validates

Honest Engineering Boundaries

4. Known Limitations & Test Verification

Release Version: v1.0.7 · Last Verified / Benchmarked: 14 November 2026 · Latency Note: Sub-millisecond figures measure in-Worker V8 compute time (typical client HTTPS network RTT to the nearest Cloudflare PoP is 15–65 ms) · See Full Portfolio Benchmarks & Corpora →

5. Marketplace Plans & Payload Quotas

Plan Monthly Price Included Requests Rate Limit Max Request Payload Best For
BASIC $0.00 / month 500 / month (hard limit) 10 req / min 64 KB Evaluation, local development & CI smoke tests
PRO $9.99 / month 15,000 / month 60 req / min 128 KB Solo developers & production apps
ULTRA $29.99 / month 100,000 / month 300 req / min 256 KB Growing SaaS & multi-agent pipelines
MEGA $79.99 / month 500,000 / month 1,000 req / min 256 KB High-volume enterprise workloads

6. Frequently Asked Questions

Why does webhook verification fail if I pass JSON.stringify(req.body)?

HMAC signatures are computed over the exact raw byte string sent by the provider. Always pass the unparsed raw request body.

Does it check for replay attacks on Stripe and Slack webhooks?

Yes, it validates that the signed timestamp is within the configurable tolerance_seconds window (default 300s).

Is my webhook secret logged?

Never. Secrets are used solely for the in-memory WebCrypto HMAC calculation and discarded immediately.

Zero Payload Logging

7. Data Handling, Privacy & Marketplace Proxy Disclosure

Webhook signing secrets and raw bodies are verified in volatile V8 memory and never logged or stored.

Worker Zero-Logging Guarantee: Cloudflare Workers Observability and invocation logging are disabled in configuration (observability.enabled = false, head_sampling_rate = 0, invocation_logs = false). Payloads are processed strictly in volatile V8 memory and never logged or stored by Tinplate.

Marketplace Proxies vs. Direct Bearer Key: Requests sent via RapidAPI or Zyla API Hub pass through those marketplaces' proxy infrastructure (subject to their respective privacy policies). Security-sensitive workloads requiring end-to-end zero-intermediary processing can connect directly to https://api.tinplate.dev using a Direct Bearer Key (Authorization: Bearer <API_KEY>). Read our full Privacy Notice and OpenAPI 3.0.3 JSON Schema.

Related Tinplate APIs

✉️ POST /v1/consent-tokens/issue Email & Domain

Stateless Consent & One-Click Unsubscribe Tokens API

Issue and verify stateless HMAC unsubscribe tokens and RFC 8058 List-Unsubscribe headers.

📜 POST /v1/agent-action-receipts/issue AI Safety & Agents

Agent Action Receipts API

Issue and verify tamper-evident HMAC-signed receipts for autonomous AI agent actions.

🔑 POST /v1/secret-scanner Tier 1

Log Redact & Secret Scanner API

Detect and mask leaked API keys, JWTs, and private keys in logs, diffs, and prompts.