<!-- Generated by `just docs` from catalog/toolkits/plaid.yaml, catalog/expansions/plaid.yaml, catalog/evals/scorecard.json. Edit the source, not this file. -->

# Plaid

Bank connections. Link an account, then read balances, transactions, identity, and account numbers, and manage the link itself.

| Property | Value |
| --- | --- |
| Slug | `plaid` |
| Definition version | `0.1.0` |
| Base URL | `https://production.api.plaid.com` |
| Auth schemes | `api_key` |
| Action tools | 28 |
| By class | 16 read, 10 write, 2 destructive |
| Triggers | 0 |
| Provider rate limit | not declared, so outbound calls are unpaced |

## Measured routing accuracy

42 golden cases replayed through the router over the whole index: measured over corpus `ea4f12ad2948` (65 toolkits, 2283 tools indexed and 13 declared uncallable), 28 cases written by hand and 14 cases from the paraphrase pass. A case counts as top-1 when its gold tool ranked first and top-8 when it reached the slate at all.

| Measure | Cases | Share |
| --- | --- | --- |
| top-1 | 29/42 | 69.0% |
| top-8 | 39/42 | 92.9% |

The sweep is offline: the reranker is a deterministic identity fake that returns candidates in the order retrieval produced them, so top-1 measures retrieval order rather than a reranked slate. `just eval-live` measures the same cases through the live reranker.

## Authentication

Connect an entity with `ConnectionsService.InitiateConnection`, naming this toolkit's slug. Credentials stay in the connections vault; callers hold connected-account ids only.

### `api_key`

| Property | Value |
| --- | --- |
| Placement | `header` |
| Name | `PLAID-SECRET` |
| Rendered as | `{key}` |

Submit the key with `ConnectionsService` rather than putting it in a request; it is sealed at rest and never returned.

## Tools

28 action tools. The catalog-wide slug is `plaid.<tool>`, which is what `search_tools` returns and `call_tool` takes.

### `plaid.create_link_token`

Create a Plaid Link token to start a bank-connection flow for a user. Use when the user wants to connect, link, or add a bank account for the first time. Give an existing item's access_token instead of new products to open Link in update mode and repair or re-authenticate a connection that broke.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /link/token/create`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | no | An existing item's access token. Set this to open Link in update mode instead of creating a brand new item. |
| `client_name` | string | **yes** | Your app's name, shown to the user inside Link. |
| `client_user_id` | string | **yes** | Your own unique id for this end user, e.g. "user-1234". |
| `country_codes` | array of string | **yes** | ISO country codes to show institutions for, e.g. ["US"]. |
| `language` | string | **yes** | ISO 639-1 language code for the Link UI, e.g. "en". |
| `products` | array of string | **yes** | Plaid products to enable, e.g. ["transactions", "auth"]. |
| `webhook` | string | no | URL Plaid calls with updates for items created from this session. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `expiration` | string |  |
| `link_token` | string |  |
| `request_id` | string |  |

Also retrieved by: "let this person hook up their bank account", "start the flow where a user adds their checking account", "I need a session so someone can plug in their bank", "kick off the bank-connect popup for a new user", "open the widget that lets them pick their bank", "give me a fresh session to repair a broken bank hookup".

### `plaid.get_link_token`

Look up a previously created Plaid Link token: its expiration and the products and webhook it was configured with. Use when the user asks why a Link session behaved a certain way or whether a token has expired.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /link/token/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `link_token` | string | **yes** | Link token to look up, e.g. "link-sandbox-1234abcd". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `created_at` | string |  |
| `expiration` | string |  |
| `link_token` | string |  |
| `metadata` | object |  |
| `metadata.initial_products` | array of string |  |
| `metadata.webhook` | string |  |

Also retrieved by: "why did that connect popup behave weirdly", "check when this session expires", "pull up what a link session was configured with", "look up the settings behind this connect flow".

### `plaid.exchange_public_token`

