---
title: "Data mapping guide | Plaid Docs"
description: "Avoid common mapping errors and learn how to handle complex mapping edge cases"
canonical: "https://plaid.com/core-exchange/docs/data-mapping-guide/"
---

Data mapping guide 
===================

#### Avoid common mapping errors and learn how to handle complex mapping edge cases 

Common mapping mistakes to avoid 
---------------------------------

### Sending only the required fields 

Send every field you can. The more fields you provide, the better data quality your customers will experience when using Plaid-powered apps. Sending just the required fields alone is the most common source of avoidable rework when integrating with Core Exchange.

### Reusing one transactionId across two transactions 

A `transactionId` must be unique within the account, and the `PENDING` and `POSTED` versions of the same transaction need different IDs.

When two transactions share an ID, the entire transactions response fails validation, so your customer receives no transactions at all. The usual cause is a pair of offsetting entries: a debit and a credit with the same amount, description, and timestamps, posted under a single ID. Give each entry its own ID.

### Using the wrong debitCreditMemo 

`amount` is an absolute value, so `debitCreditMemo` is the only thing that tells Plaid which direction money moved. `DEBIT` means money left the account, and `CREDIT` means money entered it. Don't signal direction by sending a negative `amount`.

### Putting an account in the wrong container 

If your `accountType` looks right but validation rejects the response, check the container field holding the account, not just the `accountType` inside it: the `accountCategory` if using API version 6.0 or later, or the wrapper key such as `depositAccount` when using version 5.x or earlier. Make sure the container name is spelled correctly (with no typos) and corresponds to a valid enum value for that account type. For example, `LOAN_ACCOUNT` with a `CREDITCARD` `accountType` fails, because `CREDITCARD` isn't a `LoanAccountType`.

### Omitting principalBalance on a loan account, or sending the origination amount 

Loan accounts have no `currentBalance` field. Instead, `principalBalance` is required on every loan account. Two common mistakes:

*   Omitting `principalBalance`. Customers see a $0 or empty balance on a loan they know carries a balance.
*   Setting `principalBalance` as the origination amount instead of the current outstanding balance. The origination amount should go in the `originalPrincipal` field.

### Reporting available credit as a line of credit's balance 

On a line of credit, the three balance figures are distinct, and HELOCs in particular are often mapped incorrectly:

*   `currentBalance` is the amount the customer currently owes.
*   `availableCredit` is what's left to borrow. It's required on every account type except `CHARGE`, and omitting it on the others fails validation for the whole accounts response.
*   `creditLine` is the credit limit.

### Timestamps that omit the UTC offset, or that deviate from RFC 3339 

Timestamp fields take an ISO 8601 date-time in the form `YYYY-MM-DDThh:mm:ss.nnn[Z|[+|-]hh:mm]`, and date fields take `YYYY-MM-DD`. Both follow [IETF RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6) .

Deviations that Plaid encounters regularly include placeholder offset values, offsets written without the colon (`-0400`), ISO 8601 basic-form dates (`20260420`), a date-only value in a field that expects a full timestamp, and a number instead of a date-time string. Sending incorrect values may cause Plaid to reject the entire transaction, or to associate the transaction with the wrong date.

### An accountNumberDisplay that isn't the last four digits 

Plaid expects the last four digits of this masked number to match the last four digits of the account number. Values that break this include a currency code, a differently-truncated number such as the first eight digits of a twelve-digit account number, and a number carrying separators.

Your customers rely on the mask to recognize their accounts and to detect accounts they've already linked. A mask that changes can also cause the account churn described under [accountId](https://plaid.com/core-exchange/docs/data-mapping-guide/index.html.md#whats-the-difference-between-accountid-accountnumber-accountnumberdisplay-and-identifier) below.

### Returning an empty /accounts/{accountId}/contact response 

`holders`, `emails`, `addresses`, and `telephones` are all required, and each needs at least one entry. An empty response fails validation, which fails Identity for the whole account. If your customer records regularly have no email or telephone on file, tell Plaid before you launch.

