Language

Introduction

Welcome to the Dwolla Transfer documentation. Connect your software to the banking infrastructure. Transfer is for customers building applications where the end user interacts with the Dwolla branded interface. Transfer integrations leverage OAuth to facilitate user on-boarding and Dwolla account authorization. Upgrades to additional features like Next Day ACH, increased transaction limits, and priority support are available. Platforms requiring full customization of the payments experience should contact Sales to learn more about our Dwolla API.

Making requests

All requests should supply the Accept: application/vnd.dwolla.v1.hal+json header. POST requests must specify the Content-Type: application/vnd.dwolla.v1.hal+json header. Request and response bodies are JSON encoded.

Requests must be made over HTTPS. Any non-secure requests are met with a redirect (HTTP 302) to the HTTPS equivalent URI.

POST https://api.dwolla.com/funding-sources/a84222d5-31d2-4290-9a96-089813ef96b3
Content-Type: application/json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer myOAuthAccessToken

{
  "name": "John Doe - Checking"
}

... or ...

GET https://api.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3/transfers

Authorization

All requests require either an OAuth access token or a client_id and client_secret (Application Key and Secret). OAuth access tokens are passed via the Authorization HTTP header:

Authorization: Bearer {access_token_here}

Requests that require a client_id and client_secret can be sent using the application/x-www-form-urlencoded Content-Type or via a JSON body with the application/json Content-Type.

API Host

Production: https://api.dwolla.com

Sandbox: https://api-sandbox.dwolla.com

Idempotency key

To prevent an operation from being performed more than once, Dwolla supports passing in an Idempotency-Key header with a unique key as the value. Multiple POSTs with the same idempotency key won’t result in multiple resources being created.

For example, if a request to initiate a transfer fails due to a network connection issue, you can reattempt the request with the same idempotency key to guarantee that only a single transfer is created.

If you reattempt a POST request with the same value for the Idempotency-Key, you will receive the original response. It is recommended to use a random value for the idempotency key, like a UUID (i.e. - Idempotency-Key: d2adcbab-4e4e-430b-9181-ac9346be723a). Idempotency keys are intented to prevent conflicts over a short period of time, therefore keys will expire after 24 hours. If the Dwolla server is still processing the original POST, you will receive a 409 Conflict error response on the subsequent request.

Example transfer using an Idempotency Key

curl -X POST -H "Content-Type: application/vnd.dwolla.v1.hal+json" -H "Accept: application/vnd.dwolla.v1.hal+json" -H "Authorization: Bearer asdfwXTdDQFimVQOMdn9bOGHJh8KrqnFi34sugYqgrULRCb" -H "Idempotency-Key: d2adcbab-4e4e-430b-9181-ac9346be723a" -d '{
    "_links": {
        "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/28baca50-12ef-4a26-a14b-adf75af694d4"
        },
        "destination": {
            "href": "http://api-sandbox.dwolla.com/accounts/dee319e6-26d0-4dc6-a5bf-f1e0f4c677ad"
        }
    },
    "amount": {
        "currency": "USD",
        "value": "1337.00"
    }
}' "https://api-sandbox.dwolla.com/transfers" -v

Errors

Error responses use HTTP status codes to indicate the type of error. The JSON response body will contain a top-level error code and a message with a detailed description of the error. Errors will contain their own media type and will closely align with this spec.

Example HTTP 401 error

{
  "code": "InvalidAccessToken",
  "message": "Invalid access token."
}

Common errors

The following errors are common across all API endpoints.

HTTP Status Error Code Description
400 BadRequest The request body contains bad syntax or is incomplete.
400 ValidationError Validation error(s) present. See embedded errors list for more details. (See below)
401 InvalidCredentials Missing or invalid Authorization header.
401 InvalidAccessToken Invalid access token.
401 ExpiredAccessToken Generate a new access token using a valid refresh token.
401 InvalidAccountStatus Invalid access token account status.
401 InvalidApplicationStatus Invalid application status.
401 InvalidScopes Missing or invalid scopes for requested endpoint.
403 Forbidden The supplied credentials are not authorized for this resource.
403 InvalidResourceState Resource cannot be modified.
404 NotFound The requested resource was not found.
405 MethodNotAllowed (varies)
406 InvalidVersion Missing or invalid API version.
500 ServerError A server error occurred. Error ID: 63e92a2a-fb48-4a23-ab4c-24a6764f1593.
500 RequestTimeout The request timed out.

Validation errors

Responses with a top-level error code of ValidationError are returned when it’s possible to correct a specific problem with your request. The response will include a message: “Validation error(s) present. See embedded errors list for more details.” At least one, but possibly more, detailed error will be present in the list of embedded errors. Multiple errors are represented in a collection of embedded error objects.

_embedded JSON object

Parameter Description
errors An array of JSON object(s) that contain a code, message, and path.

The path field is a JSON pointer to the specific field in the request that has a problem. The message is a human readable description of the problem. The code is a detailed error code that can have one of the following values:

  • Required
  • Invalid - not a valid value for this field
  • InvalidFormat - chars in an amount field, for instance
  • Duplicate - “A customer with the specified email already exists.”
  • ReadOnly - this field is not allowed to be modified
  • NotAllowed - value, while valid/exists, is not allowed to be used
  • Restricted - account or customer restricted from this activity
  • InsufficientFunds - used on source or destination fields of transfer endpoint
  • RequiresFundingSource - used on destination field of transfer endpoint to indicate customer needs a bank
  • FileTooLarge - used on document upload

Example HTTP 400 validation error

{
    "code": "ValidationError",
    "message": "Validation error(s) present. See embedded errors list for more details.",
    "_embedded": {
        "errors": [
            {
                "code": "Required",
                "message": "FirstName is required.",
                "path": "/firstName",
            }
        ]
    }
}

Relationships and available actions for a resource are represented with links. All resources have a _links attribute. At a minimum, all resources will have a self link which indicates the URL of the resource itself.

Some links, such as funding-sources, give you a URL which you can follow to access related resources. For example, the Account resource has a funding-sources link which, when followed, will list the Account’s available funding sources.

Responses which contain a collection of resources have pagination links, first, next, last, and prev.

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "account"
    },
    "receive": {
      "href": "https://api-sandbox.dwolla.com/transfers",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    },
    "funding-sources": {
      "href": "https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe/funding-sources",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    },
    "transfers": {
      "href": "https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe/transfers",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    },
    "send": {
      "href": "https://api-sandbox.dwolla.com/transfers",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    }
  },
  "id": "07844b76-bfeb-4a81-87ec-adebc7fa6cfe",
  "name": "Dwolla Sandbox",
  "timezoneOffset": 0
}

SDK Support

The Dwolla API has officially maintained software packages to make it easier for developers to get started with making requests. This section is here to provide basic instructions on how to install these packages and get up and running with them. We recommend you use a POSIX-standardized shell on your development machine, and assume that you are already familiar and set-up with any tools required for your specific technical ecosystem.

Officially maintained SDKs are available for Ruby, Node.js, Python, and C#.

PHP and Java SDKs autogenerated by swagger-codegen and are versioned in accordance with our API schema. Each endpoint grouping is assigned a class and then an operation which you can use to make a request. You can choose which environment to target (e.g production vs sandbox) by providing the SDK a different API host value. These libraries are not actively maintained, therefore we encourage community contribution.

Base URLs

Production Sandbox
https://api.dwolla.com https://api-sandbox.dwolla.com

Ruby

dwolla_v2 is available on RubyGems with source code available on our GitHub page. More information is available on the project’s README.

Installation

gem install dwolla_v2

Quickstart

Let’s retrieve an Account’s list of funding sources with a pre-existing OAuth account access token:

require 'dwolla_v2'

# Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application key and secret.
app_key = "..."
app_secret = "..."
$dwolla = DwollaV2::Client.new(key: app_key, secret: app_secret) do |config|
  config.environment = :sandbox # optional - defaults to production
end

account_token = $dwolla.tokens.new access_token: "...", refresh_token: "..."

account_url = 'https://api-sandbox.dwolla.com/accounts/dee319e6-26d0-4dc6-a5bf-f1e0f4c677ad'

funding_sources = account_token.get "#{account_url}/funding-sources"
funding_sources._embedded['funding-sources'][0].name # => "Dwolla Sandbox Checking"

Python

dwollav2 is available on PyPi with source code available on our GitHub page. More information is available on the project’s README.

Installation

pip install dwollav2

Quickstart

Let’s retrieve an Account’s list of funding sources with a pre-existing OAuth account access token:

import dwollav2

# Navigate to https://www.dwolla.com/applications (production) or https://sandbox.dwolla.com/applications (Sandbox) for your application key and secret.
app_key = '...'
app_secret = '...'
client = dwollav2.Client(key = app_key,
                         secret = app_secret,
                         environment = 'sandbox') # optional - defaults to production

account_token = client.Token(access_token = '...', refresh_token = '...')

# An account_url can be obtained by calling the root of the API: https://docsv2.dwolla.com/transfer/#root
account_url = 'https://api-sandbox.dwolla.com/accounts/dee319e6-26d0-4dc6-a5bf-f1e0f4c677ad'


funding_sources = account_token.get('%s/funding-sources' % account_url)
funding_sources.body['_embedded']['funding-sources'][0]

PHP

dwolla-swagger-php is available on Packagist with source code available on our GitHub page. More information is available on the project’s README.

Installation

composer require dwolla/dwollaswagger
composer install

Quickstart

Let’s retrieve an Account’s list of funding sources with a pre-existing OAuth account access token:

<?php
require('../path/to/vendor/autoload.php');

DwollaSwagger\Configuration::$access_token = '...';
$apiClient = new DwollaSwagger\ApiClient("https://api-sandbox.dwolla.com/");

$accountUrl = 'https://api-sandbox.dwolla.com/accounts/dee319e6-26d0-4dc6-a5bf-f1e0f4c677ad';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fundingSources = $fsApi->getAccountFundingSources($accountUrl);
$fundingSources->_embedded->{'funding-sources'}[0]->name); # => "Jane Doe’s Checking"
?>

C#

Dwolla.Client is available on Nuget with source code available on our GitHub page. More information is available on the project’s README.

Installation

Install-Package Dwolla.Client

Quickstart

Let’s fetch the root of the API:

var client = DwollaClient.Create(isSandbox: true);

var headers = new Headers {{"Authorization", "Bearer ..."}};
var rootRes = (await client.GetAsync<RootResponse>(new Uri(client.ApiBaseAddress), headers)).Content;

Java

dwolla-swagger-java is not actively maintained by Dwolla, however source code is available on our GitHub page and community contribution is encouraged. More information is available on the project’s README.

Installation

You will be required to install from source, please have Git and mvn installed and in your path, then:

git clone https://github.com/Dwolla/dwolla-swagger-java
cd dwolla-swagger-java
mvn install package

Quickstart

Let’s fetch the root of the API:

import io.swagger.client.ApiClient;
import io.swagger.client.api.*;
import io.swagger.client.model.*;

ApiClient a = new ApiClient();
a.setBasePath("https://api-sandbox.dwolla.com");
a.setAccessToken("...");

RootApi r = new RootApi(a);
CatalogResponse root = r.root();

JavaScript

dwolla-v2 is available on NPM with source code available on our GitHub page. More information is available on the project’s README.

Installation

npm install dwolla-v2

Quickstart

Let’s retrieve an Account’s list of funding sources with a pre-existing OAuth account access token:

const dwolla = require('dwolla-v2');

// Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application key and secret.
const appKey = '...';
const appSecret = '...';
const client = new dwolla.Client({
  key: appKey,
  secret: appSecret,
  environment: 'sandbox' // optional - defaults to production
});

var accountToken = new client.Token({ access_token: "...", refresh_token: "..." });

var accountUrl = 'https://api-sandbox.dwolla.com/accounts/dee319e6-26d0-4dc6-a5bf-f1e0f4c677ad';

accountToken
  .get(`${accountUrl}/funding-sources`)
  .then(res => res.body._embedded['funding-sources'][0].name); // => 'Dwolla Sandbox Checking'

Authorization

Dwolla utilizes the OAuth 2 protocol to facilitate authorization. OAuth is an authorization framework that enables a third-party application to obtain access to protected resources (Transfers, Funding Sources, etc.) in the Dwolla API. Access to the Dwolla API can be granted to an application either on behalf of a user or on behalf of the application itself. The following section will walk through Dwolla’s implementation of OAuth 2 and the various flows that can be leveraged by your application.

Creating an application

Before you can get started with making OAuth requests, you’ll need to first register an application with Dwolla by logging in and navigating to the applications page. Once an application is registered you will obtain your client_id and client_secret (aka application Key and Secret), which will be used to identify your application when calling the Dwolla API. The Sandbox environment provides you with a created application once you have signed up for an account. Learn more in our getting started guide. Remember: Your client_secret should be kept a secret! Be sure to store your client credentials securely.

Dwolla’s authorization flows

