{"id":62,"library":"plaid-python","title":"Plaid","description":"Official Python client for the Plaid API (bank account linking, transactions, identity, income verification). Auto-generated from OpenAPI spec. Updated monthly, major versions contain breaking changes. Only supports the 2020-09-14 API version (no version selection in client — API version is fixed per SDK release).","status":"active","version":"38.3.0","language":"python","source_language":"en","source_url":"https://github.com/plaid/plaid-python","tags":["payments","banking","fintech","plaid","open-banking","python","transactions"],"install":[{"cmd":"pip install plaid-python","lang":"bash","label":"Python"}],"dependencies":[{"reason":"HTTP client used internally.","package":"urllib3","optional":false}],"imports":[{"note":"Old Client() class was removed in v8.0.0 (August 2021). All pre-v8 import patterns fail. The new pattern requires Configuration + ApiClient + PlaidApi.","wrong":"from plaid import Client\nclient = Client(client_id=..., secret=..., environment='sandbox')","symbol":"PlaidApi","correct":"import plaid\nfrom plaid.api import plaid_api\n\nconfiguration = plaid.Configuration(\n    host=plaid.Environment.Sandbox,\n    api_key={'clientId': CLIENT_ID, 'secret': SECRET}\n)\napi_client = plaid.ApiClient(configuration)\nclient = plaid_api.PlaidApi(api_client)"}],"quickstart":{"code":"import plaid\nfrom plaid.api import plaid_api\nfrom plaid.model.transactions_sync_request import TransactionsSyncRequest\nimport json\n\nconfiguration = plaid.Configuration(\n    host=plaid.Environment.Sandbox,  # or Production\n    api_key={\n        'clientId': 'your_client_id',\n        'secret': 'your_secret'\n    }\n)\napi_client = plaid.ApiClient(configuration)\nclient = plaid_api.PlaidApi(api_client)\n\n# Sync transactions\nrequest = TransactionsSyncRequest(access_token='access-sandbox-...')\nresponse = client.transactions_sync(request)\ntransactions = response.added\n\n# Error handling\ntry:\n    response = client.transactions_sync(request)\nexcept plaid.ApiException as e:\n    error = json.loads(e.body)\n    print(error['error_code'])  # e.g. 'ITEM_LOGIN_REQUIRED'","lang":"python","description":"Plaid uses strongly-typed request/response models. Each endpoint has its own request model (e.g. TransactionsSyncRequest). Import the specific model for each call."},"warnings":[{"fix":"Use Configuration + ApiClient + PlaidApi pattern. See README for current quickstart.","message":"v8.0.0 (August 2021) completely removed the old Client class and all previous import patterns. Any tutorial using 'from plaid import Client' or 'Client(client_id=..., secret=..., environment=...)' fails with ImportError.","severity":"breaking","affected_versions":"< 8.0.0"},{"fix":"Pin to a specific version in production: pip install plaid-python==38.3.0. Monitor changelog before upgrading major versions.","message":"plaid-python ships a major version (x.0.0) roughly monthly. Major versions may include breaking changes — new required fields, renamed parameters, or removed endpoints. Unpinned installs will auto-upgrade.","severity":"breaking","affected_versions":"all"},{"fix":"Import the model for each endpoint: from plaid.model.transactions_sync_request import TransactionsSyncRequest, then pass an instance.","message":"Each endpoint requires importing its specific request model. Passing a plain dict instead of the typed request object raises a TypeError. Old-style dict-based calls from pre-v8 tutorials do not work.","severity":"breaking","affected_versions":">= 8.0.0"},{"fix":"Get environment-specific secrets from Plaid Dashboard > Team Settings > Keys. Store separately as PLAID_SECRET_SANDBOX and PLAID_SECRET_PRODUCTION.","message":"Sandbox and Production have separate API secrets. The client_id is shared but the secret differs per environment. Using the wrong secret for an environment returns 401.","severity":"gotcha","affected_versions":"all"},{"fix":"Access typed attributes: response.added for new transactions, response.next_cursor for pagination cursor, etc.","message":"Plaid API responses are typed objects, not dicts. Code trying to access response['transactions'] fails with TypeError. Attributes are accessed as response.added, response.modified, etc.","severity":"gotcha","affected_versions":">= 8.0.0"},{"fix":"Monitor Plaid changelog for beta product changes. For GA products, upgrade SDK major versions intentionally, not automatically.","message":"Beta product APIs (e.g. Assets, CRA) are subject to breaking changes without versioning, with 30 days notice. GA products are versioned but the SDK fixes to a single API version — there is no per-request API version override.","severity":"gotcha","affected_versions":"all"}],"env_vars":{"optional":[{"name":"PLAID_ENV","note":"Convention for storing 'sandbox' or 'production'. Map to plaid.Environment.Sandbox or plaid.Environment.Production."}],"required":[{"name":"PLAID_CLIENT_ID","note":"Client ID from Plaid Dashboard. Used in api_key dict."},{"name":"PLAID_SECRET","note":"Secret key for the target environment (Sandbox and Production have separate secrets)."}]},"last_verified":"2026-05-12T06:19:08.174Z","next_check":"2026-04-01T00:00:00.000Z","problems":[{"fix":"import plaid","cause":"The `plaid-python` package is installed as `plaid`, so the import statement should use `import plaid`.","error":"ModuleNotFoundError: No module named 'plaid'"},{"fix":"import plaid\n# ...\nclient = plaid.PlaidApi(api_client)","cause":"The `PlaidApi` class was moved to be directly under the `plaid` module in recent versions (e.g., v30+); the old import path is no longer valid.","error":"ImportError: cannot import name 'PlaidApi' from 'plaid.api.plaid_api'"},{"fix":"Verify that your `CLIENT_ID`, `SECRET`, and `ENVIRONMENT` variables are correctly set and correspond to a valid Plaid application's credentials.","cause":"The configured Plaid `client_id` is either incorrect, missing, or does not match the specified environment (e.g., Sandbox, Development, Production).","error":"\"error_code\":\"INVALID_CLIENT_ID\""},{"fix":"Ensure the `LinkTokenCreateRequestUser` object correctly includes a unique `client_user_id` string, for example: `LinkTokenCreateRequestUser(client_user_id='unique-user-id')`.","cause":"When creating a `LinkTokenCreateRequest`, the `user` object's `client_user_id` field is mandatory and was either not provided or was provided incorrectly.","error":"\"missing required field 'user.client_user_id'\""}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":8.4,"disk_size":"76.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":8.4,"disk_size":"77M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":9.7,"disk_size":"85.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.39,"mem_mb":9.7,"disk_size":"86M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.42,"mem_mb":10.3,"disk_size":"74.4M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":10.3,"disk_size":"75M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":10.4,"disk_size":"73.8M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.4,"mem_mb":10.4,"disk_size":"74M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.3,"mem_mb":8.2,"disk_size":"76.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":8.2,"disk_size":"77M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}