### Omitting joint account holders 

List every owner of the account in `holders`, each with the `relationship` that describes them. Two common errors are returning only one holder for a jointly held account, and marking a sole owner `SECONDARY`.

Note that Plaid doesn't associate `emails`, `addresses`, or `telephones` with individual holders, so contact details for every owner belong in those account-level arrays.

### Returning fully divested positions as holdings 

A holding represents a position the customer currently holds. When a sold-out position stays in the `holdings` array with `units` and `marketValue` set to `0`, Plaid passes it through as a live holding, and because most systems keep repricing it, the customer sees a position they no longer own with a price that updates daily. Omit positions the customer has fully divested.

### Reporting borrowing power as available cash 

`availableCashBalance` is the cash held across all sub-accounts, including sweep funds. On a margin-enabled account, don't map buying power or margin availability into it: doing so reports borrowed funds as cash the customer holds. Likewise, `currentValue` is the total current value of all investments, not the account's purchasing power.

A cash or sweep position also needs `cashAccount` set to `true`, or an explicit `isCashEquivalent` value in `fiAttributes`, so that Plaid can classify it as cash rather than as a security.

Data mapping FAQs 
------------------

### What if we can't source a required field, such as availableBalance? 

If you can't provide a required field, contact Plaid to discuss possible solutions. Don't omit the field and don't substitute a value you do have.

### Are credit cards a line of credit or a loan? 

In Core Exchange, if the customer can pay the balance down and draw on it again, use line of credit; if they can only pay it off, use loan. Credit cards therefore correspond to a line of credit with `accountType` `CREDITCARD`, under `accountCategory` `LOC_ACCOUNT` (or the `locAccount` wrapper key if using an API version earlier than 6.0).

### What's the difference between accountId, accountNumber, accountNumberDisplay, and identifier? 

`accountId` is the account's long-term identity within your organization. It isn't an account number, shouldn't be derived from one, and should never change, even if the account number changes. If it changes, Plaid sees a new account rather than the same one, which causes "account churn" and disruption for your customers using Plaid-linked accounts for long-lived use cases, such as personal financial management.

`accountNumberDisplay` is the masked number your customer recognizes.

`accountNumber` is the full account number, and is only used for loan accounts.

For depository accounts, the account number should be returned in the `identifier` field of `GET /accounts/{accountId}/payment-networks`. If this number ever changes, begin returning the new number, and Plaid will detect the new number if it ever changes.

### How much transaction history should we serve? 

Serve as much as your systems retain, up to 24 months. Use cases such as mortgage underwriting and cash flow analysis depend on the full two years being available. Sending more than 24 months does not cause an error, but is unnecessary: Plaid will simply discard any transaction data beyond 730 days.

Note: when Plaid requests a start date older than you support, return the FDX `invalid date range` error, code `703`, with an HTTP 400 status. Returning a shorter window or an empty array instead can look like missing transactions data and result in support tickets.

### How should we model multi-currency or foreign currency accounts? 

Every account has exactly one required `currency.currencyCode`, so there's no way to express a single account holding several currencies.

Supported payment networks compatible with Core Exchange cover US and Canadian rails only. Accounts denominated in currencies other than USD or CAD can be listed with balances and transactions, but they aren't Auth-eligible. If your product is built around multi-currency or non-North-American rails, consult with Plaid before you build.

### Our security has no CUSIP, ISIN, SEDOL, or ticker. What do we send? 

Some securities, such as private funds, non-traded partnerships, and physical collectibles may not have identifier symbols. In this case, set `holdingName` to the security's name, `holdingType` to `OTHER`, and `units` to the number held, and omit `symbol` along with `securityIds` (or `securityId` and `securityIdType` if using an API version earlier than 6.0).

Example

```json
{
  "holdingName": "1794 Flowing Hair Dollar",
  "holdingType": "OTHER",
  "units": 1,
  "marketValue": 7500000.00,
  "cashAccount": false,
  "currency": {
    "currencyCode": "USD"
  }
}
```