The OAuth 2 protocol defines four main authorization grant types, more commonly referred to as OAuth flows. Dwolla implements two of the four grant types depending on how your application accesses data within the API.

  • Flow 1 (Account authorization): - Using the authorization code grant flow, your application will redirect the user to Dwolla (typically via a web browser) to authenticate and authorize your application. If the user grants permission, your application will be issued an access token that is used to make requests to the API on the user’s behalf. This is a browser-based flow with interaction between an end-user, a third-party application, and the Dwolla API; also known as 3-legged OAuth.
  • Flow 2 (Application authorization): - Using the client credentials grant flow, your application will obtain authorization to interact with the API on its own behalf. This is a server-to-server flow with interaction between an application and the Dwolla API; also known as 2-legged OAuth. An application will exchange it’s client_id, client_secret, and grant_type=client_credentials for an application access token. An application access token is for managing webhooks, webhook-subscriptions, and events.

Token lifetimes

Access tokens are short lived: 1 hour.

Refresh tokens are long lived: 60 days.

A refresh token can be used within 60 days to generate a new OAuth account account access_token and refresh_token pair. So long as you refresh your authorization at least every 60 days, your application can maintain authorization indefinitely without requiring the user to re-authorize.

Account authorization

Step 1: Request user authorization

To start the OAuth process, construct the initiation URL which the user will visit in order to grant permission to your application. It describes the permissions your application requires (scope), who the client application is (client_id), and where the user should be redirected to after they grant or deny permissions to your application (redirect_uri).

URL Format:

Production:https://www.dwolla.com/oauth/v2/authenticate?client_id={client_id}&response_type=code&redirect_uri={redirect_uri}&scope={scope}

Sandbox: https://sandbox.dwolla.com/oauth/v2/authenticate?client_id={client_id}&response_type=code&redirect_uri={redirect_uri}&scope={scope}

Request parameters

Parameter Required Type Description
client_id yes string Application key. Navigate to https://www.dwolla.com/applications (production) or https://sandbox.dwolla.com/applications (Sandbox) for your application key and secret.
response_type yes string This must always be set to code.
redirect_uri yes string URL where the user will be redirected to afterwards. The value of this parameter must match one of the values that appear in your application details page. (We compare: protocol, subdomain, domain, tld, and file path. Querystring parameters are ignored)
scope yes string Permissions you are requesting. See below for list of available scopes. Scopes are delimited by a pipe (“|”)
state no string Primary purpose is protection against cross-site request forgery (CSRF) attacks. A random value set by the client (you) in the initial OAuth authorization request, and is then made available to you in the redirect (along with the authorization code).
verified_account no string Require new users opting to register for Dwolla to create a fully-verified Dwolla account instead of a default lightweight Direct account.
dwolla_landing no string An optional override that force displays either the login or create an account screen. Possible values are: login, register, or null.
  1. Remember to url-encode all querystring parameters!

OAuth scopes

Applications may request the following permission scopes when requesting authorization:

Scope Name Description
Transactions Access the user’s transfer data.
Send Transfer money on the user’s behalf.
Funding Access names of funding sources the user has connected to Dwolla, access available balance information for Dwolla Balance, add new funding sources, verify funding sources, initiate transfers to and from funding sources.
AccountInfoFull Includes name and Dwolla account ID

Example complete OAuth flow

/**
 *  No example for this language yet.
 **/
import dwollav2

# Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application key and secret.
app_key = '...'
app_secret = '...'
client = dwollav2.Client(key = app_key,
                         secret = app_secret,
                         environment = 'sandbox') # optional - defaults to production

state = binascii.b2a_hex(os.urandom(15))
client.Auth(redirect_uri = 'https://yoursite.com/callback',
            scope = 'Send|Funding|Transactions|AccountInfoFull',
            state = state)

# redirect the user to dwolla.com for authorization
redirect_to(auth.url)

# exchange the code for a token using the query params provided to the redirect_uri
token = auth.callback(req.GET)
// where to send the user after they grant permission:
var redirect_uri = "https://www.myredirect.com/redirect";  

var auth = new client.Auth({
  redirect_uri: redirect_uri,
  scope: 'Send|Funding|Transactions|AccountInfoFull',
  state: getRandomHex(), // optional - https://tools.ietf.org/html/rfc6749#section-10.12
  verified_account: false, // optional
  dwolla_landing: 'register', // optional
});

// redirect to `auth.url`
auth.callback(req.query) // pass the code and optional state to the callback
  .then(function(token) {
    return token.get('/');
  })
  .then(function(res) {
    console.log(JSON.stringify(res.body));
  });

# config/initializers/dwolla.rb
require 'dwolla_v2'

# Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application key and secret.
app_key = "..."
app_secret = "..."
$dwolla = DwollaV2::Client.new(key: app_key, secret: app_secret) do |config|
  config.environment = :sandbox # optional - defaults to production
end

# app/controllers/your_auth_controller.rb
class YourAuthController
  # redirect the user to dwolla.com/oauth/v2/authenticate
  def authenticate
    redirect_to auth.url
  end

  # exchange the code for a token
  def callback
    account_token = auth.callback(params)
  end

  private

  def auth
    $dwolla.auths.new redirect_uri: "https://www.myredirect.com/redirect",
                      scope: "Send|Funding|Transactions|AccountInfoFull",
                      state: session[:state] ||= SecureRandom.hex
  end
end
not applicable

Example initiation URL (where you send the user):

https://sandbox.dwolla.com/oauth/v2/authenticate?client_id=PO%2BSzGAsZCE4BTG7Cw4OAL40Tpf1008mDjGBSVo6QLNfM4mD%2Ba&response_type=code&redirect_uri=https://developers.dwolla.com/dev/token/callback?env=sandbox&scope=Balance%7CAccountInfoFull

Step 2: Finish user authorization

Once the user returns to your application via the redirect_uri you specified, there will be a code querystring parameter appended to that URL. The redirect_uri specified in the initial authorization request is used by Dwolla to handle both the approval of authorization, as well as if the user cancels out of the flow or denies authorization. If the user denies authorization an error will be returned as an error querystring parameter. Exchange the authorization code for an access_token and refresh_token pair.

HTTP request

Production: POST https://www.dwolla.com/oauth/v2/token

sandbox: POST https://sandbox.dwolla.com/oauth/v2/token

Including the Content-Type: application/x-www-form-urlencoded header, the request is sent to the token endpoint with the following form-encoded parameters:

Request parameters

Parameter Required Type Description
client_id yes string Application key. Navigate to https://www.dwolla.com/applications (production) or https://sandbox.dwolla.com/applications (Sandbox) for your application key.
client_secret yes string Application secret. Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application secret.
code yes string The authorization code included in the redirect URL. Single use code with an expiration of 60 seconds.
grant_type yes string This must be set to authorization_code.
redirect_uri yes string The same redirect_uri specified in the intiation step.

Response parameters

Parameter Description
_links Contains a link to the associated user account resource
access_token A new access token with requested scopes
expires_in The lifetime of the access token, in seconds. Default is 3600.
refresh_token New refresh token
refresh_expires_in The lifetime of the refresh token, in seconds. Default is 5184000.
token_type Always bearer.
scope Pipe | delimited list of permission scopes granted
account_id A unique user account ID for the associated user account

Request

POST https://sandbox.dwolla.com/oauth/v2/token
Content-Type: application/x-www-form-urlencoded

client_id=CGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkwasGMuGhkem9Bo&client_secret=g7QLwvO37aN2HoKx1amekWi8a2g7AIuPbD5CcJSLqXIcDOxfTr&code=h6TvQZHr5BsVcfO43uOJ0uRkBLki&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fwww.myapplication.com%2Fredirect

Successful response

{
  "_links": {
    "account": {
      "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
    }
  },
  "access_token": "sdWPNdPyteKlVEmudKa9K2oFGs4s7VpiGfxBGFyDsolvuveafk",
  "expires_in": 3600,
  "refresh_token": "EDidiHt28eRzthBlXvDDECz67wK3rNEA2fGdq46t8jOYqAuC4N",
  "refresh_expires_in": 5184000,
  "token_type": "bearer",
  "scope": "send|transactions|funding|accountinfofull",
  "account_id": "ca32853c-48fa-40be-ae75-77b37504581b"
}

Refresh account authorization

Use a valid refresh_token to generate a new access_token and refresh_token pair.

NOTE: The refresh_token you receive will change every time you exchange either an authorization_code or refresh_token for a new token pair. However, If you exchange your last valid refresh_token within a short timespan of being issued a new token pair, Dwolla will return most recently issued token pair for a short duration of time.

HTTP request

Production: POST https://www.dwolla.com/oauth/v2/token

Sandbox: POST https://sandbox.dwolla.com/oauth/v2/token

Including the Content-Type: application/x-www-form-urlencoded header, the request is sent to the token endpoint with the following form-encoded parameters:

Request parameters

Parameter Required Type Description
client_id yes string Application key. Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application key.
client_secret yes string Application secret. Navigate to https://www.dwolla.com/applications (production) or https://dashboard-sandbox.dwolla.com/applications (Sandbox) for your application secret.
refresh_token yes string A valid refresh token.
grant_type yes string This must be set to refresh_token.

Response parameters

Parameter Description
_links Contains a link to the associated user account resource
access_token A new access token with requested scopes
expires_in The lifetime of the access token, in seconds. Default is 3600.
refresh_token New refresh token
refresh_expires_in The lifetime of the refresh token, in seconds. Default is 5184000.
token_type Always bearer.
scope Pipe | delimited list of permission scopes granted
account_id A unique user account ID for the associated user account

Request

POST https://sandbox.dwolla.com/oauth/v2/token
Content-Type: application/x-www-form-urlencoded

client_id=CGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkwasGMuGhkem9Bo&client_secret=g7QLwvO37aN2HoKx1amekWi8a2g7AIuPbD5CcJSLqXIcDOxfTr&grant_type=refresh_token&refresh_token=Pgkel9okjwTCfsvIvEDPrsomE1er1txeyoaAkTIBAuXza8WvZY

Successful response

{
  "_links": {
    "account": {
      "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
    }
  },
  "access_token": "F3jK4rg7FGlq4yRQ7vWECoXVD4zQq9Xg26VnxzMbHGusZqr7dF",
  "expires_in": 3600,
  "refresh_token": "DRlqGJ0IFsRK8xzjkKhjTOgz3meet6E91T2oacGCefHGU4h1hj",
  "refresh_expires_in": 5184000,
  "token_type": "bearer",
  "scope": "send|transactions|funding|managecustomers",
  "account_id": "ca32853c-48fa-40be-ae75-77b37504581b"
}

Invalid or expired refresh token response

{
  "error": "access_denied",
  "error_description": "Invalid refresh token."
}
{
  "error": "access_denied",
  "error_description": "Expired refresh token."
}

Application authorization

Some endpoints require an application access token, which is different from a user account access token. Application access tokens don’t require any particular user’s authorization, since they grant an application access to resources which belong to the application itself (i.e. events, webhooks, and webhook-subscriptions), rather than an account. Provide your client credentials to receive an application access token.

HTTP request

Production: POST https://www.dwolla.com/oauth/v2/token

Sandbox: POST https://sandbox.dwolla.com/oauth/v2/token

Including the Content-Type: application/x-www-form-urlencoded header, the request is sent to the token endpoint with the following form-encoded parameters:

Request parameters

Parameter Required Type Description
client_id yes string Application key. Navigate to https://www.dwolla.com/applications (production) or https://sandbox.dwolla.com/applications (Sandbox) for your application key.
client_secret yes string Application secret. Navigate to https://www.dwolla.com/applications (production) or https://sandbox.dwolla.com/applications (Sandbox) for your application secret.
grant_type yes string This must be set to client_credentials.

Response parameters

Parameter Description
access_token A new access token that is used to authenticate against resources that belong to the app itself.
expires_in The lifetime of the access token, in seconds. Default is 3600.
token_type Always bearer.

Request

POST https://sandbox.dwolla.com/oauth/v2/token
Content-Type: application/x-www-form-urlencoded

client_id=CGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkwasGMuGhkem9Bo&client_secret=g7QLwvO37aN2HoKx1amekWi8a2g7AIuPbD5CcJSLqXIcDOxfTr&grant_type=client_credentials
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python
# This example assumes you've already intialized the client. Reference the SDKs page for more information: https://developers.dwolla.com/pages/sdks.html
application_token = client.Auth.client()
// Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-node
// This example assumes you've already intialized the client. Reference the SDKs page for more information: https://developers.dwolla.com/pages/sdks.html
client.auth.client()
  .then(function(appToken) {
    return appToken.get('webhook-subscriptions');
  })
  .then(function(res) {
    console.log(JSON.stringify(res.body));
  });
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby
# This example assumes you've already intialized the client. Reference the SDKs page for more information: https://developers.dwolla.com/pages/sdks.html
application_token = $dwolla.auths.client
# => #<DwollaV2::Token client=#<DwollaV2::Client id="..." secret="..." environment=:sandbox> access_token="..." expires_in=3600 scope="...">
/**
 *  No support for this language yet. We recommend using an external REST client for making OAuth requests.
 **/

Root

The “root” serves as an entry point to the API, providing your application with the ability to fetch and discover resources available based on the OAuth access_token provided in the request. If a user account access token is provided in the request, the API will return links to resources that belong to a Dwolla account of that user (i.e. “accounts”). Alternatively, if an application access token is provided in the request, the API will return links to resources that belong to the Dwolla application (i.e. “events” and “webhook-subscriptions”).

  1. This endpoint requires an OAuth account access token or an Application access token but does not require a particular scope.

HTTP request

GET https://api.dwolla.com/

Request and response

