Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.
Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate the signature before trusting the payload.
Webhook endpoints are publicly reachable URLs. Anyone who knows the URL can send a POST to it. Always validate the signature before processing. Don’t take an unsigned or invalid-signature request seriously.
Use a constant-time comparison for the signature check (e.g. crypto.timingSafeEqual in Node) to avoid timing attacks.
Stringify the body identically to how it was received - middleware that reformats JSON will break the signature. Either store the raw body before parsing or use a body parser that preserves the exact byte sequence.
Reject stale events by checking X-Timestamp is within (e.g.) 5 minutes of now. Combined with signature validation, this protects against replay attacks.
Don’t log the secret. It should only ever appear in your secret manager and in memory inside the validation routine.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Political Comms","description":"Documentation for the Political Comms P2P texting platform - help center, onboarding, compliance, and API reference.","colors":{"primary":"#1E3A8A","light":"#3B82F6","dark":"#1E3A8A"},"logo":{"light":"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/logo/main.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=694b5108d71882d5774bc62c478bc370","dark":"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/logo/main.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=694b5108d71882d5774bc62c478bc370","href":"/"},"favicon":"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/favicon.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=63a87e09739757db232880f7adfda947","navbar":{"links":[{"href":"mailto:support@politicalcomms.com","label":"Support"}],"primary":{"type":"button","label":"Sign in","href":"https://app.politicalcomms.com"}},"footer":{"socials":{"website":"https://politicalcomms.com"},"links":[{"header":"Product","items":[{"label":"Dashboard","href":"https://app.politicalcomms.com"},{"label":"Pricing","href":"https://politicalcomms.com/pricing"},{"label":"Status","href":"https://status.politicalcomms.com"}]},{"header":"Resources","items":[{"label":"Help Center","href":"/help/getting-started"},{"label":"Onboarding","href":"/onboarding/overview"},{"label":"Compliance","href":"/compliance/overview"},{"label":"API Reference","href":"/api-reference/introduction"}]},{"header":"Legal","items":[{"label":"Terms of Use","href":"/legal/terms"},{"label":"Privacy Policy","href":"/legal/privacy"}]}]},"seo":{"metatags":{"og:site_name":"Political Comms Docs","og:type":"website","og:locale":"en_US","og:image":"https://politicalcomms.com/opengraph-image","og:image:width":"1200","og:image:height":"630","og:image:alt":"Political Comms. The direct-to-carrier political texting platform.","twitter:card":"summary_large_image","twitter:image":"https://politicalcomms.com/opengraph-image","twitter:image:alt":"Political Comms. The direct-to-carrier political texting platform.","robots":"index, follow, max-image-preview:large, max-snippet:-1","author":"Political Comms","publisher":"Political Comms","application-name":"Political Comms Docs","apple-mobile-web-app-title":"Political Comms Docs","theme-color":"#254692","msapplication-TileColor":"#254692","category":"Political Technology, Communications Infrastructure","keywords":"political texting, political SMS, P2P messaging, 10DLC registration, Campaign Verify, TCPA compliance, FCC political rules, MCP server, AI agent integration"},"indexing":"all"},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"Dashboard","icon":"arrow-up-right-from-square","href":"https://app.politicalcomms.com"},{"anchor":"Status","icon":"signal","href":"https://status.politicalcomms.com"},{"anchor":"Changelog","icon":"clock-rotate-left","href":"/changelog"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"politicalcomms","hasAudioNarration":false,"actualSubdomain":"politicalcomms","customDomains":["docs.politicalcomms.com"],"gitSource":{"type":"github","owner":"political-comms","repo":"political-comms-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6af3f37017d318bea1ca068f","clientVersion":"0.0.4102","searchFilterCounts":[{"language":"default","tag":"API Reference","count":68},{"language":"default","tag":"Endpoints","count":55},{"language":"default","tag":"Documentation","count":40},{"language":"default","tag":"Email","count":22},{"language":"default","tag":"Text","count":19},{"language":"default","tag":"Assets","count":14},{"language":"default","tag":"Help Center","count":13},{"language":"default","tag":"Projects","count":13},{"language":"default","tag":"Get Started","count":8},{"language":"default","tag":"Compliance","count":8}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/webhooks/signature-validation","slug":"/api-reference/webhooks/signature-validation","pageMetadata":{"title":"Signature Validation","description":"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.","icon":"shield-check","href":"/api-reference/webhooks/signature-validation"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Every webhook request is signed with `,_jsx(_components.strong,{children:`HMAC-SHA256`}),` using your endpoint secret. Validate the signature before trusting the payload.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Webhook endpoints are publicly reachable URLs. Anyone who knows the URL can send a `,_jsx(_components.code,{children:`POST`}),` to it. `,_jsx(_components.strong,{children:`Always validate the signature`}),` before processing. Don’t take an unsigned or invalid-signature request seriously.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`headers`,children:`Headers`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`http`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`http`,children:_jsxs(_components.code,{language:`http`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`POST`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /your-webhook-endpoint `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`HTTP`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`/`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1.1`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Host`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` your-domain.com`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Content-Type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` application/json`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`X-Webhook-Signature`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` sha256=abc123...`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`X-Event-Type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` message.delivered`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`X-Event-ID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` msg_7f8a9b0c1d2e3f4g`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`X-Timestamp`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 1705488600`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`node-js-example`,children:`Node.js example`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`20`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`20`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` crypto`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` require`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'crypto'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` validateWebhook`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`webhookSecret`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` signature`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`headers`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'x-webhook-signature'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` body`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` JSON`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`stringify`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`body`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` hmac`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` crypto`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`createHmac`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'sha256'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`webhookSecret`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` hmac`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`update`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`body`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` expectedSignature`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `sha256=\"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`hmac`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`digest`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'hex'`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` signature`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` expectedSignature`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`app`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`post`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'/webhooks'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, (`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`validateWebhook`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`req`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`process`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`env`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`WEBHOOK_SECRET`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`status`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`401`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'Invalid signature'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Process webhook...`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` res`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`status`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`200`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'OK'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`tips`,children:`Tips`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Use a constant-time comparison`}),` for the signature check (e.g. `,_jsx(_components.code,{children:`crypto.timingSafeEqual`}),` in Node) to avoid timing attacks.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Stringify the body identically to how it was received`}),` - middleware that reformats JSON will break the signature. Either store the raw body before parsing or use a body parser that preserves the exact byte sequence.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Reject stale events`}),` by checking `,_jsx(_components.code,{children:`X-Timestamp`}),` is within (e.g.) 5 minutes of now. Combined with signature validation, this protects against replay attacks.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Don’t log the secret.`}),` It should only ever appear in your secret manager and in memory inside the validation routine.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Signature Validation","description":"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.","icon":"shield-check","href":"/api-reference/webhooks/signature-validation"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Headers","slug":"headers","depth":2,"children":[]},{"title":"Node.js example","slug":"node-js-example","depth":2,"children":[]},{"title":"Tips","slug":"tips","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"politicalcomms","siteName":"Political Comms","title":"Signature Validation - Political Comms","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-05-13T14:06:27.127Z","originalFileLocation":"api-reference/webhooks/signature-validation.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.\">\u003cmeta data-mint-head name=\"keywords\" content=\"political texting, political SMS, P2P messaging, 10DLC registration, Campaign Verify, TCPA compliance, FCC political rules, MCP server, AI agent integration\">\u003cmeta data-mint-head name=\"application-name\" content=\"Political Comms\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow, max-image-preview:large, max-snippet:-1\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Signature Validation - Political Comms\">\u003cmeta data-mint-head property=\"og:description\" content=\"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Political Comms Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://politicalcomms.com/opengraph-image\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Signature Validation - Political Comms\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://politicalcomms.com/opengraph-image\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Political Comms Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#254692\">\u003cmeta data-mint-head name=\"og:locale\" content=\"en_US\">\u003cmeta data-mint-head name=\"og:image:alt\" content=\"Political Comms. The direct-to-carrier political texting platform.\">\u003cmeta data-mint-head name=\"twitter:image:alt\" content=\"Political Comms. The direct-to-carrier political texting platform.\">\u003cmeta data-mint-head name=\"author\" content=\"Political Comms\">\u003cmeta data-mint-head name=\"publisher\" content=\"Political Comms\">\u003cmeta data-mint-head name=\"application-name\" content=\"Political Comms Docs\">\u003cmeta data-mint-head name=\"theme-color\" content=\"#254692\">\u003cmeta data-mint-head name=\"category\" content=\"Political Technology, Communications Infrastructure\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/webhooks/signature-validation.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.politicalcomms.com/#organization\",\"name\":\"Political Comms\",\"url\":\"https://docs.politicalcomms.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/logo/main.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=694b5108d71882d5774bc62c478bc370\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.politicalcomms.com#website\",\"name\":\"Political Comms\",\"url\":\"https://docs.politicalcomms.com\",\"publisher\":{\"@id\":\"https://docs.politicalcomms.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation#webpage\",\"url\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation\",\"name\":\"Signature Validation\",\"description\":\"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.\",\"dateModified\":\"2026-05-13T14:06:27.127Z\",\"isPartOf\":{\"@id\":\"https://docs.politicalcomms.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Webhooks\",\"item\":\"https://docs.politicalcomms.com/api-reference/webhooks/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Signature Validation\",\"item\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation#article\",\"headline\":\"Signature Validation\",\"name\":\"Signature Validation\",\"description\":\"Every webhook request is signed with HMAC-SHA256 using your endpoint secret. Validate before trusting the payload.\",\"url\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation\",\"mainEntityOfPage\":{\"@id\":\"https://docs.politicalcomms.com/api-reference/webhooks/signature-validation#webpage\"},\"image\":\"https://politicalcomms.com/opengraph-image\",\"dateModified\":\"2026-05-13T14:06:27.127Z\",\"publisher\":{\"@id\":\"https://docs.politicalcomms.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.politicalcomms.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Political Comms\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Political Comms\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/webhooks/signature-validation.md","siteName":"Political Comms","nav":{"global":{"anchors":[{"anchor":"Dashboard","icon":"arrow-up-right-from-square","href":"https://app.politicalcomms.com"},{"anchor":"Status","icon":"signal","href":"https://status.politicalcomms.com"},{"anchor":"Changelog","icon":"clock-rotate-left","href":"/changelog"}]},"tabs":[{"tab":"Documentation","pages":[{"title":"Documentation","href":"/introduction"}]},{"tab":"API Reference","groups":[{"group":"Introduction","pages":[{"title":"Introduction","icon":"code","href":"/api-reference/introduction"},{"title":"Authentication","icon":"key","href":"/api-reference/authentication"},{"title":"Rate Limits","icon":"gauge-high","href":"/api-reference/rate-limits"},{"title":"Error Handling","icon":"circle-exclamation","href":"/api-reference/errors"},{"title":"Versioning \u0026 Deprecation","href":"/api-reference/versioning"},{"title":"Best Practices","icon":"stars","href":"/api-reference/best-practices"},{"title":"Two-Way Conversations","icon":"messages","href":"/api-reference/two-way-conversations"}]},{"group":"Webhooks","pages":[{"title":"Overview","icon":"webhook","href":"/api-reference/webhooks/overview"},{"title":"Setup \u0026 Configuration","description":"Add a webhook endpoint, subscribe to events, copy the signing secret, and send a test webhook.","icon":"plug","href":"/api-reference/webhooks/setup"},{"title":"Signature Validation","icon":"shield-check","href":"/api-reference/webhooks/signature-validation"},{"title":"Event Types","description":"Full JSON payload samples for message.sent, message.delivered, message.failed, message.replied, link.clicked, the email events, and contact_list.analyzed.","icon":"code","href":"/api-reference/webhooks/events"},{"title":"Delivery Error Codes","icon":"triangle-exclamation","href":"/api-reference/webhooks/error-codes"},{"title":"Retry Policy","icon":"rotate-right","href":"/api-reference/webhooks/retry-policy"}]},{"group":"Endpoints","pages":[{"group":"Text","pages":[{"group":"Projects","pages":[{"title":"List Projects","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects","href":"/api-reference/projects/list-projects"},{"title":"Create Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects","href":"/api-reference/projects/create-project"},{"title":"Get Project Stats (all)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/stats","href":"/api-reference/projects/get-project-stats-all"},{"title":"Get Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}","href":"/api-reference/projects/get-project"},{"title":"Update Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /projects/{id}","href":"/api-reference/projects/update-project"},{"title":"Get Project Stats (single)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}/stats","href":"/api-reference/projects/get-project-stats-single"},{"title":"Get Project Throughput","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}/throughput","href":"/api-reference/projects/get-project-throughput"},{"title":"Get Survey Results","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}/survey-results","href":"/api-reference/projects/get-survey-results"},{"title":"Test Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/test","href":"/api-reference/projects/test-project"},{"title":"Schedule Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/schedule","href":"/api-reference/projects/schedule-project"},{"title":"Unschedule Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/unschedule","href":"/api-reference/projects/unschedule-project"},{"title":"Pause Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/pause","href":"/api-reference/projects/pause-project"},{"title":"Copy Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/copy","href":"/api-reference/projects/copy-project"}]},{"group":"Phone Numbers","pages":[{"title":"List Phone Numbers","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /phone-numbers","href":"/api-reference/phone-numbers/list-phone-numbers"}]},{"group":"Toll-Free Verifications","pages":[{"title":"List Toll-Free Verifications","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /toll-free-verifications","href":"/api-reference/toll-free-verifications/list-toll-free-verifications"},{"title":"Get Toll-Free Verification","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /toll-free-verifications/{id}","href":"/api-reference/toll-free-verifications/get-toll-free-verification"}]},{"group":"Brands","pages":[{"title":"List Brands","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /brands","href":"/api-reference/brands/list-brands"}]},{"group":"10DLC Campaigns","pages":[{"title":"List Campaigns","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /campaigns","href":"/api-reference/10dlc-campaigns/list-campaigns"},{"title":"Get Campaign Throughput","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /campaigns/{id}/throughput","href":"/api-reference/10dlc-campaigns/get-campaign-throughput"}]}]},{"group":"Email","pages":[{"group":"Email Campaigns","pages":[{"title":"List Campaigns","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/campaigns","href":"/api-reference/email-campaigns/list-campaigns"},{"title":"Create Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/campaigns","href":"/api-reference/email-campaigns/create-campaign"},{"title":"Get Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/campaigns/{id}","href":"/api-reference/email-campaigns/get-campaign"},{"title":"Schedule Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/campaigns/{id}/schedule","href":"/api-reference/email-campaigns/schedule-campaign"},{"title":"Unschedule Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/campaigns/{id}/unschedule","href":"/api-reference/email-campaigns/unschedule-campaign"},{"title":"Get Campaign Stats","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/campaigns/{id}/stats","href":"/api-reference/email-campaigns/get-campaign-stats"}]},{"group":"Email Templates","pages":[{"title":"List Email Templates","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/templates","href":"/api-reference/email-templates/list-email-templates"},{"title":"Create Email Template","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/templates","href":"/api-reference/email-templates/create-email-template"},{"title":"Get Email Template","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/templates/{id}","href":"/api-reference/email-templates/get-email-template"}]},{"group":"Email Senders","pages":[{"title":"List Sender Identities","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/senders","href":"/api-reference/email-senders/list-sender-identities"},{"title":"Get Sender Identity","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/senders/{id}","href":"/api-reference/email-senders/get-sender-identity"}]},{"group":"Email Suppressions","pages":[{"title":"List Suppressions","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/suppressions","href":"/api-reference/email-suppressions/list-suppressions"},{"title":"Add Suppressions","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/suppressions","href":"/api-reference/email-suppressions/add-suppressions"},{"title":"Remove Suppressions","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /email/suppressions","href":"/api-reference/email-suppressions/remove-suppressions"}]}]},{"group":"Assets","pages":[{"group":"Contact Lists","pages":[{"title":"List Contact Lists","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /contact-lists","href":"/api-reference/contact-lists/list-contact-lists"},{"title":"Get Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /contact-lists/{id}","href":"/api-reference/contact-lists/get-contact-list"},{"title":"Delete Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /contact-lists/{id}","href":"/api-reference/contact-lists/delete-contact-list"},{"title":"Import List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /contact-lists/import","href":"/api-reference/contact-lists/import-list"},{"title":"Analyze Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /contact-lists/{id}/analyze","href":"/api-reference/contact-lists/analyze-contact-list"}]},{"group":"Email Lists","pages":[{"title":"List Email Lists","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/lists","href":"/api-reference/email-lists/list-email-lists"},{"title":"Create Email List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists","href":"/api-reference/email-lists/create-email-list"},{"title":"Get Email List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/lists/{id}","href":"/api-reference/email-lists/get-email-list"},{"title":"List Contacts","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/lists/{id}/contacts","href":"/api-reference/email-lists/list-contacts"},{"title":"Add Contacts","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists/{id}/contacts","href":"/api-reference/email-lists/add-contacts"}]},{"group":"Media Files","pages":[{"title":"List Media Files","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /media","href":"/api-reference/media-files/list-media-files"},{"title":"Import Media","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /media","href":"/api-reference/media-files/import-media"},{"title":"Get Media File","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /media/{id}","href":"/api-reference/media-files/get-media-file"},{"title":"Delete Media File","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /media/{id}","href":"/api-reference/media-files/delete-media-file"}]}]},{"group":"Billing \u0026 Usage","pages":[{"group":"Billing","pages":[{"title":"Get Usage","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /ledger/usage","href":"/api-reference/billing/get-usage"},{"title":"Get Usage by Initiator","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /ledger/usage/by-initiator","href":"/api-reference/billing/get-usage-by-initiator"}]},{"group":"Analytics","pages":[{"title":"Get Message Stats","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /messages/stats","href":"/api-reference/analytics/get-message-stats"}]}]},{"group":"Admin","pages":[{"group":"Sending Domains","pages":[{"title":"List Sending Domains","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/domains","href":"/api-reference/sending-domains/list-sending-domains"},{"title":"Get Sending Domain","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/domains/{id}","href":"/api-reference/sending-domains/get-sending-domain"}]},{"group":"Tracking Domains","pages":[{"title":"List Tracking Domains","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /tracking-domains","href":"/api-reference/tracking-domains/list-tracking-domains"}]},{"group":"Organizations","pages":[{"title":"List Organizations","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /organizations","href":"/api-reference/organizations/list-organizations"},{"title":"Get Hierarchy","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /hierarchy","href":"/api-reference/organizations/get-hierarchy"}]}]}]}]}]},"basePath":"","title":"Signature Validation - Political Comms","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":[],"chunks":[]}