Exchange a Link public_token, returned when a user finishes connecting their bank, for a permanent access_token and item_id. Use right after Link succeeds; the public_token itself expires within about 30 minutes and cannot be used for anything else.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /item/public_token/exchange`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `public_token` | string | **yes** | Public token returned by Link on success, e.g. "public-sandbox-1234". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `access_token` | string |  |
| `item_id` | string |  |
| `request_id` | string |  |

Also retrieved by: "finish hooking up the account now that the popup closed", "swap the temporary token for a real one", "turn what Link gave back into something we can actually use", "the user just finished linking, wrap that up".

### `plaid.get_item`

Get the status of a connected bank item: which institution it belongs to, its configured webhook, which products are enabled, and any standing error. Use when the user asks whether a connection is healthy or why data has stopped updating.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /item/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to check. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `item` | object |  |
| `item.available_products` | array of string |  |
| `item.billed_products` | array of string |  |
| `item.error` | object |  |
| `item.error.error_code` | string |  |
| `item.error.error_message` | string |  |
| `item.institution_id` | string |  |
| `item.item_id` | string |  |
| `item.webhook` | string |  |

Also retrieved by: "is this bank hookup still working", "why did the data stop updating for this connection", "check on the health of a linked account", "what's wrong with this connection", "see what's enabled on this bank link".

### `plaid.update_item_webhook`

Change the webhook URL a connected item posts updates to. Use when the user wants to point transaction or item notifications at a new endpoint. This does not touch which products the item has enabled.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /item/webhook/update`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to update. |
| `webhook` | string | **yes** | New webhook URL Plaid should post events to. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `item` | object |  |
| `item.item_id` | string |  |
| `item.webhook` | string |  |
| `request_id` | string |  |

Also retrieved by: "point notifications at a different endpoint", "change where updates for this connection get sent", "redirect the callback url for this bank hookup", "swap the notification address on a linked account".

### `plaid.invalidate_access_token`

Rotate a connected item's access token, permanently invalidating the old one and issuing a new one in its place. Irreversible: any caller still holding the old token loses access immediately. Use only when the user explicitly asks to rotate, refresh, or invalidate a stored credential, e.g. after a suspected leak.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). No scopes beyond the connection's defaults. Calls `POST /item/access_token/invalidate`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token to invalidate and replace. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `new_access_token` | string |  |
| `request_id` | string |  |

Also retrieved by: "this credential might have leaked, rotate it", "swap out the stored secret for this connection", "issue a fresh token and kill the old one", "somebody got a hold of this token, replace it".

### `plaid.remove_item`

Permanently remove a connected bank item, revoking Plaid's access to that account entirely. Irreversible; the user must go through Link again to reconnect. Use only when the user explicitly asks to disconnect, unlink, or remove a bank connection for good.

