Payable API Overview

Block Quote

Introduction

The Payable API is designed to allow data to flow from your system of record for Workers and Work into Payable.  This allows administrators to manage these Workers, Work and the resulting Payments within the Payable User Interface.

Versioning

The current major API version is v1. All urls will contain v1 at the root of the path.

Within a major version the API uses the 'Dated Version' scheme to introduce any changes in behavior. Each dated version is tested to ensure it’s behavior stays constant as new versions are released.

When you begin development we will track the current dated minor version on your company. As such, you do not ever need to explicitly pass a version header in your requests and can expect the API behavior to stay constant as we add endpoints and new behavior.

You can specify a Accept-Version header to if you want to start testing/consuming new versions of the API before being ready to update your company-wide default. When specifying an explicit version, please ensure you specify the ISO date string.

Example with explicit versioning:

curl -u company_id:api_key -H "Accept-Version:2017-03-29" https://api.payable.com/v1/

The API version you are currently consuming is sent back in the response header as X-Payable-API-Version. EG:

X-Payable-API-Version: 2017-03-29

Authentication

Payable uses HTTP Basic Authentication in the API. Configure your HTTP client with your Company ID and API Key.

For example, in Node.js you could configure request like so:

require('dotenv').config();

var request = require('request');

var baseRequest = request.defaults({

   json: true,

   auth: {

       user: process.env.PAYABLE_COMPANY_ID,

       pass: process.env.PAYABLE_API_KEY,

       sendImmediately: false

   }

});

You can then make calls by referencing your baseRequest with additional parameters:

           var listWorkers = function (callback) {

   var uri = process.env.PAYABLE_HOST + '/v1/workers';

   baseRequest.get(uri, function(error, response, body) {

       // check for success etc...

       callback(body);

   });

};

In Ruby, using HTTParty:

HTTParty.get("https://api.payable.com/v1/workers",

 :basic_auth => {:username => company_id, :password => api_key},

 :headers => { 'Content-Type' => 'application/json'})

As a good security practice, ensure that you externalize the ID and Key from your code and provide it to your application through environment variables or other means of secrets management at your disposal.

Testing

Test Companies

We recommend creating a test company in Payable and letting us know which one is it - we can disable the ability to send real payments and tax forms. This also keeps your test data separate from your production data.

Test Workers

It’s a good practice to use synthetic data for your test Workers - one technique is to use a Gmail accounts and the ‘+’ pattern. For example, the Gmail account myuser@gmail.com will receive emails from myuser+test1@gmail.com as well.  You can then harmlessly create Workers using different suffixes on the one account that your development team can manage.

Resources

In this document, resources are the data entities that you interact with in Payable such as Workers, Work, and Payments. These resource names are part of the URI you will use to access them, for example:

/v1/work

or

/v1/workers

Unique Identifiers in Payable

Payable IDs

Payable data you interact with will have a unique identifier (UID) created by Payable.  When you create data (a Worker, or Work Entry for example), you will get a payload back that contains the UID for that resource in the id field.  You will need to create a relationship between the resource in your system and this ID in Payable. There are a variety of data patterns that can achieve this, ranging from adding a column to your resource’s table to store the Payable ID (not the best option) to creating a mapping table that contains columns for your resourece’s_id and the Payable ID (better option). For example, to link your Workers with Payable Workers, you could implement a table like the following:

TABLE PAYABLE_USER_MAPPING

| user_id | payable_worker_id |

|-----------------------------|

| 12345   | 82734292          |

External IDs

Rather than keeping track of Payable IDs in your system, you can provide Payable with your UIDs for resources and refer to them using those UIDs. This functionality minimizes changes to your data modeling and can get you up and running with your Payable integration much faster.

To leverage External IDs you must provide a UID in the external_id field when creating the resource. For example:

POST https://api.payable.com/v1/worker/

{

     "external_id": "worker_18377",

     "email": "testworker@example.com",

     "display_name": "Test Worker"

}

The return payload will echo back your external_id as well as the Payable ID (as the id field).  The resource is now accessible by both types of IDs.

HTTP/1.1 201 OK{    "id": 4135931640,    "external_id": "worker_18377",    "display_name": "Test Worker",    "email": "testworker@example.com",    "signed_up": false,    "invite_status": "invited",    "payable": false,    "created_at": "2016-04-22T04:34:16Z",    "updated_at": "2016-07-01T21:23:51Z"}

If you don’t provide an External ID when you create the resource, you will need to refer to it by the Payable ID.

Rates

Rates are not currently accessible in the API.

Work Types

Work Types represent the type of work that is being done and how it is measured. There are 4 different types of measurement:

money - pre-calculated amount of money in centsunits - input for calculated values based on unitstime - input for calculated values based on time in secondsdistance - input for calculated values based on distance

Create the Work Types in the Payable UI, set any appropriate Rates and tax treatment, then with the API retrieve the Work Types for your company. When creating Work, you will need to reference the appropriate Work Type by it’s ID. In your integration you can create configuration variables for these values, or a mapping table for more flexible longer-term management if you have your own concept of Work Types.

Workers

