By: Shea Daniels,

Bank transfers and the world of ACH can be notoriously complex. At Dwolla, our mission is to tackle that complexity head-on so you can focus on building out your company’s vision. We combined current best practices and partner feedback to create a modern and easy-to-implement API for moving money.

That all sounds great, but what does it actually mean?

Well, just like a building, every API has a foundation. With a house the building blocks can be wood or bricks or stone, but with an API the foundation is a set of technical choices that underpin everything. These choices can either make a developer’s life much easier or far more difficult. As we built the Access API, the choices we made were focused on making the API straightforward and pleasant to use.

Read on to learn more about the foundational technologies that underpin the Access API.

 

Dwolla gives you a modern REST API for bank transfers

The Access API is RESTful, which stands for Representational State Transfer. Simply put, we use URLs to represent resources in our system (individual customers, bank accounts, money transfers, etc.) and you can manipulate these by using HTTP verbs (GET, POST, DELETE). Requests and responses are encoded in JSON.

The end result is that you get an easy-to-understand and consistent interface to move money between bank accounts in your app. You have the flexibility to programmatically build the flow you need, whether it’s payouts, pay-ins, or transfers between customers. Our client SDKs make things even simpler.

For example, this is all it takes to create an unverified Customer in the Access API:

curl -X POST -H "Accept: application/vnd.dwolla.v1.hal+json" -H "Content-Type: application/json" -H "Authorization: Bearer LlcntSzAKFLC9rnhlTBflutTqSCOfZavWUizDQJVtkS5noVHt2" -d '{
    "firstName": "Jane",
    "lastName": "Merchant",
    "email": "jmerchant@nomail.com"
}' "https://api-sandbox.dwolla.com/customers" -v

 

Dwolla’s business logic stays out of your app (or, what the heck is HATEOAS?)

A lot of people say they have RESTful APIs, but the truth is that many of them are missing a piece: HATEOAS. Woof, what does that mean? How do you even say it? (Answer: HAT-EE-OHS)

HATEOAS stands for Hypermedia as the Engine of Application State. If you’ve used a web browser at all, you are familiar with hypermedia even if you don’t know the word. The gist of it is that you get served up links to other things, which you can follow if you want to.

In the context of an API, the HATEOAS constraint means that the API itself serves links back to tell you the relationships between resources, and also what you can do in the system. Each link includes a descriptor that tells you what the link is for and an href to an API endpoint.

This turns out to be super useful for keeping business logic in our API rather than in your application. A simple example would be that, if you ask for a list of customers, we return a paged result and we return a link you can call to get the next set of results. Once you reach the end of the results and you wouldn’t get more in the next request, the link goes away.

 

HAL is your pal

HATEOAS is a great concept, but it doesn’t actually say anything about how to return links or format them. HAL (Hypertext Application Language) is one standard for doing just that in a JSON API like Dwolla’s.

Each response can have the following:

Here’s what an example HAL response from the Access API looks like:

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/customers/FC451A7A-AE30-4404-AB95-E3553FCD733F"
    }
  },
  "id": "FC451A7A-AE30-4404-AB95-E3553FCD733F",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "janedoe@nomail.com",
  "type": "unverified",
  "status": "unverified",
  "created": "2015-09-03T23:56:10.023Z"
}

All of the links that we return as a part of the HAL response are also the inputs we expect back in request fields. In addition, you don’t have to figure out how to take the ID of a resource and transform it into a full URL to call.

Take a look at an example of creating a transfer in the Access API to  see what we mean:

curl -X POST -H "Authorization: Bearer GnlMMOlLLTTwRRC44gGPkjfsVbVtwzkptDVdIB0fwGwLnV481N" -H "Content-Type: application/vnd.dwolla.v1.hal+json" -H "Accept: application/vnd.dwolla.v1.hal+json" -d '{
    "_links": {
        "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/118b08b9-e1eb-48b7-94ad-866989b0764e"

        },
        "destination": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/836ce660-d46f-43f4-8c7c-002291d1452e"
        }
    },
    "amount": {
        "currency": "USD",
        "value": "100.00"
    }
}' 'https://api-sandbox.dwolla.com/transfers' -v

You can read more about links in our API Docs.

 

Embedded errors give you details on what went wrong.

Occasionally things go wrong—even in the best integration. The Access API closely aligns with the vnd.error spec to return these error messages in a logical and consistent way.

Of special interest is the case where the API receives input that triggers a validation error, especially since the input is probably coming from an end-user indirectly and not you. When that happens, the API will try to tell you as much as possible about what field is invalid and why it’s invalid so it can be corrected.

To do this, we take advantage of a neat HAL feature. Inside the response we embed a detailed list of any validation errors:

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

You can read more about errors in our API Docs.

 

HAL Forms keep you up-to-date on the information you need to collect

When you create a Customer and add their bank account using the Access API, you need to collect various pieces of information from that person in your application in order to pass it along to us. But what happens if the information we need to collect changes on you?

We do our best to communicate all API changes to our partners in a clear and timely manner, but we thought there was a better way here too. What if we could use the API to return information about the data fields that need to be collected and how they should be validated?

We developed the Dwolla HAL Form spec as an extension of the basic HAL spec to do just that. Here’s what it looks like:

{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/customers/9bafa1d6-a419-451a-9722-4c07cf8437f0",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "customer"
    }
  },
  "_forms": {
    "edit": {
      "_links": {
        "target": {
          "href": "https://api-sandbox.dwolla.com/customers/9bafa1d6-a419-451a-9722-4c07cf8437f0",
          "type": "application/vnd.dwolla.v1.hal+json",
          "resource-type": "customer"
        }
      },
      "method": "POST",
      "contentType": "application/vnd.dwolla.v1.hal+json",
      "fields": [
        {
          "name": "firstName",
          "path": "/firstName",
          "value": "John",
          "type": "string",
          "displayText": "First Name",
          "validations": {
            "required": true
          }
        },
        {
          "name": "lastName",
          "path": "/lastName",
          "value": "smith",
          "type": "string",
          "displayText": "Last Name",
          "validations": {
            "required": true
          }
        },
        {
          "name": "email",
          "path": "/email",
          "value": "john.smith@nomail.com",
          "type": "email",
          "displayText": "Email",
          "validations": {
            "required": true
          }
        }
      ]
    }
  }
}

 

If you’re interested in learning more, we’ve written a full blog post on HAL Forms that fully explains our rationale and how to use it for collecting customer information.

 

Get started with ACH transfers

We'll help you design your ideal payments experience.

Loading...

Thanks!

We’ve sent you a message to kick off the conversation with our team. Please check your inbox.

Sorry

There was an error and the form was not submitted.

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.