GET https://api.dwolla.com/
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "account": {
      "href": "https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "account"
    }
  }
}
root = token.get "/"
root._links.account.href # => "https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc"
<?php
$rootApi = new DwollaSwagger\RootApi($apiClient);

$root = $rootApi->root();
$accountUrl = $root->_links["account"]->href; # => "https://api-sandbox.dwolla.com/accounts/ad5f2162-404a-4c4c-994e-6ab6c3a13254"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
root = token.get('/')
root.body['_links']['account']['href'] # => 'https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc'
token
  .get('/')
  .then(res => res.body._links.account.href); // => 'https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc'

Accounts

An Account represents a Dwolla account that was either established on dwolla.com, or created inline with the capture of the user account’s permissions via Dwolla’s OAuth flow. A user account grants authorization to an application via OAuth, which gives the application permission to interact with the API on their behalf.

Verified and unverified Accounts

With a transfer of money, at least one party must complete the identity verification process through creation of a Transfer CIP Verified account, either the sender or the receiver. It’s your decision about which party completes this process, based on your business model, and you may want to have both parties complete the identity verification process. In cases where a Dwolla user Account is sending funds to or receiving funds from your Account, the Account can remain unverified because your account is already verified. However, if you need to transfer funds between your users, at least one of them will need to have a Transfer CIP Verified Dwolla account.

For more information on Transfer accounts, both Transfer CIP Verified and Dwolla Direct, reference the account types resource article.

Migrating Dwolla user Accounts to Dwolla API Customers

Dwolla offers a seamless process for migrating existing user Accounts managed via OAuth on your platform to Dwolla API Customers. The user Account will maintain existing functionality on dwolla.com and will act as a separate Dwolla API Customer upon completion of the migration. To learn more about upgrading to the Dwolla API, please contact Sales.

Link Description
self URL of the Account resource
receive Follow the link to create a transfer to this Account.
funding-sources GET this link to list the Accounts’s funding sources.
transfers GET this link to list the Account’s transfers
customers (optional) If this link exists, this account can create and manage Dwolla API Customers.
send Follow the link to create a transfer to this Account.

Retrieve account details

This section shows you how to retrieve account information belonging to the authorized user. The developer can pass either an id or the entire location resource to make this request.

  1. This endpoint requires an OAuth account access token but does not require a particular scope.

HTTP request

GET https://api.dwolla.com/accounts/{id}

Request parameters

Parameter Required Type Description
id yes string Account unique identifier.

Errors

HTTP Status Message
403 Not authorized to get an Account by id.
404 Account not found.

Request and response

GET https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "account"
    },
    "receive": {
      "href": "https://api-sandbox.dwolla.com/transfers",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    },
    "funding-sources": {
      "href": "https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe/funding-sources",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    },
    "transfers": {
      "href": "https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe/transfers",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    },
    "send": {
      "href": "https://api-sandbox.dwolla.com/transfers",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    }
  },
  "id": "07844b76-bfeb-4a81-87ec-adebc7fa6cfe",
  "name": "Dwolla Sandbox",
  "timezoneOffset": 0
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
account_url = 'https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe'

account = account_token.get account_url
account.name # => "Jane Doe"
<?php
$accountUrl = 'https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe';

$accountsApi = new DwollaSwagger\AccountsApi($apiClient);

$account = $accountsApi->id($accountUrl);
print($account->name); # => "Dwolla Sandbox"
?>
account_url = 'https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe'

account = account_token.get(account_url)
account.body['name']
var accountUrl = 'https://api-sandbox.dwolla.com/accounts/07844b76-bfeb-4a81-87ec-adebc7fa6cfe';

accountToken
  .get(accountUrl)
  .then(res => res.body.name); // => 'Dwolla Sandbox'

List funding sources for an account

Retrieve a list of funding sources that belong to an Account. By default, all funding sources are returned unless the removed querystring parameter is set to false in the request.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

GET https://api.dwolla.com/accounts/{id}/funding-sources

Request parameters

Parameter Required Type Description
id yes string Account’s unique identifier.
removed no boolean Filter removed funding sources. Defaults to true. Set to false to filter out removed funding sources from list (i.e. - /accounts/{id}/funding-sources?removed=false).

Errors

HTTP Status Message
403 Not authorized to list funding sources.
404 Account not found.

Request and response

GET https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc/funding-sources
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc/funding-sources",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    }
  },
  "_embedded": {
    "funding-sources": [
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/118b08b9-e1eb-48b7-94ad-866989b0764e",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
          },
          "account": {
            "href": "https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "account"
          }
        },
        "id": "118b08b9-e1eb-48b7-94ad-866989b0764e",
        "status": "verified",
        "type": "bank",
        "name": "First Midwestern Bank",
        "created": "2015-08-31T14:52:55.000Z",
        "removed": false,
        "channels": [
          "ach"
        ]
      },
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/297460a0-101b-498c-8184-2eb33ff22d34",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
          },
          "account": {
            "href": "https://api-sandbox.dwolla.com/accounts/dcbb698d-bee7-4f79-8576-e4301bdc57fc",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "account"
          },
          "with-available-balance": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/297460a0-101b-498c-8184-2eb33ff22d34",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
          },
          "balance": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/297460a0-101b-498c-8184-2eb33ff22d34/balance",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "balance"
          }
        },
        "id": "297460a0-101b-498c-8184-2eb33ff22d34",
        "status": "verified",
        "type": "balance",
        "name": "Balance",
        "created": "2015-08-31T14:52:55.000Z",
        "removed": false,
        "channels": []
      }
    ]
  }
}
account_url = 'https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b'

funding_sources = account_token.get "#{account_url}/funding-sources"
funding_sources._embedded['funding-sources'][0].name # => "Jane Doe's Checking"
<?php
$accountUrl = 'https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fundingSources = $fsApi->getAccountFundingSources($accountUrl);
$fundingSources->_embedded->{'funding-sources'}[0]->name); # => "Jane Doe’s Checking"
?>
account_url = 'https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b'

funding_sources = account_token.get('%s/funding-sources' % account_url)
funding_sources.body['_embedded']['funding-sources'][0]
var accountUrl = 'https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b';

accountToken
  .get(`${accountUrl}/funding-sources`)
  .then(res => res.body._embedded['funding-sources'][0].name); // => 'ABC Bank Checking'

List and search transfers for an account

This section covers how to retrieve an Account’s list of transfers. Transaction search is supported by passing in optional querystring parameters such as: search which represents a term to search on, startAmount, endAmount, startDate, and endDate.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP request

GET https://api.dwolla.com/accounts/{id}/transfers

Request parameters

Parameter Required Type Description
id yes string Account unique identifier to get transfers for.
search no string A string to search on fields: firstName, lastName, email, businessName, and Account Id. (/transfers?search=Doe)
startAmount no string Only include transactions with an amount equal to or greater than startAmount. Can optionally be used with endAmount to specify an amount range.
endAmount no string Only include transactions with an amount equal to or less than endAmount. Can optionally be used with startAmount to specify an amount range.
startDate no string Only include transactions created after this date. ISO-8601 format: YYYY-MM-DD. Can optionally be used with endDate to specify a date range.
endDate no string Only include transactions created before than this date. ISO-8601 format: YYYY-MM-DD. Can optionally be used with startDate to specify a date range.
status no string Filter results on transaction status. Possible values: pending, processed, failed, reclaimed, or cancelled.
limit no integer Number of search results to return. Defaults to 25.
offset no integer Number of search results to skip. Used for pagination.

Errors

HTTP Status Message
404 Account not found.

Request and response

GET https://api.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3/transfers
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3/transfers"
    },
    "first": {
      "href": "https://api-sandbox.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3/transfers?limit=25&offset=0"
    },
    "last": {
      "href": "https://api-sandbox.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3/transfers?limit=25&offset=0"
    }
  },
  "_embedded": {
    "transfers": [
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/transfers/DC68A3DC-3C61-E511-80DA-0AA34A9B2388"
          },
          "source": {
            "href": "https://api-sandbox.dwolla.com/accounts/CA32853C-48FA-40BE-AE75-77B37504581B"
          },
          "destination": {
            "href": "https://api-sandbox.dwolla.com/accounts/A84222D5-31D2-4290-9A96-089813EF96B3"
          }
        },
        "id": "DC68A3DC-3C61-E511-80DA-0AA34A9B2388",
        "status": "processed",
        "amount": {
          "value": "50.00",
          "currency": "USD"
        },
        "created": "2015-09-22T15:16:14.180Z"
      },
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/transfers/D36FD9AA-6E5C-E511-80DA-0AA34A9B2388"
          },
          "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/2BFF2631-4006-45D6-BBBD-A7BE4853E870"
          },
          "destination": {
            "href": "https://api-sandbox.dwolla.com/accounts/A84222D5-31D2-4290-9A96-089813EF96B3"
          }
        },
        "id": "D36FD9AA-6E5C-E511-80DA-0AA34A9B2388",
        "status": "processed",
        "amount": {
          "value": "5000.00",
          "currency": "USD"
        },
        "created": "2015-09-03T18:11:53.410Z"
      }
    ]
  },
  "total": 2
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
account_url = 'https://api-sandbox.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3'

transfers = account_token.get "#{account_url}/transfers"
transfers._embedded.transfers[0].status # => "processed"
<?php
$accountUrl = 'https://api-sandbox.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3';

$transfersApi = new DwollaSwagger\TransfersApi($apiClient);

$transfers = $transfersApi->getAccountTransfers($accountUrl);
$transfers->_embedded->transfers[0]->status; # => "processed"
?>
account_url = 'https://api-sandbox.dwolla.com/accounts/a84222d5-31d2-4290-9a96-089813ef96b3'

transfers = account_token.get('%s/transfers' % account_url)
transfers.body['_embedded']['transfers'][0]['status'] # => "processed"
var accountUrl = 'https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b';

accountToken
  .get(`${accountUrl}/transfers`)
  .then(res => res.body._embedded.transfers.[0].status); // => 'processed'

List mass payments for an account

This section covers how to retrieve an Account’s list of previously created mass payments. Mass payments are returned ordered by date created, with most recent mass payments appearing first.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP request

GET https://api.dwolla.com/accounts/{id}/mass-payments

Request parameters

Parameter Required Type Description
id yes string Account unique identifier to get mass payments for.
limit no integer How many results to return. Defaults to 25.
offset no integer How many results to skip.

HTTP Status and Error Codes

HTTP Status Code Description
403 NotAuthorized Not authorized to list mass payments.
404 NotFound Account not found.

Request and response

GET https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b/mass-payments
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

....

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b/mass-payments"
    },
    "first": {
      "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b/mass-payments?limit=25&offset=0"
    },
    "last": {
      "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b/mass-payments?limit=25&offset=0"
    }
  },
  "_embedded": {
    "mass-payments": [
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/mass-payments/b4b5a699-5278-4727-9f81-a50800ea9abc"
          },
          "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/84c77e52-d1df-4a33-a444-51911a9623e9"
          },
          "items": {
            "href": "https://api-sandbox.dwolla.com/mass-payments/b4b5a699-5278-4727-9f81-a50800ea9abc/items"
          }
        },
        "id": "b4b5a699-5278-4727-9f81-a50800ea9abc",
        "status": "complete",
        "created": "2015-09-03T14:14:10.000Z",
        "metadata": {
          "UserJobId": "some ID"
        }
      }
    ]
  },
  "total": 1
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
account_url = 'https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b'

mass_payments = account_token.get "#{account_url}/mass-payments", limit: 10
mass_payments._embedded['mass-payments'][0].status # => "complete"
/**
 *  No example for this language yet. Coming soon.
 **/
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python
account_url = 'https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b'

transfers = account_token.get('%s/mass-payments' % account_url, limit = 10)
transfers.body['_embedded']['mass-payments'][0]['status'] # => "complete"
var accountUrl = 'https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b';

accountToken
  .get(`${accountUrl}/mass-payments`)
  .then(res => res.body._embedded['mass-payments'][0].status); // => 'complete'

Funding sources

Add and retrieve ACH bank account information via funding sources, which are available to the Accounts resource. Transfer CIP accounts can have a maximum of two funding sources, whereas Direct accounts can have a maximum of one funding source.

Funding source resource

Parameter Description
id The funding source unique identifier.
status Possible values are unverified or verified. Determines if the funding source has completed verification.
type Type of funding source. Possible values are bank or balance.
bankAccountType An optional attribute for bank funding sources that determines the type of account. Possible values are checking or savings.
name Arbitrary nickname for the funding source.
created ISO-8601 timestamp for when the funding source was created.
removed Determines if the funding source has been removed. A boolean true if the funding source was removed or false if the funding source is not removed.
channels List of processing channels. ACH is the default processing channel for bank transfers. Possible values are ach or wire.
bankName The financial institution name.
{
    "routingNumber": "222222226",
    "accountNumber": "123456789",
    "bankAccountType": "checking",
    "name": "Jane Doe - Checking"
}

Create a funding source

This section details how to add a bank account to a Dwolla account. The bank account will have a status of unverified upon creation. Before a Dwolla account is eligible to transfer money from their bank or credit union account they need to verify ownership of the account via micro-deposit verification.

For more information on micro-deposit verification, reference the funding source verification resource article.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

POST https://api.dwolla.com/funding-sources

Request parameters

Parameter Required Type Description
accountNumber yes string The bank account number.
routingNumber yes string The bank account’s routing number.
bankAccountType yes string Type of bank account: checking or savings.
name yes string Arbitrary nickname for the funding source.