Adding a worker is as simple as providing a display name and an email address.  We take things from there.  Specifically, we invite your user to set up their account in Payable, to provide us their legal, tax and banking information. Operationally, when you create an account for your contractor in your system, just send us that information and we'll do the same.

Controlling The Invitation Process

If you do NOT want to invite the user to set up their Payable account, send the invite=false parameter, by default it is true.

Onboarding Status

As part of the Worker response payload, you will see fields that provide some information about the state of that Worker in Payable as it relates to them being onboarded in our system.

signed_up

Boolean

Indicates if this individual has an active membership to your company.  A Non-User in the App would be considered false, a Worker would be true.

invite_status

String

Indicates if this individual has a pending invite to your company. Can be one of 'invited', 'accepted', or 'not_invited'.

payable

Boolean

Indicates if this account able to receive payments.

These statuses are also clearly visible in the App that the company admins will be using.

Work

You compensate your contractors based on their work. Payable has a very flexible model for handling the different types of work your contractors do. You can provide us time, units, or money amounts, and manage the rates applied to these at the global, service or contractor level.

Effects of Creating Work

Work entries will asynchronously show up in the app as they are created - Workers will see the work, and administrators can review and edit it.

Sending us Work entries accrues into payments.  These should be reflected shortly after the Work entry is created.  See the Payments section for more details.

Specifying Work Types and Quantities

Each Work entry must have a Work Type ID specified with it - this governs how Payable interprets the quantity values (as money, time, etc).  See the section on Work Types for more details.

Adding additional Metadata

Work data can be enriched with additional Metadata using simple name-value pairs.  See the section on Custom Field Definitions for more details about this capability.

Real-Time vs. Batched Work Creation Considerations

We recommend sending work entries as they occur; this allows approvers and contractors alike to see the activity that is happening, and gives you and your contractors to the ability to detect discrepancies earlier in the game.

Work entries can be as discrete or aggregated as you want.  For example, if you were paying a writer to produce four blog posts in a week period, you could send a work entry for every blog post (as they are completed) OR send one work entry at the end of the week for four blog posts (assuming your system was aggregating them).

Payments

Work entries accrue into Payments.  It is important to note that Payments are not automatically sent when Work is created.  Payments can only be initiated by administrators in the Payable UI.

The Payment Lifecycle

Payments transition between various states in the system. The API provides statuses for these states:

draft_readypayment_pendingpaidcredit_faileddebit_failedrefunded

Draft

As Work to be paid accrues, a Draft payment is created and updated with the Work entries.  Draft payments respect Pay Schedules, and as such Work entries may be bucketed into multiple Draft Payments depending on when the Work took place.

Pending

When a Payment is initiated by an administrator, the Payment transitions to a Pending state.

Paid

Once we have confirmation that either the ACH transaction was executed (or Check mailed) the Payment transitions to Paid.

Debit and Credit Failed

Payments can also Fail.  This can happen due to problems with the Worker’s bank, insufficient funds on the part of your Company or system errors.  Administrators and/or Payable support must intervene to resolve these issues.

Refunded

In rare cases, Payments may be refunded.  This can occur when a Worker never finished setting up their Bank Account, and we were unable to deposit funds after 30 days.  The funds would then go back into the Company account.

Query Filters

Payments can be queried with various filters, including

Worker -  eg: &worker_id=1234Paid Date - eg: &paid_after=2016-12-04T19:27:21ZInitiated Date - eg &sent_after=2016-12-04T19:27:21Z

Custom Field Definitions

Understanding Custom Fields

Custom Fields allow you to enrich the Work Entries (and soon Workers) that you provide to Payable with additional data. You can think of Custom Fields as name/value pairs of freeform data that are associated with the Payable Work Entry. Work has a lot of context around it - from the time it was performed, whom it was performed for, where it was performed, what project it may have been associated with, etc... While some of these attributes of Work are required for Payable to calculate payments, the rest only have meaning to you, the provider of this information.

Custom Field data appears not only in API calls, but also in CSV exports. As a result, the work data within a Work Export contains all the contextual information you provided at the time, which can make it easier to associate with existing data in your system, filter and slice up work by certain criteria, and analyze and report on data in ways that are essential to your business.

Configuring Custom Fields

To provide consistency in how your Custom Fields are handled in both the API and in CSV import/export, we require you to define your Custom Fields before you can use them. This means that the names of the fields you wish to use need to be defined prior to associating name/value pairs to the Payable data.  For example, if you want to track a field named 'City' with each Work entry, define the 'City' field and associate it with the resource_type of 'work'. EG:

POST https://api.payable.com/v1/custom_fields/

{

     "name": "City",

     "resource_type": "work"

}

With this configured, 'City' is now a column in your CSV export, and of course comes back with any Retrieve or List operation in the API.

You can then submit the 'City' field with any Work data.  EG:

POST https://api.payable.com/v1/work/

{

     "worker_id": 123456,

     "work_type_id": 123456,

     "quantity": 35400,

     "start": "2017-02-28T08:00:00Z",

     "notes": "Gotham Gala - Setup and Tear Down",

     "custom_fields": {"City": "Chicago"}

}

To take advantage of this new functionality, be sure to set your API version to > 2017.3.13.  If you would like this to be your default version, let us know and we can configure that.