Profiles·Public

plaid

semver>=9.0.0postconditions31functions20last verified2026-04-13coverage score83%

Postconditions — what we check

  • linkTokenCreate · api-error
    error
    WhenPlaid API error (INVALID_REQUEST, INVALID_INPUT, RATE_LIMIT_EXCEEDED, API_ERROR) or network failure connecting to Plaid.
    ThrowsAxios 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
    Sources[1][2]
  • itemPublicTokenExchange · api-error
    error
    WhenINVALID_INPUT / INVALID_PUBLIC_TOKEN (token already exchanged, expired, or malformed) or API_ERROR (internal Plaid error) or network failure.
    ThrowsAxios 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
    Sources[3][4]
  • transactionsSync · api-error
    error
    WhenITEM_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.
    ThrowsAxios 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
    Sources[5][6]
  • accountsGet · api-error
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED (credentials expired or revoked), INSTITUTION_ERROR (bank unavailable), INVALID_INPUT / INVALID_ACCESS_TOKEN, or network failure.
    ThrowsAxios 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
    Sources[7][6]
  • authGet · api-error
    error
    WhenITEM_ERROR / PRODUCT_NOT_READY (Auth product not yet initialized), ITEM_ERROR / ITEM_LOGIN_REQUIRED, INVALID_INPUT (institution does not support Auth), or network failure.
    ThrowsAxios 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
    Sources[8][6]
  • transferCreate · api-error
    error
    WhenTRANSFER_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.
    ThrowsAxios 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
    Sources[9][2]
  • identityGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's bank credentials have expired or been revoked. Identity data cannot be refreshed without re-authentication.
    ThrowsAxios 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
    Sources[10][6]
  • identityGet · institution-error
    warning
    WhenINSTITUTION_ERROR / INSTITUTION_DOWN or INSTITUTION_NOT_RESPONDING when the bank is unavailable and identity data cannot be fetched.
    ThrowsAxios 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
    Sources[2][10]
  • liabilitiesGet · no-liability-accounts
    error
    WhenITEM_ERROR / NO_LIABILITY_ACCOUNTS when the Item has no credit, student loan, PayPal, or mortgage accounts matching the product scope.
    ThrowsAxios 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
    Sources[6][11]
  • liabilitiesGet · products-not-supported
    error
    WhenITEM_ERROR / PRODUCTS_NOT_SUPPORTED when the financial institution does not support the liabilities product. Common for smaller or international banks.
    ThrowsAxios 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
    Sources[6][11]
  • liabilitiesGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and liability data cannot be refreshed.
    ThrowsAxios 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
    Sources[6][11]
  • investmentsHoldingsGet · no-investment-accounts
    error
    WhenITEM_ERROR / NO_INVESTMENT_ACCOUNTS when the Item has no investment accounts at the institution.
    ThrowsAxios 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
    Sources[6][12]
  • investmentsHoldingsGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when credentials have expired and investment holdings data cannot be refreshed.
    ThrowsAxios 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
    Sources[6][12]
  • investmentsTransactionsGet · no-investment-accounts
    error
    WhenITEM_ERROR / NO_INVESTMENT_ACCOUNTS when no investment accounts are available on the Item.
    ThrowsAxios 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
    Sources[6][12]
  • investmentsTransactionsGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when credentials have expired.
    ThrowsAxios 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
    Sources[6][12]
  • transactionsGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and transaction data cannot be fetched.
    ThrowsAxios 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
    Sources[6][13]
  • transactionsGet · product-not-ready
    warning
    WhenITEM_ERROR / PRODUCT_NOT_READY when the initial transaction pull is still in progress. Common immediately after Item creation.
    ThrowsAxios 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
    Sources[6][13]
  • transactionsRefresh · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when credentials have expired and a fresh pull cannot be initiated.
    ThrowsAxios 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
    Sources[6][13]
  • transactionsRefresh · institution-error
    warning
    WhenINSTITUTION_ERROR when the bank is temporarily unavailable and the refresh request cannot be queued.
    ThrowsAxios 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
    Sources[2][13]
  • accountsBalanceGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the institution session has expired. Real-time balance cannot be fetched without valid credentials.
    ThrowsAxios 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
    Sources[6][14]
  • accountsBalanceGet · institution-error
    error
    WhenINSTITUTION_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.
    ThrowsAxios 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
    Sources[2][14]
  • itemGet · item-not-found
    error
    WhenINVALID_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.
    ThrowsAxios 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
    Sources[15][2]
  • itemRemove · api-error
    error
    WhenINVALID_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.
    ThrowsAxios 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
    Sources[16][2]
  • transferAuthorizationCreate · transfer-account-blocked
    error
    WhenTRANSFER_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.
    ThrowsAxios 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
    Sources[17][18]
  • transferAuthorizationCreate · transfer-unsupported-account-type
    error
    WhenTRANSFER_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).
    ThrowsAxios 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
    Sources[17][18]
  • transferAuthorizationCreate · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and the authorization cannot be evaluated.
    ThrowsAxios 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
    Sources[6][18]
  • transferGet · api-error
    error
    WhenINVALID_INPUT when the transfer_id is invalid or does not exist in this client's scope, or API_ERROR on Plaid infrastructure failure.
    ThrowsAxios 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
    Sources[18][2]
  • signalEvaluate · signal-error
    error
    WhenSIGNAL_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.
    ThrowsAxios 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
    Sources[19][2]
  • itemWebhookUpdate · api-error
    warning
    WhenINVALID_INPUT (invalid webhook URL format or HTTPS requirement not met), ITEM_ERROR / ITEM_NOT_FOUND (stale access_token), or API_ERROR.
    ThrowsAxios 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
    Sources[20][2]
  • transactionsRecurringGet · item-login-required
    error
    WhenITEM_ERROR / ITEM_LOGIN_REQUIRED when the user's credentials have expired and recurring transaction analysis cannot be refreshed.
    ThrowsAxios 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
    Sources[6][13]
  • transactionsRecurringGet · product-not-ready
    warning
    WhenITEM_ERROR / PRODUCT_NOT_READY when the transactions product has not yet completed its initial pull for this Item.
    ThrowsAxios 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[6][13]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]plaid.com/docs/apihttps://plaid.com/docs/api/tokens/#linktokencreate
  2. [2]plaid.com/docs/errorshttps://plaid.com/docs/errors/
  3. [3]plaid.com/docs/apihttps://plaid.com/docs/api/tokens/#itempublictokenexchange
  4. [4]plaid.com/docs/errorshttps://plaid.com/docs/errors/invalid-input/
  5. [5]plaid.com/docs/apihttps://plaid.com/docs/api/products/transactions/#transactionssync
  6. [6]plaid.com/docs/errorshttps://plaid.com/docs/errors/item/
  7. [7]plaid.com/docs/apihttps://plaid.com/docs/api/accounts/#accountsget
  8. [8]plaid.com/docs/apihttps://plaid.com/docs/api/products/auth/#authget
  9. [9]plaid.com/docs/apihttps://plaid.com/docs/api/products/transfer/#transfercreate
  10. [10]plaid.com/docs/apihttps://plaid.com/docs/api/products/identity/#identityget
  11. [11]plaid.com/docs/apihttps://plaid.com/docs/api/products/liabilities/
  12. [12]plaid.com/docs/apihttps://plaid.com/docs/api/products/investments/
  13. [13]plaid.com/docs/apihttps://plaid.com/docs/api/products/transactions/
  14. [14]plaid.com/docs/apihttps://plaid.com/docs/api/accounts/
  15. [15]plaid.com/docs/apihttps://plaid.com/docs/api/items/#itemget
  16. [16]plaid.com/docs/apihttps://plaid.com/docs/api/items/#itemremove
  17. [17]plaid.com/docs/errorshttps://plaid.com/docs/errors/transfer/
  18. [18]plaid.com/docs/apihttps://plaid.com/docs/api/products/transfer/
  19. [19]plaid.com/docs/apihttps://plaid.com/docs/api/products/signal/
  20. [20]plaid.com/docs/apihttps://plaid.com/docs/api/items/#itemwebhookupdate
Need a different package?
Request a profile