Errors

HTTP Status Message
400 Duplicate funding source or validation error.
403 Not authorized to create funding source.

Request and response

POST /funding-sources
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
{
    "routingNumber": "222222226",
    "accountNumber": "123456789",
    "bankAccountType": "checking",
    "name": "My Bank"
}

...

HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/funding-sources/04173e17-6398-4d36-a167-9d98c4b1f1c3

Retrieve a funding source

This section covers how to retrieve a funding source by id.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

GET https://api.dwolla.com/funding-sources/{id}

Request parameters

Parameter Required Type Description
id yes string id of funding source to retrieve.

Errors

HTTP Status Message
404 Funding source not found.

Request and response

GET https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
    "_links": {
        "self": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        },
        "account": {
            "href": "https://api-sandbox.dwolla.com/accounts/ad5f2162-404a-4c4c-994e-6ab6c3a13254",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "account"
        }
    },
    "id": "a46441a8-2243-4a8b-b8e4-429f633b02ca",
    "status": "verified",
    "type": "bank",
    "bankAccountType": "checking",
    "name": "Test checking account",
    "created": "2016-08-15T17:05:49.000Z",
    "removed": false,
    "channels": [
        "ach"
    ]
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

funding_source = account_token.get funding_source_url
funding_source.name # => "Test checking account"
<?php
$fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fundingSource = $fsApi->id($fundingSourceUrl);
$fundingSource->name; # => "Test checking account"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

funding_source = account_token.get(funding_source_url)
funding_source.body['name'] # => 'Test checking account'
var fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';

accountToken
  .get(fundingSourceUrl)
  .then(res => res.body.name); // => "Test checking account"

Update a funding source

This section covers how to update a bank funding source. The accountNumber, routingNumber, type, and name are all optional attributes that can be updated on a funding source when it has an unverified status. You can choose to update only name, name and routingNumber, name and accountNumber, name and type, or all four attributes. Any attribute that isn’t updated remains the same as it was prior to update, including the funding source id. The name attribute can be updated when a funding source has either an unverified or verified status.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

POST https://api.dwolla.com/funding-sources/{id}

Request parameters

Parameter Required Type Description
id yes string id of funding source to update.
name no string Arbitrary nickname for the funding source. Must be 50 characters or less.
bankAccountType no string Type of bank account: checking or savings.
accountNumber no string The bank account number.
routingNumber no string The bank account routing number.

HTTP Status and Error Codes

HTTP Status Code Description
404 NotFound Funding source not found.
400 ValidationError Only funding sources of type=“bank” can be updated.
400 ValidationError Invalid bank name.
403 InvalidResourceState A removed bank cannot be updated.

Request and response

POST https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "name": "Test Checking - 1234"
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'
request_body = {
      "name" => "Test Checking - 1234",
}

funding_source = account_token.post "#{funding_source_url}", request_body
funding_source.name # => "Test Checking - 1234"
/**
 *  No example for this language yet. Coming soon.
 **/
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'
request_body = {
  "name": "Test Checking - 1234"
}

funding_source = account_token.post('funding-sources', request_body)
funding_source.body['name'] # => 'Test Checking - 1234'
var fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';
var requestBody = {
  name: "Test Checking - 1234"
};

accountToken
  .post(fundingSourceUrl, requestBody)
  .then(res => res.body.name); // => "Test Checking - 1234"

Initiate micro-deposits

This section covers how to initiate micro-deposits for bank verification. Reference the funding source verification resource article for more information on the micro-deposit method of bank account verification.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

POST https://api.dwolla.com/funding-sources/{id}/micro-deposits

Request parameters

Parameter Required Type Description
id yes string id of funding source to initiate micro-deposits to.

HTTP Status and Error Codes

HTTP Status Code Description
201 Created Micro deposits initiated
404 NotFound Funding source not found

Request and response

POST /funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909/micro-deposits
Authorization: Bearer 8tJjM7iTjujLthkbVPMUcHLqMNw4uv5kG712g9j1RRBHplGpwo
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Cache-Control: no-cache

HTTP/1.1 201 Created
Location: https://api.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909/micro-deposits
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source_url = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909'

account_token.post "#{funding_source_url}/micro-deposits"
var fundingSourceUrl = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909';

accountToken.post(`#{fundingSourceUrl}/micro-deposits`);
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
funding_source_url = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909'

account_token.post('%s/micro-deposits' % funding_source_url)
<?php
$fundingSourceUrl = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fsApi->microDeposits(null, $fundingSourceUrl);
?>

Verify micro-deposits

This section covers how to verify micro-deposits for bank verification. Reference the funding source verification resource article for more information on the micro-deposit method of bank account verification.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

POST https://api.dwolla.com/funding-sources/{id}/micro-deposits

Request parameters

Parameter Required Type Description
id yes string id of funding source to verify micro-deposits on.
amount1 yes string An amount JSON object of first micro-deposit. Contains value and currency.
amount2 yes string An amount JSON object of second micro-deposit. Contains value and currency.

HTTP Status and Error Codes

HTTP Status Code Description
200 OK Micro deposits verified
202 TryAgainLater “Invalid wait time.”
400 ValidationError InvalidAmount
400 ValidationError “Wrong amount(s).”
403 InvalidResourceState “Too many attempts.”
403 InvalidResourceState “Bank already verified.”
404 NotFound Micro deposits not initiated
404 NotFound Funding source not found
500 Unknown “Verify microdeposits returned an unknown error.”

Request and response

POST /funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909/micro-deposits
Authorization: Bearer 8tJjM7iTjujLthkbVPMUcHLqMNw4uv5kG712g9j1RRBHplGpwo
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json

{
    "amount1": {
        "value": "0.03",
        "currency": "USD"
    },
    "amount2": {
        "value": "0.09",
        "currency": "USD"
    }
}

HTTP 200 OK
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source_url = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909'
request_body = {
  :amount1 => {
    :value => "0.03",
    :currency => "USD"
  },
  :amount2 => {
    :value => "0.09",
    :currency => "USD"
  }
}

account_token.post "#{funding_source_url}/micro-deposits", request_body
var fundingSourceUrl = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909';
var requestBody = {
  amount1: {
    value: '0.03',
    currency: 'USD'
  },
  amount2: {
    value: '0.09',
    currency: 'USD'
  }
};

accountToken.post(`${fundingSourceUrl}/micro-deposits`, requestBody);
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
funding_source_url = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909'
request_body = {
    "amount1": {
        "value": "0.03",
        "currency": "USD"
    },
    "amount2": {
        "value": "0.09",
        "currency": "USD"
    }
}

account_token.post('%s/micro-deposits' % funding_source_url, request_body)
<?php
$fundingSourceUrl = 'https://api-sandbox.dwolla.com/funding-sources/e52006c3-7560-4ff1-99d5-b0f3a6f4f909';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fsApi->microDeposits([
  'amount1' => [
    'value' => '0.03',
    'currency' => 'USD'
  ],
  'amount2' => [
    'value' => '0.09',
    'currency' => 'USD'
  ],
  $fundingSourceUrl
]);
?>

Retrieve micro-deposits details

This section shows how to retrieve the status of micro-deposits and check if micro-deposits are eligible for verification. If the status of micro-deposits is failed, a failure object will be returned in the response body which includes the ACH return code and description.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

GET https://api.dwolla.com/funding-sources/{id}/micro-deposits

Request parameters

Parameter Required Type Description
id no string id of funding source to check status of validation deposits.

HTTP Status and Error Codes

HTTP Status Code Description
200 Ok Pending micro-deposits exist.

Request and response

GET https://api.dwolla.com/funding-sources/dfe59fdd-7467-44cf-a339-2020dab5e98a/micro-deposits
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/dfe59fdd-7467-44cf-a339-2020dab5e98a/micro-deposits",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "micro-deposits"
    },
    "verify-micro-deposits": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/dfe59fdd-7467-44cf-a339-2020dab5e98a/micro-deposits",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "micro-deposits"
    }
  },
  "created": "2016-12-30T20:56:53.000Z",
  "status": "failed",
  "failure": {
    "code": "R03",
    "description": "No Account/Unable to Locate Account"
  }
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

funding_source = account_token.get "#{funding_source_url}/micro-deposits"
funding_source.status # => "failed"
<?php
$fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fundingSource = $fsApi->verifyMicroDepositsExist($fundingSourceUrl);
$fundingSource->status; # => "failed"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

funding_source = account_token.get('%s/micro-deposits' % funding_source_url)
funding_source.body['status'] # => 'failed'
var fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';

accountToken
  .get(`${fundingSourceUrl}/micro-deposits`)
  .then(res => res.body.status); // => "failed"

Remove a funding source

Remove a funding source by id. A removed funding source is soft deleted and can still be accessed when retrieved.

  1. This endpoint requires an OAuth account access token with the Funding scope.

HTTP request

POST https://api.dwolla.com/funding-sources/{id}

Request parameters

Parameter Required Type Description
id yes id of funding source to delete.
removed yes Specify a value of true to remove the associated funding source.

Errors

HTTP Status Message
404 Funding source not found.

Request and response

POST /funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
{
    "removed": true
}

...

HTTP 200 OK
{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c",
      "type": "funding-source"
    }
  },
  "id": "692486f8-29f6-4516-a6a5-c69fd2ce854c",
  "status": "verified",
  "type": "bank",
  "bankAccountType": "checking",
  "name": "Test bank account",
  "created": "2016-06-08T21:37:30.000Z",
  "removed": true,
  "channels": [
      "ach"
  ]
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

request_body = {
  :removed => true
}

account_token.post "#{funding_source_url}", request_body
<?php
$fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';

$fsApi = new DwollaSwagger\FundingsourcesApi($apiClient);

$fsApi->softDelete(['removed' => true ], $fundingSourceUrl);
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
funding_source_url = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

account_token.delete(funding_source_url)
var fundingSourceUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';
var requestBody = {
  removed: true
};

accountToken.post(fundingSourceUrl, requestBody);

Transfers

A transfer represents money being transferred from a source to a destination.

Transfer resource

Parameter Description
id Transfer unique identifier
status Either processed, pending, cancelled, failed, or reclaimed
amount An amount JSON object. See below
created ISO-8601 timestamp
metadata A metadata JSON object
clearing A clearing JSON object.
correlationId A unique string value attached to a transfer resource which can be used for traceability between Dwolla and a partner application.
{
  "_links": {},
  "_embedded": {},
  "id": "string",
  "status": "string",
  "amount": {
    "value": "string",
    "currency": "string"
  },
  "created": "2015-10-02T19:48:40.485Z",
  "metadata": {},
  "correlationId": "string"
}

Amount JSON object

Parameter Description
value Amount of money
currency String, USD

Initiate a transfer

This section covers how to initiate a transfer from a Dwolla Account resource.

  1. This endpoint requires an OAuth account access token with the Send scope.

HTTP request

POST https://api.dwolla.com/transfers

Request parameters

Parameter Required Type Description
_links yes object A _links JSON object describing the desired source and destination of a transfer. See below for possible values for source and destination.
amount yes object An amount JSON object. See above.
metadata no object A metadata JSON object with a maximum of 10 key-value pairs (each key and value must be less than 255 characters).
fees no array an array of fee JSON objects that contain unique fee transfers. See below.
correlationId no string A unique string value attached to a transfer which can be used for traceability between Dwolla and a partner application. Must be less than 255 characters and contain no spaces. Acceptable characters are: a-Z, 0-9, -, ., and _.

Source and destination types

Source Type URI Description
Funding source https://api.dwolla.com/funding-sources/{id} A bank or balance funding source.
Destination Type URI Description
Account https://api.dwolla.com/accounts/{id} Destination Account of a transfer.
Email mailto:johndoe@email.com Email address of existing Dwolla Account or recipient (recipient will create a Dwolla Account to claim funds)
Funding source https://api.dwolla.com/funding-sources/{id} Destination of an Account’s own bank or balance funding source.

Facilitator fee

The facilitator fee is a feature allowing for a flat rate amount to be removed from a payment as a fee, and sent to the creator of the Dwolla application. The fee does not affect the original payment amount, and exists as a separate Transfer resource with a unique transfer ID. Within a transfer request you can specify an optional fees request parameter, which is an array of fee objects that can represent many unique fee transfers.

For more information on collecting fees on payments, reference the facilitator fee resource article.

A fee JSON object

Parameter Description
_links Contains a charge-to JSON object with a link to the associated source or destination Account resource.
amount Amount of fee to charge. An amount JSON object. See above

Fee example:

"fees": [
  {  
     "_links":{  
        "charge-to":{  
           "href":"https://api-sandbox.dwolla.com/accounts/d795f696-2cac-4662-8f16-95f1db9bddd8"
        }
     },
     "amount":{  
        "value":"4.00",
        "currency":"USD"
     }
  }
]

HTTP Status and Error Codes

HTTP Status Message
400 Transfer failed.
403 OAuth token does not have Send scope.

Request and response

POST https://api.dwolla.com/transfers
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
Idempotency-Key: 19051a62-3403-11e6-ac61-9e71128cae77

