Add Auth to your app 
=====================

#### Use Auth to connect user bank accounts 

In this guide, we'll demonstrate how to add [Auth](https://plaid.com/docs/api/products/auth/index.html.md) to your app so that you can connect to your users' bank accounts and obtain the information needed to set up funds transfers.

If you're already familiar with using Plaid and are set up to make calls to the Plaid API, see [Getting Auth data](https://plaid.com/docs/auth/add-to-app/index.html.md#getting-auth-data) . If you're interested in using a Plaid partner, such as Stripe or Dwolla, to process payments, see [Moving funds with a payment partner](https://plaid.com/docs/auth/add-to-app/index.html.md#moving-funds-with-a-payment-partner) .

Prefer to learn by watching? A [video guide](https://youtu.be/FlZ5nzlIq74) is available for this topic.

#### Get Plaid API keys and complete application and company profile 

If you don't already have one, you'll need to [create a Plaid developer account](https://dashboard.plaid.com/signup) . After creating your account, you can find your [API keys](https://dashboard.plaid.com/developers/keys) under the Developers menu on the Plaid Dashboard.

You will also need to complete your [application profile](https://dashboard.plaid.com/settings/company/app-branding) and [company profile](https://dashboard.plaid.com/settings/company/profile) in the Dashboard. The information in your profile will be shared with users of your application when they manage their connection on the [Plaid Portal](https://my.plaid.com) . Your application profile and company profile must be completed before connecting to certain institutions in Production.

#### Install and initialize Plaid libraries 

You can use our official server-side client libraries to connect to the Plaid API from your application:

```node
// Install via npm
npm install --save plaid

```

```bash
## Not applicable with curl calls

```

```ruby
# Available as a gem
gem install plaid

```

```java
/*
For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from
- https://github.com/plaid/plaid-java/releases/latest
*/
implementation "com.plaid:plaid-java:{VERSION}"

/*
For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from
- https://github.com/plaid/plaid-java/releases/latest
*/

  com.plaid
  plaid-java
  {VERSION}


```

```python
# Install through pip, only supports Python 3
pip install --upgrade plaid-python

```

```go
go get github.com/plaid/plaid-go

```

After you've installed Plaid's client libraries, you can initialize them by passing in your `client_id`, `secret`, and the environment you wish to connect to (Sandbox or Production). This will make sure the client libraries pass along your `client_id` and `secret` with each request, and you won't need to explicitly include them in any other calls.

```node
// Using Express
const express = require('express');
const app = express();
app.use(express.json());

const { Configuration, PlaidApi, PlaidEnvironments } = require('plaid');

const configuration = new Configuration({
  basePath: PlaidEnvironments.sandbox,
  baseOptions: {
    headers: {
      'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
      'PLAID-SECRET': process.env.PLAID_SECRET,
    },
  },
});

const client = new PlaidApi(configuration);

```

```bash
## Not applicable with curl calls

```

```ruby
require 'sinatra'
require 'plaid'

set :port, ENV['APP_PORT'] || 8000

configuration = Plaid::Configuration.new
configuration.server_index = Plaid::Configuration::Environment[ENV['PLAID_ENV'] || 'sandbox']
configuration.api_key['PLAID-CLIENT-ID'] =  ENV['PLAID_CLIENT_ID']
configuration.api_key['PLAID-SECRET'] = ENV['PLAID_SECRET']

api_client = Plaid::ApiClient.new(
  configuration
)

client = Plaid::PlaidApi.new(api_client)

```

```java
import java.net.*;
import java.io.*;
import retrofit2.Response;
import java.util.Arrays;
import com.sun.net.httpserver.*;

import com.plaid.client.ApiClient;
import com.plaid.client.request.PlaidApi;

public class PlaidExample {
  private static final String CLIENT_ID = System.getenv("PLAID_CLIENT_ID");
  private static final String SECRET = System.getenv("PLAID_SECRET");

  public static void main(String[] args) {
    HttpServer server = HttpServer.create(
      new InetSocketAddress("localhost", 8000), 0);
    server.createContext("/create_link_token", new GetLinkToken());
    server.setExecutor(null);
    server.start();
  }

  // Additional server code goes here

}

```

```python
import plaid
from plaid.api import plaid_api

from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify

app = Flask(name)

configuration = plaid.Configuration(
  host=plaid.Environment.Sandbox,
  api_key={
    'clientId': PLAID_CLIENT_ID,
    'secret': PLAID_SECRET,
  }
)

api_client = plaid.ApiClient(configuration)
client = plaid_api.PlaidApi(api_client)

# Additional server code goes here

if __name__ == "__main__":
    app.run(port=8000)

```

```go
import (
    "context"
    "net/http"
    "os"

    "github.com/gin-gonic/gin"
    "github.com/plaid/plaid-go/v3/plaid"
)


configuration := plaid.NewConfiguration()
configuration.AddDefaultHeader("PLAID-CLIENT-ID", os.Getenv("CLIENT_ID"))
configuration.AddDefaultHeader("PLAID-SECRET", os.Getenv("SECRET"))
configuration.UseEnvironment(plaid.Sandbox)
client := plaid.NewAPIClient(configuration)


func main() {
  r := gin.Default()
  // Server endpoints would be declared here
  // e.g.  r.POST("/create_link_token", createLinkToken)
 r.POST("/create_link_token", createLinkToken)

  err := r.Run(":8000")
  if err != nil {
    panic("unable to start server")
  }
}

```

#### Create an Item using Link 

These instructions cover Link for web applications. For instructions on using Link in mobile apps, see the [Link documentation](https://plaid.com/docs/link/index.html.md) .

Plaid Link is the client-side component that your users interact with to securely connect their bank accounts to your app. An [Item](https://plaid.com/docs/quickstart/glossary/index.html.md#item) is created when a user successfully logs into their financial institution using Link. An Item represents a single login at a financial institution. Items do not represent individual bank accounts, although all bank accounts are associated with an Item. For example, if a user has a single login at a bank that allows them to access both a checking account and a savings account, only a single Item would be associated with both of the accounts.

When using Auth, you will typically only need access to the specific bank account that will be used to transfer funds, rather than all of the accounts a user may have at an institution. Because of this, it is recommended that you configure Link with [Account Select](https://plaid.com/docs/link/customization/index.html.md#account-select) when using Auth. Configuring Link with Account Select will limit unnecessary access to user accounts. You can [enable Account Select from the Dashboard](https://dashboard.plaid.com/link/account-select) .

To create an Item, you'll first need to create a [Link token](https://plaid.com/docs/quickstart/glossary/index.html.md#link-token) on your application server. You can create a Link token by calling the [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) endpoint. Then, on the client-side of your application, you'll initialize Link using the Link token you created.

The code samples below demonstrate how to create a Link token and how to initialize Link using the token.

##### Create a Link token 

```node
app.post('/api/create_link_token', async function (request, response) {
  // Get the client_user_id by searching for the current user
  const user = await User.find(...);
  const clientUserId = user.id;
  const linkTokenRequest = {
    user: {
      // This should correspond to a unique id for the current user.
      client_user_id: clientUserId,
    },
    client_name: 'Plaid Test App',
    products: ['auth'],
    language: 'en',
    webhook: 'https://webhook.example.com',
    redirect_uri: 'https://domainname.com/oauth-page.html',
    country_codes: ['US'],
  };
  try {
    const createTokenResponse = await client.linkTokenCreate(linkTokenRequest);
    response.json(createTokenResponse.data);
  } catch (error) {
    // handle error
  }
});

```

```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}",
  "client_name": "Plaid Test App",
  "user": { "client_user_id": "${UNIQUE_USER_ID}" },
  "products": ["auth"],
  "country_codes": ["US"],
  "language": "en",
  "webhook": "https://webhook.example.com",
  "redirect_uri": "https://domainname.com/oauth-page.html"
}'

```

```ruby
post '/api/create_link_token' do
  # Get the client_user_id by searching for the current user
  current_user = User.find(...)
  client_user_id = current_user.id

  # Create a link_token for the given user
  request = Plaid::LinkTokenCreateRequest.new(
    {
      user: { client_user_id: client_user_id },
      client_name: 'Plaid Test App',
      products: ['auth'],
      country_codes: ['US'],
      language: "en",
      redirect_uri: nil_if_empty_envvar('PLAID_REDIRECT_URI'),
      webhook: 'https://webhook.example.com'
    }
  )
  response = client.link_token_create(request)
  content_type :json
  response.to_json
end

```

```java
import com.plaid.client.model.Products;
import com.plaid.client.model.CountryCode;
import com.plaid.client.model.LinkTokenCreateRequest;
import com.plaid.client.model.LinkTokenCreateRequestUser;
import com.plaid.client.model.LinkTokenCreateResponse;

public class PlaidExample {

  ...
  static class GetLinkToken implements HttpHandler {
    private static PlaidApi plaidClient;

    public void handle(HttpExchange t) throws IOException {
      // Create your Plaid client
      HashMap apiKeys = new HashMap();
      apiKeys.put("clientId", CLIENT_ID);
      apiKeys.put("secret", SECRET);
      ApiClient apiClient = new ApiClient(apiKeys);
      apiClient.setPlaidAdapter(ApiClient.Sandbox);

      plaidClient = apiClient.createService(PlaidApi.class);

      // Get the clientUserId by searching for the current user
      User userFromDB = db.find(...);
      String clientUserId = userFromDB.id;
      LinkTokenCreateRequestUser user = new LinkTokenCreateRequestUser()
        .clientUserId(clientUserId);

      // Create a link_token for the given user
      LinkTokenCreateRequest request = new LinkTokenCreateRequest()
        .user(user)
        .clientName("Plaid Test App")
        .products(Arrays.asList(Products.fromValue("auth")))
        .countryCodes(Arrays.asList(CountryCode.US))
        .language("en")
        .redirectUri("https://domainname.com/oauth-page.html")
        .webhook("https://webhook.example.com");

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

      // Send the data to the client
      return response.body();
    }
  }
}

```

```python
from plaid.model.link_token_create_request import LinkTokenCreateRequest
from plaid.model.link_token_create_request_user import LinkTokenCreateRequestUser
from plaid.model.products import Products
from plaid.model.country_code import CountryCode

@app.route("/create_link_token", methods=['POST'])
def create_link_token():
    # Get the client_user_id by searching for the current user
    user = User.find(...)
    client_user_id = user.id

    # Create a link_token for the given user
    request = LinkTokenCreateRequest(
            products=[Products("auth")],
            client_name="Plaid Test App",
            country_codes=[CountryCode('US')],
            redirect_uri='https://domainname.com/oauth-page.html',
            language='en',
            webhook='https://webhook.example.com',
            user=LinkTokenCreateRequestUser(
                client_user_id=client_user_id
            )
        )
    response = client.link_token_create(request)

    # Send the data to the client
    return jsonify(response.to_dict())


```

```go
func createLinkToken(c *gin.Context) {
  ctx := context.Background()

  // Get the client_user_id by searching for the current user
  user, _ := usermodels.Find(...)
  clientUserId := user.ID.String()

  // Create a link_token for the given user
  request := plaid.NewLinkTokenCreateRequest("Plaid Test App", "en", []plaid.CountryCode{plaid.COUNTRYCODE_US}, *plaid.NewLinkTokenCreateRequestUser(clientUserId))
  request.SetWebhook("https://webhook.sample.com")
  request.SetRedirectUri("https://domainname.com/oauth-page.html")
  request.SetProducts([]plaid.Products{plaid.PRODUCTS_AUTH})

  resp, _, err := testClient.PlaidApi.LinkTokenCreate(ctx).LinkTokenCreateRequest(*request).Execute()

  // Send the data to the client
  c.JSON(http.StatusOK, gin.H{
    "link_token": resp.GetLinkToken(),
  })
}


```

##### Initialize Link with the Link token 

If your use case involves a pay-by-bank payments flow where the end user can choose between paying via a credit card and paying via a bank account, it is highly recommended to use the [Embedded experience](https://plaid.com/docs/link/embedded-institution-search/index.html.md) for Link to increase uptake of pay-by-bank. If your use case is an account opening or funding flow that requires the customer to use a bank account, or has a surcharge for credit card use, use the standard Link experience.

Select group for content switcher

Account funding (standard Link)Pay by Bank (Embedded Link)

app.js

```javascript
const handler = Plaid.create({
  token: (await $.post('/create_link_token')).link_token,
  onSuccess: (public_token, metadata) => {
    // Upon successful linking of a bank account,
    // Link will return a public token.
    // Exchange the public token for an access token
    // to make calls to the Plaid API.
    $.post('/exchange_public_token', {
      public_token: public_token,
    });
  },
  onLoad: () => {},
  onExit: (err, metadata) => {
    // Optionally capture when your user exited the Link flow.
    // Storing this information can be helpful for support.
  },
  onEvent: (eventName, metadata) => {
    // Optionally capture Link flow events, streamed through
    // this callback as your users connect an Item to Plaid.
  },
});

handler.open();
```

The sample code below is for JavaScript. For more examples for other platforms, see [Embedded Link](https://plaid.com/docs/link/embedded-institution-search/index.html.md#integration-steps) .

Embedded Institution search - web (HTML)

```html
<div id="plaid-embedded-link-container"></div>
```

Embedded Institution Search - web (JavaScript)

```javascript
// The container at `#plaid-embedded-link-container` will need to be sized in order to
// control the size of the embedded Plaid module
const embeddedLinkOpenTarget = document.querySelector('#plaid-embedded-link-container');

Plaid.createEmbedded(
    {
      token: 'GENERATED_LINK_TOKEN',
      onSuccess: (public_token, metadata) => {},
      onLoad: () => {},
      onExit: (err, metadata) => {},
      onEvent: (eventName, metadata) => {},
    },
    embeddedLinkOpenTarget,
);
```

#### Obtain an access token 

When a user successfully links an Item via Link, the [onSuccess](https://plaid.com/docs/link/web/index.html.md#onsuccess) callback will be called. The `onSuccess` callback returns a [public token](https://plaid.com/docs/quickstart/glossary/index.html.md#public-token) . On your application server, exchange the public token for an [access token](https://plaid.com/docs/quickstart/glossary/index.html.md#access-token) and an [Item ID](https://plaid.com/docs/quickstart/glossary/index.html.md#item-id) by calling `/item/public_token/exchange/`. The access token will allow you to make authenticated calls to the Plaid API.

Store the access token and Item ID in a secure datastore, as they're used to access Item data and identify webhooks, respectively. The access token will remain valid unless you actively expire it via rotation or remove it by calling [/item/remove](https://plaid.com/docs/api/items/index.html.md#itemremove) on the corresponding Item. For security purposes, never store the access token in client-side code. The public token is a one-time use token with a lifetime of 30 minutes, so there is no need to store it.

##### Exchange public token for an access token 

```node
app.post('/api/exchange_public_token', async function (
  request,
  response,
  next,
) {
  const publicToken = request.body.public_token;
  try {
    const tokenResponse = await client.itemPublicTokenExchange({
      public_token: publicToken,
    });

    // These values should be saved to a persistent database and
    // associated with the currently signed-in user
    const accessToken = tokenResponse.data.access_token;
    const itemID = tokenResponse.data.item_id;

    response.json({ public_token_exchange: 'complete' });
  } catch (error) {
    // handle error
  }
});

```

```bash
curl -X POST https://sandbox.plaid.com/item/public_token/exchange \
-H 'Content-Type: application/json' \
-d '{
  "client_id": "${PLAID_CLIENT_ID}",
  "secret": "${PLAID_SECRET}",
  "public_token": "public-sandbox-12345678-abcd-1234-abcd-1234567890ab"
}'

```

```ruby
access_token = nil

post '/api/exchange_public_token' do
  request = Plaid::ItemPublicTokenExchangeRequest.new(
    {
      public_token: params["public_token"]
    }
  )
  response = client.item_public_token_exchange(request)

  # These values should be saved to a persistent database and
  # associated with the currently signed-in user
  access_token = response.access_token
  item_id = response.item_id

  content_type :json
  {public_token_exchange: "complete"}.to_json
end

```

```java
import com.plaid.client.model.ItemPublicTokenExchangeRequest;
import com.plaid.client.model.ItemPublicTokenExchangeResponse;

public class PlaidExample {

  ...
  static class GetAccessToken implements HttpHandler {
    private static PlaidClient plaidClient;

    private String publicToken;
    private String accessToken;
    private String itemId;

    public void handle(HttpExchange t) throws IOException {
      // Simplified pseudo-code for obtaining public_token
      InputStream is = t.getRequestBody();
      publicToken = is.publicToken();

      // Create your Plaid client
      HashMap apiKeys = new HashMap();
      apiKeys.put("clientId", CLIENT_ID);
      apiKeys.put("secret", SECRET);
      apiKeys.put("plaidVersion", "2020-09-14");
      apiClient = new ApiClient(apiKeys);
      apiClient.setPlaidAdapter(ApiClient.Sandbox);

      plaidClient = apiClient.createService(PlaidApi.class);

      // Exchange public_token for an access_token
      ItemPublicTokenExchangeRequest request = new ItemPublicTokenExchangeRequest()
        .publicToken(publicToken);

      Response response = plaidClient
        .itemPublicTokenExchange(request)
        .execute();

      // These values should be saved to a persistent database and
      // associated with the currently signed-in user
      accessToken = response.body().getAccessToken();
      itemId      = response.body().getItemId();

      String message = "{\"public_token_exchange\": \"complete\"}";
      return Response
        .status(Response.Status.OK)
        .entity(message)
        .type(MediaType.APPLICATION_JSON)
      }
  }
}

```

```python
access_token = None
item_id = None

@app.route('/exchange_public_token', methods=['POST'])
def exchange_public_token():
    global access_token
    public_token = request.form['public_token']
    request = ItemPublicTokenExchangeRequest(
      public_token=public_token
    )
    response = client.item_public_token_exchange(request)

    # These values should be saved to a persistent database and
    # associated with the currently signed-in user
    access_token = response['access_token']
    item_id = response['item_id']

    return jsonify({'public_token_exchange': 'complete'})

```

```go
func getAccessToken(c *gin.Context) {
  ctx := context.Background()
  publicToken := c.PostForm("public_token")

  // exchange the public_token for an access_token
  exchangePublicTokenReq := plaid.NewItemPublicTokenExchangeRequest(publicToken)
    exchangePublicTokenResp, _, err := client.PlaidApi.ItemPublicTokenExchange(ctx).ItemPublicTokenExchangeRequest(
        *exchangePublicTokenReq,
    ).Execute()

  // These values should be saved to a persistent database and
  // associated with the currently signed-in user
  accessToken := exchangePublicTokenResp.GetAccessToken()
  itemID := exchangePublicTokenResp.GetItemId()

  c.JSON(http.StatusOK, gin.H{"public_token_exchange": "complete"})
}



```

#### Getting Auth data 

Now that you have an access token, you can begin making authenticated calls to the Plaid API. If you are processing payments yourself, call the [/auth/get](https://plaid.com/docs/api/products/auth/index.html.md#authget) endpoint to retrieve the bank account and bank identification numbers (such as routing numbers, for US accounts) associated with an Item's accounts. You can then supply these to your payment system. If you are using a Plaid partner to move funds, you will not need to call [/auth/get](https://plaid.com/docs/api/products/auth/index.html.md#authget) . Instead, see [Moving funds with a payment partner](https://plaid.com/docs/auth/add-to-app/index.html.md#moving-funds-with-a-payment-partner) .

```node
const { AuthGetRequest } = require('plaid');

// Call /auth/get and retrieve account numbers for an Item
const request = {
  access_token: access_token,
};
try {
  const response = await plaidClient.authGet(request);
  const accountData = response.data.accounts;
  if (response.data.numbers.ach.length > 0) {
    // Handle ACH numbers (US accounts)
    const achNumbers = response.data.numbers.ach;
  }
  if (response.data.numbers.eft.length > 0) {
    // Handle EFT numbers (Canadian accounts)
    const eftNumbers = response.data.numbers.eft;
  }
  if (response.data.numbers.international.length > 0) {
    // Handle International numbers
    const internationalNumbers = response.data.numbers.international;
  }
  if (response.data.numbers.bacs.length > 0) {
    // Handle BACS numbers (British accounts)
    const bacsNumbers = response.data.numbers.bacs;
  }
} catch (error) {
  //handle error
}

```

```bash
curl -X POST https://sandbox.plaid.com/auth/get \
-H 'Content-Type: application/json' \
-d '{
  "client_id": "${PLAID_CLIENT_ID}",
  "secret": "${PLAID_SECRET}",
  "access_token": String
}'

```

```ruby
require 'plaid'

# Call /auth/get and retrieve account numbers for an Item
request = Plaid::AuthGetRequest.new({ access_token: access_token })
response = client.auth_get(request)
numbers = response.numbers
if numbers.ach.length > 0
  # Handle ACH numbers (US accounts)
  achNumbers = numbers.ach
end
if numbers.eft.length > 0
  # Handle EFT numbers (Canadian accounts)
  eftNumbers = numbers.eft
end
if numbers.international.length > 0
  # Handle International numbers (Standard International accounts)
  internationalNumbers = numbers.international
end
if numbers.bacs.length > 0
  # Handle BACS numbers (British accounts)
  bacsNumbers = numbers.bacs
end

```

```java
import com.plaid.client.model.AuthGetRequest;
import com.plaid.client.model.AuthGetResponse;

// Call /auth/get and retrieve account numbers for an Item
AuthGetRequest request = new AuthGetRequest()
  .accessToken(accessToken);

Response response = client()
  .authGet(request)
  .execute();
if (response.body().getNumbers().getACH().size() > 0) {
  // Handle ACH numbers (US accounts)
  for (AuthGetResponse.NumberACH numberACH :
response.body().getNumbers().getACH()) { ... }
}
if (response.body().getNumbers().getEFT().size() > 0) {
  // Handle EFT numbers (Canadian accounts)
  for (AuthGetResponse.NumberEFT numberEFT :
response.body().getNumbers().getEFT()) { ... }
}
if (response.body().getNumbers().getInternational().size() > 0) {
  // Handle International numbers (Standard International accounts)
  for (AuthGetResponse.NumberInternational numberInternational :
response.body().getNumbers().getInternational()) { ... }
}
if (response.body().getNumbers().getBACS().size() > 0) {
  // Handle BACS numbers (British accounts)
  for (AuthGetResponse.NumberBACS numberBACS :
response.body().getNumbers().getBACS()) { ... }
}

```

```python
import plaid
from plaid.model.auth_get_request import AuthGetRequest

# Call /auth/get and retrieve account numbers for an Item
request = AuthGetRequest(access_token=access_token)
response = client.auth_get(request)
numbers = response['numbers']
if len(numbers['ach']) > 0:
    # Handle ACH numbers (US accounts)
    achNumbers = numbers['ach']
if len(numbers['eft']) > 0:
    # Handle EFT numbers (Canadian accounts)
    eftNumbers = numbers['eft']
if len(numbers['international']) > 0:
    # Handle International numbers (Standard International accounts)
    internationalNumbers = numbers['international']
if len(numbers['bacs']) > 0:
    # Handle BACS numbers (British accounts)
    bacsNumbers = numbers['bacs']

```

```go
import (
    "context"

    "github.com/plaid/plaid-go/v42/plaid"
)

// Call /auth/get and retrieve account numbers for an Item
authGetResp, _, err := client.PlaidApi.AuthGet(ctx).AuthGetRequest(
  *plaid.NewAuthGetRequest(accessToken),
).Execute()

numbers := authGetResp.GetNumbers()

```

Example response data is below. Note that this is test account data; real accounts would not include all four sets of numbers.

/auth/get sample response

```json
{
  "accounts": [
    {
      "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
      "balances": {
        "available": 100,
        "current": 110,
        "limit": null,
        "iso_currency_code": "USD",
        "unofficial_currency_code": null
      },
      "mask": "9606",
      "name": "Plaid Checking",
      "official_name": "Plaid Gold Checking",
      "subtype": "checking",
      "type": "depository"
    }
  ],
  "numbers": {
    "ach": [
      {
        "account": "9900009606",
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "routing": "011401533",
        "wire_routing": "021000021"
      }
    ],
    "eft": [
      {
        "account": "111122223333",
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "institution": "021",
        "branch": "01140"
      }
    ],
    "international": [
      {
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "bic": "NWBKGB21",
        "iban": "GB29NWBK60161331926819"
      }
    ],
    "bacs": [
      {
        "account": "31926819",
        "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",
        "sort_code": "601613"
      }
    ]
  },
  "item": {
    "available_products": [
      "balance",
      "identity",
      "payment_initiation",
      "transactions"
    ],
    "billed_products": ["assets", "auth"],
    "consent_expiration_time": null,
    "error": null,
    "institution_id": "ins_117650",
    "item_id": "DWVAAPWq4RHGlEaNyGKRTAnPLaEmo8Cvq7na6",
    "webhook": "https://www.genericwebhookurl.com/webhook"
  },
  "request_id": "m8MDnv9okwxFNBV"
}
```

#### Moving funds with a payment partner 

You can move money via ACH transfer by pairing Auth with one of Plaid's payment partners. When using a partner to move money, the partner's payments service will initiate the transfer; Plaid does not function as the payment processor. For the full list of payments platforms who have partnered with Plaid to provide ACH money movement, see [Auth Partnerships](https://plaid.com/docs/auth/partnerships/index.html.md) .

To move money using a Plaid partner, first create an Item using Link and obtain an access token as described above. Then, instead of calling Plaid's Auth endpoints, call one of Plaid's [processor token endpoints](https://plaid.com/docs/api/processors/index.html.md) to create a processor token. You can then send this processor token to one of Plaid's partners by using endpoints that are specific to the payment platform. Refer to the partner's technical documentation for more information. Using a partner to transfer funds gives you access to payment functionality while freeing you from having to securely store sensitive bank account information.

The sample code below demonstrates a call to [/processor/token/create](https://plaid.com/docs/api/processors/index.html.md#processortokencreate) using Dwolla as the payment processor.

```bash
# Create a processor token for a specific account id.
curl \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "${PLAID_CLIENT_ID}",
    "secret": "${PLAID_SECRET}",
    "access_token": "${ACCESS_TOKEN}",
    "account_id": "${ACCOUNT_ID}",
    "processor": "dwolla"
  }' \
  -X POST \
  https://sandbox.plaid.com/processor/token/create

```

```java
import com.plaid.client.model.ProcessorTokenCreateRequest;
import com.plaid.client.model.ProcessorTokenCreateResponse;

// Create a processor token for a specific account id
ProcessorTokenCreateRequest request = new ProcessorTokenCreateRequest()
  .accessToken(accessToken)
  .processor("dwolla")
  .accountId("ACCOUNT_ID");

Response dwollaResponse = client()
  .processorTokenCreate(request)
  .execute();

String dwollaProcessorToken = dwollaResponse.body().getProcessorToken();

```

```ruby
require 'plaid'
# Create a processor token for a specific account id
processor_token_create_request = Plaid::ProcessorTokenCreateRequest.new({
    access_token: access_token,
    account_id: account_id,
    processor: "dwolla"
  }
)

create_response = client.processor_token_create(processor_token_create_request)
processor_token = create_response.processor_token

```

```python
from plaid.model.processor_token_create_request import ProcessorTokenCreateRequest

# Create a processor token for a specific account id
create_request = ProcessorTokenCreateRequest(
    access_token=access_token,
    account_id=account_id,
    processor='dwolla'
)
create_response = client.processor_token_create(create_request)
processor_token = create_response['processor_token']

```

```node
const { ProcessorTokenCreateRequest } = require('plaid');

try {
  // Create a processor token for a specific account id
  const request: ProcessorTokenCreateRequest = {
    access_token: accessToken,
    account_id: accountID,
    processor: 'dwolla',
  };
  const processorTokenResponse = await plaidClient.processorTokenCreate(
    request,
  );
  const processorToken = processorTokenResponse.data.processor_token;
} catch (error) {
  // handle error
}

```

```go
import (
  "context"
  "os"

  plaid "github.com/plaid/plaid-go/v42/plaid"
)


// Get the account id
accountsResp, _, err := client.PlaidApi.AccountsGet(ctx).AccountsGetRequest(plaid.AccountsGetRequest{
  AccessToken: accessToken,
}).Execute()
accountID := accountsResp.GetAccounts()[0].GetAccountId()

// Create a dwolla token for the specific account id
request := plaid.NewProcessorTokenCreateRequest(accessToken, accountID, "dwolla")
processorTokenResp, _, err := client.PlaidApi.ProcessorTokenCreate(ctx).ProcessorTokenCreateRequest(
  *request,
).Execute()

```

#### Tutorial and example code in Plaid Pattern 

For a real-life example of an app that incorporates Auth, see the Node-based [Plaid Pattern Account Funding](https://github.com/plaid/pattern-account-funding) sample app. Pattern Account Funding is a sample account funding app that fetches Auth data in order to set up funds transfers. The Auth code can be found in [items.js](https://github.com/plaid/pattern-account-funding/blob/master/server/routes/items.js#L81-L135) .

For a step-by-step tutorial on how to implement account funding, see the [Account funding tutorial](https://github.com/plaid/account-funding-tutorial) .

#### Next steps 

Once Auth is implemented in your app, see [Micro-deposit and database verification](https://plaid.com/docs/auth/coverage/index.html.md) to make sure your app is supporting the maximum number of institutions and verification methods (US only).

If your use case is an account funding use case, see [the Account funding solutions guide](https://plaid.com/documents/plaid-account-funding-guide.pdf) for a set of recommendations on how to implement Auth.