Plaid Webhooks
Receives Plaid webhook events at a Monad-hosted endpoint, optionally verifies each delivery's Plaid-Verification signature, filters to the webhook types you select, and emits the raw payload.
Sync Type: Push (Webhook)
Overview
Plaid emits webhooks for the connections (Items) linked through it — lifecycle events (ITEM), plus product events like AUTH, TRANSACTIONS, and IDENTITY. This input is a webhook receiver: Plaid pushes events to a Monad-hosted endpoint rather than Monad polling an API.
Each delivery is (optionally) cryptographically verified to confirm it genuinely came from Plaid, filtered to the webhook types you selected, and emitted with its original payload preserved verbatim — so no fields are dropped or reshaped, and new Plaid fields flow through automatically.
Why a webhook, not a poll
Plaid has no API to list or replay past webhook events, and no endpoint to enumerate your Items. The webhook push is the only programmatic feed of these events.
Example: ITEM events
ITEM webhooks are the connection-lifecycle/security audit trail and a common reason to use this input:
| Webhook Code | Meaning |
|---|---|
ERROR | An error occurred on the Item — most often the bank login stopped working (ITEM_LOGIN_REQUIRED) and the user must re-authenticate. |
LOGIN_REPAIRED | A previously broken login recovered without user action. |
PENDING_EXPIRATION | The user's consent for the Item expires within 7 days. |
PENDING_DISCONNECT | The Item is scheduled to be disconnected within 7 days. |
USER_PERMISSION_REVOKED | The end user revoked Plaid's access to the entire Item. |
USER_ACCOUNT_REVOKED | The end user revoked access to a specific account within the Item. |
NEW_ACCOUNTS_AVAILABLE | Plaid detected a new account the user could add. |
WEBHOOK_UPDATE_ACKNOWLEDGED | Confirmation that an Item's webhook URL was changed. |
Other webhook types (AUTH, TRANSACTIONS, IDENTITY, …) are delivered to the same URL and can be selected via the Webhook Types setting.
How It Works
- Plaid delivers a webhook POST to the input's ingest URL. A single webhook URL receives all of an Item's webhooks across every type.
- If Verify Webhooks is enabled (default), the input verifies each delivery's
Plaid-VerificationJWT (anES256signature): it fetches Plaid's public verification key (/webhook_verification_key/get) using your Client ID and Secret, checks the signature, rejects webhooks older than 5 minutes (replay protection), and confirms the body's SHA-256 matches the signed value. Keys are cached, so this adds no per-event call to Plaid. - The input keeps deliveries whose
webhook_typeis in the configured Webhook Types (or all types if none are selected) and emits them; other types are acknowledged and dropped.
Events are attributed by the item_id in each payload (and account_id for account-level events), so a single webhook URL serves your entire Item population — there is no need for a per-Item URL.
One webhook URL = one pipeline
Plaid sends every webhook type for an Item to the one URL you configure, and each Monad pipeline has its own ingest URL. So you cannot split event types across pipelines (e.g. an "ITEM pipeline" and an "AUTH pipeline") — Plaid would deliver everything to whichever single URL is set, and the other pipeline would receive nothing.
To route different event types to different destinations, use one Plaid Webhooks input (leave Webhook Types empty to keep all) and route by webhook_type downstream to separate destinations.
Prerequisites
Before configuring this input, you need:
- Plaid Production API credentials — your Client ID and Production Secret (Plaid Dashboard → Developers → Keys), required when verification is enabled. They are used only to fetch Plaid's webhook verification keys; the input never pulls data from Plaid.
- The ability to set your Plaid webhook URL — you configure the Monad ingest URL on your Items via Plaid's API (see Setup, Step 2). This is done in your own Plaid integration code.
Setup
Step 1: Create the input in Monad
-
Create a Plaid Webhooks input and add it to a pipeline.
-
Configure the Webhook Types you want (or leave empty for all), and — if Verify Webhooks is enabled — the Client ID and Secret (Production).
-
Copy the Pipeline ID from the pipeline details page. Your ingest URL is:
https://app.monad.com/api/v2/http/send/{pipeline_id}
Step 2: Point your Plaid Items at the ingest URL
Plaid sets the webhook URL per Item, but you use the same Monad ingest URL for all of them:
- New Items — set the
webhookfield in/link/token/createto the ingest URL. Every Item created from that Link token inherits it. - Existing Items — call
/item/webhook/updatewith each Item'saccess_tokenand the ingest URL.
On a successful /item/webhook/update, Plaid fires a WEBHOOK_UPDATE_ACKNOWLEDGED event to the new URL — a built-in reachability check.
Use one URL for all Items
Do not create a separate URL per Item or per account. Monad distinguishes every event by the item_id (and account_id) inside the payload, so one shared ingest URL handles your entire Item population.
Configuration
Settings
| Setting | Type | Required | Default | Description |
|---|---|---|---|---|
| Verify Webhooks | bool | No | true | Verify each delivery's Plaid-Verification signature (ES256) before ingesting. Strongly recommended. When disabled, the endpoint accepts any payload (still protected by the pipeline's Monad API key). |
| Webhook Types | array | No | (all) | Which webhook_type values to emit (e.g. ITEM, AUTH). Leave empty to emit every type. |
| Client ID | string | If verifying | - | Your Plaid API client_id. Used with the secret to fetch Plaid's webhook verification keys. |
| Secret | secret | If verifying | - | Your Plaid Production API secret. Used with the client ID to fetch verification keys. Stored as a secret. |
Client ID and Secret are required only when Verify Webhooks is enabled. This input targets Production only.
Record Fields
Each record is one webhook delivery, emitted as Plaid's original payload verbatim, plus a single added field:
| Field | Description |
|---|---|
received_at | RFC3339 timestamp added by Monad when the delivery was processed. Plaid does not include an event timestamp, so this is the best available event time. |
| (all Plaid fields) | Every field from the original webhook is preserved unchanged — webhook_type, webhook_code, item_id, environment, and any code-specific fields (e.g. error, consent_expiration_time, account_id, new_accounts). |
Because the payload is passed through untouched, records stay correct even as Plaid adds or changes webhook fields.
Sample Record
Code
Limitations
- No backfill. Webhooks are forward-only and Plaid does not replay past events, so only events that occur after the webhook URL is configured are ingested.
- One URL = one pipeline. You can't split webhook types across multiple pipelines (see the warning above); route by
webhook_typedownstream instead. - No
user_id. Plaid webhooks do not include an end-user identifier. Records carryitem_id; map it to a user in your own system if you need that association. - Production only. This input handles Production webhooks. Sandbox is not supported today.
- Dashboard-configured webhooks excluded. Plaid sends
TRANSFER,MONITOR,IDENTITY_VERIFICATION, and a few other webhook types to a URL configured in the Plaid Dashboard, not the one set via/link/token/create. Those do not arrive at this input. - Delivery reliability. Ingestion is at-least-once; Plaid retries deliveries that don't receive a success response.
Troubleshooting
1. Deliveries rejected (401) — when verification is enabled
- Signature failure: Confirm the Client ID and Secret are the correct Production credentials — verification fetches keys with them. A mismatched or non-Production secret will fail key retrieval and reject deliveries.
- Stale deliveries: Webhooks older than 5 minutes are rejected as possible replays. Persistent rejections can indicate severe clock skew between Plaid and the receiver.
- To rule out signature issues during setup, you can temporarily disable Verify Webhooks (not recommended for production).
2. No data
- Webhook URL not set: Confirm your Items point at the Monad ingest URL via
/link/token/create(new Items) or/item/webhook/update(existing Items). A successful update firesWEBHOOK_UPDATE_ACKNOWLEDGED. - Types filtered out: If Webhook Types is set, only those types are emitted. Widen the selection or leave it empty to keep all.
- No matching events yet: Events fire only when something happens on a connection. An idle, healthy Item produces nothing.
3. Missing historical events
- Expected — there is no backfill. Only events after the webhook URL is configured are captured.
Related Articles
- Plaid Webhooks overview
- Plaid Item webhooks reference
- Webhook verification
/link/token/create/item/webhook/update
Sync frequency
This is a push (receiver) input: Monad ingests records as the source sends them, so there is no polling interval. See Input Sync Frequency for details.