{
    "_links": {
        "source": {
            "href": "https://api.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4"
        },
        "destination": {
            "href": "https://api.dwolla.com/accounts/07D59716-EF22-4FE6-98E8-F3190233DFB8"
        }
    },
    "amount": {
        "currency": "USD",
        "value": "10.00"
    },
    "correlationId": "8a2cdc8d-629d-4a24-98ac-40b735229fe2"
}

...

HTTP/1.1 201 Created
Location: https://api.dwolla.com/transfers/74c9129b-d14a-e511-80da-0aa34a9b2388
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
request_body = {
  :_links => {
    :source => {
      :href => "https://api.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4"
    },
    :destination => {
      :href => "https://api.dwolla.com/accounts/07D59716-EF22-4FE6-98E8-F3190233DFB8"
    }
  },
  :amount => {
    :currency => "USD",
    :value => "1.00"
  }
}

transfer = account_token.post "transfers", request_body
transfer.headers[:location] # => "https://api.dwolla.com/transfers/74c9129b-d14a-e511-80da-0aa34a9b2388"
<?php
$transfersApi = new DwollaSwagger\TransfersApi($apiClient);

$transfer = $transfersApi->create([
  '_links' => [
    'source' => [
      'href' => 'https://api.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4',
    ],
    'destination' => [
      'href' => 'https://api.dwolla.com/customers/07D59716-EF22-4FE6-98E8-F3190233DFB8'
    ]
  ],
  'amount' => [
    'currency' => 'USD',
    'value' => '1.00'
  ]
]);
$transfer; # => "https://api.dwolla.com/transfers/74c9129b-d14a-e511-80da-0aa34a9b2388"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
request_body = {
  '_links': {
    'source': {
      'href': 'https://api.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4'
    },
    'destination': {
      'href': 'https://api.dwolla.com/customers/07D59716-EF22-4FE6-98E8-F3190233DFB8'
    }
  },
  'amount': {
    'currency': 'USD',
    'value': '1.00'
  }
}

transfer = account_token.post('transfers', request_body)
transfer.headers['location'] # => 'https://api.dwolla.com/transfers/74c9129b-d14a-e511-80da-0aa34a9b2388'
var requestBody = {
  _links: {
    source: {
      href: 'https://api.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4'
    },
    destination: {
      href: 'https://api.dwolla.com/customers/07D59716-EF22-4FE6-98E8-F3190233DFB8'
    }
  },
  amount: {
    currency: 'USD',
    value: '1.00'
  }
};

accountToken
  .post('transfers', requestBody)
  .then(res => res.headers.get('location')); // => 'https://api.dwolla.com/transfers/74c9129b-d14a-e511-80da-0aa34a9b2388'

Retrieve a transfer

This section covers how to retrieve a transfer belonging to an Account by its id.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP request

GET https://api.dwolla.com/transfers/{id}

Request parameters

Parameter Required Type Description
id yes string The id of the transfer to be retrieved.

Errors

HTTP Status Message
404 Transfer not found.

Request and response

GET https://api.dwolla.com/transfers/4C8AD8B8-3D69-E511-80DB-0AA34A9B2388
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/transfers/4C8AD8B8-3D69-E511-80DB-0AA34A9B2388"
    },
    "source": {
      "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
    },
    "destination": {
      "href": "https://api.dwolla.com/customers/01B47CB2-52AC-42A7-926C-6F1F50B1F271"
    }
  },
  "id": "4C8AD8B8-3D69-E511-80DB-0AA34A9B2388",
  "status": "pending",
  "amount": {
    "value": "225.00",
    "currency": "USD"
  },
  "created": "2015-10-02T19:42:32.950Z",
  "metadata": {
    "foo": "bar",
    "baz": "foo"
  }
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
transfer_url = 'https://api.dwolla.com/transfers/4C8AD8B8-3D69-E511-80DB-0AA34A9B2388'

transfer = account_token.get transfer_url
transfer.status # => "pending"
<?php
$transferUrl = 'https://api.dwolla.com/transfers/4C8AD8B8-3D69-E511-80DB-0AA34A9B2388';

$transfersApi = new DwollaSwagger\TransfersApi($apiClient);

$transfer = $transfersApi->byId($transferUrl);
$transfer->status; # => "pending"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
transfer_url = 'https://api.dwolla.com/transfers/4C8AD8B8-3D69-E511-80DB-0AA34A9B2388'

fees = account_token.get(transfer_url)
fees.body['status'] # => 'pending'
var transferUrl = 'https://api.dwolla.com/transfers/4C8AD8B8-3D69-E511-80DB-0AA34A9B2388';

accountToken
  .get(transferUrl)
  .then(res => res.body.status); // => 'pending'

List fees for a transfer

This section outlines how to retrieve fees charged on a created transfer. Fees are visible to the Account that is charged the fee, as well as the Dwolla Account that is involved in receiving the fee.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP request

GET https://api.dwolla.com/transfers/{id}/fees

Request parameters

Parameter Required Type Description
id yes string The id of the transfer to retrieve fees for.

Errors

HTTP Status Message
404 Transfer not found.

Request and response

GET https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388/fees
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "transactions": [
    {
      "_links": {
        "self": {
          "href": "https://api-sandbox.dwolla.com/transfers/416a2857-c887-4cca-bd02-8c3f75c4bb0e"
        },
        "source": {
          "href": "https://api-sandbox.dwolla.com/customers/b442c936-1f87-465d-a4e2-a982164b26bd"
        },
        "destination": {
          "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
        },
        "created-from-transfer": {
          "href": "https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388"
        }
      },
      "id": "416a2857-c887-4cca-bd02-8c3f75c4bb0e",
      "status": "pending",
      "amount": {
        "value": "2.00",
        "currency": "usd"
      },
      "created": "2016-02-22T20:46:38.777Z"
    },
    {
      "_links": {
        "self": {
          "href": "https://api-sandbox.dwolla.com/transfers/e58ae1f1-7007-47d3-a308-7e9aa6266d53"
        },
        "source": {
          "href": "https://api-sandbox.dwolla.com/customers/b442c936-1f87-465d-a4e2-a982164b26bd"
        },
        "destination": {
          "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
        },
        "created-from-transfer": {
          "href": "https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388"
        }
      },
      "id": "e58ae1f1-7007-47d3-a308-7e9aa6266d53",
      "status": "pending",
      "amount": {
        "value": "1.00",
        "currency": "usd"
      },
      "created": "2016-02-22T20:46:38.860Z"
    }
  ],
  "total": 2
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby
transfer_url = 'https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388'

fees = account_token.get "#{transfer_url}/fees"
fees.total # => 2
/**
 *  No example for this language yet.
 **/
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
transfer_url = 'https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388'

fees = account_token.get('%s/fees' % transfer_url)
fees.body['total'] # => 2
var transferUrl = 'https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388';

accountToken
  .get(`${transferUrl}/fees`)
  .then(res => res.body.total); // => 2

Retrieve a transfer failure reason

When a bank transfer fails for an Account, Dwolla returns a failure link when retrieving the transfer by its Id. This failure link is used to retrieve the ACH return code and description. For reference, the list of possible failure codes and descriptions are shown in the Transfer failures resource article.

Note: If a transfer fails to/from a bank account then the bank will automatically be removed from the Dwolla system for all ACH return codes except an R01.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP Request

GET https://api.dwolla.com/transfers/{id}/failure

Request parameters

Parameter Required Type Description
id yes string Transfer unique identifier.

Request and Response

GET https://api-sandbox.dwolla.com/transfers/e6d9a950-ac9e-e511-80dc-0aa34a9b2388/failure
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/transfers/E6D9A950-AC9E-E511-80DC-0AA34A9B2388/failure"
    }
  },
  "code": "R1",
  "description": "Insufficient Funds"
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby
transfer_url = 'https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388'

failure = account_token.get "#{transfer_url}/failure"
failure.code # => "R1"
/**
 *  No example for this language yet.
 **/
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
transfer_url = 'https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388'

failure = account_token.get('%s/failure' % transfer_url)
failure.body['code'] # => 'R1'
var transferUrl = 'https://api-sandbox.dwolla.com/transfers/83eb4b5e-a5d9-e511-80de-0aa34a9b2388';

accountToken
  .get(`${transferUrl}/failure`)
  .then(res => res.body.code); // => 'R1'

Cancel a transfer

When a bank transfer is eligible for cancellation, Dwolla returns a cancel link when getting the transfer by Id. This cancel link is used to trigger the cancellation, preventing the bank transfer from processing further. A bank transfer is cancellable up until 4pm CT on that same business day if the transfer was initiated prior to 4PM CT. If a transfer was initiated after 4pm CT, it can be cancelled anytime before 4pm CT on the following business day.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP Request

POST https://api.dwolla.com/transfers/{id}

Request parameters

Parameter Required Type Description
status yes string Possible value: cancelled.

Request and Response

POST https://api-sandbox.dwolla.com/transfers/3d48c13a-0fc6-e511-80de-0aa34a9b2388
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

{
    "status": "cancelled"
}

...

{
  "_links": {
    "cancel": {
      "href": "https://api-sandbox.dwolla.com/transfers/3d48c13a-0fc6-e511-80de-0aa34a9b2388"
    },
    "source": {
      "href": "https://api-sandbox.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
    },
    "funding-transfer": {
      "href": "https://api-sandbox.dwolla.com/transfers/3c48c13a-0fc6-e511-80de-0aa34a9b2388"
    },
    "self": {
      "href": "https://api-sandbox.dwolla.com/transfers/3d48c13a-0fc6-e511-80de-0aa34a9b2388"
    },
    "destination": {
      "href": "https://api-sandbox.dwolla.com/customers/05e267e5-c13d-491a-93a8-da52b721f123"
    }
  },
  "id": "3d48c13a-0fc6-e511-80de-0aa34a9b2388",
  "status": "cancelled",
  "amount": {
    "value": "22.00",
    "currency": "usd"
  },
  "created": "2016-01-28T22:34:02.663Z",
  "metadata": {
    "foo": "bar",
    "baz": "boo"
  }
}

MassPay

Dwolla MassPay allows you to easily send up to 5,000 payments one API request. The payments are funded from a single user’s specified funding source and processed asynchronously upon submission.

Your mass payment will initially be pending and then processed. As the service processes your mass payment, each item is processed one after the other, at a rate between 0.5 sec. - 1 sec. / item. Therefore, you can expect a 1000-item MassPay to be completed between 8-16 minutes.

MassPay offers a significant advantage over repeatedly calling the Transfers endpoint for each individual transaction. A key benefit is that a bank-funded MassPay only incurs a single ACH debit from the bank account to fund the entire batch of payments. The alternative approach will incur an ACH debit from the bank funding source for each individual payment. Those who used this approach have reported incurring fees from their financial institutions for excessive ACH transactions.

Mass payment resource

Parameter Description
id Mass payment unique identifier.
status Either deferred: A created mass payment that can be processed at a later time. pending: A mass payment that is pending and awaiting processing. A mass payment has a pending status for a brief period of time and cannot be cancelled. processing: A mass payment that is processing. complete: A mass payment successfully completed processing.
created ISO-8601 timestamp.
metadata A metadata JSON object.
total The sum amount of all items in the mass payment.
totalFees The sum amount of all fees charged for the mass payment.
correlationId A unique string value attached to a mass payment resource which can be used for traceability between Dwolla and a partner application.
{
    "_links": {
        "self": {
            "href": "https://api-sandbox.dwolla.com/mass-payments/da835c07-1e12-4212-8b93-a7e0013dfd98",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "mass-payment"
        },
        "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        },
        "items": {
            "href": "https://api-sandbox.dwolla.com/mass-payments/da835c07-1e12-4212-8b93-a7e0013dfd98/items",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "mass-payment-item"
        }
    },
    "id": "da835c07-1e12-4212-8b93-a7e0013dfd98",
    "status": "complete",
    "created": "2017-08-31T19:18:02.000Z",
    "metadata": {
        "batch": "batch1"
    },
    "total": {
        "value": "0.02",
        "currency": "USD"
    },
    "totalFees": {
        "value": "0.00",
        "currency": "USD"
    },
    "correlationId": "d028beed-8152-481d-9427-21b6c4d99644"
}

Initiate a mass payment

This section covers how to initiate a mass payment from an Account resource. A mass payment contains a list of items representing individual payments. Optionally, mass payments can contain metadata and a correlationId on the mass payment itself as well as items contained in the mass payment, which can be used to pass along additional information with the mass payment and item respectively. If a correlationId is included on a mass payment item it will be passed along to the transfer created from the item and can be searched on.

Deferred mass payment

A mass payment can be created with a status of deferred, which allows you to create the mass payment and defer processing to a later time. To trigger processing on a deferred mass payment, you’ll update the mass payment with a status of pending. A deferred mass payment can be cancelled by updating the mass payment with a status of cancelled.

  1. This endpoint requires an OAuth account access token with the Send scope.

HTTP request

POST https://api.dwolla.com/mass-payments

Request parameters

Parameter Required Type Description
_links yes object A _links JSON object describing the desired source of a mass payment. See below for possible values for source and destination.
items yes array an array of item JSON objects that contain unique payments. See below
metadata no object A metadata JSON object with a maximum of 10 key-value pairs (each key and value must be less than 255 characters).
status no string Acceptable value is: deferred.
correlationId no string A unique string value attached to a mass payment which can be used for traceability between Dwolla and a partner application. Must be less than 255 characters and contain no spaces. Acceptable characters are: a-Z, 0-9, -, ., and _.