Class `destructive` (held by the mutation gate until the call's own arguments carry `"confirm": true`). No scopes beyond the connection's defaults. Calls `POST /item/remove`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to remove. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `request_id` | string |  |

Also retrieved by: "disconnect this bank account for good", "the user wants to unlink their checking account", "cut this connection off entirely", "take this bank hookup off our books", "they revoked access, tear down the link".

### `plaid.search_institutions`

Search banks and financial institutions by name for a given set of products and countries. Use when the user is looking for their bank by name before linking it, or checking whether a bank supports a product. For a known institution id, use get_institution.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /institutions/search`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `country_codes` | array of string | **yes** | ISO country codes to search within, e.g. ["US"]. |
| `products` | array of string | **yes** | Only institutions supporting all of these products. |
| `query` | string | **yes** | Institution name or partial name to search for, e.g. "chase". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `institutions` | array of object |  |
| `institutions[].country_codes` | array of string |  |
| `institutions[].institution_id` | string |  |
| `institutions[].name` | string |  |
| `institutions[].products` | array of string |  |

Also retrieved by: "find their bank by name", "which banks support this feature", "look up a financial institution before hooking it up", "search for chase or another bank".

### `plaid.get_institution`

Get one bank or financial institution by its Plaid institution_id: name, supported products, and countries. Use when the user names a specific institution id, typically read off get_item's result. For finding an institution by name, use search_institutions.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /institutions/get_by_id`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `country_codes` | array of string | **yes** | ISO country codes the institution should be resolved within. |
| `institution_id` | string | **yes** | Plaid institution id, e.g. "ins_109508". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `institution` | object |  |
| `institution.country_codes` | array of string |  |
| `institution.institution_id` | string |  |
| `institution.name` | string |  |
| `institution.products` | array of string |  |
| `institution.url` | string |  |

Also retrieved by: "what bank is this id", "pull up details on this specific financial institution", "which countries does this bank operate in".

### `plaid.list_institutions`

Browse the full catalog of banks and financial institutions Plaid supports, a page at a time. Use when the user wants to explore or count available institutions rather than search for one by name.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /institutions/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `count` | integer | **yes** | Institutions to return, max 500. |
| `country_codes` | array of string | **yes** | ISO country codes to list institutions for, e.g. ["US"]. |
| `offset` | integer | **yes** | Institutions to skip, for paging past a previous page. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `institutions` | array of object |  |
| `institutions[].institution_id` | string |  |
| `institutions[].name` | string |  |
| `institutions[].products` | array of string |  |
| `total` | integer |  |

Also retrieved by: "show me every bank you support", "browse the full list of supported banks", "how many financial institutions are available".

### `plaid.get_accounts`

List the accounts on a connected item: checking, savings, and credit accounts with their name, mask, type, and last-known balance. Use when the user asks what accounts a bank connection exposes. For a guaranteed fresh balance, use get_balances instead.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /accounts/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item whose accounts to list. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `accounts` | array of object |  |
| `accounts[].account_id` | string |  |
| `accounts[].balances` | object |  |
| `accounts[].balances.available` | number |  |
| `accounts[].balances.current` | number |  |
| `accounts[].balances.iso_currency_code` | string |  |
| `accounts[].mask` | string |  |
| `accounts[].name` | string |  |
| `accounts[].subtype` | string |  |
| `accounts[].type` | string |  |

Also retrieved by: "what accounts came through on this hookup", "list the checking and savings accounts on this connection", "show me every account tied to this bank link".

### `plaid.get_balances`

Get a real-time, forced-fresh balance for one or more accounts on an item, bypassing Plaid's cache. Use when the user asks for the current or up-to-the-minute balance rather than the last-synced one from get_accounts.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /accounts/balance/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to check. |
| `account_ids` | array of string | no | Only these account ids. Omit for every account on the item. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `accounts` | array of object |  |
| `accounts[].account_id` | string |  |
| `accounts[].balances` | object |  |
| `accounts[].balances.available` | number |  |
| `accounts[].balances.current` | number |  |
| `accounts[].balances.iso_currency_code` | string |  |
| `accounts[].name` | string |  |

Also retrieved by: "what's the actual balance right now, not a cached one", "pull a fresh number straight from the bank", "double check how much money is really in there".

### `plaid.get_auth`

Get the routing and account numbers behind a connected account, for setting up ACH transfers or direct deposit. Use when the user wants to pay someone, set up payroll, or fund a transfer using the linked bank account rather than a card.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /auth/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to get numbers for. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `accounts` | array of object |  |
| `accounts[].account_id` | string |  |
| `accounts[].name` | string |  |
| `numbers` | object |  |
| `numbers.ach` | array of object |  |
| `numbers.ach[].account` | string |  |
| `numbers.ach[].account_id` | string |  |
| `numbers.ach[].routing` | string |  |
| `numbers.ach[].wire_routing` | string |  |

Also retrieved by: "I need this account's routing number", "get the numbers so we can set up direct deposit", "pull the ach details for an ACH transfer", "what account number do we wire money to".

### `plaid.sync_transactions`

Pull transaction changes since the last check: added, modified, and removed transactions, using a cursor instead of a date range. Use when the user wants to keep a transaction feed up to date incrementally. For a one-time pull over an explicit date range, use get_transactions.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /transactions/sync`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to sync. |
| `count` | integer | no | Transactions to return per page, max 500. Defaults to 100. |
| `cursor` | string | no | Cursor from a previous sync's next_cursor. Omit for the very first sync. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `added` | array of object |  |
| `added[].account_id` | string |  |
| `added[].amount` | number |  |
| `added[].date` | string |  |
| `added[].merchant_name` | string |  |
| `added[].name` | string |  |
| `added[].pending` | boolean |  |
| `added[].transaction_id` | string |  |
| `has_more` | boolean |  |
| `modified` | array of object |  |
| `modified[].amount` | number |  |
| `modified[].pending` | boolean |  |
| `modified[].transaction_id` | string |  |
| `next_cursor` | string |  |
| `removed` | array of object |  |
| `removed[].transaction_id` | string |  |

Also retrieved by: "pull whatever changed since I last checked", "keep the spending feed current with a cursor", "grab new activity without redoing the whole history".

### `plaid.get_transactions`

List transactions on an item over an explicit date range, optionally filtered to specific accounts. Use when the user asks for spending or transaction history between two dates. For incremental updates since a previous check, use sync_transactions instead.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /transactions/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to query. |
| `account_ids` | array of string | no | Only transactions on these account ids. |
| `count` | integer | no | Results per page, max 500. Defaults to 100. |
| `end_date` | string | **yes** | End of the range, YYYY-MM-DD, e.g. "2026-06-30". |
| `offset` | integer | no | Results to skip, for paging past a previous page. |
| `start_date` | string | **yes** | Start of the range, YYYY-MM-DD, e.g. "2026-06-01". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `total_transactions` | integer |  |
| `transactions` | array of object |  |
| `transactions[].account_id` | string |  |
| `transactions[].amount` | number |  |
| `transactions[].category` | array of string |  |
| `transactions[].date` | string |  |
| `transactions[].iso_currency_code` | string |  |
| `transactions[].merchant_name` | string |  |
| `transactions[].name` | string |  |
| `transactions[].pending` | boolean |  |
| `transactions[].transaction_id` | string |  |

Also retrieved by: "show spending between these two dates", "pull last month's activity on this account", "what did they buy between June 1st and June 30th", "give me a statement-style list of purchases".

### `plaid.refresh_transactions`

Ask Plaid to reach out to the institution right now for the latest transactions, ahead of its normal schedule. Use when the user wants to force, trigger, or hurry up a transaction update instead of waiting. New data arrives shortly after via sync_transactions or a webhook, not in this call's response.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /transactions/refresh`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to refresh. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `request_id` | string |  |

Also retrieved by: "go get the latest activity right now, don't wait", "hurry up and pull new spending from the bank", "force an update instead of waiting for the schedule".

### `plaid.get_recurring_transactions`

Detect recurring inflows and outflows on an item, such as a paycheck or a subscription charge, with their average amount and frequency. Use when the user asks about recurring bills, subscriptions, or regular income rather than one-off transactions.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /transactions/recurring/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to inspect. |
| `account_ids` | array of string | no | Only streams on these account ids. Omit for every account. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `inflow_streams` | array of object |  |
| `inflow_streams[].average_amount` | number |  |
| `inflow_streams[].description` | string |  |
| `inflow_streams[].frequency` | string |  |
| `inflow_streams[].is_active` | boolean |  |
| `inflow_streams[].merchant_name` | string |  |
| `outflow_streams` | array of object |  |
| `outflow_streams[].average_amount` | number |  |
| `outflow_streams[].description` | string |  |
| `outflow_streams[].frequency` | string |  |
| `outflow_streams[].is_active` | boolean |  |
| `outflow_streams[].merchant_name` | string |  |

Also retrieved by: "find their subscriptions", "what bills come out every month", "detect their paycheck and regular charges", "spot the recurring stuff versus one-off purchases".

### `plaid.get_identity`

Get the account holder identity data a bank has on file for an item: names, emails, phone numbers, and addresses per account. Use when the user wants to confirm who owns a linked account, e.g. for KYC. For scoring how well a given name or email matches instead, use match_identity.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /identity/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to read identity data from. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `accounts` | array of object |  |
| `accounts[].account_id` | string |  |
| `accounts[].owners` | array of object |  |
| `accounts[].owners[].addresses` | array of object |  |
| `accounts[].owners[].emails` | array of object |  |
| `accounts[].owners[].names` | array of string |  |
| `accounts[].owners[].phone_numbers` | array of object |  |

Also retrieved by: "whose name is on this account", "pull the contact info the bank has on file", "what address does the bank have for them".

### `plaid.match_identity`

Score how closely a name, phone number, email, or address you already have on file matches what the bank has for an account holder. Use when the user wants to verify or check identity against a specific candidate value rather than pull the raw identity record with get_identity.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /identity/match`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item to match against. |
| `email_address` | string | no | Candidate email address to score. |
| `legal_name` | string | no | Candidate legal name to score, e.g. "Jane Doe". |
| `phone_number` | string | no | Candidate phone number to score. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `accounts` | array of object |  |
| `accounts[].account_id` | string |  |
| `accounts[].email_address` | object |  |
| `accounts[].email_address.score` | integer |  |
| `accounts[].legal_name` | object |  |
| `accounts[].legal_name.score` | integer |  |
| `accounts[].phone_number` | object |  |
| `accounts[].phone_number.score` | integer |  |

Also retrieved by: "does this name line up with what the bank has", "check if their email matches the account holder", "score how well this phone number fits the real owner".

### `plaid.create_identity_verification`

Start a new hosted identity verification session for a user, such as a document and selfie check, ahead of a bank connection. Use when the user wants to verify, vet, or run KYC on someone before onboarding them, not to check on a session already running.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /identity_verification/create`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `client_user_id` | string | **yes** | Your own unique id for this end user. |
| `email_address` | string | no | The user's email address, if already known. |
| `legal_name` | string | no | The user's legal name, if already known. |
| `phone_number` | string | no | The user's phone number, if already known. |
| `template_id` | string | **yes** | Identity Verification template configured in the Plaid dashboard. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `client_user_id` | string |  |
| `created_at` | string |  |
| `id` | string |  |
| `shareable_url` | string |  |
| `status` | string |  |
| `template_id` | string |  |

Also retrieved by: "run a kyc check on this new user", "start the id and selfie check before onboarding them", "vet this person before we let them in".

### `plaid.get_identity_verification`

Check the status and per-step results of an identity verification session: whether the document check, selfie check, and watchlist screen passed. Use when the user asks if someone's identity verification is done or why it failed.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /identity_verification/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `identity_verification_id` | string | **yes** | Identity verification session id to check. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `client_user_id` | string |  |
| `id` | string |  |
| `status` | string |  |
| `steps` | object |  |
| `steps.accept_tos` | string |  |
| `steps.documentary_verification` | string |  |
| `steps.kyc_check` | string |  |
| `steps.selfie_check` | string |  |
| `steps.verify_sms` | string |  |

Also retrieved by: "did they pass the id check", "why did their verification session fail", "check the status of someone's kyc screening".

### `plaid.retry_identity_verification`

Start a fresh attempt for a user whose identity verification session failed or expired, reusing the same template. Use when the user wants to retry, redo, or give someone another shot at verification instead of starting an unrelated new session with create_identity_verification.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /identity_verification/retry`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `client_user_id` | string | **yes** | Client user id from the failed or expired session. |
| `template_id` | string | **yes** | Identity Verification template to retry against. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `id` | string |  |
| `shareable_url` | string |  |
| `status` | string |  |

Also retrieved by: "give them another shot at the id check", "their verification expired, let them try again", "redo the kyc flow for this user".

### `plaid.get_categories`

List every transaction category Plaid uses to classify spending, with its hierarchy, e.g. "Food and Drink > Restaurants". Use when the user asks what spending categories exist or wants to map a category id to its name.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /categories/get`.

Takes no arguments.

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `categories` | array of object |  |
| `categories[].category_id` | string |  |
| `categories[].group` | string |  |
| `categories[].hierarchy` | array of string |  |

Also retrieved by: "what spending categories exist", "list every way transactions get classified", "show the category hierarchy for restaurants and shopping".

### `plaid.get_webhook_verification_key`

Fetch the public key used to verify that a received webhook actually came from Plaid. Use when the user, or the app on their behalf, needs to check a webhook's signature before trusting its payload.

Class `read` (reads only). No scopes beyond the connection's defaults. Calls `POST /webhook_verification_key/get`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `key_id` | string | **yes** | Key id from the "kid" field of the webhook's JWT header. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `key` | object |  |
| `key.alg` | string |  |
| `key.kid` | string |  |
| `key.kty` | string |  |
| `key.use` | string |  |
| `request_id` | string |  |

Also retrieved by: "make sure this webhook really came from plaid", "I need the key to check a signature", "verify this notification wasn't spoofed".

### `plaid.create_processor_token`

Create a processor token for one account, to hand a linked bank account to a payment partner such as Dwolla or Wise instead of Plaid itself. Use when the user wants to connect a linked account onward to a payments or payroll partner.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /processor/token/create`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the item the account belongs to. |
| `account_id` | string | **yes** | Account id within the item to create a processor token for. |
| `processor` | string | **yes** | Partner name the token is scoped to, e.g. "dwolla" or "wise". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `processor_token` | string |  |
| `request_id` | string |  |

Also retrieved by: "hand this account off to dwolla", "connect the linked bank onward to our payments partner", "generate a token so wise can use this account".

### `plaid.sandbox_create_public_token`

Mint a test public_token for a sandbox institution, standing in for a real Link session. Use when the user wants to test, simulate, or script a bank connection without actually running Link. Exchange it the normal way with exchange_public_token.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /sandbox/public_token/create`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `initial_products` | array of string | **yes** | Products to enable on the simulated item, e.g. ["transactions"]. |
| `institution_id` | string | **yes** | Sandbox institution id to simulate, e.g. "ins_109508". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `public_token` | string |  |
| `request_id` | string |  |

Also retrieved by: "fake a bank connection for testing", "mint a test token without opening the real popup", "simulate someone linking a bank in the test environment".

### `plaid.sandbox_fire_webhook`

Force a specific webhook to fire for a sandbox item, without waiting for the real trigger condition. Use when the user is testing webhook handling and wants to simulate, trigger, or replay a specific event code on demand.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /sandbox/item/fire_webhook`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the sandbox item to fire the webhook on. |
| `webhook_code` | string | **yes** | Webhook code to simulate, e.g. "DEFAULT_UPDATE" or "SYNC_UPDATES_AVAILABLE". |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `request_id` | string |  |
| `webhook_fired` | boolean |  |

Also retrieved by: "trigger that notification manually for testing", "make the callback fire so I can test our handler", "simulate the update event without waiting for it".

### `plaid.sandbox_reset_login`

Force a sandbox item into a login-required error state, to test how the app handles a broken connection and update-mode Link. Use when the user wants to simulate, reproduce, or test an expired login without waiting for a real bank session to lapse.

Class `write` (writes, no confirmation needed). No scopes beyond the connection's defaults. Calls `POST /sandbox/item/reset_login`.

Arguments:

| Argument | Type | Required | Notes |
| --- | --- | --- | --- |
| `access_token` | string | **yes** | Access token for the sandbox item to break. |

Result fields (the payload is trimmed to these before it reaches the model):

| Field | Type | Notes |
| --- | --- | --- |
| `request_id` | string |  |
| `reset_login` | boolean |  |

Also retrieved by: "break this test connection on purpose", "simulate an expired login for our test suite", "force a re-auth prompt so I can test that flow".
