1try{let e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},o=(new e.Error).stack;o&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[o]="cb5640fd-d48f-4f3c-a555-f69c3b883885",e._sentryDebugIdIdentifier="sentry-dbid-cb5640fd-d48f-4f3c-a555-f69c3b883885")}catch(e){}(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[58364],{89554:function(e,o,t){"use strict";t.r(o),t.d(o,{default:function(){return k},metadata:function(){return d},tableOfContents:function(){return b}});var a=t(36864),n=t(4730);t(67294);var i=t(3905),r=t(47608);t(40750);var s=t(4534);t(32134),t(90182),t(15930);var p=["components"],d={toc:!0,source:"webhook",layout:"reference",description:"API reference for webhooks, which allow you to receive programmatic updates when an Item goes into an error state or its account information is updated"},l=function(e){return function(o){return console.warn("Component "+e+" was not imported, exported, or provided by MDXProvider as global scope"),(0,i.kt)("div",o)}},h=l("Header"),c=l("Callout"),u={metadata:d};function k(e){var o=e.components,t=(0,n.Z)(e,p);return(0,i.kt)("wrapper",(0,a.Z)({},u,t,{components:o,mdxType:"MDXLayout"}),(0,i.kt)(h,{title:"Webhooks",subtitle:"API reference for webhooks",mdxType:"Header"}),(0,i.kt)(c,{icon:(0,i.kt)(s.default,{mdxType:"Video"}),mdxType:"Callout"},(0,i.kt)("p",null,"Prefer to learn by watching? Our ",(0,i.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=0E0KEAVeDyc"},"video tutorial")," walks you through the basics of incorporating Plaid webhooks into your application.")),(0,i.kt)(c,{mdxType:"Callout"},(0,i.kt)("p",null,"Looking for webhook schemas? The reference documentation for specific webhooks (",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/transactions/#webhooks"},"Transactions"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/auth/#webhooks"},"Auth"),",\n",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/assets/#webhooks"},"Assets"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/identity/#webhooks-beta"},"Identity"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/identity-verification/#webhooks"},"Identity Verification"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/monitor/"},"Monitor"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/investments/#webhooks"},"Investments"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/liabilities/#webhooks"},"Liabilities"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/payment-initiation/#webhooks"},"Payment Initiation"),",\n",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/income/#webhooks"},"Income"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/virtual-accounts/#webhooks"},"Virtual Accounts"),", ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/items/#webhooks"},"Items"),", and ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/products/transfer"},"Transfer"),") has moved to its respective API reference pages.")),(0,i.kt)("h4",{id:"introduction-to-webhooks"},"Introduction to webhooks"),(0,i.kt)("p",null,"A webhook is an HTTP request used to provide push notifications. Plaid sends webhooks to programmatically inform you about changes to Plaid Items or the status of asynchronous processes. For example, Plaid will send a webhook when an Item is in an error state or has additional data available, or when a non-blocking process (like gathering transaction data or verifying a bank account via micro-deposits) is complete."),(0,i.kt)("p",null,"To receive Plaid webhooks, set up a dedicated endpoint on your server as a webhook listener that can receive POST requests, then provide this endpoint URL to Plaid as described in the next section. You can also test webhooks without setting up your own endpoint following the instructions in ",(0,i.kt)("a",{parentName:"p",href:"#testing-webhooks-in-sandbox"},"Testing webhooks in Sandbox"),"."),(0,i.kt)("h4",{id:"configuring-webhooks"},"Configuring webhooks"),(0,i.kt)("p",null,"Webhooks are typically configured via the ",(0,i.kt)("inlineCode",{parentName:"p"},"webhook")," parameter of ",(0,i.kt)("inlineCode",{parentName:"p"},"/link/token/create"),", although some webhooks (especially those used in contexts where Link tokens are not always required), such as Identity Verification webhooks, are configured via the ",(0,i.kt)("a",{parentName:"p",href:"https://dashboard.plaid.com/developers/webhooks"},"Plaid Dashboard")," instead. When specifying a webhook, the URL must be in the standard format of ",(0,i.kt)("inlineCode",{parentName:"p"},"http(s)://(www.)domain.com/")," and, if https, must have a valid SSL certificate. "),(0,i.kt)("p",null,"To view response codes and debug any issues with webhook setup, see the ",(0,i.kt)("a",{parentName:"p",href:"https://dashboard.plaid.com/activity/logs"},"Logs section in the Dashboard"),"."),(0,i.kt)("p",null,"Plaid sends POST payloads with raw JSON to your webhook URL from one of the following IP addresses:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"52.21.26.131"),(0,i.kt)("li",{parentName:"ul"},"52.21.47.157"),(0,i.kt)("li",{parentName:"ul"},"52.41.247.19"),(0,i.kt)("li",{parentName:"ul"},"52.88.82.239")),(0,i.kt)("p",null,"Note that these IP addresses are subject to change."),(0,i.kt)("p",null,"You can optionally verify webhooks to ensure they are from Plaid. For more information, see ",(0,i.kt)("a",{parentName:"p",href:"/docs/api/webhooks/webhook-verification"},"webhook verification"),"."),(0,i.kt)("h4",{id:"webhook-retries"},"Webhook retries"),(0,i.kt)("p",null,"If there is a non-200 response or no response within 10 seconds from the webhook endpoint, Plaid will keep attempting to send the webhook for up to 24 hours. Each attempt will be tried after a delay that is 4 times longer than the previous delay, starting with 30 seconds."),(0,i.kt)("p",null,"If your endpoint returns a ",(0,i.kt)("inlineCode",{parentName:"p"},"429 Too Many Requests")," response, Plaid will honor the ",(0,i.kt)("inlineCode",{parentName:"p"},"Retry-After")," header if present, waiting the specified duration for up to a maximum of 4 hours later before the next attempt instead of applying the standard exponential backoff. The ",(0,i.kt)("inlineCode",{parentName:"p"},"Retry-After")," value may be an integer number of seconds (e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"120"),"), an HTTP date (e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"Wed, 21 Oct 2026 07:28:00 GMT"),"), or an ISO 8601 timestamp (e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"2026-10-21T07:28:00Z"),")."),(0,i.kt)("h4",{id:"best-practices-for-applications-using-webhooks"},"Best practices for applications using webhooks"),(0,i.kt)("p",null,"You should design your application to handle duplicate and out-of-order webhooks. Ensure ",(0,i.kt)("a",{parentName:"p",href:"https://martinfowler.com/articles/patterns-of-distributed-systems/idempotent-receiver.html"},"idempotency")," on actions you take when receiving a webhook. If you drive application state with webhooks, ensure your co
1de doesn't rely on a specific order of webhook receipt."),(0,i.kt)("p",null,"If you (or Plaid) experience downtime for longer than Plaid's ",(0,i.kt)("a",{parentName:"p",href:"#webhook-retries"},"retry period"),", you will lose webhooks. Ensure your application can recover by implementing endpoint polling or other appropriate logic if a webhook is not received within an expected window. All data present in webhooks is also present in our other APIs."),(0,i.kt)("p",null,"It's best to keep your receiver as simple as possible, such as a receiver whose only job is to write the webhook into a queue or reliable storage. This is important for two reasons. First, if the receiver does not respond within 10 seconds, the delivery is considered failed. Second, because webhooks can arrive at unpredictable rates. Therefore if you do a lot of work in your receiver - e.g. generating and sending an email - spikes are likely to overwhelm your downstream services, or cause you to be rate-limited if the downstream is a third-party."),(0,i.kt)("h4",{id:"testing-webhooks-in-sandbox"},"Testing webhooks in Sandbox"),(0,i.kt)("p",null,"Webhooks will fire as normal in the Sandbox environment, with the exception of Transfer webhooks. For testing purposes, you can also use ",(0,i.kt)("inlineCode",{parentName:"p"},"/sandbox/item/fire_webhook"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"/sandbox/user/fire_webhook"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"/sandbox/income/fire_webhook"),", or ",(0,i.kt)("inlineCode",{parentName:"p"},"/sandbox/transfer/fire_webhook")," to fire a webhook on demand. If you don't have a webhook endpoint configured yet, you can also use a tool such as ",(0,i.kt)("a",{parentName:"p",href:"https://webhook.site"},"Webhook.site")," or ",(0,i.kt)("a",{parentName:"p",href:"https://requestbin.com/"},"Request Bin")," to quickly and easily set up a webhook listener endpoint. When directing webhook traffic to third-party tools, make sure you are using Plaid's Sandbox environment and not sending out live data."),(0,i.kt)("h4",{id:"example-in-plaid-pattern"},"Example in Plaid Pattern"),(0,i.kt)("p",null,"For real-life examples of handling webhooks that illustrate how to handle sample transactions and Item webhooks, see ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/plaid/pattern/blob/master/server/webhookHandlers/handleTransactionsWebhook.js"},"handleTransactionsWebhook.js")," and ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/plaid/pattern/blob/master/server/webhookHandlers/handleItemWebhook.js"},"handleItemWebhook.js")," These files contain webhook handling code for the Node-based ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/plaid/pattern"},"Plaid Pattern")," sample app."))}k.isMDXComponent=!0;var b=[{id:"introduction-to-webhooks",level:4,title:"Introduction to webhooks"},{id:"configuring-webhooks",level:4,title:"Configuring webhooks"},{id:"webhook-retries",level:4,title:"Webhook retries"},{id:"best-practices-for-applications-using-webhooks",level:4,title:"Best practices for applications using webhooks"},{id:"testing-webhooks-in-sandbox",level:4,title:"Testing webhooks in Sandbox"},{id:"example-in-plaid-pattern",level:4,title:"Example in Plaid Pattern"}];u.tableOfContents=b,k.layoutProps=u,k.layout=function(e){return(0,i.kt)(r.Z,e)}},63351:function(e,o,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/docs/api/webhooks",function(){return t(89554)}])}},function(e){e.O(0,[49774,86898,26736,29622,12291,22359,68239,79255,92888,40179],function(){return e(e.s=63351)}),_N_E=e.O()}]); 2//# sourceMappingURL=webhooks-506146fa45c74590.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.