Source and destination values

Source Type URI Description
Funding source https://api.dwolla.com/funding-sources/{id} A bank or balance funding source of an Account.
Destination Type URI Description
Account https://api.dwolla.com/accounts/{id} Destination Account of a transfer.
Email mailto:johndoe@email.com Email address of existing Dwolla Account or recipient (recipient will create a Dwolla Account to claim funds)

Mass payment item

Parameter Description
_links A _links JSON object describing the desired destination of a mass payment. See above for possible values for destination.
amount An amount JSON object containing currency and value keys.
metadata A metadata JSON object with a maximum of 10 key-value pairs (each key and value must be less than 255 characters).
correlationId A unique string value attached to a mass payment item which can be used for traceability between Dwolla and a partner application. The correlationId will be passed along to a transfer that is created from an item and can be searched on. Must be less than 255 characters and contain no spaces. Acceptable characters are: a-Z, 0-9, -, ., and _.

Item object example:

{
  "_links": {
      "destination": {
          "href": "https: //api.dwolla.com/funding-sources/01B47CB2-52AC-42A7-926C-6F1F50B1F271"
      }
  },
  "amount": {
      "currency": "USD",
      "value": "1.00",
  },
  "metadata": {
      "key1": "value1"
  },
  "correlationId": "d028beed-8152-481d-9427-21b6c4d99644"
}

HTTP Status and Error Codes

HTTP Status Code Description
201 Created A mass payment resource was created
400 ValidationError Can be: Items exceeded maximum count of 5000, Invalid amount, Invalid metadata, Invalid job item correlation ID, or Invalid funding source.
401 NotAuthorized OAuth token does not have Send scope.

Request and response (transfer from Account to Customers)

POST https://api-sandbox.dwolla.com/mass-payments
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
Idempotency-Key: 19051a62-3403-11e6-ac61-9e71128cae77
{
    "_links": {
        "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4"
        }
    },
    "items": [
      {
        "_links": {
            "destination": {
                "href": "https://api-sandbox.dwolla.com/accounts/9c7f8d57-cd45-4e7a-bf7a-914dbd6131db"
            }
        },
        "amount": {
            "currency": "USD",
            "value": "1.00"
        },
        "metadata": {
            "payment1": "payment1"
        }
      },
            {
        "_links": {
            "destination": {
                "href": "https://api-sandbox.dwolla.com/accounts/b442c936-1f87-465d-a4e2-a982164b26bd"
            }
        },
        "amount": {
            "currency": "USD",
            "value": "5.00"
        },
        "metadata": {
            "payment2": "payment2"
        }
      }
    ],
    "metadata": {
        "batch1": "batch1"
    },
    "correlationId": "6d127333-69e9-4c2b-8cae-df850228e130"
}

...

HTTP/1.1 201 Created
Location: https://api.dwolla.com/mass-payments/d093bcd1-d0c1-41c2-bcb5-a5cc011be0b7
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
request_body = {
  _links: {
    source: {
      href: "https://api-sandbox.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4"
    }
  },
  items: [
    {
      _links: {
        destination: {
          href: "https://api-sandbox.dwolla.com/accounts/9c7f8d57-cd45-4e7a-bf7a-914dbd6131db"
        }
      },
      amount: {
        currency: "USD",
        value: "1.00"
      },
      metadata: {
        payment1: "payment1"
      }
    },
    {
      _links: {
        destination: {
          href: "https://api-sandbox.dwolla.com/accounts/b442c936-1f87-465d-a4e2-a982164b26bd"
        }
      },
      amount: {
        currency: "USD",
        value: "5.00"
      },
      metadata: {
        payment2: "payment2"
      }
    }
  ],
  metadata: {
    batch1: "batch1"
  }
}

mass_payment = account_token.post "mass-payments", request_body
mass_payment.headers[:location] # => "https://api-sandbox.dwolla.com/mass-payments/cf1e9e00-09cf-43da-b8b5-a43b3f6192d4"
/**
 *  No example for this language yet. Coming soon.
 **/
# No example for this language yet. Coming soon.
var requestBody = {
  _links: {
    source: {
      href: 'https://api-sandbox.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4'
    }
  },
  items: [
    {
      _links: {
        destination: {
          href: 'https://api-sandbox.dwolla.com/accounts/9c7f8d57-cd45-4e7a-bf7a-914dbd6131db'
        }
      },
      amount: {
        currency: 'USD',
        value: '1.00'
      },
      metadata: {
        payment1: 'payment1'
      }
    },
    {
      _links: {
        destination: {
          href: 'https://api-sandbox.dwolla.com/accounts/b442c936-1f87-465d-a4e2-a982164b26bd'
        }
      },
      amount: {
        currency: 'USD',
        value: '5.00'
      },
      metadata: {
        payment2: 'payment2'
      }
    }
  ],
  metadata: {
    batch1: 'batch1'
  }
}

accountToken
  .post('mass-payments', requestBody)
  .then(res => res.headers.get('location')); // => 'https://api-sandbox.dwolla.com/mass-payments/cf1e9e00-09cf-43da-b8b5-a43b3f6192d4'

Retrieve a mass payment

This section outlines how to retrieve a mass payment by its id. All mass payments will have a status of pending upon creation and will move to processing and finally complete as the service runs. It is recommended that you retrieve your list of mass payment items when your mass payment has a status of complete to determine if any items failed to process successfully.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP request

GET https://api.dwolla.com/mass-payments/{id}

Request parameters

Parameter Required Type Description
id yes string The id of the mass payment to retrieve information for.

HTTP Status and Error Codes

HTTP Status Code Description
404 NotFound Mass payment not found.

Request and response

GET https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"
    },
    "source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/707177c3-bf15-4e7e-b37c-55c3898d9bf4"
    },
    "items": {
      "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items"
    }
  },
  "id": "eb467252-808c-4bc0-b86f-a5cd01454563",
  "status": "processing",
  "created": "2016-03-18T19:44:16.000Z",
  "metadata": {}
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
mass_payment_url = "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"

mass_payment = account_token.get mass_payment_url
mass_payment.status # => "processing"
/**
 *  No example for this language yet. Coming soon.
 **/
# No example for this language yet. Coming soon.
var massPaymentUrl = 'https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563';

accountToken
  .get(massPaymentUrl)
  .then(res => res.body.status); // => 'processing'

Update a mass payment

This section covers how to update a mass payment’s status to pending which triggers processing on a created and deferred mass payment, or cancelled which cancels a created and deferred mass payment.

  1. This endpoint requires an OAuth access token with the Send scope.

HTTP request

POST https://api.dwolla.com/mass-payments/{id}

Request parameters

Parameter Required Type Description
id yes string id of mass payment to update.
status yes string Either pending or cancelled depending on the action you want to take on a deferred mass payment.

HTTP Status and Error Codes

HTTP Status Code Description
404 NotFound Mass payment not found.
400 ValidationError Invalid status. Allowed types are pending, cancelled.

Request and response

POST https://api.dwolla.com/mass-payments/692486f8-29f6-4516-a6a5-c69fd2ce854c
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "status": "pending"
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
mass_payment_url = 'https://api.dwolla.com/mass-payments/692486f8-29f6-4516-a6a5-c69fd2ce854c'
request_body = {
      "status" => "pending",
}

mass_payment = account_token.post "#{mass_payment_url}", request_body
mass_payment.status # => "pending"
/**
 *  No example for this language yet. Coming soon.
 **/
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
mass_payment_url = 'https://api.dwolla.com/mass-payments/692486f8-29f6-4516-a6a5-c69fd2ce854c'
request_body = {
  "status": "pending"
}

mass_payments = account_token.post('mass-payments', request_body)
mass_payments.body['status'] # => 'pending'
var massPaymentUrl = 'https://api.dwolla.com/mass-payments/692486f8-29f6-4516-a6a5-c69fd2ce854c';
var requestBody = {
  status: "pending"
};

accountToken
  .post(massPaymentUrl, requestBody)
  .then(res => res.body.status); // => "pending"

List items for a mass payment

A mass payment contains a list of payments called items. An item is distinct from the transfer which it creates. An item can contain a status of either failed, pending, or success depending on whether the payment was created by the Dwolla service or not. A mass payment item status of success is an indication that a transfer was successfully created. A mass payment’s items will be returned in the _embedded object as a list of items.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP Request

GET https://api.dwolla.com/mass-payments/{id}/items

Request parameters

Parameter Required Type Description
id yes string Mass payment unique identifier.
limit no integer How many results to return. Defaults to 25.
offset no integer How many results to skip.
status no string Filter results on item status. Possible values: failed, pending, and success. Values delimited by &status= (i.e. - /items?status=failed&status=pending).

HTTP Status and Error Codes

HTTP Status Code Description
403 Forbidden Not authorized to list mass payment items.
404 NotFound Mass payment not found.

Request and response

GET https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items"
    },
    "first": {
      "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items?limit=25&offset=0"
    },
    "last": {
      "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items?limit=25&offset=0"
    }
  },
  "_embedded": {
    "items": [
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/mass-payment-items/2f845bc9-41ed-e511-80df-0aa34a9b2388"
          },
          "mass-payment": {
            "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"
          },
          "destination": {
            "href": "https://api-sandbox.dwolla.com/accounts/9c7f8d57-cd45-4e7a-bf7a-914dbd6131db"
          },
          "transfer": {
            "href": "https://api-sandbox.dwolla.com/transfers/fa3999db-41ed-e511-80df-0aa34a9b2388"
          }
        },
        "id": "2f845bc9-41ed-e511-80df-0aa34a9b2388",
        "status": "success",
        "amount": {
          "value": "1.00",
          "currency": "USD"
        },
        "metadata": {
          "item1": "item1"
        }
      },
      {
        "_links": {
          "self": {
            "href": "https://api-sandbox.dwolla.com/mass-payment-items/30845bc9-41ed-e511-80df-0aa34a9b2388"
          },
          "mass-payment": {
            "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"
          },
          "destination": {
            "href": "https://api-sandbox.dwolla.com/accounts/b442c936-1f87-465d-a4e2-a982164b26bd"
          },
          "transfer": {
            "href": "https://api-sandbox.dwolla.com/transfers/fb3999db-41ed-e511-80df-0aa34a9b2388"
          }
        },
        "id": "30845bc9-41ed-e511-80df-0aa34a9b2388",
        "status": "success",
        "amount": {
          "value": "2.00",
          "currency": "USD"
        },
        "metadata": {
          "item2": "item2"
        }
      }
    ]
  },
  "total": 2
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
mass_payment_url = 'https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563'

mass_payment_items = account_token.get "#{mass_payment_url}/items"
mass_payment_items.total # => 2
/**
 *  No example for this language yet. Coming soon.
 **/
# No example for this language yet. Coming soon.
var massPaymentUrl = 'https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563'

// For Dwolla API applications, an appToken can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
accountToken
  .get(`${massPaymentUrl}/items`)
  .then(res => res.body.total); // => 2

Retrieve a mass payment item

This section covers how to retrieve a mass payment item by its unique identifier. An item can contain _links to: the mass payment the item belongs to, the transfer created from the item, and the destination user.

  1. This endpoint requires an OAuth account access token with the Transactions scope.

HTTP request

GET https://api.dwolla.com/mass-payment-items/{id}

Request parameters

Parameter Required Type Description
id yes string The id of the item to be retrieved in a mass payment.

HTTP Status and Error Codes

HTTP Status Code Description
403 Forbidden Not authorized to list mass payment items.
404 NotFound Mass payment not found.

Request and response

GET https://api-sandbox.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/mass-payment-items/2f845bc9-41ed-e511-80df-0aa34a9b2388"
    },
    "mass-payment": {
      "href": "https://api-sandbox.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"
    },
    "destination": {
      "href": "https://api-sandbox.dwolla.com/accounts/9c7f8d57-cd45-4e7a-bf7a-914dbd6131db"
    },
    "transfer": {
      "href": "https://api-sandbox.dwolla.com/transfers/fa3999db-41ed-e511-80df-0aa34a9b2388"
    }
  },
  "id": "2f845bc9-41ed-e511-80df-0aa34a9b2388",
  "status": "success",
  "amount": {
    "value": "1.00",
    "currency": "USD"
  },
  "metadata": {
    "item1": "item1"
  }
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
mass_payment_item_url = 'https://api-sandbox.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388'

mass_payment_item = account_token.get mass_payment_item_url
mass_payment_item.status # => "success"
/**
 *  No example for this language yet. Coming soon.
 **/
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
mass_payment_item_url = 'https://api-sandbox.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388'

mass_payment_item = account_token.get(mass_payment_item_url)
mass_payment_item.body['status'] # => 'success'
var massPaymentItemUrl = 'https://api-sandbox.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388';

// For Dwolla API applications, an appToken can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
accountToken
  .get(massPaymentItemUrl)
  .then(res => res.body.status); // => 'success'

Events

When the state of a resource changes, we create a new event resource to record the change. For instance, if a Customer’s status changes to verified, a customer_verified event will be created. When an Event is created, a Webhook will be created to deliver the Event to any URLs specified by your active Webhook Subscriptions.

Events resource

