Plaid logo
Docs
ALL DOCS

Transactions

  • Introduction to Transactions
  • Add Transactions to your app
  • Transactions webhooks
  • Transaction states
  • Transactions Sync migration guide
  • Personal Finance Category migration guide
  • Transactions partners
  • Troubleshooting
Plaid logo
Docs
Close search modal
Ask Bill!
Ask Bill!
Hi! I'm Bill! You can ask me all about the Plaid API. Try asking questions like:
    Note: Bill isn't perfect. He's just a robot platypus that reads our docs for fun. You should treat his answers with the same healthy skepticism you might treat any other answer on the internet. This chat may be logged for quality and training purposes. Please don't send Bill any PII -- he's scared of intimacy. All chats with Bill are subject to Plaid's Privacy Policy.
    Plaid.com
    Log in
    Get API Keys
    Open nav

    Transaction states

    Learn about the differences between pending and posted transactions

    Pending and posted transactions

    There are two types of transactions: pending and posted. A transaction begins its life as a pending transaction, then becomes posted once the funds have actually been transferred. It typically takes about one to five business days for a transaction to move from pending to posted, although it can take up to fourteen days in rare situations.

    When a transaction posts, the transition from a pending to posted transaction will be represented through the /transactions/sync endpoint with the pending transaction's id in the removed field of the response and the new posted transaction in the added section of the response -- note that these aren't guaranteed to be in the same page, but should happen within the same overall update. If Plaid matches the pending transaction to the new posted transaction, the pending transaction's id will be marked in the pending_transaction_id of the posted transaction.

    Some institutions, such as Capital One and USAA, do not provide pending transaction data. If no pending transaction is provided, or the pending transaction cannot be matched, the pending_transaction_id will be null.

    1{
    2 "added": [
    3 {
    4 "transaction_id": "lPNjeW1nR6CDn5okmGQ6hEpMo4lLNoSrzqDje",
    5 "pending_transaction_id": "no86Eox18VHMvaOVL7gPUM9ap3aR1LsAVZ5nc",
    6 "account_id": "BxBXxLj1m4HMXBm9WZZmCWVbPjX16EHwv99vp"
    7 "pending": false,
    8 "name": "Apple Store",
    9 "amount": 2307.21
    10 /* ... */
    11 }
    12 ],
    13 "removed": [
    14 {
    15 "transaction_id": "CmdQTNgems8BT1B7ibkoUXVPyAeehT3Tmzk0l",
    16 "account_id": "BxBXxLj1m4HMXBm9WZZmCWVbPjX16EHwv99vp",
    17
    18 /* ... */
    19 }
    20 ],
    21 "modified": []
    22 /* ... */
    23}

    The pending and posted versions of a transaction may not necessarily share the same details: their name and amount may change. For example, the pending charge for a meal at a restaurant may not include a tip, but the posted version will include the final amount spent, including the tip. In some cases, a pending transaction may not convert to a posted transaction at all and will simply disappear; this can happen, for example, if the pending transaction was used as an "authorization hold," which is a sort of a deposit for a potential future transaction, frequently used by gas stations, hotels, and rental-car companies. Pending transactions are short-lived and frequently altered or removed by the institution before finally settling as a posted transaction.

    Note that while transactions will rarely change once they have posted, a posted transaction cannot necessarily be considered immutable. For example, a refund or a recategorization of a transaction by the institution could cause a previously posted transaction to change. This is why it's important to apply all modified, added, and removed updates surfaced through /transactions/sync in order to maintain consistency with the underlying account data.

    Testing pending and posted transactions

    To test dynamic transactions behavior in Sandbox, use the test user user_transactions_dynamic with any non-blank password. You can create a public token for this user using /sandbox/public_token/create; if using the interactive Link flow, you must use a non-OAuth test institution such as First Platypus Bank (ins_109508). An Item associated with this user will be created with 50 transactions in both the pending and posted state. You can then simulate Plaid receiving more data for this Item by calling /transactions/refresh. This will generate new pending transactions, all previously pending transactions will be moved to posted, and the amount of one previous transaction will be incremented by $1.00. All appropriate transaction webhooks will also be fired at this time.

    Remember that in Production, you don't need to call /transactions/refresh unless you want to force Plaid to update its transaction data outside of its usual schedule.

    Example code in Plaid Pattern

    For a real-life example, see update_transactions.js. This file demonstrates code for handling transaction states in the Node-based Plaid Pattern sample app.

    Transaction state changes with /transactions/get

    The content in this section and below applies only to existing integrations using the /transactions/get endpoint. It is recommended that any new integrations use /transactions/sync instead of /transactions/get, for easier and simpler handling of Transaction state changes.

    Reconciling transactions

    /transactions/get returns both pending and posted transactions; however, some institutions do not provide pending transaction data and will only supply posted transactions. The pending boolean field in the transaction indicates whether the transaction is pending or posted.

    Plaid does not model the transition of a pending to posted transaction as a state change for an existing transaction; instead, the posted transaction is a new transaction with a pending_transaction_id field that matches it to a corresponding pending transaction. When a pending transaction is converted to a posted transaction, Plaid removes the pending transaction, sends a TRANSACTIONS_REMOVED webhook, and returns the new, posted transaction. The posted transaction will have a pending_transaction_id field whose value is the transaction_id of the now-removed pending transaction. The posted transaction’s date will reflect the date the transaction was posted, which may differ from the date on which the transaction actually occurred.

    In some rare cases, Plaid will fail to match a posted transaction to its pending counterpart. On such occasions, the posted transaction will be returned without a pending_transaction_id field, and its pending transaction is removed.

    Handling pending and posted transactions

    To manage the movement of a transaction from pending to posted state, you will need to handle the TRANSACTIONS_REMOVED webhook to identify the removed transactions, then delete them from your records. For detailed instructions, see Transactions webhooks.

    Was this helpful?
    Developer community
    GitHub
    GitHub
    Stack Overflow
    Stack Overflow
    YouTube
    YouTube
    Discord
    Discord