API template library

Plaid Items & Webhooks mock API and live sandbox

A WireMock simulation of Plaid's REST API — covering Item import, inspection, webhook management, access-token rotation, and removal.

Vendor
Plaid
Functionality
Item lifecycle and webhooks
Spec version
2020-09-14_1.688.6
Endpoints
7
Stubs
11
Protocol
REST
Validation
AI-validated Before publication, an AI agent exercised these endpoints against the real Plaid API through WireMock's recording proxy, and the recorded traffic was used to verify each stub's request and response shapes.

Live sandbox · no signup, no API key

Plaid Items & Webhooks

A running WireMock Cloud instance of this template, callable right now from a terminal, a script, or an AI agent.

Base URL
https://98wm4.wiremockapi.cloud

POST Import Item

curl -s -X POST 'https://98wm4.wiremockapi.cloud/item/import' \
  -H 'Content-Type: application/json' \
  -d '{}'

POST Get Webhook Verification Key

curl -s -X POST 'https://98wm4.wiremockapi.cloud/webhook_verification_key/get' \
  -H 'Content-Type: application/json' \
  -d '{}'

POST Handle Fraud Report

curl -s -X POST 'https://98wm4.wiremockapi.cloud/item/handle_fraud_report' \
  -H 'Content-Type: application/json' \
  -d '{}'
Method Path Summary
POST /item/access_token/invalidate Invalidate access_token
POST /item/get Retrieve an Item
POST /item/handle_fraud_report Report fraud for an Item
POST /item/import Import Item
POST /item/remove Remove an Item
POST /item/webhook/update Update Webhook URL
POST /webhook_verification_key/get Get webhook verification key

Unauthenticated WireMock Cloud demo sandbox for Plaid — not an official Plaid sandbox, and it returns simulated example data only.

What's inside the Items & Webhooks template

Seven endpoints, and the registry behind them is live. /item/import issues a fresh access-sandbox token on every call, and that token becomes the key to everything else: /item/get answers with the full Item record — institution, billed and consented products, the status block with its last-webhook entry — for tokens the registry knows, and with Plaid's INVALID_ACCESS_TOKEN envelope for ones it doesn't. Writes stick, too: a URL changed through /item/webhook/update appears in every later read, /item/access_token/invalidate retires a credential and hands back a working successor, and /item/remove ends the record for good.

  • Item records — the /item/get envelope with products, consented scopes, and webhook status, gated by the token registry
  • Import — per-call token issuance — the entry point that seeds everything else
  • Webhook management — an update route whose new URL persists across reads, plus the ES256 JWK from the verification-key route
  • Token rotation — invalidate retiring one credential and issuing its replacement
  • Removal & fraud — the remove ack that revokes access, and a minted report id from the fraud-report route

Example implementation using plaid-python

The whole lifecycle runs through plaid-python with nothing changed but the host — import an Item, read it back, rotate its credential:

Credential rotation is the piece of Plaid plumbing teams most often ship untested, because in production it only runs when something has gone wrong. Here the invalidate path executes on every CI push: old token in, working replacement out, and the retired token verifiably dead on the next read.

A WireMock Cloud copy of the template drops into the same host field when a test needs an Item in a specific error state — ITEM_LOGIN_REQUIRED on the get route, say — which the shared instance's always-healthy records never show.

import plaid
from plaid.api import plaid_api
from plaid.model.item_import_request import ItemImportRequest
from plaid.model.item_import_request_user_auth import ItemImportRequestUserAuth
from plaid.model.item_get_request import ItemGetRequest
from plaid.model.item_access_token_invalidate_request import ItemAccessTokenInvalidateRequest
from plaid.model.products import Products

configuration = plaid.Configuration(
    host="https://98wm4.wiremockapi.cloud",
    # required by the client, ignored by the mock
    api_key={"clientId": "any-value", "secret": "any-value"},
)
client = plaid_api.PlaidApi(plaid.ApiClient(configuration))

imported = client.item_import(
    ItemImportRequest(
        products=[Products("identity")],
        user_auth=ItemImportRequestUserAuth(
            user_id="user-123", auth_token="token-123"
        ),
    )
)
token = imported.access_token

item = client.item_get(ItemGetRequest(access_token=token))
print(item.item.institution_name, item.item.webhook)

rotated = client.item_access_token_invalidate(
    ItemAccessTokenInvalidateRequest(access_token=token)
)
print("new token:", rotated.new_access_token)

Frequently asked questions

The route checks its token against the registry that /item/import feeds, and nothing else passes. Call import first and use the token it returns; a token from Plaid's own sandbox, or one you invented in the right format, draws the 400 no matter how plausible it looks.

Yes — the store writes it. Change the URL, read the Item again, and the new address is there, so a read-after-write test asserts something the mock actually did rather than a canned reply. The same persistence applies to removal and rotation.

In production Plaid signs webhook bodies with a JWT, and this route serves the public JWK a verifier fetches to check the signature. The sandbox returns a syntactically valid ES256 key with an empty kid — enough to exercise fetch-and-cache logic, though no signed webhook traffic ever originates from a mock for it to verify.

From the Link exchange, which belongs to the Link & Tokens template. Note that its minted tokens and this registry are separate: an exchange performed there does not unlock /item/get here, so a cross-template test should import on this instance rather than carry tokens over.

Vendor names identify APIs represented by WireMock template sources. This page does not imply vendor endorsement, certification, partnership, or official integration status.