Parameter Description
_links Contains links to the event, associated resource, the Account associated with the event, and the Customer associated with the event (if any).
id Event id
created ISO-8601 timestamp when event was created
topic Type of event
resourceId id of the resource associated with the event.
{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/events/f8e70f48-b7ff-47d0-9d3d-62a099363a76"
    },
    "resource": {
      "href": "https://api.dwolla.com/transfers/48CFDDB4-1E74-E511-80DB-0AA34A9B2388"
    },
    "account": {
      "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
    }
  },
  "id": "f8e70f48-b7ff-47d0-9d3d-62a099363a76",
  "created": "2015-10-16T15:58:15.000Z",
  "topic": "transfer_created",
  "resourceId": "48CFDDB4-1E74-E511-80DB-0AA34A9B2388"
}

Event topics - (Accounts)

Topic Description
funding_source_added A funding source was added to a Dwolla account.
funding_source_removed A funding source was removed from a Dwolla account.
funding_source_verified A funding source was marked as verified.
microdeposits_added Two <=10¢ transfers to a Dwolla account’s linked bank account were initiated.
microdeposits_failed The two <=10¢ transfers to a Dwolla account’s linked bank account failed to clear successfully.
microdeposits_completed The two <=10¢ transfers to a Dwolla account’s linked bank account have cleared successfully.
microdeposits_maxattempts The account has reached their max verification attempts limit of three. The account can no longer verify their funding source with the completed micro-deposit amounts.
bank_transfer_created A bank transfer was created.
bank_transfer_cancelled A pending bank transfer has been cancelled, and will not process further.
bank_transfer_failed A transfer failed to clear successfully. Usually, this is a result of an ACH failure (insufficient funds, etc.).
bank_transfer_completed A bank transfer has cleared successfully.
transfer_created A transfer was created.
transfer_cancelled A pending transfer has been cancelled, and will not process further.
transfer_failed A transfer failed to clear successfully.
transfer_reclaimed The transfer was returned to the sender after remaining unclaimed by the intended recipient for a period of time.
transfer_completed A transfer has cleared successfully.
mass_payment_created A mass payment was created.
mass_payment_completed A mass payment completed.
mass_payment_cancelled A created and deferred mass payment was cancelled.
account_suspended An account was suspended.
account_activated A Dwolla account moves from deactive or suspended to active state of verification.

List events

Retrieve a list of events for the application.

  1. This endpoint requires an OAuth application access token.

HTTP request

GET https://api.dwolla.com/events

Request parameters

Parameter Required Type Description
limit no integer How many results to return
offset no integer How many results to skip

Errors

HTTP Status Message
404 Resource not found.

Request and response

GET https://api.dwolla.com/events
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/events"
    },
    "first": {
      "href": "https://api.dwolla.com/events?limit=25&offset=0"
    },
    "last": {
      "href": "https://api.dwolla.com/events?limit=25&offset=150"
    },
    "next": {
      "href": "https://api.dwolla.com/events?limit=25&offset=25"
    }
  },
  "_embedded": {
    "events": [
      {
        "_links": {
          "self": {
            "href": "https://api.dwolla.com/events/78e57644-56e4-4da2-b743-059479f2e80f"
          },
          "resource": {
            "href": "https://api.dwolla.com/transfers/47CFDDB4-1E74-E511-80DB-0AA34A9B2388"
          },
          "account": {
            "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
          }
        },
        "id": "78e57644-56e4-4da2-b743-059479f2e80f",
        "created": "2015-10-16T15:58:18.000Z",
        "topic": "bank_transfer_created",
        "resourceId": "47CFDDB4-1E74-E511-80DB-0AA34A9B2388"
      },
      {
        "_links": {
          "self": {
            "href": "https://api.dwolla.com/events/f8e70f48-b7ff-47d0-9d3d-62a099363a76"
          },
          "resource": {
            "href": "https://api.dwolla.com/transfers/48CFDDB4-1E74-E511-80DB-0AA34A9B2388"
          },
          "account": {
            "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
          }
        },
        "id": "f8e70f48-b7ff-47d0-9d3d-62a099363a76",
        "created": "2015-10-16T15:58:15.000Z",
        "topic": "transfer_created",
        "resourceId": "48CFDDB4-1E74-E511-80DB-0AA34A9B2388"
      },
      {
        "_links": {
          "self": {
            "href": "https://api.dwolla.com/events/9f0167e0-dce6-4a1a-ad26-30015d6f1cc1"
          },
          "resource": {
            "href": "https://api.dwolla.com/transfers/08A166BC-1B74-E511-80DB-0AA34A9B2388"
          },
          "account": {
            "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
          }
        },
        "id": "9f0167e0-dce6-4a1a-ad26-30015d6f1cc1",
        "created": "2015-10-16T15:37:03.000Z",
        "topic": "bank_transfer_created",
        "resourceId": "08A166BC-1B74-E511-80DB-0AA34A9B2388"
      },
      {
        "_links": {
          "self": {
            "href": "https://api.dwolla.com/events/81f6e13c-557c-4449-9331-da5c65e61095"
          },
          "resource": {
            "href": "https://api.dwolla.com/transfers/09A166BC-1B74-E511-80DB-0AA34A9B2388"
          },
          "account": {
            "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
          },
          "customer": {
            "href": "https://api.dwolla.com/customers/07d59716-ef22-4fe6-98e8-f3190233dfb8"
          }
        },
        "id": "81f6e13c-557c-4449-9331-da5c65e61095",
        "created": "2015-10-16T15:37:02.000Z",
        "topic": "customer_transfer_created",
        "resourceId": "09A166BC-1B74-E511-80DB-0AA34A9B2388"
      }
    ]
  },
  "total": 4
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
events = app_token.get "events"
events.total # => 4
<?php
$eventsApi = new DwollaSwagger\EventsApi($apiClient);

$events = $eventsApi->events();
$events->total; # => 4
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
events = app_token.get('events')
events.body['total'] # => 4
applicationToken
  .get('events')
  .then(res => res.body.total); // => 4

Retrieve an event

This section covers how to retrieve an event by id.

  1. This endpoint requires an OAuth application access token.

HTTP Request

GET https://api.dwolla.com/events/{id}

Request parameters

Parameter Required Type Description
id yes string ID of application event to get.

Errors

HTTP Status Message
404 Application event not found.

Request and response

GET /events/81f6e13c-557c-4449-9331-da5c65e61095
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/events/81f6e13c-557c-4449-9331-da5c65e61095"
    },
    "resource": {
      "href": "https://api.dwolla.com/transfers/09A166BC-1B74-E511-80DB-0AA34A9B2388"
    },
    "account": {
      "href": "https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b"
    },
    "customer": {
      "href": "https://api.dwolla.com/customers/07d59716-ef22-4fe6-98e8-f3190233dfb8"
    }
  },
  "id": "81f6e13c-557c-4449-9331-da5c65e61095",
  "created": "2015-10-16T15:37:02.000Z",
  "topic": "customer_transfer_created",
  "resourceId": "09A166BC-1B74-E511-80DB-0AA34A9B2388"
}
event_url = 'https://api.dwolla.com/events/81f6e13c-557c-4449-9331-da5c65e61095'

# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
event = app_token.get event_url
event.topic # => "customer_transfer_created"
<?php
$eventUrl = 'https://api.dwolla.com/events/81f6e13c-557c-4449-9331-da5c65e61095';

$eventsApi = new DwollaSwagger\EventsApi($apiClient);

$event = $eventsApi->id($eventUrl);
$event->topic; # => "customer_transfer_created"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
event_url = 'https://api.dwolla.com/events/81f6e13c-557c-4449-9331-da5c65e61095'

event = app_token.get(event_url)
event.body['topic'] # => 'customer_transfer_created'
var eventUrl = 'https://api.dwolla.com/events/81f6e13c-557c-4449-9331-da5c65e61095';

applicationToken
  .get(eventUrl)
  .then(res => res.body.topic); // => 'customer_transfer_created'

Webhook subscriptions

Create a webhook subscription to receive POST requests from Dwolla (called webhooks) when events associated with your application occur. Webhooks are sent to a URL which you provide when creating a webhook subscription. If you are a Dwolla API partner, you will use these events to notify your customers via email as described in the Dwolla API terms of service. Refer to the events section for the list of events that trigger webhooks.

Automatic pause of a webhook subscription

Dwolla will automatically pause subscribed webhook endpoints that are no longer reachable. The webhook subscription will be paused after 400 consecutive failures. This will help us to ensure that unavailable endpoints don’t cause delays or issues in delivery of notifications for other API partners. Webhook subscriptions can be unpaused by calling this endpoint.

Acknowledgement and retries

When your application receives a webhook, it should respond with a HTTP 2xx status code to indicate successful receipt. If Dwolla receives a status code greater than or equal to 400, or your application fails to respond within 20 seconds of the attempt, another attempt will be made.

Dwolla will re-attempt delivery 8 times over the course of 72 hours according the backoff schedule below. If a webhook was successfully received but you would like the information again, you can call retrieve a webhook by its Id.

Retry number Interval (relative to last retry) Interval (relative to original attempt)
1 15 min 15 min
2 45 min 1 h
3 2 h 3 h
4 3 h 6 h
5 6 h 12 h
6 12 h 24 h
7 24 h 48 h
8 24 h 72 h

Webhook subscription resource

Parameter Description
id Webhook subscription unique identifier.
url Subscribed url where Dwolla should deliver the webhook notification.
paused A boolean true or false value indicating if the webhook subscription is paused. A webhook subscription will be automatically paused after 400 consecutive failures. In addition, a subscription can be paused or unpaused by calling this endpoint in the API.
created ISO-8601 timestamp

Create a webhook subscription

This section details how to create a webhook subscription to deliver webhooks to a specified URL.

  1. This endpoint requires an OAuth application access token.

HTTP Request

POST https://api.dwolla.com/webhook-subscriptions

Request parameters

Parameter Required Type Description
url yes string Where Dwolla should deliver the webhook notification.
secret yes string A random, secret key, only known by your application. This secret key should be securely stored and used later when validating the authenticity of the webhook request from Dwolla.

Request and response

POST https://api-sandbox.dwolla.com/webhook-subscriptions
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q
{
    "url": "http://myapplication.com/webhooks",
    "secret": "sshhhhhh"
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
request_body = {
  :url => "http://myawesomeapplication.com/destination",
  :secret => "your webhook secret"
}

subscription = app_token.post "webhook-subscriptions", request_body
subscription.headers[:location] # => "https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216"
var requestBody = {
  url: 'http://myawesomeapplication.com/destination',
  secret: 'your webhook secret'
};

applicationToken
  .post('webhook-subscriptions', requestBody)
  .then(res => res.headers.get('location')); // => 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
request_body = {
  'url': 'http://myapplication.com/webhooks',
  'secret': 'sshhhhhh'
}

retries = app_token.post('webhook-subscriptions', request_body)
retries.body['total'] # => 1
<?php
$webhookApi = new DwollaSwagger\WebhooksubscriptionsApi($apiClient);

$subscription = $webhookApi->create(array (
  'url' => 'http://myapplication.com/webhooks',
  'secret' => 'sshhhhhh',
));
$subscription; # => "https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216"
?>

Retrieve a webhook subscription

This section details how to retrieve a webhook subscription by its id.

  1. This endpoint requires an OAuth application access token.

HTTP request

GET https://api.dwolla.com/webhook-subscriptions/{id}

Request parameters

Parameter Required Type Description
id yes string Webhook subscription unique identifier.

Errors

HTTP Status Message
404 Webhook subscription not found.

Request and response

GET https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589"
    },
    "webhooks": {
      "href": "https://api-sandbox.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589/webhooks"
    }
  },
  "id": "077dfffb-4852-412f-96b6-0fe668066589",
  "url": "http://myapplication.com/webhooks",
  "created": "2015-10-28T16:20:47+00:00"
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_subscription_url = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

webhook_subscription = app_token.get webhook_subscription_url
webhook_subscription.created # => 2015-10-28T16:20:47+00:00
var webhookSubscriptionUrl = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216';

applicationToken
  .get(webhookSubscriptionUrl)
  .then(res => res.body.created); // => '2016-04-20T15:49:50.340Z'
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_subscription_url = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

webhook_subscription = app_token.get(webhook_subscription_url)
webhook_subscription.body['created'] # => '2015-10-28T16:20:47+00:00'
<?php
$webhookApi = new DwollaSwagger\WebhooksubscriptionsApi($apiClient);
$retrieved = $webhookApi->id('https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216');

$retrieved->created; # => 2015-10-28T16:20:47+00:00
?>

Update a webhook subscription

This section details how to pause a webhook subscription. When a webhook subscription is paused Dwolla will continue to create webhooks but not send them to your subscribed webhook url. This is useful if your webhook endpoint is unavailable and you want to temporarily disable webhook requests.

  1. This endpoint requires an OAuth application access token.

HTTP Request

POST https://api.dwolla.com/webhook-subscriptions/{id}

Request parameters

Parameter Required Type Description
id yes string Webhook unique identifier.
paused yes string Specify a value of true to pause the associated webhook subscription.

Request and response

