{"openapi":"3.1.0","info":{"title":"Webhook Signature Debug API","summary":"Verify and debug common webhook signatures.","description":"Submit provider headers, the exact raw request body, and the webhook secret. The API returns provider-specific pass/fail diagnostics for GitHub, Slack, Stripe, Shopify, and generic HMAC-SHA256 signatures without storing payloads or secrets.","contact":{"name":"LinkRidge API Tools","url":"https://webhook-signature-debug-api.linkridge.net/","email":"api-support@makersridge.com"},"version":"0.1.0"},"servers":[{"url":"https://webhook-signature-debug-api.linkridge.net","description":"Production"},{"url":"https://dev.webhook-signature-debug-api.mfsoho.linkridge.net","description":"Development"}],"paths":{"/health":{"get":{"tags":["system"],"summary":"Health check","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Health Health Get"}}}}}}},"/admin/metrics":{"get":{"tags":["admin"],"summary":"Early validation metrics","description":"Returns in-memory aggregate counters when an admin key is configured.","operationId":"metrics_admin_metrics_get","parameters":[{"name":"x-admin-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Metrics Admin Metrics Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/verify":{"post":{"tags":["webhook-signatures"],"summary":"Verify and debug a webhook signature","description":"Submit provider headers, raw body, and signing secret. The API returns provider-specific diagnostics without storing or logging the payload or secret.","operationId":"verify_webhook_signature_v1_webhooks_verify_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookVerifyRequest"},"examples":{"github":{"summary":"Verify a GitHub webhook signature","value":{"provider":"github","payload":"Hello, World!","headers":{"X-Hub-Signature-256":"sha256=757107ea0eb2509fc211221cce984b8a37570b6d7586c22c46f4379c8b043e17"},"secret":"It's a Secret to Everybody"}},"slack":{"summary":"Verify a Slack request signature","value":{"provider":"slack","payload":"token=xyzz&team_id=T1DC2JH3J","headers":{"X-Slack-Request-Timestamp":"1531420618","X-Slack-Signature":"v0=replace-with-real-signature"},"secret":"signing-secret","tolerance_seconds":300}}}}}},"responses":{"200":{"description":"Verification completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookVerifyResponse"}}}},"401":{"description":"Missing or invalid API key."},"429":{"description":"Monthly quota exceeded."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"CheckResult":{"properties":{"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["name","status","detail"],"title":"CheckResult"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WebhookVerifyRequest":{"properties":{"provider":{"type":"string","title":"Provider","description":"Webhook provider or generic-hmac.","examples":["github","slack","stripe","shopify","generic-hmac"]},"payload":{"type":"string","title":"Payload","description":"Exact raw request body as sent by the provider. Whitespace and encoding matter."},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers","description":"Webhook request headers. Header names are matched case-insensitively."},"secret":{"type":"string","minLength":1,"title":"Secret","description":"Webhook signing secret. The API does not store or log this value."},"tolerance_seconds":{"type":"integer","maximum":86400.0,"minimum":0.0,"title":"Tolerance Seconds","description":"Allowed timestamp skew for providers that include replay-protection timestamps.","default":300},"now_epoch_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Now Epoch Seconds","description":"Optional override for deterministic testing; omit in normal use."},"generic":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Generic","description":"Generic HMAC options: header_name, encoding hex|base64, and optional prefix."}},"type":"object","required":["provider","payload","headers","secret"],"title":"WebhookVerifyRequest"},"WebhookVerifyResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"provider":{"type":"string","title":"Provider"},"reason":{"type":"string","title":"Reason"},"signature_scheme":{"type":"string","title":"Signature Scheme"},"replay_protected":{"type":"boolean","title":"Replay Protected"},"matched_signature_header":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Matched Signature Header"},"checks":{"items":{"$ref":"#/components/schemas/CheckResult"},"type":"array","title":"Checks"}},"type":"object","required":["valid","provider","reason","signature_scheme","replay_protected","matched_signature_header","checks"],"title":"WebhookVerifyResponse"}}}}