Plaid webhook verification
Plaid signs webhooks with a JWT scheme that differs from the HMAC pattern most teams expect. The route records below document the verification flow plus the related identity/auth ownership checks.
Sourced from 4 live route records · regenerated 2026-07-08
Part of the webhook verification series — also see: Stripe · DocuSign · Typeform · Attio
Documented failure modes
plaid.comsampled
- JWT alg must be ES256 — reject anything else
- Cache the verification key by kid; Plaid rotates keys
- Body hash must be computed over the exact raw bytes
plaid.com/docs/identity-verificationsampled
- The template_id controls which steps are included (document, selfie, KBA, watchlist); create and configure templates in the Plaid dashboard before coding.
- Plaid Identity Verification and Plaid Monitor (ongoing screening) are separate products; do not conflate the one-time IDV result with ongoing watchlist monitoring.
- Shareable URLs bypass Link and can be sent via email; they expire and are tied to a single user, so never reuse them.
plaid.comsampled
- Not all institutions support instant auth; fallback to micro-deposit verification can add 1-3 business days to the onboarding flow
- /identity/get may return multiple owners per account; match all returned names against your KYC records, not just the first
- Auth and Identity data can become stale; re-fetch before high-value transfers rather than relying on cached results
plaid.com/docs/authsampled
- ACH account numbers returned by Plaid Auth are sensitive; store them encrypted and only use them for the permitted payment purpose.
- Some financial institutions use Instant Auth (credentials-based) while others require micro-deposit verification (Automated Micro-deposits or Same-Day Micro-deposits); your integration must handle both flows.
- Plaid access tokens do not expire on their own but can become invalid if the user revokes access at their bank; implement webhook handling for ITEM errors.
The working procedure
- Read the Plaid-Verification header (a JWT)
- Decode the JWT header to get kid, then POST /webhook_verification_key/get with the kid
- Verify the JWT signature (ES256) with the returned JWK
- Compare request body SHA-256 against the JWT's request_body_sha256 claim
Source: Handle Plaid webhook verification — a live route record (status: sampled). Route content is community/operator contributed and re-checked over time; read the live record for the current version.
How agents avoid this automatically
Agents wired to Waymark's MCP server pull this route (and its gotchas) at plan time instead of rediscovering the failure modes in production. Reads are free and keyless.
# Any MCP client — one call, no key:
waymark_query({ "task": "plaid webhook verification jwt" })
# Or plain HTTP:
curl -s "https://mcp.waymark.network/search?q=plaid%20webhook%20verification%20jwt"