Dwolla Developers Logo
API Reference
  • SDK Support
    Drop-in Components
    Knowledge-based Authentication (KBA)
    Beneficial Owners
    Funding Sources
    Mass payments
    Webhook subscriptions
CommunityOpen in new tabChangelog
Get API Keys
CommunityOpen in new tabChangelog
Get API Keys

Introduction #

Welcome to the Dwolla API documentation. This API will give you the ability to connect your software to banking infrastructure to move money, store funds, validate customer identities, and verify bank accounts.

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/customers
Content-Type: application/json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer myOAuthAccessToken123

  "foo": "bar"

... 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. OAuth access tokens are passed via the Authorization HTTP header:

Authorization: Bearer {access_token_here}

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 and request body won't result in multiple resources being created. It is recommended to use a random value for the idempotency key, like a UUID (i.e. - Idempotency-Key: d2adcbab-4e4e-430b-9181-ac9346be723a).

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, rather than creating new or potentially duplicate resources, you will receive a 201 Created, with the original response of the created resource. If the Dwolla server is still processing the original POST request, you will receive a 409 Conflict error response on the subsequent request. Multiple POSTs with the same idempotency key including an exact match request body won’t result in multiple resources being created. Idempotency keys are intended to prevent conflicts over a short period of time, therefore keys which are paired with a request body expire after 24 hours.

To prevent resources from being created more than once, we highly recommend making all requests idempotent.

Example transfer using an Idempotency Key

var headers = {
  "Idempotency-Key": "19051a62-3403-11e6-ac61-9e71128cae77",
var requestBody = {
  _links: {
    source: {
    destination: {
  amount: {
    currency: "USD",
    value: "1.00",

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

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 StatusError CodeDescription400BadRequestThe request body contains bad syntax or is incomplete.400ValidationErrorValidation error(s) present. See embedded errors list for more details. (See below)401InvalidCredentialsMissing or invalid Authorization header.401InvalidAccessTokenInvalid access token.401ExpiredAccessTokenGenerate a new access token using your client credentials.401InvalidAccountStatusInvalid access token account status.401InvalidApplicationStatusInvalid application status.401InvalidScopesMissing or invalid scopes for requested endpoint.403ForbiddenThe supplied credentials are not authorized for this resource.403InvalidResourceStateResource cannot be modified.404NotFoundThe requested resource was not found.405MethodNotAllowed(varies)406InvalidVersionMissing or invalid API version.500ServerErrorA server error occurred. Error ID: {ID}500RequestTimeoutThe 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

ParameterDescriptionerrorsAn 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 - {field name} is required. For example, null or empty string in required field.
  • Invalid - {field name} invalid.
  • InvalidFormat - {field name} is not in a valid format. For example, characters in the amount field.
  • 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 required.",
                "path": "/firstName",
                "_links": {}

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 customer resource has a funding-sources link which, when followed, will list the customer's available funding sources.

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

  "_links": {
    "self": {
      "href": "https://api.dwolla.com/customers/132681FA-1B4D-4181-8FF2-619CA46235B1"
    "funding-sources": {
      "href": "https://api.dwolla.com/customers/132681FA-1B4D-4181-8FF2-619CA46235B1/funding-sources"
    "transfers": {
      "href": "https://api.dwolla.com/customers/132681FA-1B4D-4181-8FF2-619CA46235B1/transfers"
    "retry-verification": {
      "href": "https://api.dwolla.com/customers/132681FA-1B4D-4181-8FF2-619CA46235B1"
  "id": "132681FA-1B4D-4181-8FF2-619CA46235B1",
  "firstName": "Jane",
  "lastName": "doe",
  "email": "jdoe@nomail.com",
  "type": "personal",
  "status": "retry",
  "created": "2015-09-29T19:47:28.920Z"

Tools #

The following section will outline development tools you can take advantage of to assist in your integration with the Dwolla API. The available tools can help to improve your testing and development workflow, as well as aid in solving a difficult problem (e.g. UI generation) when integrating Dwolla into your application.

Dwolla Hal-Forms #

Dwolla HAL-Forms is an extension of the HAL spec and was created to describe how Dwolla represents forms in the API. The extension starts with the media type. The media type should be used as a profile link as part of the Accept header of the request in conjunction with the Dwolla HAL style media type. By including these two media-type identifiers in the Accept header, the API knows that you’re looking for a form for the given resource.

Example Accept header value

application/vnd.dwolla.v1.hal+json; profile="https://github.com/dwolla/hal-forms"

The primary benefit is the ability to dynamically generate your UI based on the state of a particular resource. Your application can easily transition state without knowing Dwolla's business rules and what information needs to included in the actual request to transition state. When an "edit-form" link relation is returned on the resource, then your application can follow the link by making a GET request to that resource, including the header shown above. The response will include a simple JSON response body that contains information on the HTTP method, message content-type, and the request parameters used when sending the request to the Dwolla API. Note: Currently, forms are only returned for creating & editing customers, but we’re looking forward to expanding them across our existing and future endpoints.

Reference the spec for more information on the properties that can be returned in the Dwolla HAL-FORMS response. Or read a blog post from one of our developers on building out this functionality.

2021 All Rights Reserved


  • About
  • Blog
  • Pricing
  • Contact Sales
  • Terms of Service
  • Privacy Policy
Financial institutions play an important role in our network.

Dwolla, Inc. is the operator of a software platform that communicates user instructions for funds transfers to our financial institution partners.

Dwolla is an agent of Veridian Credit Union. All ACH and Wire transfers are performed by Veridian Credit Union. Your Dwolla Balance, if any, is held in one or more pooled holding accounts held by Veridian Credit Union. These funds may not be eligible for share insurance by the National Credit Union Share Insurance Fund.

Sponsorship and Settlement of Push-to-Debit payment services provided by MetaBank®, N.A.
Push-to-Debit payments are typically available within 30 minutes.

Real-Time Payments are performed by Cross River Bank, which holds funds on behalf of the Receiver of such transactions in one or more pooled custodial accounts. These funds are not subject to FDIC pass-through deposit insurance.