> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synctera.com/llms.txt
> Use this file to discover all available pages before exploring further.

# External Accounts

> External accounts represent a customer's accounts at other financial institutions. Verify ownership through Plaid or Finicity, then check balances and transactions or move money via ACH.

## Overview

An external account is a customer's account at another financial institution — checking, savings, credit card, or investment. To use one, you must **verify ownership**. Synctera has partnered with Plaid and Finicity to verify ownership and retrieve balance and transaction information.

**Verifying an external account** unlocks capabilities such as balance checks before issuing ACH debits (to reduce overdrafts) and account-owner validation. You can originate ACH credits without verifying the owner, but ACH debits require the customer to have verified that they own the external account.

Key characteristics:

* **Ownership-verified** — accounts are linked through Plaid Link or Finicity Connect, which confirm the customer controls the account.
* **Vendor-backed** — link through `PLAID` or `FINICITY`; each has slightly different flows.
* **Actionable** — once added, you can list transactions and fetch balances (except for micro-deposit links).
* **Manageable** — accounts can be listed, viewed, updated (for manual accounts), synced, and deleted.

<Info>
  If you use another provider such as MX, you can create external accounts directly by posting to the `/v0/external_accounts` API. Synctera confirms that customers validate ownership of the external account as part of the launch process.
</Info>

## Prerequisites

This guide assumes you have:

* Created a [personal customer](/docs/create-a-personal-customer) or [business customer](/docs/create-a-business)

You should also be familiar with:

