Migrate from Transactions to Plaid Consumer Report 
===================================================

#### Switch to CRA Base Report for FCRA-compliant reporting with enhanced data coverage 

This guide will walk you through how to migrate from accessing bank data with Plaid's [Transactions](https://plaid.com/products/transactions/) product to generating Base Reports with Plaid's [Consumer Report](https://plaid.com/check/income-and-underwriting/) product.

The CRA Base Report includes account balance, account ownership, and transaction data, and is designed for use cases that require FCRA-compliant consumer reporting, such as tenant screening, income verification, and credit decisioning.

#### Why migrate? 

While the Transactions product gives you historical transaction data, the CRA Base Report enhances this by:

*   Supporting FCRA-compliant usage
*   Bundling additional data (identity, balance, account metadata) in a single report
*   Managing the explicit consumer consent and disclosures required for underwriting use cases in the US

If your use case involves evaluating the financial standing of US-based end users for underwriting, credit, or leasing, you should use the CRA Base Report instead of Transactions.

#### Prerequisites 

1.  To use Consumer Report, it is strongly recommended to update your Plaid client library to the latest version. The minimum required versions for new Consumer Report integrations are:
    
    *   Python: 38.0.0
    *   Go: 41.0.0
    *   Java: 39.0.0
    *   Node: 41.0.0
    *   Ruby: 45.0.0
2.  [Confirm](https://dashboard.plaid.com/settings/team/products) you have access to Plaid Check products in Production. If not, [request access via the Dashboard](https://dashboard.plaid.com/overview/request-products) .
    

#### Changes to Plaid Link initialization 

When using Plaid Check products, you must create a user before initializing Link. This allows Plaid to associate multiple Items with a single user.

1.  Call [/user/create](https://plaid.com/docs/api/users/index.html.md#usercreate) before [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) .
    
    *   Include the `identity` object. At minimum, the following fields must be provided and non-empty: `name`, `date_of_birth`, `emails`, `phone_numbers`, and `addresses` (with at least one email address, phone number, and address designated as `primary`). If you intend to share the report with a GSE (Government-Sponsored Enterprise) such as Fannie or Freddie, the full SSN is also required via the `id_numbers` field. For all use cases, providing at least a partial SSN is highly recommended, since it improves the accuracy of matching user records during compliance processes such as file disclosure, dispute, or security freeze requests.
    *   Store the `user_id` in your database.
2.  Update your [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) call:
    
    *   Remove the `transactions` object (if present) from the call.
    *   Include the `user_id` from [/user/create](https://plaid.com/docs/api/users/index.html.md#usercreate) .
    *   Replace `transactions` with `cra_base_report` (and any other CRA products) in the `products` array.
    *   Add a `cra_options` object with `days_requested` (min 180).
    *   Provide a `consumer_report_permissible_purpose`.
    *   (Optional) To allow multi-institution linking, set `enable_multi_item_link` to `true`.

```node
const request: LinkTokenCreateRequest = {
  loading_sample: true
};
try {
  const response = await plaidClient.linkTokenCreate(request);
  const linkToken = response.data.link_token;
} catch (error) {
  // handle error
}
```

```python
request = LinkTokenCreateRequest(
  loading_sample=True
)
# create link token
response = client.link_token_create(request)
link_token = response['link_token']
```

```bash
curl -X POST https://sandbox.plaid.com/link/token/create -H 'Content-Type: application/json' -d '{
  "client_id": "${PLAID_CLIENT_ID}",
  "secret": "${PLAID_SECRET}",
  "loading_sample": true
}'
```

```ruby
link_token_create_request = Plaid::LinkTokenCreateRequest.new(
  {
    loading_sample: true
  }
)

response = client.link_token_create(
  link_token_create_request
)
link_token = response.link_token
```

```java
LinkTokenCreateRequest request = new LinkTokenCreateRequest()
  .loadingSample(true);

Response response = client
  .linkTokenCreate(request)
  .execute();

String linkToken = response.body().getLinkToken();
```

```go
request := plaid.NewLinkTokenCreateRequest(
  "Sample App App",
  "en",
  []plaid.CountryCode{plaid.COUNTRYCODE_US},
  user,
)
request.SetLoadingSample(true)

linkTokenCreateResp, _, err := client.PlaidApi.LinkTokenCreate(ctx).LinkTokenCreateRequest(*request).Execute()
if err != nil {
  panic(err)
}
linkToken := linkTokenCreateResp.GetLinkToken();
```

##### Adding Consumer Report alongside Transactions on existing Items 

If you want an existing Transactions-enabled Item to also be enabled for Consumer Report (keeping both products active on the same Item), call [/user/create](https://plaid.com/docs/api/users/index.html.md#usercreate) and [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) as described above, but include the Item's `access_token` when calling [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) . When Link is launched, the end user will go through the Consumer Report consent flow, and on successful completion of the flow, the Item will be enabled for Consumer Report in addition to Transactions.

#### Update product API calls and webhook listeners 

1.  Update your webhook listener endpoints, adding listeners for Plaid Check.
    
    *   Upon receiving the [USER\_CHECK\_REPORT\_READY](https://plaid.com/docs/api/products/check/index.html.md#user_check_report_ready) webhook, call product endpoints such as [/cra/check\_report/base\_report/get](https://plaid.com/docs/api/products/check/index.html.md#cracheck_reportbase_reportget) or (if using) [/cra/check\_report/partner\_insights/get](https://plaid.com/docs/api/products/check/index.html.md#cracheck_reportpartner_insightsget) .
        
    *   Upon receiving the [USER\_CHECK\_REPORT\_FAILED](https://plaid.com/docs/api/products/check/index.html.md#user_check_report_failed) webhook, call [/user/items/get](https://plaid.com/docs/api/users/index.html.md#useritemsget) to determine why Items are in a bad state. If appropriate, send the user through [update mode](https://plaid.com/docs/link/update-mode/index.html.md) to repair the Item.
        
2.  If you're still using other Plaid products like [Auth](https://plaid.com/products/auth/) or [Balance](https://plaid.com/products/balance/) on the same Item, continue exchanging the public token for an access token after Link. (Note that public token exchange is also still required to obtain an access token for Plaid Check itself.)
    

#### Mapping API responses 

This [Google Sheet](https://docs.google.com/spreadsheets/d/1toj71Afemtu0rSjgh7AAGgBcZC7U0vYXKCDvKSSWTls/edit?gid=820738585#gid=820738585) highlights the correspondences between Transactions and CRA Base Report schemas.

If you are using other Plaid Inc. products, note that the `account_id` returned in API responses from endpoints prefixed with `/cra/` will not match the `account_id` returned in responses from non-CRA Plaid endpoints.

#### Migrating existing Items fully off Transactions 

If you want to replace Transactions with Plaid Check on an existing Item (rather than running both alongside, as described above), there is no way to do this directly. Instead, you must delete the old Item using [/item/remove](https://plaid.com/docs/api/items/index.html.md#itemremove) and prompt the user to go through the Link flow again, using a Link token that is enabled for Plaid Check.

If you are ready to migrate all Items, use [/item/remove](https://plaid.com/docs/api/items/index.html.md#itemremove) to delete the Transactions-enabled Items, and prompt your users to return to your app to re-add their accounts using the new Plaid Check-enabled flow. You can also perform this process in stages, disabling only a percentage of Items at a time.

The most conservative gradual migration strategy is to not delete the Transactions-enabled Item until it is in an unhealthy state that requires user interaction to fix (e.g. `ITEM_LOGIN_REQUIRED`). At that time, instead of sending the Item through update mode, delete the Item using [/item/remove](https://plaid.com/docs/api/items/index.html.md#itemremove) and prompt your users to re-add their accounts using the new Plaid Check-enabled flow.

#### Removing Transactions logic for existing Items 

Depending on your use case and business, you may want to leave existing Transactions-enabled Items in place and perform a gradual migration, as described above. Do not remove Transactions logic unless you are no longer using any Transactions-enabled Items.

1.  Remove handling for Transactions webhooks, including `SYNC_UPDATES_AVAILABLE`, `INITIAL_UPDATE`, `HISTORICAL_UPDATE`, `DEFAULT_UPDATE`, `TRANSACTIONS_REMOVED`, and `RECURRING_TRANSACTIONS_UPDATE`.
    
2.  Remove calls to `/transactions/` endpoints such as [/transactions/get](https://plaid.com/docs/api/products/transactions/index.html.md#transactionsget) , [/transactions/sync](https://plaid.com/docs/api/products/transactions/index.html.md#transactionssync) , or [/transactions/recurring/get](https://plaid.com/docs/api/products/transactions/index.html.md#transactionsrecurringget) , as well as any handling for transactions-specific logic, such as transactions updates and pagination.
    
3.  Remove handling for the `TRANSACTIONS_SYNC_MUTATION_DURING_PAGINATION` error.
    
4.  If you have existing Transactions-enabled Items you will no longer be using, call [/item/remove](https://plaid.com/docs/api/items/index.html.md#itemremove) to delete these Items so you will no longer be billed for Transactions.