POST https://api.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q
{
    "paused": true
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_subscription_url = 'https://api.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

request_body = {
  :paused => true
}

subscription = app_token.post "#{webhook_subscription_url}", request_body
var webhookSubscriptionUrl = 'https://api.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c';

var requestBody = {
  paused: true
};

applicationToken
  .post(webhookSubscriptionUrl, requestBody)
  .then(res => res.body.paused); // => 'true'
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_subscription_url = 'https://api.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

request_body = {
  'paused': true
}

subscription = app_token.post(webhook_subscription_url, request_body)
subscription.body['paused'] # => true
<?php
$webhookSubscriptionUrl = 'https://api.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

$webhookApi = new DwollaSwagger\WebhooksubscriptionsApi($apiClient);

$subscription = $webhookApi->updateSubscription(array (
  'paused' => true
), $webhookSubscriptionUrl);
?>

List webhook subscriptions

This section covers how to retrieve a list of webhook subscriptions that belong to an application.

  1. This endpoint requires an OAuth application access token.

HTTP request

GET https://api.dwolla.com/webhook-subscriptions

Request and response

GET https://api.dwolla.com/webhook-subscriptions
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/webhook-subscriptions"
    }
  },
  "_embedded": {
    "webhook-subscriptions": [
      {
        "_links": {
          "self": {
            "href": "https://api.dwolla.com/webhook-subscriptions/f4d21628-fde2-4d3a-b69a-0a7cb42adc4c"
          },
          "webhooks": {
            "href": "https://api.dwolla.com/webhook-subscriptions/f4d21628-fde2-4d3a-b69a-0a7cb42adc4c/webhooks"
          }
        },
        "id": "f4d21628-fde2-4d3a-b69a-0a7cb42adc4c",
        "url": "https://destination.url",
        "created": "2015-08-19T21:43:49.000Z"
      }
    ]
  },
  "total": 1
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_subscriptions = app_token.get "webhook-subscriptions"
webhook_subscriptions.total # => 1
applicationToken
  .get('webhook-subscriptions')
  .then(res => res.body.total); // => 1
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_subscriptions = app_token.get('webhook-subscriptions')
webhook_subscriptions.body['total'] # => 1
<?php
$webhookApi = new DwollaSwagger\WebhooksubscriptionsApi($apiClient);

$retrieved = $webhookApi->_list();
$retrieved->total; # => 1
?>

Delete a webhook subscription

Delete a Webhook Subscription to stop receiving Webhooks at the URL specified. If using an SDK, the request was successful unless an exception was thrown stating otherwise.

  1. This endpoint requires an OAuth application access token.

HTTP request

DELETE https://api.dwolla.com/webhook-subscriptions/{id}

Request parameters

Parameter Required Type Description
id yes string Webhook unique identifier.

Errors

HTTP Status Message
404 Webhook subscription not found.

Request and response

DELETE https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_subscription_url = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

app_token.delete webhook_subscription_url
var webhookSubscriptionUrl = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216';

applicationToken.delete(webhookSubscriptionUrl);
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_subscription_url = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

app_token.delete(webhook_subscription_url)
<?php
$webhookApi = new DwollaSwagger\WebhooksubscriptionsApi($apiClient);
$webhookApi->deleteById('https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216');
?>

List webhooks for a webhook subscription

This section covers how to view all fired webhooks for a webhook subscription.

  1. This endpoint requires an OAuth application access token.

HTTP request

GET https://api.dwolla.com/webhook-subscriptions/{id}/webhooks

Request parameters

Parameter Required Type Description
id yes string Webhook subscription unique identifier.
limit no integer How many results to return. Defaults to 25.
offset no integer How many results to skip.

Request and response

GET /webhook-subscriptions/10d4133e-b308-4646-b276-40d9d36def1c/webhooks
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {},
  "total": 0,
  "items": [
    {
      "_links": {},
      "id": "string",
      "topic": "string",
      "accountId": "string",
      "eventId": "string",
      "subscriptionId": "string",
      "attempts": [
        {
          "id": "string",
          "request": {
            "created": "2015-07-23T14:19:37.006Z",
            "url": "string",
            "headers": [
              {
                "name": "string",
                "value": "string"
              }
            ],
            "body": "string"
          },
          "response": {
            "created": "2015-07-23T14:19:37.006Z",
            "headers": [
              {
                "name": "string",
                "value": "string"
              }
            ],
            "statusCode": 0,
            "body": "string"
          }
        }
      ]
    }
  ]
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_subscription_url = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

hooks = app_token.get "#{webhook_subscription_url}/webhooks"
hooks.total # => 5
var webhookSubscriptionUrl = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216';

applicationToken
  .get(`${webhookSubscriptionUrl}/webhooks`)
  .then(res => res.body.total); // => 5
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_subscription_url = 'https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'

hooks = app_token.get('%s/hooks' % webhook_subscription_url)
hooks.body['total'] # => 5
<?php
$webhookApi = new DwollaSwagger\WebhooksApi($apiClient);

$hooks = $webhookApi->hooksById('https://api-sandbox.dwolla.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216');
$hooks->total; # => 5
?>

Webhooks

When a new event is created and there is an active webhook subscription, a new webhook is created in order to deliver that event. Attempted deliveries are recorded under the webhook’s attempts property. Each attempt includes the recorded request and response of the delivery attempt. Webhooks are sent asynchronously and are not guaranteed to be delivered in order. We recommend that applications protect against duplicated events by making event processing idempotent.

Note: Webhooks containing an event are only fired if an application has a valid refresh_token for the Dwolla user Account that an event is created on.

Webhook resource

Parameter Description
id Webhook unique identifier
topic Type of webhook subscription
accountId Account associated with the webhook notification
eventId Event id for this webhook
subscriptionId Webhook subscription id for this event
attempts Array of attempt JSON object

Attempts JSON object

Parameter Description
id Unique id of webhook delivery attempt.
request Request JSON object
response Response JSON object

Request/response JSON object

Parameter Description
created ISO-8601 timestamp
url URL where data was sent to/received from
headers Array of objects with keys name and value representative of HTTP headers
body An Event for the webhook

Retrieve a webhook

This section covers how to retrieve a single webhook.

  1. This endpoint requires an OAuth application access token.

HTTP request

GET https://api.dwolla.com/webhooks/{id}

Request parameters

Parameter Required Type Description
id yes string Id of webhook to retrieve.

Errors

HTTP Status Message
404 Webhook not found.

Request and response

GET https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8"
    },
    "subscription": {
      "href": "https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83"
    },
    "retry": {
      "href": "https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries"
    },
    "event": {
      "href": "https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50"
    }
  },
  "id": "9ece9660-aa34-41eb-80d7-0125d53b45e8",
  "topic": "transfer_created",
  "accountId": "ca32853c-48fa-40be-ae75-77b37504581b",
  "eventId": "03c7e14c-7f15-44a2-bcf7-83f2f7e95d50",
  "subscriptionId": "a0943041-7a5c-4e8f-92de-b55711ef3a83",
  "attempts": [
    {
      "id": "d4d16621-c6b0-40cb-8dc3-0469fa9dc4e8",
      "request": {
        "timestamp": "2015-10-27T17:07:34.304Z",
        "url": "https://myapp.runscope.net",
        "headers": [
          {
            "name": "X-Dwolla-Topic",
            "value": "transfer_created"
          },
          {
            "name": "X-Request-Signature",
            "value": "bd93780bd7e1ad77ab821094aaa0f9e3dece5ee3"
          }
        ],
        "body": "{\"id\":\"03c7e14c-7f15-44a2-bcf7-83f2f7e95d50\",\"resourceId\":\"81BA6F36-CD7C-E511-80DB-0AA34A9B2388\",\"topic\":\"transfer_created\",\"timestamp\":\"2015-10-27T17:07:34.207Z\",\"_links\":{\"self\":{\"href\":\"https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50\"},\"account\":{\"href\":\"https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b\"},\"resource\":{\"href\":\"https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388\"}}}"
      },
      "response": {
        "timestamp": "2015-10-27T17:07:34.308Z",
        "headers": [
          {
            "name": "Date",
            "value": "Tue, 27 Oct 2015 17:07:34 GMT"
          },
          {
            "name": "Content-Type",
            "value": "application/json; charset=UTF-8"
          },
          {
            "name": "Content-Length",
            "value": "1093"
          },
          {
            "name": "Connection",
            "value": "keep-alive"
          },
          {
            "name": "Access-Control-Allow-Credentials",
            "value": "true"
          },
          {
            "name": "Access-Control-Allow-Methods",
            "value": "GET, PUT, POST, PATCH, DELETE, OPTIONS, HEAD"
          },
          {
            "name": "Server",
            "value": "Runscope-Gateway/1.0"
          },
          {
            "name": "Runscope-Message-Id",
            "value": "97aa5bbd-784f-4007-80cc-8f56919000a0"
          },
          {
            "name": "Access-Control-Allow-Origin",
            "value": "*"
          }
        ],
        "statusCode": 200,
        "body": "{\"body\":\"{\"id\":\"03c7e14c-7f15-44a2-bcf7-83f2f7e95d50\",\"resourceId\":\"81BA6F36-CD7C-E511-80DB-0AA34A9B2388\",\"topic\":\"transfer_created\",\"timestamp\":\"2015-10-27T17:07:34.207Z\",\"_links\":{\"self\":{\"href\":\"https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50\"},\"account\":{\"href\":\"https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581b\"},\"resource\":{\"href\":\"https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388\"}}}\",\"files\":[],\"form\":{},\"fragment\":\"\",\"headers\":{\"Connection\":[\"close\"],\"Content-Length\":[\"453\"],\"Content-Type\":[\"application/json; charset=UTF-8\"],\"Host\":[\"myapp.runscope.net\"],\"User-Agent\":[\"dwolla-webhooks/1.0\"],\"X-Dwolla-Topic\":[\"transfer_created\"],\"X-Request-Signature\":[\"bd93780bd7e1ad77ab821094aaa0f9e3dece5ee3\"]},\"host\":\"myapp.runscope.net\",\"method\":\"POST\",\"params\":{},\"path\":\"/\",\"region\":\"us5\",\"runscope_host\":\"prod078.runscope.in\",\"scheme\":\"https\",\"source\":\"capture\",\"source_ip\":\"52.24.10.184\",\"timestamp\":1.4459656543078682e+09,\"url\":\"https://myapp.runscope.net/\"}"
      }
    }
  ]
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_url = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8'

webhook = app_token.get webhook_url
webhook.topic # => "transfer_created"
<?php
$webhookUrl = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8';

$webhooksApi = new DwollaSwagger\WebhooksApi($apiClient);

$webhook = $webhooksApi->id($webhookUrl);
$webhook->topic; # => "transfer_created"
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_url = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8'

webhook = app_token.get(transfer_url)
webhook.body['topic'] # => 'transfer_created'
var webhookUrl = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8';

applicationToken
  .get(webhookUrl)
  .then(res => res.body.topic); // => 'transfer_created'

Retry a webhook

This section details how to retry a webhook by id.

  1. This endpoint requires an OAuth application access token.

HTTP Request

POST https://api.dwolla.com/webhooks/{id}/retries

Request parameters

Parameter Required Type Description
id yes string Id of webhook to retry.

Errors

HTTP Status Message
404 Webhook not found.

Request and response

POST /webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

HTTP/1.1 201 Created
Location: https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries/5aa27a0f-cf99-418d-a3ee-67c0ff99a494
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_url = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8'

app_token.post "#{webhook_url}/retries"
<?php
$webhookUrl = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8';

$webhooksApi = new DwollaSwagger\WebhooksApi($apiClient);

$webhooksApi->retryWebhook($webhookUrl);
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_url = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8'

app_token.post('%s/retries' % webhook_url)
var webhookUrl = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8';

applicationToken.post(`${webhookUrl}/retries`);

List retries for a webhook

This section covers how to retrieve webhook retries by id.

  1. This endpoint requires an OAuth application access token.

HTTP Request

GET https://api.dwolla.com/webhooks/{id}/retries

Request parameters

Parameter Required Type Description
id yes string Id of webhook to get retries for.

Errors

HTTP Status Message
404 Webhook not found.

Request and response

GET /webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries"
    }
  },
  "_embedded": {
    "retries": [
      {
        "_links": {
          "self": {
            "href": "https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries/5aa27a0f-cf99-418d-a3ee-67c0ff99a494"
          },
          "webhook": {
            "href": "https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8"
          }
        },
        "id": "5aa27a0f-cf99-418d-a3ee-67c0ff99a494",
        "timestamp": "2015-11-02T17:43:26.000Z"
      }
    ]
  },
  "total": 1
}
# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
webhook_url = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8'

retries = app_token.get "#{webhook_url}/retries"
retries.total # => 1
<?php
$webhookUrl = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8';

$webhooksApi = new DwollaSwagger\WebhooksApi($apiClient);

$retries = $webhooksApi->retriesById($webhookUrl);
$retries->total; # => 1
?>
# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
webhook_url = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8'

retries = app_token.get('%s/retries' % webhook_url)
retries.body['total'] # => 1
var webhookUrl = 'https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8';

applicationToken
  .get(`${webhookUrl}/retries`)
  .then(res => res.body.total); // => 1
Financial institutions play an important role in the Dwolla network.

Dwolla, Inc. is an agent of Veridian Credit Union and Compass Bank and all funds associated with your account in the Dwolla network are held in pooled accounts at Veridian Credit Union and Compass Bank. These funds are not eligible for individual insurance, including FDIC insurance and may not be eligible for share insurance by the National Credit Union Share Insurance Fund. Dwolla, Inc. is the operator of a software platform that communicates user instructions for funds transfers to Veridian Credit Union and Compass Bank.