* [Need to Know — Environments](/reference/need-to-know#environments)
* [Need to Know — Authentication](/reference/need-to-know#authentication)

Throughout, provide `customer_id` for personal customers or `business_id` for business customers. If you have not created a customer yet, do so first via the [Customer API](/reference/createcustomer).

<Info>
  **Plaid vs Finicity.** Both provide similar services; the main difference is account linking. Plaid Link requires you to integrate Plaid's SDKs directly. Finicity Connect is a web interface hosted by Finicity where users enter their account credentials. Note that **micro-deposits are only supported by Plaid**.
</Info>

## Verification steps (Plaid)

<Steps>
  <Step title="Request a link token and launch Plaid Link">
    A link token is the first step to verifying an external account; it grants access to Plaid Link, the UI where customers provide their bank details. Integrate [Plaid Link](https://plaid.com/docs/link/) ([Android](https://plaid.com/docs/link/android/), [iOS](https://plaid.com/docs/link/ios/), [WebView](https://plaid.com/docs/link/webview/), [React Native](https://plaid.com/docs/link/react-native/), [web](https://plaid.com/docs/link/web/)), or use our [test page](https://app.synctera.com/widgets/plaid-link) to try calls before integrating.

    Request a link token with [Create Link Token](/reference/createverificationlinktoken):

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/link_tokens \
      --data-binary '
      {
        "client_name": "Name of your application",
        "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
        "country_codes": ["US"],
        "type": "DEPOSITORY",
        "language": "EN"
      }'
    ```

    The `type` of link token determines what kind of account can be verified:

    | Type            | Use                                                                                                                                                           |
    | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `DEPOSITORY`    | Checking and savings accounts.                                                                                                                                |
    | `MICRO_DEPOSIT` | Depository accounts verified via micro-deposits — for institutions without instant verification, or when the customer prefers not to share login credentials. |
    | `CREDIT`        | Credit card accounts.                                                                                                                                         |
    | `INVESTMENT`    | Investment accounts.                                                                                                                                          |

    ```json theme={"system"}
    {
      "client_name": "Name of your application",
      "country_codes": ["US"],
      "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
      "expiration": "2022-03-08T21:29:13Z",
      "language": "EN",
      "link_token": "link-sandbox-b68c1a6f-c514-4535-9781-0c2b8e2281ad",
      "request_id": "Roius8bd2DeXq6D",
      "type": "DEPOSITORY",
      "verify_owner": false
    }
    ```

    Use the `link_token` to launch Plaid Link. When the customer confirms their account, Plaid sends an [onSuccess callback](https://plaid.com/docs/link/web/#onsuccess) with account metadata and a `public_token` — the input for the next step. (On the test page, enter the `link_token`, click **Link Account**, and the `public_token` appears at the top.)
  </Step>

  <Step title="Request an access token">
    The access token holds the details Plaid retrieved and lets you manage the account through Synctera. Create one with [Access Token](/reference/createaccesstoken). For all link token types **except** `MICRO_DEPOSIT`, Plaid's success response includes `vendor_public_token` and `vendor_institution_id`, which must be included here.

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/access_tokens \
      --data-binary '
      {
        "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
        "vendor_institution_id": "ins_3",
        "vendor_public_token": "public-sandbox-45524484-45f9-490e-bb44-aec4131f6fb8"
      }'
    ```

    ```json theme={"system"}
    {
      "customer_id": "17f4c82d-a398-48ed-a9c8-5bd9a53fe862",
      "request_id": "xsHszMQwyB4IbeP",
      "vendor_access_token": "access-sandbox-2fa1d335-2d85-4563-8faa-d5e2a022d4db",
      "vendor_customer_id": "17f4c82d-a398-48ed-a9c8-5bd9a53fe862",
      "vendor_institution_id": "ins_3",
      "vendor_public_token": "public-sandbox-46a9e08e-a153-4189-85ac-143f8061746b"
    }
    ```

    The response returns the `vendor_access_token`; verification is complete. For the micro-deposit variant, see [Micro-deposits flow](#micro-deposits-flow).
  </Step>

  <Step title="Add the verified external accounts">
    Persist the `vendor_access_token` and add the accounts the customer selected with [Add External Accounts](/reference/addvendorexternalaccounts). Include:

    * `customer_id` or `business_id` — the customer associated with these accounts.
    * `customer_type` — `PERSONAL` or `BUSINESS`.
    * `vendor` — `PLAID` for this flow.
    * `vendor_access_token` — from the previous step.
    * `vendor_account_ids` — the vendor account IDs the customer chose to link (Plaid `account_id`s).
    * `verify_owner` — whether to verify account-owner info against Synctera records. Not supported for business customers or the micro-deposit flow.

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/add_vendor_accounts \
      --data-binary '
      {
        "customer_id": "3bd1a112-a98e-49ab-831c-33278cab49fb",
        "customer_type": "PERSONAL",
        "vendor": "PLAID",
        "vendor_access_token": "access-sandbox-de3ce8ef-33f8-452c-a685-8671031fc0f6",
        "vendor_account_ids": ["blgvvBlXw3cq5GMPwqB6s6q4dLKB9WcVqGDGo"],
        "verify_owner": false
      }'
    ```

    The response lists both added and failed accounts, so check which succeeded:

    ```json theme={"system"}
    {
      "added_accounts": [
        {
          "id": "df0978ca-9816-4b3f-b3c1-9f1354e062fe",
          "customer_id": "1381e689-90ff-4176-8f65-a4a1225120ff",
          "nickname": "Home Loan Account",
          "type": "CHECKING",
          "status": "ACTIVE",
          "account_identifiers": {
            "iban": "LB7750793201TP7049N596464T98",
            "number": "78277121"
          },
          "account_owner_names": ["Jay Hansen"],
          "routing_identifiers": {
            "ach_routing_number": "756392185",
            "bank_countries": ["US"],
            "bank_name": "Chase",
            "eft_routing_number": "02101140",
            "swift_code": "CHASUS3AXXX",
            "wire_routing_number": "756392185"
          },
          "verification": {
            "status": "VERIFIED",
            "vendor": "PLAID"
          }
        }
      ],
      "failed_accounts": [
        {
          "reason": "FAILED_VERIFICATION",
          "reason_description": "string",
          "vendor_account_id": "blgvvBlXw3cq5GMPwqB6s6q4dLKB9WcVqGDGo",
          "vendor_error_message": "string",
          "vendor_request_id": "string"
        }
      ]
    }
    ```

    You can also retrieve all linked accounts with [List External Accounts](/reference/listexternalaccounts).
  </Step>
</Steps>

### Micro-deposits flow

Micro-deposits verify a depository account by depositing \$0.01 whose transaction description contains a code the customer must confirm. This flow assumes you have already created a `MICRO_DEPOSIT` link token and launched Plaid Link (choosing **Manual**, or **Link With Account Numbers**), entered the account information, and received a `public_token`.

<Steps>
  <Step title="Request an access token">
    Create an access token as usual, but because institution information is not returned in the micro-deposit flow, set `vendor_institution_id` to `"-"`:

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/access_tokens \
      --data-binary '
      {
        "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
        "vendor_institution_id": "-",
        "vendor_public_token": "public-sandbox-45524484-45f9-490e-bb44-aec4131f6fb8"
      }'
    ```

    The response returns the `vendor_access_token`. Wait up to 48 hours for the micro-deposit to arrive (or use the [test data](/docs/sandbox-external-account-test-cases#micro-deposit-testing-scenarios) to proceed immediately).
  </Step>

  <Step title="Create a second link token">
    Create another link token, this time including the `vendor_access_token`. This secondary token lets the customer enter the code from the micro-deposit's transaction description via Plaid Link.

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/link_tokens \
      --data-binary '
      {
        "type": "MICRO_DEPOSIT",
        "language": "EN",
        "client_name": "Name of your application",
        "country_codes": ["US"],
        "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
        "vendor_access_token": "access-sandbox-bf7436d8-8a18-4a11-a293-66cee2355eb6"
      }'
    ```

    Launch Plaid Link with this token and prompt the customer to submit the 3-letter code from the micro-deposit description.
  </Step>

  <Step title="Add the verified account">
    Once the code is submitted, verification is complete. Add the account as in the standard [Add the verified external accounts](#add-the-verified-external-accounts) step.
  </Step>
</Steps>

### Update mode

Update mode lets you re-authenticate a disconnected account or link additional accounts at the same bank. Create a new link token that includes both `vendor_institution_id` and `vendor_access_token`:

```shell theme={"system"}
curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/external_accounts/link_tokens \
  --data-binary '
  {
    "type": "DEPOSITORY",
    "language": "EN",
    "client_name": "Synctera",
    "country_codes": ["US"],
    "customer_id": "8bb5f852-5b53-4b0e-97f0-43bcb4f8532b",
    "vendor_institution_id": "ins_56",
    "vendor_access_token": "access-sandbox-23ac17ff-b4b7-4dce-8194-2e17f9656ccb"
  }'
```

Launch Plaid Link with the returned token: already-linked accounts appear in the list, and the customer can add or remove accounts. After submitting, you receive a new access token — use it to persist the changes with [Sync Vendor Accounts](/reference/syncvendorexternalaccounts).

## Verification steps (Finicity)

<Steps>
  <Step title="Request a Connect URL from Finicity">
    The Connect URL opens Finicity's hosted web interface where customers link their accounts. Request it with [Create Link Token](/reference/createverificationlinktoken):

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/link_tokens \
      --data-binary '
      {
        "client_name": "Name of your application",
        "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
        "country_codes": ["US"],
        "type": "DEPOSITORY",
        "language": "EN"
      }'
    ```

    Finicity supports `DEPOSITORY`, `CREDIT`, and `INVESTMENT` link tokens (no micro-deposits).

    ```json theme={"system"}
    {
      "client_name": "Name of your application",
      "country_codes": ["US"],
      "customer_id": "27b1bfd0-d83f-42bc-9b2a-a0241adcba9a",
      "expiration": "2022-03-08T21:29:13Z",
      "language": "EN",
      "link_token": "https://connect2.finicity.com?customerId=6003202401&experience=8ab62f1c-5f9b-4f3f-a20f-377aa28a8de2&origin=url&partnerId=2445583932772&signature=bdc6b061a8b25822de164fc857a74601c1c1f1b816d9200a8d14dd57c1095246&timestamp=1656025350309&ttl=1656032550309",
      "request_id": "Roius8bd2DeXq6D",
      "type": "DEPOSITORY",
      "verify_owner": false
    }
    ```

    Save the vendor customer ID for later — it is the `customerId` query parameter in the URL (here, `6003202401`).
  </Step>

  <Step title="Link the accounts">
    Load the returned URL so the customer can search for their financial institution, provide credentials, and link their accounts.
  </Step>

  <Step title="Add the external accounts">
    Persist the linked accounts with [Sync External Accounts](/reference/syncvendorexternalaccounts). Include:

    * `customer_id` or `business_id` — the customer associated with these accounts.
    * `customer_type` — `PERSONAL` or `BUSINESS`.
    * `vendor` — `FINICITY` for this flow.
    * `vendor_customer_id` — the customer ID returned by the vendor.
    * `verify_owner` — not supported for business customers.

    ```shell theme={"system"}
    curl \
      -X POST \
      -H "Authorization: Bearer $apikey" \
      -H 'Content-Type: application/json' \
      https://api.synctera.com/v0/external_accounts/add_vendor_accounts \
      --data-binary '
      {
        "customer_id": "3bd1a112-a98e-49ab-831c-33278cab49fb",
        "customer_type": "PERSONAL",
        "vendor": "FINICITY",
        "vendor_customer_id": "6003202403",
        "verify_owner": false
      }'
    ```

    All accounts selected in Finicity Connect are added as verified external accounts. Re-run the call after linking or unlinking accounts to add or remove them.

    <Warning>
      The Finicity flow only supports adding accounts through [Sync External Accounts](/reference/syncvendorexternalaccounts), not through [Add External Accounts](/reference/addvendorexternalaccounts).
    </Warning>
  </Step>
</Steps>

## Operations

Once an account is linked and added, you can list transactions and fetch balances. These operations are **not** available for micro-deposit links, since Plaid does not allow Auth on micro-deposits.

### List transactions

Retrieve transactions for an external account with [List Transactions](/reference/getexternalaccounttransactions). `start_date` is inclusive and `end_date` is exclusive — for all transactions on 2022-01-01, use `start_date=2022-01-01&end_date=2022-01-02`.

```shell theme={"system"}
curl \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  "https://api.synctera.com/v0/external_accounts/df0978ca-9816-4b3f-b3c1-9f1354e062fe/transactions?start_date=2022-02-01&end_date=2022-02-02"
```

```json theme={"system"}
{
  "transactions": [
    {
      "amount": 0,
      "currency": "USD",
      "category": ["string"],
      "check_number": "string",
      "is_pending": true,
      "date": "2022-02-01",
      "authorized_date": "2022-02-01",
      "merchant_name": "Fancy store",
      "payment_channel": "IN_STORE",
      "payment_method": "string",
      "transaction_id": "string"
    }
  ]
}
```

### Get balance

Fetch an account balance by `external_account_id`. The response reports `available` and `current` balances in cents (1000 = \$10.00), the ISO 4217 `currency`, and the balance `limit`.

```shell theme={"system"}
curl \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/external_accounts/df0978ca-9816-4b3f-b3c1-9f1354e062fe/balance
```

```json theme={"system"}
{
  "available": 10000,
  "current": 11000,
  "currency": "SEK",
  "limit": 20000
}
```

## Account management

### List external accounts

View all external accounts, optionally filtered by `customer_id` or `business_id`, with [List External Accounts](/reference/listexternalaccounts):

```shell theme={"system"}
curl \
  -H "Authorization: Bearer $apikey" \
  https://api.synctera.com/v0/external_accounts
```

```json theme={"system"}
{
  "external_accounts": [
    {
      "id": "1542ea0f-09ef-410c-9d66-57f36af5b52b",
      "customer_id": "17f4c82d-a398-48ed-a9c8-5bd9a53fe862",
      "nickname": "Plaid Checking",
      "type": "CHECKING",
      "status": "ACTIVE",
      "account_identifiers": { "number": "0000" },
      "routing_identifiers": {
        "ach_routing_number": "1533",
        "bank_countries": ["US"],
        "bank_name": "Chase"
      },
      "vendor_data": { "account_number_mask": "0000", "institution_id": "ins_3" },
      "verification": { "status": "VERIFIED", "vendor": "PLAID" }
    }
  ]
}
```

### View a specific external account

Fetch a single account by ID with [Get External Account](/reference/getexternalaccount):

```shell theme={"system"}
curl \
  -H "Authorization: Bearer $apikey" \
  https://api.synctera.com/v0/external_accounts/1542ea0f-09ef-410c-9d66-57f36af5b52b
```

### Sync vendor accounts

After running Plaid Link in [update mode](#update-mode), persist the changes (adds the newly linked accounts and deletes the unlinked ones) with [Sync Vendor Accounts](/reference/syncvendorexternalaccounts). Owner-identity verification is not supported for business customers — omit `verify_owner` or set it to `false`.

```shell theme={"system"}
curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/external_accounts/sync_vendor_accounts \
  --data-binary '
  {
    "customer_id": "0d36a87d-a3dc-4ab9-8732-6c05e955c7fa",
    "customer_type": "PERSONAL",
    "vendor": "PLAID",
    "vendor_access_token": "access-sandbox-de3ce8ef-33f8-452c-a685-8671031fc0f6",
    "vendor_account_ids": ["blgvvBlXw3cq5GMPwqB6s6q4dLKB9WcVqGDGo"],
    "verify_owner": false
  }'
```

The response contains `added_accounts`, `deleted_accounts`, and `failed_accounts`.

### Unlink an external account

<Warning>
  Deleting an account from Synctera does **not** unlink it from Plaid. To fully unlink, follow this section before deleting.
</Warning>

Create a link token in [update mode](#update-mode) (include `vendor_institution_id`), launch Plaid Link, uncheck the accounts to unlink, and click Continue. The unlinked accounts can then be [deleted from Synctera](#delete-an-external-account). If you linked new accounts, persist them with [Sync Vendor Accounts](#sync-vendor-accounts).

### Delete an external account

Delete an account from Synctera with [Delete External Account](/reference/deleteexternalaccount). If it is still linked at Plaid, you can add it back.

```shell theme={"system"}
curl \
  -X DELETE \
  -H "Authorization: Bearer $apikey" \
  https://api.synctera.com/v0/external_accounts/1542ea0f-09ef-410c-9d66-57f36af5b52b
```

```json theme={"system"}
{
  "id": "1542ea0f-09ef-410c-9d66-57f36af5b52b",
  "resource": "external_account"
}
```

### Create an external account manually

If you verify account ownership outside Synctera's API, create the external account manually with [Add an External Account](/reference/addexternalaccounts):

```shell theme={"system"}
curl \
  -X POST \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/external_accounts \
  --data-binary '
  {
    "type": "CHECKING",
    "customer_id": "17f4c82d-a398-48ed-a9c8-5bd9a53fe862",
    "customer_type": "PERSONAL",
    "account_official_name": "Primary checking",
    "vendor_account_id": "m1w75KWEQQh57qaZlo6mIGVR5r64vDSLP74dr",
    "account_owner_names": ["Sponge Bob"],
    "routing_identifiers": {
      "bank_name": "Bank of Orion",
      "bank_countries": ["US"],
      "ach_routing_number": "110001001"
    },
    "account_identifiers": { "number": "31131242233323021" }
  }'
```

### Update an external account

Update details of a **manually created** account with [Update External Account](/reference/updateexternalaccount). Do not use this for accounts whose details came directly from a vendor.

```shell theme={"system"}
curl \
  -X PATCH \
  -H "Authorization: Bearer $apikey" \
  -H 'Content-Type: application/json' \
  https://api.synctera.com/v0/external_accounts/1542ea0f-09ef-410c-9d66-57f36af5b52b \
  --data-binary '
  {
    "nickname": "Super Exciting Account"
  }'
```

## Troubleshooting

Common errors when using the External Accounts API:

| Error                        | What it means and how to handle it                                                                                                                                                          |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ITEM_LOGIN_REQUIRED`        | The connection was reset (bank security, password, or MFA change). Re-link the account through Plaid Link in [update mode](#update-mode). If it persists, open a Support ticket with Plaid. |
| `PRODUCTS_NOT_SUPPORTED`     | The institution does not support returning all accounts in update mode. This is not an integration problem.                                                                                 |
| `INSTITUTION_NOT_RESPONDING` | The institution is unavailable or under maintenance. Retry later; if persistent, open a "Persistent HTTP 500 errors" Support ticket with Plaid.                                             |
| `NO_AUTH_ACCOUNTS`           | Plaid could not find account and routing numbers. The customer may need to opt in to sharing account/routing details during the OAuth flow.                                                 |
| Available balance is `null`  | Some institutions do not return the available balance.                                                                                                                                      |

## Best practices

* **Verify before debiting** — ACH debits require a verified external account; only ACH credits can be originated without owner verification.
* **Check balances first** — call the balance endpoint before ACH debits to reduce the chance of overdrafts (not available for micro-deposit links).
* **Handle failed accounts** — always inspect `failed_accounts` in add/sync responses rather than assuming every account linked.
* **Unlink before deleting** — deleting in Synctera does not unlink at Plaid; follow the [unlink flow](#unlink-an-external-account) first.
* **Use update mode to re-auth** — resolve `ITEM_LOGIN_REQUIRED` by re-running Plaid Link in update mode instead of recreating the account.

## Related guides

<CardGroup cols={2}>
  <Card title="Create a Personal Customer" href="/docs/create-a-personal-customer" icon="user" horizontal>
    Create the customer an external account belongs to.
  </Card>

  <Card title="Create a Business Customer" href="/docs/create-a-business" icon="briefcase" horizontal>
    Link external accounts to a business customer.
  </Card>

  <Card title="Sandbox Test Cases" href="/docs/sandbox-external-account-test-cases" icon="flask" horizontal>
    Test data for micro-deposit and linking scenarios.
  </Card>
</CardGroup>

## API reference

* [Create a link token](/reference/createverificationlinktoken)
* [Create an access token](/reference/createaccesstoken)
* [Add external accounts](/reference/addvendorexternalaccounts)
* [Sync external accounts](/reference/syncvendorexternalaccounts)
* [List external accounts](/reference/listexternalaccounts)
* [Get an external account](/reference/getexternalaccount)
* [Add an external account (manual)](/reference/addexternalaccounts)
* [Update an external account](/reference/updateexternalaccount)
* [Delete an external account](/reference/deleteexternalaccount)
* [List transactions](/reference/getexternalaccounttransactions)
