plaid
semver
>=9.0.0postconditions31functions20last verified2026-04-13coverage score83%Postconditions — what we check
- linkTokenCreate · api-errorerrorWhenPlaid API error (INVALID_REQUEST, INVALID_INPUT, RATE_LIMIT_EXCEEDED, API_ERROR) or network failure connecting to Plaid.Throws
Axios error. Access PlaidError via error.response.data. Fields include: error_type (e.g. 'RATE_LIMIT_EXCEEDED', 'API_ERROR'), error_code, error_message, request_id.Required handlingCaller MUST wrap in try-catch. A failed linkTokenCreate means the user cannot open Plaid Link at all. Handle RATE_LIMIT_EXCEEDED with backoff; return a 5xx to the client for API_ERROR. Never surface raw Plaid errors to end users.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - itemPublicTokenExchange · api-errorerrorWhenINVALID_INPUT / INVALID_PUBLIC_TOKEN (token already exchanged, expired, or malformed) or API_ERROR (internal Plaid error) or network failure.Throws
Axios error with PlaidError in error.response.data. INVALID_PUBLIC_TOKEN is the most common: token was already exchanged (double-submit) or expired after 30 minutes.Required handlingCaller MUST wrap in try-catch. Failure means the user's bank connection is lost — they must restart the Link flow. Store the access_token only after successful exchange. INVALID_PUBLIC_TOKEN should prompt the user to re-link, not be shown as a generic error.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transactionsSync · api-errorerrorWhenITEM_ERROR / PRODUCT_NOT_READY (initial transaction pull still pending), ITEM_ERROR / ITEM_LOGIN_REQUIRED (user must re-authenticate), INSTITUTION_ERROR (bank connectivity failure), RATE_LIMIT_EXCEEDED, or network failure.Throws
Axios error with PlaidError in error.response.data. PRODUCT_NOT_READY is common on first call before the initial pull completes. ITEM_LOGIN_REQUIRED requires re-linking via Link update mode.Required handlingCaller MUST wrap in try-catch. This is typically called inside a webhook handler — an unhandled error silently breaks transaction sync. Handle PRODUCT_NOT_READY by retrying later; handle ITEM_LOGIN_REQUIRED by notifying the user to re-link their account.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - accountsGet · api-errorerrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED (credentials expired or revoked), INSTITUTION_ERROR (bank unavailable), INVALID_INPUT / INVALID_ACCESS_TOKEN, or network failure.Throws
Axios error with PlaidError in error.response.data. ITEM_LOGIN_REQUIRED is the most common production error -- the user's bank session expired and they must re-link.Required handlingCaller MUST wrap in try-catch. Surface ITEM_LOGIN_REQUIRED to the user as a prompt to update their bank connection. Other errors should return a 5xx to avoid exposing Plaid internals.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - authGet · api-errorerrorWhenITEM_ERROR / PRODUCT_NOT_READY (Auth product not yet initialized), ITEM_ERROR / ITEM_LOGIN_REQUIRED, INVALID_INPUT (institution does not support Auth), or network failure.Throws
Axios error with PlaidError in error.response.data. PRODUCT_NOT_READY means Auth hasn't been initialized yet for this Item. Some institutions require micro-deposit verification.Required handlingCaller MUST wrap in try-catch. Auth data is used for financial operations; unhandled errors can cause incorrect routing. Handle PRODUCT_NOT_READY with polling or retry logic. Handle ITEM_LOGIN_REQUIRED by prompting re-link.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transferCreate · api-errorerrorWhenTRANSFER_ERROR (authorization expired, duplicate transfer, account closed), INVALID_INPUT (invalid account_id or amount), API_ERROR, or network failure. Authorization IDs expire after a short window; using an expired ID returns TRANSFER_ERROR / AUTHORIZATION_EXPIRED.Throws
Axios error with PlaidError in error.response.data. AUTHORIZATION_EXPIRED is common if too much time passes between authorization and creation. DUPLICATE_TRANSFER prevents double-charging.Required handlingCaller MUST wrap in try-catch. This is a financial operation -- an unhandled error can result in a silent failure where money was not moved but the app treats it as success. Log error.response.data.request_id for reconciliation. NEVER retry without checking transfer status first.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - identityGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's bank credentials have expired or been revoked. Identity data cannot be refreshed without re-authentication.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Propagate ITEM_LOGIN_REQUIRED to trigger a re-link flow for the user. KYC verification must not silently proceed with stale or missing identity data.costhighin prodimmediate exceptionusers seelost datavisibilitysilent - identityGet · institution-errorwarningWhenINSTITUTION_ERROR / INSTITUTION_DOWN or INSTITUTION_NOT_RESPONDING when the bank is unavailable and identity data cannot be fetched.Throws
Axios error with PlaidError in error.response.data. error_type = 'INSTITUTION_ERROR'. Transient -- institution may recover without user action.Required handlingCaller MUST wrap in try-catch. Return a 503 to the client; do NOT mark KYC as failed. Queue for retry with backoff.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - liabilitiesGet · no-liability-accountserrorWhenITEM_ERROR / NO_LIABILITY_ACCOUNTS when the Item has no credit, student loan, PayPal, or mortgage accounts matching the product scope.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'NO_LIABILITY_ACCOUNTS'.Required handlingCaller MUST wrap in try-catch. This is a legitimate data absence, not a service failure. Surface a user-friendly message: "No liability accounts found." Do not treat as a generic error.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - liabilitiesGet · products-not-supportederrorWhenITEM_ERROR / PRODUCTS_NOT_SUPPORTED when the financial institution does not support the liabilities product. Common for smaller or international banks.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'PRODUCTS_NOT_SUPPORTED'.Required handlingCaller MUST wrap in try-catch. Show user an institution-not-supported message and prompt to connect a different account. Do not retry.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - liabilitiesGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and liability data cannot be refreshed.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Trigger re-link flow. Liability data used for underwriting must not be based on stale pre-error snapshots.costhighin prodimmediate exceptionusers seelost datavisibilitysilent - investmentsHoldingsGet · no-investment-accountserrorWhenITEM_ERROR / NO_INVESTMENT_ACCOUNTS when the Item has no investment accounts at the institution.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'NO_INVESTMENT_ACCOUNTS'.Required handlingCaller MUST wrap in try-catch. Show a user-friendly message; this is a data absence, not a service error. Do not retry.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - investmentsHoldingsGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when credentials have expired and investment holdings data cannot be refreshed.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Portfolio display must not show stale data without warning. Prompt re-link and flag holdings as potentially outdated.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - investmentsTransactionsGet · no-investment-accountserrorWhenITEM_ERROR / NO_INVESTMENT_ACCOUNTS when no investment accounts are available on the Item.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'NO_INVESTMENT_ACCOUNTS'.Required handlingCaller MUST wrap in try-catch. Tax reporting features must handle this gracefully; do not attempt to generate empty tax forms on error.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - investmentsTransactionsGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when credentials have expired.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Investment transaction history for tax reporting cannot be incomplete. Prompt re-link immediately.costhighin prodimmediate exceptionusers seelost datavisibilitysilent - transactionsGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and transaction data cannot be fetched.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Transaction pipelines (ETL jobs, background sync) must detect ITEM_LOGIN_REQUIRED and notify the user to re-link, not silently skip the fetch.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - transactionsGet · product-not-readywarningWhenITEM_ERROR / PRODUCT_NOT_READY when the initial transaction pull is still in progress. Common immediately after Item creation.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'PRODUCT_NOT_READY'.Required handlingCaller MUST wrap in try-catch. Use webhook (INITIAL_UPDATE, HISTORICAL_UPDATE) to trigger the first call rather than polling. Unhandled PRODUCT_NOT_READY in a sync job crashes the job loop.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transactionsRefresh · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when credentials have expired and a fresh pull cannot be initiated.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. A failed refresh means the webhook will never fire. Notify the user to re-link rather than waiting indefinitely for a webhook that won't arrive.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - transactionsRefresh · institution-errorwarningWhenINSTITUTION_ERROR when the bank is temporarily unavailable and the refresh request cannot be queued.Throws
Axios error with PlaidError in error.response.data. error_type = 'INSTITUTION_ERROR'.Required handlingCaller MUST wrap in try-catch. Retry with exponential backoff. Do not surface institution errors to the user as permanent failures.costlowin prodimmediate exceptionusers seelost datavisibilitysilent - accountsBalanceGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the institution session has expired. Real-time balance cannot be fetched without valid credentials.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. A balance check failure before a payment MUST halt the payment flow. Do not use stale cached balance as a fallback; it may be outdated by hours or days.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - accountsBalanceGet · institution-errorerrorWhenINSTITUTION_ERROR / INSTITUTION_DOWN or INSTITUTION_NOT_RESPONDING when the bank cannot respond in real time. More frequent than with accountsGet since accountsBalanceGet forces a live fetch.Throws
Axios error with PlaidError in error.response.data. error_type = 'INSTITUTION_ERROR'.Required handlingCaller MUST wrap in try-catch. If checking balance before a payment, fail-safe by blocking the payment rather than proceeding without balance verification. Return a user-friendly retry message.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - itemGet · item-not-founderrorWhenINVALID_INPUT / ITEM_NOT_FOUND when the access_token references a deleted or non-existent Item. Common if the Item was removed via itemRemove but the access token is still stored in the database.Throws
Axios error with PlaidError in error.response.data. error_type = 'INVALID_INPUT', error_code = 'ITEM_NOT_FOUND' (or 'INVALID_ACCESS_TOKEN').Required handlingCaller MUST wrap in try-catch. ITEM_NOT_FOUND means the stored access_token is stale. Delete the token from the database and prompt the user to relink. Do not treat as a transient error.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - itemRemove · api-errorerrorWhenINVALID_INPUT / ITEM_NOT_FOUND (token already removed), API_ERROR, or network failure. A failed itemRemove means the Item is NOT removed from Plaid's system and billing continues.Throws
Axios error with PlaidError in error.response.data. ITEM_NOT_FOUND is benign (already removed); API_ERROR should be retried.Required handlingCaller MUST wrap in try-catch. Log the request_id for reconciliation. ITEM_NOT_FOUND should be treated as success (idempotent removal). API_ERROR must be retried to stop subscription billing. Only delete the access_token from the database after confirmed removal.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - transferAuthorizationCreate · transfer-account-blockederrorWhenTRANSFER_ERROR / TRANSFER_ACCOUNT_BLOCKED when a previous transfer involving the same end-user account resulted in an error (e.g., NSF, unauthorized return). Plaid blocks the account from future transfers.Throws
Axios error with PlaidError in error.response.data. error_type = 'TRANSFER_ERROR', error_code = 'TRANSFER_ACCOUNT_BLOCKED'.Required handlingCaller MUST wrap in try-catch. Account is permanently blocked for transfers -- do not retry. Prompt the user to link a different account. This is a risk signal, not a transient error.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transferAuthorizationCreate · transfer-unsupported-account-typeerrorWhenTRANSFER_ERROR / TRANSFER_UNSUPPORTED_ACCOUNT_TYPE when the account type does not support the requested ACH class (e.g., credit card account selected for an ACH debit).Throws
Axios error with PlaidError in error.response.data. error_type = 'TRANSFER_ERROR', error_code = 'TRANSFER_UNSUPPORTED_ACCOUNT_TYPE'.Required handlingCaller MUST wrap in try-catch. Show a clear error: the selected account type does not support this payment method. Ask the user to select a checking or savings account.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transferAuthorizationCreate · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and the authorization cannot be evaluated.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Block the payment flow and prompt re-link before retrying the transfer. Authorization cannot proceed without valid credentials.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - transferGet · api-errorerrorWhenINVALID_INPUT when the transfer_id is invalid or does not exist in this client's scope, or API_ERROR on Plaid infrastructure failure.Throws
Axios error with PlaidError in error.response.data. error_type = 'INVALID_INPUT' or 'API_ERROR'.Required handlingCaller MUST wrap in try-catch. A failed transferGet should trigger a retry with backoff -- the transfer may still exist and be processing. Do not assume a failed GET means the transfer failed.costhighin prodimmediate exceptionusers seelost datavisibilitysilent - signalEvaluate · signal-errorerrorWhenSIGNAL_ERROR / INVALID_ACCOUNT_ID when the account has been removed or the account_id is no longer valid. Also ITEM_LOGIN_REQUIRED when bank data cannot be accessed.Throws
Axios error with PlaidError in error.response.data. error_type = 'SIGNAL_ERROR', error_code = 'INVALID_ACCOUNT_ID' or error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. A failed signal evaluation means risk cannot be assessed. Fail-safe by blocking the transfer rather than proceeding without a risk score. Log the request_id.costhighin prodimmediate exceptionusers seelost datavisibilitysilent - itemWebhookUpdate · api-errorwarningWhenINVALID_INPUT (invalid webhook URL format or HTTPS requirement not met), ITEM_ERROR / ITEM_NOT_FOUND (stale access_token), or API_ERROR.Throws
Axios error with PlaidError in error.response.data. Webhook URLs must be HTTPS; HTTP URLs are rejected with INVALID_INPUT.Required handlingCaller MUST wrap in try-catch. A failed webhook update means future transaction events won't reach the application. Verify webhook URL is HTTPS and retry on API_ERROR.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - transactionsRecurringGet · item-login-requirederrorWhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and recurring transaction analysis cannot be refreshed.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'ITEM_LOGIN_REQUIRED'.Required handlingCaller MUST wrap in try-catch. Recurring transaction data used for bill prediction must not be stale. Surface re-link prompt.costmediumin prodimmediate exceptionusers seelost datavisibilitysilent - transactionsRecurringGet · product-not-readywarningWhenITEM_ERROR / PRODUCT_NOT_READY when the transactions product has not yet completed its initial pull for this Item.Throws
Axios error with PlaidError in error.response.data. error_type = 'ITEM_ERROR', error_code = 'PRODUCT_NOT_READY'.Required handlingCaller MUST wrap in try-catch. Wait for HISTORICAL_UPDATE webhook before calling this endpoint. Show a loading state to the user.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
Sources
Every postcondition cites at least one of these. Numbered to match the footnotes above.
- [1]plaid.com/docs/apihttps://plaid.com/docs/api/tokens/#linktokencreate
- [2]plaid.com/docs/errorshttps://plaid.com/docs/errors/
- [3]plaid.com/docs/apihttps://plaid.com/docs/api/tokens/#itempublictokenexchange
- [4]plaid.com/docs/errorshttps://plaid.com/docs/errors/invalid-input/
- [5]plaid.com/docs/apihttps://plaid.com/docs/api/products/transactions/#transactionssync
- [6]plaid.com/docs/errorshttps://plaid.com/docs/errors/item/
- [7]plaid.com/docs/apihttps://plaid.com/docs/api/accounts/#accountsget
- [8]plaid.com/docs/apihttps://plaid.com/docs/api/products/auth/#authget
- [9]plaid.com/docs/apihttps://plaid.com/docs/api/products/transfer/#transfercreate
- [10]plaid.com/docs/apihttps://plaid.com/docs/api/products/identity/#identityget
- [11]plaid.com/docs/apihttps://plaid.com/docs/api/products/liabilities/
- [12]plaid.com/docs/apihttps://plaid.com/docs/api/products/investments/
- [13]plaid.com/docs/apihttps://plaid.com/docs/api/products/transactions/
- [14]plaid.com/docs/apihttps://plaid.com/docs/api/accounts/
- [15]plaid.com/docs/apihttps://plaid.com/docs/api/items/#itemget
- [16]plaid.com/docs/apihttps://plaid.com/docs/api/items/#itemremove
- [17]plaid.com/docs/errorshttps://plaid.com/docs/errors/transfer/
- [18]plaid.com/docs/apihttps://plaid.com/docs/api/products/transfer/
- [19]plaid.com/docs/apihttps://plaid.com/docs/api/products/signal/
- [20]plaid.com/docs/apihttps://plaid.com/docs/api/items/#itemwebhookupdate
Need a different package?
Request a profile