NAV Navbar
Logo
json xml

Introduction

Welcome, developers!

The Handshake API is intended to be a platform-agnostic means by which programmers can build integrations between Handshake and other applications and services. help Handshake also provides a robust set of spreadsheet / ZIP file-based methods of importing and exporting data via flat-file exchange.

However, if you want a more automated integration between Handshake and your other systems, you’ll want to connect to our API.

Quickstart

To use the Handshake API, you will need an API key, which is a long string of random numbers and letters that you will use as a password when accessing the API. You can generate (or re-generate) your API key via your user page.

Now that you have your API key, you can view some XML output from the API right in your web browser by visiting https://app.handshake.com/api/latest/orders?format=xml (you must be logged in for this to work). Firefox is an especially good browser for viewing XML in a nice readable format.

You should have seen a big pile of XML with data from the orders you’ve written in your account (assuming that you’ve actually written some). We also support generating data in JSON, which you can get by visiting https://app.handshake.com/api/latest/orders?format=json instead.

Although spitting out huge chunks of data in your browser is fun, you probably want to access the API from scripts or integration tools instead. We’ll cover that in the next page.

Authentication

# Use the command below to dump the JSON data for your orders. Replace the `2c493d74` with your own API key (which will be much longer)

curl "-u 2c493d74:X https://app.handshake.com/api/latest/orders"

Make sure to replace the 2c493d74 with your own API key.

The links in the previous page that generate API content in your browser work because you’re logged into your account and the server is already happy that you are, in fact, you. When you write scripts or tools to access the API outside of your browser session, you must provide your API key to authenticate on every request.

Taking a leaf out of the book of some other clever folks, the Handshake API requires that you use HTTP basic authentication to pass your API key with each request. You should pass the API key as the username along with ‘X’ as the password.

A note about security

Your API key uniquely identifies you and you should treat it with the same care and secrecy as you do your main account password. If your API key is compromised by an attacker, they will be able to access the data in your account, so if you suspect that this might have happened, you should generate a new one.

In particular, if you accidentally try to access the API using plain HTTP instead of HTTPS, then it is possible that a man-in-the-middle attacker has just intercepted your API key and is now able to use it to access data in your account. If you ever accidentally do this, Handshake will automatically destroy your API key to prevent anyone else from using it to access your account. You can easily generate a new one from your user page.

Conventions

API versioning

While we make every effort possible to minimize changes to the API so that we don’t break your existing integrations, it’s possible that over time there might be necessary changes. When this happens, we will continue to support the old and new versions of the API in parallel for a period of time to give you time to test your existing code against the new API. If you’re lucky, everything will work magically, but otherwise you’ll have plenty of time to migrate.

When a request is made to the API, it must include the API version in the URL. The standard format for an API request URL is /api/<versionNumber>/<resourceName>.

To default your requests to using the latest version of the API, use /latest in your request URLs:

https://app.handshake.com/api/latest/

Alternatviely, to use version 3, the request URLs should look like:

https://app.handshake.com/api/v3/

We may add to the API at any time

We reserve the right to make additions to the API without notification or altering the base version number of the API. This means we will not alter the behaviour of existing fields without warning, but will add new fields and / or resources to support new functionality as it is implemented elsewhere in Handshake.

From a practical perspective, this simply means that you should not build integrations that assume that the set of available fields will not grow (although you can of course build an integration that assumes that the set of available fields will not shrink).

Data formats

Resources can be represented as either JSON or XML. JSON is the default, but you can specify the format by appending “.json” or “.xml” to the URL.

https://app.handshake.com/api/latest/orders
https://app.handshake.com/api/latest/orders.json
https://app.handshake.com/api/latest/orders.xml

When doing a POST or PUT to the API with your own data in the request body, you must supply the Content-Type header on your request that specifies the type of data you are uploading:

Rate limiting / throttling

We allow you to make up to 60 requests to our API in a one-minute period. This should allow you enough bandwidth to perform integrations without placing an unnecessarily large burden on the Handshake servers

If you exceed this limit, your requests will be denied with a 429 (TOO MANY REQUESTS) response until the one minute window elapses and you are allowed to make requests again.

If you exceed this limit by a huge margin (i.e. our system detects that you are abusing the API), your access to the API may be revoked. We encourage you to correctly handle a 429 response code to avoid your integration being flagged for abuse.

Field name & type notation

Throughout this documentation, the data type of each field is indicated next to the name, a la:

Field Description
object.fieldName
Type: datatype
Required: false
Most fields have a description following their signature, however, where the meaning is sufficiently obvious, only the name and type of the field will be given.
Some fields are marked as readonly meaning that they are provided for your information but writing to them via a POST or PUT request will have no effect.
Some fields are marked as server-only meaning that they only exist on the website, but are not available on the iOS apps, and so should not be used in templates that need to work on iPads or iPhones.
Some fields are marked as template-only meaning that they are accessible via the templates, but are not accessible via the API.

Date / time formatting

The API returns dates in ISO-8601 format. This means they are formatted as YYYY-MM-DDTHH:MM:SSZ where:

For example, November 8th, 2010, at 5:47:40pm in New York (which is 10:47:40pm UTC since New York is UTC -5:00) would be represented as 2010-11-08T22:47:40Z.

Decimal formatting

The API returns and accepts decimals (e.g. Item.unitPrice) as strings, not floats. Float to decimal conversion is inherently lossy and to avoid this we return all decimals as strings and require that any POST / PUT requests provide them in this format.

Unicode data

All unicode data returned by the Handshake API is encoded as UTF-8. When the response is in XML format, this is explicitly indicated in the header:

<?xml version='1.0' encoding='utf-8'?>

JSON format responses also use a UTF-8 encoding, even though that fact is not explicitly stated in the response.

When pushing data into Handshake, you should (obviously) also use a UTF-8 encoding for all unicode data.

Errors

The Handshake API uses the following error codes:

Error Code Meaning
400 Bad Request – Your request is formatted incorrectly
401 Unauthorized – Your API key is wrong
403 Forbidden – The resource requested is hidden for administrators only
404 Not Found – The specified resource could not be found
405 Method Not Allowed – You tried to access a resource with an invalid method
406 Not Acceptable – You requested a format that isn’t json
410 Gone – The resource requested has been removed from our servers
418 I’m a teapot
429 Too Many Requests – You’re requesting too many resources! Slow down!
500 Internal Server Error – We had a problem with our server. Try again later.
503 Service Unavailable – We’re temporarially offline for maintanance. Please try again later.

Resources

A resource is a data type that you access via one of our exposed API URLs. You can use the standard set of RESTful verbs (GET POST PUT DELETE) on each resource to fetch, create, update, and delete, respectively.

List vs. detail operations

## Fetch all the orders in the database

curl "https://app.handshake.com/api/latest/orders"

## Fetch the order with order.objID == 89

curl "https://app.handshake.com/api/latest/orders/89"

Use the standard pattern for fetching a list of resources, or fetch a specific resource by appending the resource’s objID to the list URL.

When a GET response returns resource data, each resource has a resource_uri field indicating the specific URL where this resource can be retrieved / updated.

Supported HTTP methods

Using PATCH to update records

One change per request

Most API integrations interact with our API using the four common HTTP verbs: GET, POST, PUT, and DELETE. Our API supports fetching a list of resources using GET, but for the other three verbs, it only supports interacting with one resource at a time.

In other words, you are allowed to create a single resource via POST, update a single resource via PUT, and delete a single resource via DELETE, but if you want to do a bulk operation where you are modifying multiple resources in a single request, those verbs do not support that.

Multiple changes per request with PATCH

## Using Patch
{
//Payloads normally used in a PUT or a POST to insert / update a single record
  "objects": [
    {
        ...
    },
    {
        ...
    },
  ],
  //Detail URIs you would normally send a DELETE request to
  "deleted_objects": [
      "/api/latest/resource_name/12345",
      "/api/latest/resource_name/12346",
  ]
}

There is a fifth HTTP verb supported by our API that allows you to make multiple changes in a single request: PATCH. A PATCH request looks like this:

As noted, there are two top-level keys in a PATCH request:

A word of warning

Using PATCH might seem like a clever way to speed up your integration (and it is), however you should be aware of the below when considering using it:

We strongly recommend getting your integration working using basic POST, PUT, and DELETE before you attempt to optimize it by aggregating multiple requests together using PATCH. It is definitely an advanced usage of the API and is not for the faint of heart.

Pagination

##
curl "https://app.handshake.com/api/latest/orders"

{
  "meta":{
    "limit":100,
    "next":"/api/latest/orders?...", /* URL for the next page of results */
    "offset":0,
    "previous":null,
    "total_count":860
  },
  "objects":[
    ...
  ]
}

By default, lists of resources are returned in blocks of 100 records at a time. The meta dictionary that’s returned tells you where you are up to, and if there’s another page of results after this one, the next entry gives you the URL where it can be fetched.

Fetching fewer results per page

##
curl "https://app.handshake.com/api/latest/orders?limit=50"

{
  "meta":{
    "limit":50,
    ...
  }
}

Depending on the structure of your data, it’s possible that the API may not be able to return the number of resources requested before a HTTP 504 (Gateway Timeout) happens. For example, if your first 100 orders have 1,000 line items each, you might hit a 504 when trying to fetch them.

You can control the page size for a GET request with the limit query parameter, e.g:

If you notice that 504s are coming back, you should reduce the limit until you start getting 200s. A sensible strategy for this is probably to iteratively halve the page size until you stop getting 504s.

A related resource is a resource that is connected to the resource in question. For example, a sales order is related to the customer it was written for through its customer property. Related resources are represented in the API in one of two ways.

Full mode

## Below is a trimmed down example of a customer resource with the bill-to address in full mode:


{
   "billTo":{
      "btCustomer":"/api/latest/customers/43",
      "city":"Brooklyn",
      "country":"US",
      "fax":"555-555-5559",
      "objID":44,
      "phone":"123-456-7894",
      "postcode":"11217",
      "resource_uri":"/api/latest/addresses/44",
      "stCustomer":null,
      "state":"NY",
      "street":"8051 Brown Road",
      "street2":""
   },
   "contact":"Kelly Slater",
   "email":"foo@bar.com",
   "entityType":"Customer",
   "id":"C1004",
   "name":"The Globe"
}

<billTo>
    <btCustomer>/api/latest/customers/43</btCustomer>
    <city>Brooklyn</city>
    <country>US</country>
    <fax>555-555-5559</fax>
    <objID>44</objID>
    <phone>123-456-7894</phone>
    <postcode>11217</postcode>
    <resource_uri>/api/latest/addresses/44</resource_uri>
    <stCustomer/>
    <state>NY</state>
    <street>8051 Brown Road</street>
    <street2></street2>
</billTo>
<contact>Kelly Slater</contact>
<email>foo@bar.com</email>
<entityType>Customer</entityType>
<id>C1004</id>
<name>The Globe</name>

The complete data of the related resource is provided inline as a dictionary of values. This dictionary contains the same data that you would get if you fetched that related resource directly (including the resource_uri property as a key in the dictionary).

Reference mode

## The same customer as above is given below with the bill-to address in reference mode:

{
   "billTo":"/api/latest/addresses/44",
   "contact":"Kelly Slater",
   "email":"foo@bar.com",
   "entityType":"Customer",
   "id":"C1004",
   "name":"The Globe",
}

<billTo>/api/latest/addresses/44</billTo>
<contact>Kelly Slater</contact>
<email>foo@bar.com</email>
<entityType>Customer</entityType>
<id>C1004</id>
<name>The Globe</name>

The resource_uri of the related resource is given as a string. The same customer as above is given below with the bill-to address in reference mode:

We tend to use reference mode when returning data for GET requests, however we will use full mode for relationships where it makes sense to provide more complete info (e.g. when fetching sales orders, we assume you will usually want to see the data for the customer attached to that order). This saves an extra GET to our API to collect all the other stuff you want to know about.

Disabling full mode

## Fetch orders with all relationships in reference mode
curl "https://app.handshake.com/api/latest/orders?full=false"

Sometimes, you might prefer to fetch resources with all relationships in reference mode for efficiency’s sake. To turn off full mode for a single request, simply pass full=false as part of your query string.

When writing to the API via a POST or PUT, you can specify related resources in either format, but some recommended strategies for working with relationships are:

Common fields

The fields and methods below are available for all Handshake resources.

Field Description
object.account
Type:url
Required: false
Reference to your account information.
object.id
Type: read-only string
Required: false
This is commonly a positive integer that represents the object ID, but can also be a string that the user defines through Handshake Hub. This should not be used as a unique reference. obj.uuid or obj.objID are better suited for retrieving data.
object.objID
Type: read-only integer
Required: false
A positive integer that uniquely identifies this resource within your account. This integer forms the last part of the resource_uri for each resource.
This is not guaranteed to be globally unique and it is possible that this ID might be repeated in another Handshake account. If you only administer a single Handshake account you can treat this as globally unique.
object.uuid
Type: read-only UUID
Required: false
A UUID4 that uniquely identifies this resource and is guaranteed to be globally unique.
object.ctime
Type: datetime
Required: false
The time at which this resource was first created. If this resource was created directly on the server (e.g. during a bulk import, or through the API) then this value will be exactly correct. If this resource was created on a iOS device, then it may be off by a small amount, usually fractions of a second.
object.cdate
Type: read-only date
Required: false
The date part of the ctime without the time part.
object.entityType
Type: read-only string
Required: false
The resource type.
object.mtime
Type: read-only datetime
Required: false
The time at which this resource was last modified. It is subject to the same accuracy guarantees as ctime above.
object.ctimeOnServer
Type: read-only datetime
Required: false
The time at which this resource was first created on the server. If this resource was created directly on the server (e.g. during a bulk import, or through the API) then this will be the same as the ctime. If this resource was created on a iOS device, then it will be the time that the resource was first synced to the server.
object.mtimeOnServer
Type: read-only datetime
Required: false
The time at which this resource was last modified on the server. If this resource last modified directly on the server (e.g. during a bulk import, or through the API) then this will be the same as the mtime. If this resource was modified on a iOS device, then it will be the time that the resource was last synced to the server.
object.owner
Type: read-only reference to UseRequired: false
The User who originally created this resource.
object.resource_uri
Type: read-only uri
Required: false
The URI to retrieve the requested object.

The fields below are common, but may not be included in every resource. They appear frequently enough that, in the interest of DRY, they are included here.

Field Description
categoryPosition
Type: integer or float
Required: true
The position of this category within its parent (or at the root of the category tree if this category has no parent).
If you provide this attribute as a float instead of an int, the API will automatically shuffle existing categories in the same parent category to accomodate you “wedging” a category between two existing ones. For example if you have three existing categories at the following positions:

  • A (5)
  • B (6)
  • C (7)

And then you POST a new category D at position 5.5, the categories will be automatically shuffled like so:

  • A (5)
  • D (6)
  • B (7)
  • C (8)
obj.externalID
Type: integer
Required: false
Reference to the unique identifier in a separate system (if applicable). This is commonly used when integrating with an ERP, CRM, or other system, like QuickBooks.
obj.isHidden
Type:
Required:
obj.isHiddenForCustomers
Type:
Required:
obj.isImplicitlyHidden
Type:
Required:
obj.isImplicitlyHiddenForCustomers
Type:
Required:

Filtering

## Fetch orders as XML in the category with ID 'NYTS'
curl "https://app.handshake.com/api/latest/orders.xml?category=NYTS"

You can filter out the results that are returned to you by the server by passing filter names in your query string. The specific filters that are supported for each data type are detailed in the API documentation for that type. As an example, orders can be filtered by their category as shown.

## Fetch orders as XML in the category with ID 'NYTS 2011'
curl "https://app.handshake.com/api/latest/orders.xml?category=NYTS%202011"

When passing filter parameters in URLs you need to percent-encode them. Spaces need to be replaced with %20. Your HTTP library might do this automatically, but you should be aware of it.

## Fetch orders created after 2011-10-12 10:39:04pm UTC
curl "https://app.handshake.com/api/latest/orders?ctime__gte=2011-10-12T22:39:04Z"

Common Filters

The filters below apply to all resources, and can be used on any GET request to restrict the set of results that will be returned

Field Description
ctime
Type: datetime
Required: false
Filters by the resource’s creation time with a comparison operator, which should be one of:
  • gt (greater than)
  • gte (greater than or equal)
  • lt (less than)
  • lte (less than or equal)
mtime
Type: datetime
Required: false
Filters by the resource’s last-modified time using the same operators as ctime above.
ctimeOnServer
Type: datetime
Required: false
Filters by the resource’s creation time on the server using the same operators as ctime above.
mtimeOnServer
Type: datetime
Required: false
Filters by the resource’s last modified time on the server using the same operators as ctime above.

Ordering

You order the results that the API returns by passing the order_by parameter in your query string. By default, orderings are ascending, but the ordering key can be prefixed with a minus to request a descending sort.

## Fetch orders by date created, ascending
curl "https://app.handshake.com/api/latest/orders?order_by=ctime"
## Fetch orders by date created, descending
curl "https://app.handshake.com/api/latest/orders?order_by=-ctime"

All resources support at least the following five orderings:

Order Objects

Orders

## Orders can be accessed through the API via the orders base URL:
curl "https://app.handshake.com/api/latest/orders"

Orders can be accessed through the API via the orders base URL:

$ curl https://app.handshake.com/api/latest/orders


{
   "meta":{
      "limit":100,
      "next":null,
      "offset":0,
      "previous":null,
      "total_count":1
   },
   "objects":[
      {
         "billTo":{
            "btCustomer":"/api/latest/customers/2013",
            "city":"New York",
            "country":"US",
            "fax":"2015487645",
            "objID":2014,
            "phone":"2125551234",
            "postcode":"07875",
            "resource_uri":"/api/latest/addresses/2014",
            "stCustomer":null,
            "state":"NY",
            "street":"123 Main St",
            "street2":""
         },
         "cancelDate":null,
         "category":"/api/latest/categories/19",
         "cdate":"2010-11-23",
         "creditCard":{
            "customer":"/api/latest/customers/2013",
            "cvv":"",
            "lastFour":"5553",
            "month":"12",
            "name":"Mark Twain",
            "number":"",
            "objID":3216,
            "resource_uri":"/api/latest/credit_cards/3216",
            "type":"AMEX",
            "year":"14"
         },
         "ctime":"2010-11-24T03:55:46Z",
         "customer":{
            "billTo":{
               "btCustomer":"/api/latest/customers/2013",
               "city":"New York",
               "country":"US",
               "fax":"2015487645",
               "objID":2014,
               "phone":"2125551234",
               "postcode":"07875",
               "resource_uri":"/api/latest/addresses/2014",
               "stCustomer":null,
               "state":"NY",
               "street":"123 Main St",
               "street2":""
            },
            "cdate":"2010-10-12",
            "contact":"Obie",
            "creditCards":[
               {
                  "customer":"/api/latest/customers/2013",
                  "cvv":"",
                  "lastFour":"5553",
                  "month":"12",
                  "name":"Mark Twain",
                  "number":"",
                  "objID":3216,
                  "resource_uri":"/api/latest/credit_cards/3216",
                  "type":"AMEX",
                  "year":"14"
               },
               {
                  "customer":"/api/latest/customers/2013",
                  "cvv":"",
                  "lastFour":"4477",
                  "month":"12",
                  "name":"Obie",
                  "number":"",
                  "objID":2026,
                  "resource_uri":"/api/latest/credit_cards/2026",
                  "type":"MASTERCARD",
                  "year":"10"
               }
            ],
            "ctime":"2010-10-12T19:19:07Z",
            "customerGroup":{
               "id":"US",
               "manufacturer":null,
               "name":"US Retailers",
               "objID":946,
               "parent":null,
               "resource_uri":"/api/latest/categories/946",
               "subType":"Customer",
               "subcategories":[

               ]
            },
            "defaultShipTo":{
               "btCustomer":"/api/latest/customers/2013",
               "city":"New York",
               "country":"US",
               "fax":"2015487645",
               "objID":2014,
               "phone":"2125551234",
               "postcode":"07875",
               "resource_uri":"/api/latest/addresses/2014",
               "stCustomer":null,
               "state":"NY",
               "street":"123 Main St",
               "street2":""
            },
            "email":"Obie@bob.con",
            "entityType":"Customer",
            "id":"*2013",
            "mtime":"2012-04-12T17:57:40Z",
            "name":"Bob Smith",
            "objID":2013,
            "owner":"jenny@demo.com",
            "paymentTerms":"PREPAID",
            "resource_uri":"/api/latest/customers/2013",
            "shipTos":[
               {
                  "btCustomer":null,
                  "city":"New York",
                  "country":"US",
                  "fax":"",
                  "objID":994,
                  "phone":"5555555555",
                  "postcode":"11211",
                  "resource_uri":"/api/latest/addresses/994",
                  "stCustomer":"/api/latest/customers/2013",
                  "state":"NY",
                  "street":"154 Grand St",
                  "street2":""
               }
            ],
            "shippingMethod":"UPS",
            "userGroup":{
               "id":"test",
               "manufacturer":null,
               "name":"test",
               "objID":109180,
               "parent":"/api/latest/categories/109039",
               "resource_uri":"/api/latest/categories/109180",
               "subType":"UserProfile",
               "subcategories":[

               ]
            },
            "uuid":"a3620f47-9915-4f24-9a1a-474ec3cb8fb2"
         },
         "customerPO":null,
         "entityType":"SalesOrder",
         "freeShipping":false,
         "lastEdited":"2011-08-22T11:00:25Z",
         "lastExported":null,
         "lines":[
            {
               "barcode":"9780375766157",
               "cdate":"2010-11-23",
               "ctime":"2010-11-24T03:56:17Z",
               "description":"Tenor Trombone",
               "dimensions":null,
               "entityType":"SalesOrderLine",
               "isku":"TBN.T",
               "item":"/api/v2/items/169",
               "manufacturer":"/api/latest/manufacturers/949",
               "mtime":"2010-11-24T03:55:33Z",
               "notes":"",
               "objID":41001,
               "order":"/api/latest/orders/41000",
               "owner":"guest@demo.com",
               "qty":1,
               "resource_uri":"/api/latest/order_lines/41001",
               "sku":"TBN.T",
               "unitPrice":"1300.00",
               "uuid":"c601f9a2-9fb1-465c-ba13-b1bcd7b3e5a2",
               "vsku":null
            }
         ],
         "mtime":"2011-08-22T11:00:25Z",
         "notes":"",
         "objID":41000,
         "owner":"guest@demo.com",
         "paymentTerms":"PREPAID",
         "resource_uri":"/api/latest/orders/41000",
         "shipPartial":true,
         "shipTo":{
            "btCustomer":null,
            "city":"New York",
            "country":"US",
            "fax":"",
            "objID":3023,
            "phone":"5555555555",
            "postcode":"11211",
            "resource_uri":"/api/latest/addresses/3023",
            "stCustomer":null,
            "state":"NY",
            "street":"154 Grand St",
            "street2":null
         },
         "shippingMethod":"UPS",
         "startShipDate":null,
         "status":"Confirmed",
         "userGroup":"/api/latest/categories/109039",
         "uuid":"b111414a-6cdc-4697-a93c-964edf9530a7"
      }
   ]
}
<meta>
    <limit>100</limit>
    <next/>
    <offset>0</offset>
    <previous/>
    <total_count>1</total_count>
</meta>
<objects>
    <billTo>
        <btCustomer>/api/latest/customers/2013</btCustomer>
        <city>New York</city>
        <country>US</country>
        <fax>2015487645</fax>
        <objID>2014</objID>
        <phone>2125551234</phone>
        <postcode>07875</postcode>
        <resource_uri>/api/latest/addresses/2014</resource_uri>
        <stCustomer/>
        <state>NY</state>
        <street>123 Main St</street>
        <street2></street2>
    </billTo>
    <cancelDate/>
    <category>/api/latest/categories/19</category>
    <cdate>2010-11-23</cdate>
    <creditCard>
        <customer>/api/latest/customers/2013</customer>
        <cvv></cvv>
        <lastFour>5553</lastFour>
        <month>12</month>
        <name>Mark Twain</name>
        <number></number>
        <objID>3216</objID>
        <resource_uri>/api/latest/credit_cards/3216</resource_uri>
        <type>AMEX</type>
        <year>14</year>
    </creditCard>
    <ctime>2010-11-24T03:55:46Z</ctime>
    <customer>
        <billTo>
            <btCustomer>/api/latest/customers/2013</btCustomer>
            <city>New York</city>
            <country>US</country>
            <fax>2015487645</fax>
            <objID>2014</objID>
            <phone>2125551234</phone>
            <postcode>07875</postcode>
            <resource_uri>/api/latest/addresses/2014</resource_uri>
            <stCustomer/>
            <state>NY</state>
            <street>123 Main St</street>
            <street2></street2>
        </billTo>
        <cdate>2010-10-12</cdate>
        <contact>Obie</contact>
        <creditCards>
            <customer>/api/latest/customers/2013</customer>
            <cvv></cvv>
            <lastFour>5553</lastFour>
            <month>12</month>
            <name>Mark Twain</name>
            <number></number>
            <objID>3216</objID>
            <resource_uri>/api/latest/credit_cards/3216</resource_uri>
            <type>AMEX</type>
            <year>14</year>
        </creditCards>
        <creditCards>
            <customer>/api/latest/customers/2013</customer>
            <cvv></cvv>
            <lastFour>4477</lastFour>
            <month>12</month>
            <name>Obie</name>
            <number></number>
            <objID>2026</objID>
            <resource_uri>/api/latest/credit_cards/2026</resource_uri>
            <type>MASTERCARD</type>
            <year>10</year>
        </creditCards>
        <ctime>2010-10-12T19:19:07Z</ctime>
        <customerGroup>
            <id>US</id>
            <manufacturer/>
            <name>US Retailers</name>
            <objID>946</objID>
            <parent/>
            <resource_uri>/api/latest/categories/946</resource_uri>
            <subType>Customer</subType>
        </customerGroup>
        <defaultShipTo>
            <btCustomer>/api/latest/customers/2013</btCustomer>
            <city>New York</city>
            <country>US</country>
            <fax>2015487645</fax>
            <objID>2014</objID>
            <phone>2125551234</phone>
            <postcode>07875</postcode>
            <resource_uri>/api/latest/addresses/2014</resource_uri>
            <stCustomer/>
            <state>NY</state>
            <street>123 Main St</street>
            <street2></street2>
        </defaultShipTo>
        <email>Obie@bob.con</email>
        <entityType>Customer</entityType>
        <id>*2013</id>
        <mtime>2012-04-12T17:57:40Z</mtime>
        <name>Bob Smith</name>
        <objID>2013</objID>
        <owner>jenny@demo.com</owner>
        <paymentTerms>PREPAID</paymentTerms>
        <resource_uri>/api/latest/customers/2013</resource_uri>
        <shipTos>
            <btCustomer/>
            <city>New York</city>
            <country>US</country>
            <fax></fax>
            <objID>994</objID>
            <phone>5555555555</phone>
            <postcode>11211</postcode>
            <resource_uri>/api/latest/addresses/994</resource_uri>
            <stCustomer>/api/latest/customers/2013</stCustomer>
            <state>NY</state>
            <street>154 Grand St</street>
            <street2></street2>
        </shipTos>
        <shippingMethod>UPS</shippingMethod>
        <userGroup>
            <id>test</id>
            <manufacturer/>
            <name>test</name>
            <objID>109180</objID>
            <parent>/api/latest/categories/109039</parent>
            <resource_uri>/api/latest/categories/109180</resource_uri>
            <subType>UserProfile</subType>
        </userGroup>
        <uuid>a3620f47-9915-4f24-9a1a-474ec3cb8fb2</uuid>
    </customer>
    <customerPO/>
    <entityType>SalesOrder</entityType>
    <freeShipping>false</freeShipping>
    <lastEdited>2011-08-22T11:00:25Z</lastEdited>
    <lastExported/>
    <lines>
        <barcode>9780375766157</barcode>
        <cdate>2010-11-23</cdate>
        <ctime>2010-11-24T03:56:17Z</ctime>
        <description>Tenor Trombone</description>
        <dimensions/>
        <entityType>SalesOrderLine</entityType>
        <isku>TBN.T</isku>
        <item>/api/v2/items/169</item>
        <manufacturer>/api/latest/manufacturers/949</manufacturer>
        <mtime>2010-11-24T03:55:33Z</mtime>
        <notes></notes>
        <objID>41001</objID>
        <order>/api/latest/orders/41000</order>
        <owner>guest@demo.com</owner>
        <qty>1</qty>
        <resource_uri>/api/latest/order_lines/41001</resource_uri>
        <sku>TBN.T</sku>
        <unitPrice>1300.00</unitPrice>
        <uuid>c601f9a2-9fb1-465c-ba13-b1bcd7b3e5a2</uuid>
        <vsku/>
    </lines>
    <mtime>2011-08-22T11:00:25Z</mtime>
    <notes></notes>
    <objID>41000</objID>
    <owner>guest@demo.com</owner>
    <paymentTerms>PREPAID</paymentTerms>
    <resource_uri>/api/latest/orders/41000</resource_uri>
    <shipPartial>true</shipPartial>
    <shipTo>
        <btCustomer/>
        <city>New York</city>
        <country>US</country>
        <fax></fax>
        <objID>3023</objID>
        <phone>5555555555</phone>
        <postcode>11211</postcode>
        <resource_uri>/api/latest/addresses/3023</resource_uri>
        <stCustomer/>
        <state>NY</state>
        <street>154 Grand St</street>
        <street2/>
    </shipTo>
    <shippingMethod>UPS</shippingMethod>
    <startShipDate/>
    <status>Confirmed</status>
    <userGroup>/api/latest/categories/109039</userGroup>
    <uuid>b111414a-6cdc-4697-a93c-964edf9530a7</uuid>
</objects>

In addition to the common fields listed above, order objects contain the following fields:

Field Description
id
Type: read-only string
Required: false
The objID of this order, preceded by a hash character, e.g. "#10013". This is not the same as the numeric objID, even though it is obviously directly derived from it. This exists simply for convenience so you have a consistent way of displaying order IDs in your templates.
customer
Type: reference to Customer
Required: true
The Customer who this order was written for.
billTo
Type: references to Addresses
Required: true
The Address objects for billing & shipping respectively.
shipTo
Type: references to Addresses
Required: true
The Address objects for billing & shipping respectively.
creditCard
Type: reference to CreditCard
Required: false
The CreditCard that was selected on this order, or null if none was selected.
userGroup
Type:reference to UserGroup
Required: false
The UserGroup that this order has been restricted to. This will always be the same as the UserGroup that this order’s customer is in.
category
Type: reference to OrderCategory
Required: true
The OrderCategory that this order is in, which will be one of the categories defined here.
lines
Type: collection of SalesOrderLine
Required: false
A collection of SalesOrderLine objects for the line items on this order, returned in the order that they appear in the cart view in the iOS app.

Note that when writing order confirmation templates, you should not directly access this property and should instead use the top-level lines template variable, which will have already been filtered down if you’re emailing a manufacturer-specific portion of an order rather than the whole thing. This field always returns all the lines on the order and is therefore not always appropriate for email confirmations.
lastEdited
Type: read-only datetime
Required: false
The most recent mtimeOnServer of this order or any of the descendant objects, i.e. the most recent modified timestamp of the order itself, any of the lines on the order, the billTo or shipTo addresses, or the creditCard on the order (if there is one). You should treat this time as the most recent time a change was made to this order, useful if you are trying to build batch jobs that fetch only the orders modified since the last time the batch job was run.
manufacturerIDs
Type: template-only string
Required: false
A comma-separated string containing the manufacturer IDs of the items on this order. This is mostly intended to be used when you have multiple manufacturers but only write orders for one manufacturer at a time and want to be able to identify the manufacturer that the order is for.
manufacturerNames
Type: template-only string
Required: false
A comma-separated string containing the manufacturer names of the items on this order. This is mostly intended to be used when you have multiple manufacturers but only write orders for one manufacturer at a time and want to be able to identify the manufacturer that the order is for.
manufacturerBreakdown
Type: template-only collection of dictionaries
Required: false
A collection of data dictionaries that breaks down the lines on the order by manufacturer. Each object in the collection supports the following keys:
  • id is the manufacturer ID
  • name is the manufacturer name
  • total is the total amount of all the lines for this manufacturer
  • lines is a collection of the line items for this manufacturer
lastExported
Type: server-only datetime
Required: false
The most recent time that this order was exported from the website, or null if the order has never been exported. For the purposes of this field, any of the following actions are considered to be an export:
  • Exporting the order to CSV
  • Exporting the order headers to CSV
  • Printing the order
  • Exporting the order to PDF


Note that simply fetching the order via a GET request to the API will not set this field for you. If you want use this field to keep track of which orders you have already pulled from Handshake, you will need to make a PUT request to update this field and set it yourself.

This field can be filtered on (see below) and is especially useful for fetching only the orders that have not already been exported (using the __isnull comparator).

Note: While it is possible to set the lastExported field on a single order using a PUT request, you will need to make a PATCH request to update multiple orders at once.
status
Type: string
Required: true
The current status of this order, which will either be “Confirmed”, “Open”, or “Hold for confirm”.
shippingMethod
Type: string
Required: false
The shipping method for this order, as selected from the available choices.
paymentTerms
Type: string
Required: false
The payment terms for this order, as selected from the available choices.
subtotal
Type: template-only decimal
Required: false
The subtotal amount for this order, calculated as the sum of all the line totals.
total
Type: template-only decimal
Required: false
The total amount for this order, calculated from the subtotal less any discounts.
source
Type: string
Required: false
The source of the order: user, quote, customer.
owner.fullname
Type: string
Required: false
The rep or user that wrote the order.
notes
Type: string
Required: false
customerPO
Type: string
Required: false
emailSent
Type: boolean
Required: false
startShipDate
Type: date
Required: false
cancelDate
Type: date
Required: false
freeShipping
Type: boolean
Required: false
shipPartial
Type: boolean
Required: false
defaultWarehouse
Type: Reference to Warehouses
Required: false
Reference to the warehouse for the order
signatureURL
Type: read-only string
Required: false
A URL where the signature attached to this order can be temporarily retrieved from. This URL only remains active for a short period of time after the order is fetched through the API.
photoURLs
Type: read-only list of strings
Required: false
A list of URLs where the photos attached to this order can be temporarily retrieved from. These URLs only remain active for a short period of time after the order is fetched through the API.
percentDiscount
Type: number
Required: false
The percent discount to be applied to this order’s subtotal. Typically a value between 0 - 100, up to 20 digits in total, up to 8 after the decimal place.
totalOffDiscount
Type: number
Required: false
The total off discount to applied to this order’s subtotal. Up to 100 digits total, up to 2 after the decimal place.
formattedDiscount
Type: template-only string
Required: false
The formatted discount, e.g: 10% off.
source
Type: read-only string
Required: false
The source of this order, indicating whether it was created by a rep (user), sent as a quote (quote), or initiated by a customer (customer).

Filters

## Filter for orders in the category with user-defined ID 'NY_SUMMER'
curl "https://app.handshake.com/api/latest/orders?category=NY_SUMMER"
## Filter for orders in the user group named 'West Coast'
curl "https://app.handshake.com/api/latest/orders?userGroup=West%20Coast"
## Filter for orders belonging to the customer with ID 'ABC123'
curl "https://app.handshake.com/api/latest/orders?customerID=ABC123"
## Filter for confirmed orders
curl "https://app.handshake.com/api/latest/orders?status=Confirmed"
## Fetch orders exported after 2011-10-12 10:39:04pm UTC
curl "https://app.handshake.com/api/latest/orders?lastExported__gte=2011-10-12T22:39:04Z"
## Fetch orders that have never been exported
curl "https://app.handshake.com/api/latest/orders?lastExported__isnull=true"
## Fetch orders edited after 2011-10-12 10:30:04pm UTC
curl "https://app.handshake.com/api/latest/orders?lastEdited__gte=2011-10-12T22:39:04Z"
## Fetch orders by date exported, least recently exported first
curl "https://app.handshake.com/api/latest/orders?order_by=lastExported"
## Fetch orders by date edited, most recently edited first
curl "https://app.handshake.com/api/latest/orders?order_by=-lastEdited"
Parameter Description
category
Type: string
Filters orders by category. The filter parameter should be the category’s ID rather than its name
userGroup
Type: string
Filters order by the user group they’re in. Results include orders in that user group or any of its sub-groups.
customerID
Type: string
Filters orders so that only those belonging to the customer with the given ID are returned. Note that the filter is on the string Customer.id property, not the integer Customer.objID property.
status
Type: string
Filters orders by their status, which is one of Open, Hold For Confirm, or Confirmed.
lastExported
Type: datetime
Filters orders by their lastExported property, discussed above. Much like the ctime and mtime filters, this filter supports the standard four comparisons:

  • gt (greater than)
  • gte (greater than or equal)
  • lt (less than)
  • lte (less than or equal)


The lastExported filter also supports the isnull comparison, which should be passed as either true or false to respectively exclude or include orders that have already been exported.
lastEdited
Type: datetime
Filters orders by their lastEdited property, discussed above. Much like the ctime and mtime filters, this filter supports the standard four comparisons:

  • gt (greater than)
  • gte (greater than or equal)
  • lt (less than)
  • lte (less than or equal)


The lastExported filter also supports the isnull comparison, which should be passed as either true or false to respectively exclude or include orders that have already been exported.

Actions

Orders also have a number of actions that can be triggered with a post to the actions endpoint. By sending a payload to the orders/{orderID}/actions/{action} endpoint, you can kick off the following workflows:

Action Description
promoCode
payload: {"promoCode": promoCode}
Sets the promoCode and promoDetails on the sales order if the promo is active
send_email
payload:
Sends the order confirmation email to the customer.
promote
payload:
Implements promoting an order version back to the real.
fork
payload:
Implements forking an order for the purposes of editing.
revert
payload:
Implements reverting a versioned order to the version before it.
destory
payload:
Implements destroying an order version.
clone
payload:
Returns a cloned version of this order.
changeStatus
payload: {"old": oldStatus, "new": newStatus}
Implements changing the status of an order.
ship
payload: {"shipped": shipped}
Implements the shipping of an order. Shipped should be either true/false.

Order batches

## Order batches can be accessed through the API via the order_batches base URL:
curl "https://app.handshake.com/api/latest/order_batches"

{
    "cdate": "2010-10-06",
    "ctime": "2010-10-06T17:02:20Z",
    "entityType": "Order Batch",
    "mtime": "2011-01-31T12:04:19Z",
    "objID": 19,
    "owner": "system",
    "resource_uri": "/api/latest/order_batches/19",
    "uuid": "308bb6cc-0804-4fbf-ba67-0c37ad15a10e"
}

<cdate>2010-10-06</cdate>
<ctime>2010-10-06T17:02:20Z</ctime>
<entityType>Order Batch</entityType>
<mtime>2011-01-31T12:04:19Z</mtime>
<objID>19</objID>
<owner>system</owner>
<resource_uri>/api/latest/order_batches/19</resource_uri>
<uuid>308bb6cc-0804-4fbf-ba67-0c37ad15a10e</uuid>

This object represents a logical grouping of sales orders. This can be used to distinguish between where a certain set of orders occurred, like at various trade shows. Order batches can be accessed through the API via the order_batches base URL:

$ curl https://app.handshake.com/api/latest/order_batches

In addition to the common fields listed above, order batch objects contain the following fields:

Field Description
name
Type: string
Required: false
The full user-visible name of this category.
id
Type: string
Required: false
The ID of this category, which is typically only ever used in bulk imports and exports.
isDefault
Type: boolean
Required: false
Indicates whether or not this order category is the default for new orders.

Order categories

## Order categories can be accessed through the API via the order_categories base URL:
curl "https://app.handshake.com/api/latest/order_categories"

{
    "cdate": "2010-10-06",
    "ctime": "2010-10-06T17:02:20Z",
    "entityType": "Category",
    "id": "NYTS",
    "isDefault": true,
    "mtime": "2011-01-31T12:04:19Z",
    "name": "New York Tradeshow",
    "objID": 19,
    "owner": "system",
    "resource_uri": "/api/latest/order_categories/19",
    "uuid": "308bb6cc-0804-4fbf-ba67-0c37ad15a10e"
}

<cdate>2010-10-06</cdate>
<ctime>2010-10-06T17:02:20Z</ctime>
<entityType>Category</entityType>
<id>NYTS</id>
<isDefault>true</isDefault>
<mtime>2011-01-31T12:04:19Z</mtime>
<name>New York Tradeshow</name>
<objID>19</objID>
<owner>system</owner>
<resource_uri>/api/latest/order_categories/19</resource_uri>
<uuid>308bb6cc-0804-4fbf-ba67-0c37ad15a10e</uuid>

This object represents a logical grouping of sales orders. This can be used to distinguish between where a certain set of orders occurred, like at various trade shows. Order categories can be accessed through the API via the order_categories base URL:

$ curl https://app.handshake.com/api/latest/order_categories

In addition to the common fields listed above, order category objects contain the following fields:

Field Description
name
Type: string
Required: false
The full user-visible name of this category.
id
Type: string
Required: false
The ID of this category, which is typically only ever used in bulk imports and exports.
isDefault
Type: boolean
Required: false
Indicates whether or not this order category is the default for new orders.

Order lines

In addition to the common fields listed above, order line objects contain the following fields:

Field Description
isku
Type: string
Required: true
The SKU of the Item that this line has been written for.
vsku
Type: string
Required: false
The variant SKU of the Variant that this line has been written for, or null if this Item does not have Variants. See the bulk import docs for more information about Variants.
sku
Type: string
Required: false
If this line item has a vsku, then this will be the vsku. If not, it will be the isku. This is just a convenience field to avoid having to test for vsku == null all the time.
barcode
Type: string
Required: false
If this line has a vsku, then this will be the barcode for that variant. If not, it will be the barcode from the item, e.g. the same value as line.item.barcode.
description
Type: string
Required: false
The name of the Variant for this line item, if there is one, otherwise the name of the Item. A convenience method to avoid having to test for whether vsku is null.
discount
Type: method returning decimal
Required: false
Returns the total discount for this line item, calculated as line.qty * line.unitDiscount.
isPrimary
Type: boolean
Required: false
Indicates if this order line is the primary line on the order.
item
Type: reference to Item
Required: false
The Item that corresponds to the isku for this line.
itemStockUnit
Type: reference to Item Stock Unit
Required: false
The Item Stock Unit associated to the order.
listPrice
Type: method returning decimal
Required: false
Returns “list” unit price for this line, i.e. the full price that is paid for a single unit when no discounting is in effect.
notes
Type: string
Required: false
Notes specific to this line item.
order
Type: reference to Order
Required: false
The Order to which this order line belongs.
originalUnitPrice
Type: decimal
Required: false
The original price of the sku on this order line, before any discounts.
percentageDiscount
Type: method returning decimal
Required: false
Returns the percentage discount for this line item, calculated by dividing the unitPrice by the listPrice.
pricingUnit
Type: text
Required: false
The unit that is priced for sale. This might be, for instance, a 6-pack of beer.
pricingUnitPerSaleUnit
Type: number
Required: false
The number of pricing units included in each of the sale units. If you are limiting customers to purchasing a case of beer, then the value will be 4.
qty
Type: integer
Required: true
The number of units of the product on this line item. This is required for new order lines.
qtyFree
Type: integer
Required: false
The number of units of the product on this line item that are free of charge.
saleUnit
Type: text
Required: false
The multiple of pricing units that must be purchased. For instance, you may only allow customers to purchase a case of beer, which contains 4 6-packs.
total
Type: method returning decimal
Required: false
Returns the total amount for this line item, calculated as line.qty * line.unitPrice
unitPrice
Type: decimal
Required: true
The per-unit price of this item. Depending on discounts, this may or may not be equal to line.item.unitPrice (i.e. the “list price”). This is required for new order lines.
unitDiscount
Type: method returning decimal
Required: false
Returns the difference between the listPrice and the unitPrice that is actually being billed.
variantStockUnit
Type: reference to Variant Stock Unit
Required: false
Reference the resource URI of the Variant Stock Unit.

Invoices

## Invoices can be accessed through the API via the invoices base URL:
curl "https://app.handshake.com/api/latest/invoices"

Invoices can be accessed through the API via the invoices base URL:

$ curl https://app.handshake.com/api/latest/invoices

In addition to the common fields listed above, invoice objects contain the following fields:

Field Description
amount_discount
Type: decimal or null
Required: false
Invoice discount amount.
amount_due
Type: decimal or null
Required: false
Invoice due amount.
amount_paid
Type: decimal or null
Required: false
Invoice paid amount.
amount_remaining
Type: decimal or null
Required: false
Invoice remaining amount to be paid.
amount_subtotal
Type: decimal or null
Required: false
Invoice subtotal amount.
amount_tax
Type: decimal or null
Required: false
Invoice tax amount.
amount_total
Type: decimal or null
Required: false
Invoice total amount.
billing_to
Type: string or null
Required: false
carrier
Type: string or null
Required: false
The shipping carrier used for this invoice.
currency
Type: string or null
Required: false
Invoice currency.
customer
Type: uri or null
Required: false
URI referencing a Customer
due_at
Type: datetime or null
Required: false
ISO8061 formatted datetime.
invoice_id
Type: string or null
Required: false
Invoice ID.
notes
Type: string or null
Required: false
Invoice notes.
order
Type: uri or null
Required: false
Reference to the sales order this invoice is related to or was converted from.
private_notes
Type: string or null
Required: false
Private invoice notes.
reference
Type: string or null
Required: false
sent_at
Type: datetime or null
Required: false
ISO8061 formatted datetime.
sent_from
Type: string or null
Required: false
sent_to
Type: string or null
Required: false
service_level
Type: string or null
Required: false
Invoice service level.
ship_date
Type: datetime or null
Required: false
ISO8061 formatted datetime.
terms
Type: string or null
Required: false
Invoice terms.
tracking_link
Type: string or null
Required: false
Invoice tracking link.
tracking_number
Type: string or null
Required: false
Invoice tracking number.

Response JSON Object

Field Description
account
Type: string or null
Required: false
Account this object belongs to.
ctime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was created.
mtime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was last modified.
uuid
Type: string or null
Required: false
UUID identifier for this object.

Filters

Parameter Description
uuid
Type: string
UUID for the object to return.
## Fetch invoices by date created, ascending
curl "https://app.handshake.com/api/latest/invoices?order_by=ctime"

## Fetch invoices by date created, descending
curl "https://app.handshake.com/api/latest/invoices?order_by=-ctime"

## Fetch invoices by date modified, ascending
curl "https://app.handshake.com/api/latest/invoices?order_by=mtime"

## Fetch invoices by date modified, descending
curl "https://app.handshake.com/api/latest/invoices?order_by=-mtime"

## Fetch invoices by customer Filters on customer, supports all [Relational Filters]
curl "https://app.handshake.com/api/latest/invoices?order_by=?"

## Fetch invoices by order Filters on customer, supports all [Relational Filters]
curl "https://app.handshake.com/api/latest/invoices?order_by=?"

Invoice lines

## Invoice Lines can be accessed through the API via the invoice_lines base URL:
curl "https://app.handshake.com/api/latest/invoice_lines"

Invoice Lines can be accessed through the API via the invoice_lines base URL:

$ curl https://app.handshake.com/api/latest/invoice_lines

In addition to the common fields listed above, invoice line objects contain the following fields:

Field Description
amount_discount
Type: decimal or null
Required: false
Invoice line discount amount.
amount_tax
Type: decimal or null
Required: false
Inocie line tax amount.
amount_total
Type: decimal or null
Required: false
Invoice line total amount.
amount_unit
Type: decimal or null
Required: false
carrier
Type: string or null
Required: false
The shipping carrier used for this invoice line.
category
Type: string
Required: false
The category for this invoice line.
description
Type: string or null
Required: false
Invoice line description.
invoice
Type: uri
Required: true
URI referencing an Invoice. Required. See GET /api/latest/invoices/(str:uuid).
is_taxable
Type: boolean
Required: true
Default: true
Denotes whether this invoice line is taxable.
item
Type: uri or null
Required: false
URI referencing an Item.
note
Type: string or null
Required: false
Invoice line note.
order
Type: integer
Required: true
Reference to the sales order this invoice line is related to.
quantity
Type: decimal or null
Required: false
Invoice line quantity.
service_level
Type: string or null
Required: false
Shipping carrier service level for this invoice line.
sku
Type: string or null
Required: false
Invoice line SKU.
status
Type: string or null
Required: false
Invoice line status.
tracking_link
Type: url
Required: false
Invoice line shipping tracking link.
tracking_number
Type: string or null
Required: false
Invoice line shipping tracking number.
variant
Type: uri or null
Required: false
URI referencing a Variant.

Response JSON Object

Field Description
account
Type: string or null
Required: false
Account this object belongs to.
ctime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was created.
mtime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was last modified.
uuid
Type: string or null
Required: false
UUID identifier for this object.

Filters

Parameter Description
uuid
Type: string
UUID for the object to return.

Customer Objects

Customers

## Customers can be accessed through the API via the customers base URL:
curl "https://app.handshake.com/api/latest/customers"

{
    "billTo": {
        "btCustomer": "/api/latest/customers/43",
        "cdate": "2010-10-06",
        "city": "Brooklyn",
        "country": "US",
        "ctime": "2010-10-06T17:02:20Z",
        "entityType": "Address",
        "fax": "555-555-5559",
        "id": null,
        "mtime": "2010-10-18T20:08:51Z",
        "name": null,
        "objID": 44,
        "owner": "system",
        "phone": "123-456-7894",
        "postcode": "11217",
        "resource_uri": "/api/latest/addresses/44",
        "stCustomer": null,
        "state": "NY",
        "street": "8051 Brown Road",
        "street2": "",
        "uuid": "830a21f2-dea3-4a1c-aa8f-9cb82dca102b"
    },
    "cdate": "2010-10-06",
    "contact": "Kelly Slater",
    "creditCards": [],
    "ctime": "2010-10-06T17:02:20Z",
    "currency": "USD",
    "customerGroup": {
        "cdate": "2011-01-18",
        "ctime": "2011-01-18T12:52:03Z",
        "currencyCode": "USD",
        "entityType": "CustomerGroup",
        "id": "US",
        "isDefault": true,
        "mtime": "2011-01-31T12:04:19Z",
        "name": "US Retailers",
        "objID": 946,
        "owner": "system",
        "resource_uri": "/api/latest/customer_groups/946",
        "uuid": "3e605828-9721-4c5a-8e80-68551a364ac0"
    },
    "defaultShipTo": "/api/latest/addresses/44",
    "email": "foo@bar.com",
    "entityType": "Customer",
    "id": "C1004",
    "locale": "en_US",
    "mtime": "2012-10-25T20:49:12Z",
    "name": "The Globe",
    "objID": 43,
    "owner": "system",
    "paymentTerms": "NET 30",
    "resource_uri": "/api/latest/customers/43",
    "shipTos": [],
    "shippingMethod": "FEDEX",
    "taxID": null,
    "userGroup": {
        "cdate": "2011-08-22",
        "ctime": "2011-08-22T07:00:24Z",
        "entityType": "UserGroup",
        "id": "master",
        "isMaster": true,
        "mtime": "2011-10-08T03:23:02Z",
        "name": "Master",
        "objID": 109039,
        "owner": "system",
        "parent": null,
        "resource_uri": "/api/latest/user_groups/109039",
        "subcategories": [],
        "uuid": "d0f774ce-9f2f-4166-b418-621cb84dc0f2"
    },
    "uuid": "01ed46bc-ac2d-4749-8a3a-47c699c9d756"
}
<billTo>
    <btCustomer>/api/latest/customers/43</btCustomer>
    <cdate>2010-10-06</cdate>
    <city>Brooklyn</city>
    <country>US</country>
    <ctime>2010-10-06T17:02:20Z</ctime>
    <entityType>Address</entityType>
    <fax>555-555-5559</fax>
    <id/>
    <mtime>2010-10-18T20:08:51Z</mtime>
    <name/>
    <objID>44</objID>
    <owner>system</owner>
    <phone>123-456-7894</phone>
    <postcode>11217</postcode>
    <resource_uri>/api/latest/addresses/44</resource_uri>
    <stCustomer/>
    <state>NY</state>
    <street>8051 Brown Road</street>
    <street2></street2>
    <uuid>830a21f2-dea3-4a1c-aa8f-9cb82dca102b</uuid>
</billTo>
<cdate>2010-10-06</cdate>
<contact>Kelly Slater</contact>
<ctime>2010-10-06T17:02:20Z</ctime>
<currency>USD</currency>
<customerGroup>
    <cdate>2011-01-18</cdate>
    <ctime>2011-01-18T12:52:03Z</ctime>
    <currencyCode>USD</currencyCode>
    <entityType>CustomerGroup</entityType>
    <id>US</id>
    <isDefault>true</isDefault>
    <mtime>2011-01-31T12:04:19Z</mtime>
    <name>US Retailers</name>
    <objID>946</objID>
    <owner>system</owner>
    <resource_uri>/api/latest/customer_groups/946</resource_uri>
    <uuid>3e605828-9721-4c5a-8e80-68551a364ac0</uuid>
</customerGroup>
<defaultShipTo>/api/latest/addresses/44</defaultShipTo>
<email>foo@bar.com</email>
<entityType>Customer</entityType>
<id>C1004</id>
<locale>en_US</locale>
<mtime>2012-10-25T20:49:12Z</mtime>
<name>The Globe</name>
<objID>43</objID>
<owner>system</owner>
<paymentTerms>NET 30</paymentTerms>
<resource_uri>/api/latest/customers/43</resource_uri>
<shippingMethod>FEDEX</shippingMethod>
<taxID/>
<userGroup>
    <cdate>2011-08-22</cdate>
    <ctime>2011-08-22T07:00:24Z</ctime>
    <entityType>UserGroup</entityType>
    <id>master</id>
    <isMaster>true</isMaster>
    <mtime>2011-10-08T03:23:02Z</mtime>
    <name>Master</name>
    <objID>109039</objID>
    <owner>system</owner>
    <parent/>
    <resource_uri>/api/latest/user_groups/109039</resource_uri>
    <uuid>d0f774ce-9f2f-4166-b418-621cb84dc0f2</uuid>
</userGroup>
<uuid>01ed46bc-ac2d-4749-8a3a-47c699c9d756</uuid>

Customers can be accessed through the API via the customers base URL:

$ curl https://app.handshake.com/api/latest/customers

In addition to the common fields listed above, customer objects contain the following fields:

Field Description
id
Type: read-only string
Required: true
The user-defined ID for this customer (users normally set this to the ID of this customer in their ERP or CRM system). This is not the same as the numeric objID which is set by the system. See the bulk import docs for more information.
name
Type: string
Required: true
Customer name.
contact
Type:string
Required: false
Customer contact details.
email
Type: string
Required: false
Customer email address.
taxID
Type: string
Required: false
Customer’s tax ID, VAT number, ABN or similar
billTo
Type: read-only reference to Address
Required: false
The Address object for this customer’s billing address.
  • When doing a POST on a new customer, you must provide the details of the billTo address inline, even if this means simply posting an empty dictionary to create a blank billing address. Every customer must have a billTo even if all of its fields are blank.
  • When doing a PUT on an existing customer, you cannot provide a different resource_uri for the billTo address to connect the customer to a different address resource. The billTo that is on the customer when it is created stays with it for its lifetime and this relationship cannot be broken.
shipTos
Type: collection of Address
Required: false
A (possibly empty) collection of Address objects that represent this customer’s additional shipping addresses.
defaultShipTo
Type: read-only collection of Address
Required: false
The default shipTo for a customer.
This field will contain a resource_uri for an Address object attached to the customer. The address may be one of the customer’s existing shipTo addresses or their billTo.
defaultWarehouse
Type: Reference to Warehouses
Required: false
Reference to the warehouse for the customer
creditCards
Type: collection of CreditCard
Required: false
A (possibly empty) collection of CreditCard objects representing the credit cards that are attached to this customer.
salesOrders
Type: collection of SalesOrder
Required: false
A (possibly empty) collection of SalesOrder objects representing the orders that have been written for this customer. This will be returned with the oldest orders first.
userGroup
Type: reference to UserGroup
Required: false
The UserGroup representing the user group that this customer has been restricted to. This customer’s orders will always be restricted to the same group.
A customer will always be in a user group. If you pass null for the userGroup when creating a new customer, it will be automatically linked to the master user group.
customerGroup
Type: reference to CustomerGroup
Required: false
A reference to the CustomerGroup that this customer is in, which will be one of the groups defined here.
shippingMethod
Type: string
Required: false
The default shipping method for this customer, as selected from the available choices.
paymentTerms
Type: string
Required: false
The default payment terms for this customer, as selected from the available choices.
currency
Type: read-only string
Required: false
The three-letter currency code (e.g. “USD”, “GBP” etc) that applies to this customer.
The reason that this field is read-only is that it is actually derived from the customer group this customer belongs to, or the company itself if no customer groups are defined.
locale
Type: read-only string
Required: false
The locale code (e.g. “en_US”, “fr_FR” or similar) that applies to this customer. This field is read-only for the same reason as currency above.
percentDiscount
Type: number
Required: false
The default percent discount to be applied to orders created for this customer. Typically a value between 0 - 100, up to 20 digits in total, up to 8 after the decimal place.

Filters

## Filter for the customer with user-defined ID 'C1234'
curl "https://app.handshake.com/api/latest/customers?id=C1234"
##Filter for the customer with user-defined name 'Wobble'
curl "https://app.handshake.com/api/latest/customers?name=Wobble"
## Filter for customers in the 'Preferred' customer group
curl "https://app.handshake.com/api/latest/customers?customerGroup=Preferred"
## Filter for customers in the 'NorthWest' user group
curl "https://app.handshake.com/api/latest/customers?userGroup=NorthWest"
Parameter Description
id
Type: string**
Filters customers by an exact match against the user-defined id described above. When applying this filter you will get either 0 or 1 results.
name
Type: string**
Filters customers by an exact match against the user-defined name property. When applying this filter you will get either 0 or 1 results.
customerGroup
Type: string**
Filters customers by customer group. Pass the customer group’s ID (not its name) as the filter parameter.
userGroup
Type: string**
Filters customers by user group. Use the user group’s ID (not its name). Results include customers in that user group or any of its sub-groups.

Customer groups

## Customer groups can be accessed through the API via the customer_groups base URL:
curl "https://app.handshake.com/api/latest/customer_groups"

{
    "cdate": "2011-01-18",
    "ctime": "2011-01-18T12:52:03Z",
    "currencyCode": "USD",
    "entityType": "CustomerGroup",
    "id": "US",
    "isDefault": true,
    "mtime": "2011-01-31T12:04:19Z",
    "name": "US Retailers",
    "objID": 946,
    "owner": "system",
    "resource_uri": "/api/latest/customer_groups/946",
    "uuid": "3e605828-9721-4c5a-8e80-68551a364ac0"
}

<cdate>2011-01-18</cdate>
<ctime>2011-01-18T12:52:03Z</ctime>
<currencyCode>USD</currencyCode>
<entityType>CustomerGroup</entityType>
<id>US</id>
<isDefault>true</isDefault>
<mtime>2011-01-31T12:04:19Z</mtime>
<name>US Retailers</name>
<objID>946</objID>
<owner>system</owner>
<resource_uri>/api/latest/customer_groups/946</resource_uri>
<uuid>3e605828-9721-4c5a-8e80-68551a364ac0</uuid>

Customer groups can be accessed through the API via the customer_groups base URL:

$ curl https://app.handshake.com/api/latest/customer_groups

In addition to the common fields listed above, customer group objects contain the following fields:

Field Description
categoryPosition
Type: integer or float
Required: true
The position of this category within its parent (or at the root of the category tree if this category has no parent).
If you provide this attribute as a float instead of an int, the API will automatically shuffle existing categories in the same parent category to accomodate you “wedging” a category between two existing ones. For example if you have three existing categories at the following positions:

  • A (5)
  • B (6)
  • C (7)

And then you POST a new category D at position 5.5, the categories will be automatically shuffled like so:

  • A (5)
  • D (6)
  • B (7)
  • C (8)
name
Type: string
Required: false
The full user-visible name of this customer group.
id
Type: string
Required: false
The ID of this customer group, which is typically only ever used in bulk imports and exports.
currency
Type: read-only string
Required: false
The three-letter currency code (e.g. “USD”, “GBP” etc) that applies to this customer group.
defaultWarehouse
Type: Reference to Warehouses
Required: false
Reference to the warehouse that would serve the customer group.
isCatchAll
Type: boolean
Required: true
Is this group the one customers are assigned to if they don’t fit another customer group?
isDefault
Type: boolean
Required: true
Is this the default group to which customers are assigned?
parent
Type: reference to Customer Group
Required: true
The parent customer group to which this object belongs.

Customer notes

## Customer notes can be accessed through the API via the customer_notes base URL:
curl "https://app.handshake.com/api/latest/customer_notes"

Customer notes can be accessed through the API via the customer_notes base URL:

$ curl https://app.handshake.com/api/latest/customer_notes

In addition to the common fields listed above, customer note objects contain the following fields:

Field Description
address
Type: reference to Address or null
Required: false
The address associated with this customer note, or null if no address was specificed.
customer
Type: reference to Customer
Required: false
The customer associated with this customer note.
text
Type: string
Required: false
The body of the note as a text string.

Filters

Parameter Description
address
Filters the API response by specifying an address resource URI, e.g.:
address=/api/latest/address/1234) or where there is no address (address__isnull=true)
customer
Filters the API response by specifying a customer resource URI, e.g.:
customer=/api/latest/customer/12345)
date/time
Filters the API response by by ctime by specifying a datetime in ISO-8601 format. For example, if you want all notes created on or after noon on May 25th 2015 UTC, you’d query with ctime__gte=2015-05-25T12:00:00Z.

Addresses

## Addresses can be accessed through the API via the addresses base URL:
curl "https://app.handshake.com/api/latest/addresses"

{
  "btCustomer":"/api/latest/customers/43",
  "city":"Brooklyn",
  "country":"US",
  "fax":"555-555-5559",
  "isDefaultShipTo":false,
  "objID":44,
  "phone":"123-456-7894",
  "postcode":"11217",
  "resource_uri":"/api/latest/addresses/44",
  "stCustomer":null,
  "state":"NY",
  "street":"8051 Brown Road",
  "street2":""
}

<btCustomer>/api/latest/customers/43</btCustomer>
<city>Brooklyn</city>
<country>US</country>
<fax>555-555-5559</fax>
<isDefaultShipTo>false</isDefaultShipTo>
<objID>44</objID>
<phone>123-456-7894</phone>
<postcode>11217</postcode>
<resource_uri>/api/latest/addresses/44</resource_uri>
<stCustomer/>
<state>NY</state>
<street>8051 Brown Road</street>
<street2></street2>

Addresses can be accessed through the API via the addresses base URL:

$ curl https://app.handshake.com/api/latest/addresses

Addresses are also frequently accessed as sub-resources of either orders or customers. Please see the documentation for those resources for specific rules that may apply depending on whether the address is a bill-to or ship-to.

In addition to the common fields listed above, address objects contain the following fields:

Field Description
id
Type: string
Required: false
The id of given address. Can be set as an external ID when syncing with ERP or accounting systems.
name
Type: string
Required: false
Typically used to denote the a description of a given customer location, e.g. “Mall of America”, especially if there are multiple ship-to addresses.
street
Type:string
Required: false
Street address.
street2..11
Type: string
Required: false
Street address. Note that this field will repeat to accomodate the maximum amount of street lines across all resources, not just the requested one.
city
Type: string
Required: false
City.
state
Type: string
Required: false
State.
postcode
Type: string
Required: false
Postal or zip code.
country
Type: string
Required: false
The country in which this address is located.
phone
Type: string
Required: false
Phone number.
fax
Type: string
Required: false
Fax number.
multiLineStr
Type: read-only string
Required: false
Returns a 2-4 line string representing the location part of this address as seen in various places throughout Handshake, e.g.:
198 Fifth Ave
Apt 3F
New York NY 10012 US

If you’re rendering an address in an HTML template, you should probably render it using the linebreaksbr filter. See the template filter documentation for more information.
<p>{{ address.multiLineStr | linebreaksbr }} </p>
btCustomer
Type: read-only reference to Customer
Required: false
The customer that this is the bill-to address of, or null if this address is not the bill-to address for any customer.
stCustomer
Type: reference to Customer
Required: false
The customer that this is an additional ship-to address of, or null if this address is not an additional ship-to address for any customer.
isDefaultShipTo
Type: boolean
Required: false
This boolean is true if this address is the default ship-to address of its customer, and false otherwise.
When doing a PUT or POST, true values for this field will cause the address to become the default ship-to for its customer, and any other values (e.g. false or the field missing altogether) will have no effect. In other words, this field only has meaning when positively specified as true - you cannot make an address not the default by sending this value as false.
isDropship
Type: boolean
Required: false
This boolean is true.

Contacts

## Contacts can be accessed through the API via the contacts base URL:
curl "https://app.handshake.com/api/latest/contacts"

Contacts can be accessed through the API via the contacts base URL:

$ curl https://app.handshake.com/api/latest/contacts

Request JSON Object

Field Description
address
Type: string or null
Required: false
The address associated with this contact, or null if no address was specificed.
birthdate
Type: date or null
Required: false
ISO8061 formatted date
business_phone
Type: string or null
Required: false
Business phone number.
customer
Type: uri or null
Required: false
URI referencing a Customer
department
Type: string or null
Required: false
The department the contact is a part of.
email
Type: string or null
Required: false
Contact email address.
fax
Type: string or null
Required: false
Contact fax number.
first_name
Type: string or null
Required: false
Contact first name.
last_name
Type: string or null
Required: false
Contact last name.
mobile_phone
Type: string or null
Required: false
Contact mobile phone number.
notes
Type: string or null
Required: false
Contact notes.
salutation
Type: string or null
Required: false
Contact salutation.
title
Type: string or null
Required: false
Contact title.

Response JSON Object

Field Description
account
Type: string or null
Required: false
Account this object belongs to.
ctime
Type: datetime or null
Required: false
ISO8061 formatted datetime of when this object was created.
mtime
Type: datetime or null
Required: false
ISO8061 formatted datetime of when this object was last modified.
uuid
Type: string or null
Required: false
UUID identifier for this object.

Filters

Parameter Description
uuid
Type: string
UUID for the object to return.

Credit cards

## Credit cards can be accessed through the API via the credit_cards base URL:
curl "https://app.handshake.com/api/latest/credit_cards"

{
    "cdate": "2012-04-22",
    "ctime": "2012-04-22T20:26:19Z",
    "customer": "/api/latest/customers/2013",
    "cvv": "",
    "entityType": "CreditCard",
    "lastFour": "1234",
    "month": "12",
    "mtime": "2012-04-22T20:26:20Z",
    "name": "Jay Gatsby",
    "number": "",
    "objID": 109269,
    "owner": "Demo",
    "resource_uri": "/api/latest/credit_cards/109269",
    "type": "DISCOVER",
    "uuid": "9234e0c5-1464-41d3-b837-49ad0bacb64a",
    "year": "12"
}

<cdate>2012-04-22</cdate>
<ctime>2012-04-22T20:26:19Z</ctime>
<customer>/api/latest/customers/2013</customer>
<cvv></cvv>
<entityType>CreditCard</entityType>
<lastFour>1234</lastFour>
<month>12</month>
<mtime>2012-04-22T20:26:20Z</mtime>
<name>Jay Gatsby</name>
<number></number>
<objID>109269</objID>
<owner>Demo</owner>
<resource_uri>/api/latest/credit_cards/109269</resource_uri>
<type>DISCOVER</type>
<uuid>9234e0c5-1464-41d3-b837-49ad0bacb64a</uuid>
<year>12</year>

Credit cards can be accessed through the API via the credit_cards base URL:

$ curl https://app.handshake.com/api/latest/credit_cards

Credit cards are also frequently accessed as sub-resources of either orders or customers.

Addresses are also frequently accessed as sub-resources of either orders or customers. Please see the documentation for those resources for specific rules that may apply depending on whether the address is a bill-to or ship-to.

Security & decryption

Credit cards are the most sensitive information stored in Handshake and there is an extra layer of security around them as a result. All the card numbers and CVVs you store in Handshake are encrypted using a key that is itself safeguarded by your security token.

To provide your security token, simply base64-encode it and use it as the password in the HTTP basic authentication (as discussed here) instead of using the normal ‘X’.

For example, if your API key was “abcd1234” and the security token on your account was “c4tchm3ifyouc4n”, then the basic authentication your would provide would be abcd1234:c4tchm3ifyouc4n.

In addition to the common fields listed above, credit card objects contain the following fields:

Field Description
type
Type: string
Required: false
The type of this credit card, as selected from the available choices.
customer
Type: read-only reference to Customer
Required: false
The relation to the customer that uses this credit card.
lastFour
Type: string
Required: false
The last four digits on this credit card.
month
Type:string
Required: false
The two-digit month portion of the expiry date.
year
Type: string
Required: false
The four-digit year portion of the expiry date.
name
Type: string
Required: false
The person’s name on this credit card.
number
Type: encrypted string
Required: false
The full 15 or 16 digit card number. As discussed above, when reading resources via GET this will be a blank string unless you have provided your security token.
cvv
Type: encrypted string
Required: false
The 3 or 4 digit CVV code. As discussed above, when reading resources via GET this will be a blank string unless you have provided your security token.

Price Lists

Price lists are complex tiers for managing the assignment of different prices to different customers. They reference manufacturers, and are referenced by both items and variants, as well as specific customers.

## Price lists can be accessed through the API via the price list base URL:
curl "https://app.handshake.com/api/latest/price_lists"


{
  "cdate": "2017-02-07",
  "ctime": "2017-02-07T17:25:39Z",
  "ctimeOnServer": "2017-02-07T17:25:39Z",
  "currency": "",
  "entityType": "PriceList",
  "external_id": null,
  "id": "Price List Name",
  "manufacturer": "/api/latest/manufacturers/3",
  "mtime": "2017-02-07T17:25:39Z",
  "mtimeOnServer": "2017-02-07T17:25:39Z",
  "name": "A Price List",
  "objID": 852839,
  "owner": "sample.owner@handshake.com",
  "percentDiscount": "-50",
  "pricingUnit": null,
  "pricingUnitPerSaleUnit": null,
  "resource_uri": "/api/latest/price_lists/123",
  "saleUnit": null,
  "uuid": "a27e45d5-c241-447d-857d-7e2d8c6381ca"
}

<cdate>2017-02-07</cdate>
<ctime>2017-02-07T17:25:39Z</ctime>
<ctimeOnServer>2017-02-07T17:25:39Z</ctimeOnServer>
<currency></currency>
<entityType>PriceList</entityType>
<external_id/>
<id>Price List Name</id>
<manufacturer>/api/latest/manufacturers/3</manufacturer>
<mtime>2017-02-07T17:25:39Z</mtime>
<mtimeOnServer>2017-02-07T17:25:39Z</mtimeOnServer>
<name>A Price List</name>
<objID>852839</objID>
<owner>sample.owner@handshake.com</owner>
<percentDiscount>-50</percentDiscount>
<pricingUnit/>
<pricingUnitPerSaleUnit/>
<resource_uri>/api/latest/price_lists/123</resource_uri>
<saleUnit/>
<uuid>a27e45d5-c241-447d-857d-7e2d8c6381ca</uuid>

Price lists can be accessed through the API via the price_lists base URL:

$ curl https://app.handshake.com/api/latest/price_lists

In addition to the common fields listed above, price list objects contain the following fields:

Field Description
currency
Type: text
Required: true
Currency of the prices in the list.
external_id
Type: text
Required: false
ID from a related source. Usually populating during integrations, like with QuickBooks or NetSuite.
manufacturer
Type: reference to Manufacturer
Required: true
Resource URI of the related manufacturer.
name
Type: text
Required: true
Display name of the price list.
percentDiscount
Type: number
Required: false
Percent the product should be discounted. Note: this will mostly be a negative number to represent a discount.
pricingUnit
Type: text
Required: false
The unit that is priced for sale. This might be, for instance, a 6-pack of beer.
pricingUnitPerSaleUnit
Type: number
Required: false
The number of pricing units included in each of the sale units. If you are limiting customers to purchasing a case of beer, then the value will be 4.
saleUnit
Type: text
Required: false
The multiple of pricing units that must be purchased. For instance, you may only allow customers to purchase a case of beer, which contains 4 6-packs.

Product Objects

Items

## Items can be accessed through the API via the items base URL:
curl "https://app.handshake.com/api/latest/items"

{
    "barcode": "9780375766133",
    "category": {
        "id": "/BL/Woodwinds/Saxophones",
        "manufacturer": "/api/latest/manufacturers/949",
        "name": "Saxophones",
        "objID": 959,
        "parent": "/api/latest/categories/958",
        "resource_uri": "/api/latest/categories/959",
        "subType": "Item",
        "subcategories": []
    },
    "categoryPosition": 1,
    "cdate": "2010-10-06",
    "ctime": "2010-10-06T21:02:20Z",
    "dimensions": null,
    "entityType": "Item",
    "imageURL": "http://c496639.r39.cf2.rackcdn.com/image/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg",
    "imageURLs": [
        "http://c496639.r39.cf2.rackcdn.com/image/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg",
        "http://c496639.r39.cf2.rackcdn.com/image/09841d58cb3495ffac082c78654614ab1f82cae4.png",
        "http://c496639.r39.cf2.rackcdn.com/image/af4303a95b6531d42a85d6c3ed3eebec4cf1caa4.jpg"
    ],
    "longDesc": "You can use this long description field on each item to store extended product information.It can span multiple lines and it can be as long as you like.",
    "minQty": 1,
    "mtime": "2012-02-01T17:30:25Z",
    "multQty": 1,
    "name": "Alto Saxophone",
    "objID": 27,
    "owner": "Demo",
    "resource_uri": "/api/latest/items/27",
    "sku": "SAX.A",
    "thumbnailURL": "http://c496639.r39.cf2.rackcdn.com/thumb_48/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg",
    "thumbnailURLs": [
        "http://c496639.r39.cf2.rackcdn.com/thumb_48/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg",
        "http://c496639.r39.cf2.rackcdn.com/thumb_48/09841d58cb3495ffac082c78654614ab1f82cae4.png",
        "http://c496639.r39.cf2.rackcdn.com/thumb_48/af4303a95b6531d42a85d6c3ed3eebec4cf1caa4.jpg"
    ],
    "unitPrice": "1495.00",
    "uuid": "18616a19-6508-42d6-9e32-bbc10537a385",
    "variants": []
}

<barcode>9780375766133</barcode>
<category>
    <id>/BL/Woodwinds/Saxophones</id>
    <manufacturer>/api/latest/manufacturers/949</manufacturer>
    <name>Saxophones</name>
    <objID>959</objID>
    <parent>/api/latest/categories/958</parent>
    <resource_uri>/api/latest/categories/959</resource_uri>
    <subType>Item</subType>
</category>
<categoryPosition>1</categoryPosition>
<cdate>2010-10-06</cdate>
<ctime>2010-10-06T21:02:20Z</ctime>
<dimensions/>
<entityType>Item</entityType>
<imageURL>http://c496639.r39.cf2.rackcdn.com/image/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg</imageURL>
<imageURLs>http://c496639.r39.cf2.rackcdn.com/image/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg</imageURLs>
<imageURLs>http://c496639.r39.cf2.rackcdn.com/image/09841d58cb3495ffac082c78654614ab1f82cae4.png</imageURLs>
<imageURLs>http://c496639.r39.cf2.rackcdn.com/image/af4303a95b6531d42a85d6c3ed3eebec4cf1caa4.jpg</imageURLs>
<longDesc>You can use this long description field on each item to store extended product information.It can span multiple lines and it can be as long as you like.</longDesc>
<minQty>1</minQty>
<mtime>2012-02-01T17:30:25Z</mtime>
<multQty>1</multQty>
<name>Alto Saxophone</name>
<objID>27</objID>
<owner>Demo</owner>
<resource_uri>/api/latest/items/27</resource_uri>
<sku>SAX.A</sku>
<thumbnailURL>http://c496639.r39.cf2.rackcdn.com/thumb_48/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg</thumbnailURL>
<thumbnailURLs>http://c496639.r39.cf2.rackcdn.com/thumb_48/35dbf08257af8710c74a43b061bc13e3ccec08cd.jpg</thumbnailURLs>
<thumbnailURLs>http://c496639.r39.cf2.rackcdn.com/thumb_48/09841d58cb3495ffac082c78654614ab1f82cae4.png</thumbnailURLs>
<thumbnailURLs>http://c496639.r39.cf2.rackcdn.com/thumb_48/af4303a95b6531d42a85d6c3ed3eebec4cf1caa4.jpg</thumbnailURLs>
<unitPrice>1495.00</unitPrice>
<uuid>18616a19-6508-42d6-9e32-bbc10537a385</uuid>

Items can be accessed through the API via the items base URL:

$ curl https://app.handshake.com/api/latest/items

In addition to the common fields listed above, item objects contain the following fields:

Field Description
sku
Type: string
Required: true
The SKU or “product code” of the item. This must be unique within your account; you cannot have two items with the same sku.
name
Type: string
Required: true
Item name.
longDesc
Type:string
Required: false
Item description.
barcode
Type: string
Required: false
Item barcode, UPC number or similar.
unitPrice
Type: decimal
Required: false
The price for a single unit of this Item. Even if the multQty of this product is greater than 1 (i.e. it is only sold in case packs), this always represents the cost of a single unit of the Item, not the cost of a case pack.
A By default, this is the “base” unit price of the Item, however, the pricesForCustomer query parameter (see below) can be used to cause a GET to return the pricing that is applicable to a particular Customer.
minQty
Type: integer
Required: false
The minimum quantity of this Item that can be ordered. If you allow customers to order just one unit of this product, then this should be 1.
multQty
Type: integer
Required: false
The multiple quantity of this Item (i.e. the case pack). If you allow customers to order single units of the product, then this should be 1.
category
Type: reference to Category
Required: true
The Category that this product is in.
categoryPosition
Type: integer or float
Required: false
The position of this item in its category. If this is not provided when a new item is created via the API, the system will default it to be at the end of the category (i.e. one higher than all the existing items). This is required for new items only
If you provide this attribute as a float instead of an int, the API will automatically shuffle existing items in the same category to accomodate you “wedging” an item between two existing ones. For example if you have three existing items at the following positions:
  • A (5)
  • B (6)
  • C (7)

And then you POST a new item D at position 5.5, the category will be automatically shuffled like so:
  • A (5)
  • B (6)
  • C (7)
  • C (8)
.
variants
Type: collection of Variants
Required: false
The variants of this item (e.g. variations on color or size or similar).
dimensions
Type: read-only dictionary
Required: false
For items that have variants, this dictionary will be a mapping of product dimensions (e.g. ‘Color’, 'Size’ etc) to the supported values for those dimensions. This is a convenience parameter and allows you to figure out the set of product dimensions without having to traverse the variants collection and figure it out for yourself.
For example:
{'Color': ['Blue', 'Green', 'Red'],'Size', ['4', '6', '8', '10', '12']}
additionalPrices
Type: dictionary
Required: false
A dictionary mapping CustomerGroup IDs to prices specific to those customer groups.
For example, if there was a customer group with ID “UK” and the price for an item in that customer group was 12.34, this dictionary would contain:
{'UK': "12.34",}
manufacturer
Type: read-only reference to Manufacturer
Required: false
The Manufacturer of this product, whether this is an additional manufacturer or the company itself. This is never null.
This field is read-only because it is actually derived from the Category that this Item belongs to; the Item does itself have a direct relationship to the Manufacturer.
imageURLs
Type: list of strings
Required: false
This property provides a method of both reading and writing the list of images that are attached to this item.
These URLs are useful for including links to images in confirmation emails, although you should probably avoid including these images directly in the email because they could be large and will render slowly when your customer reads your email. You should use thumbnailURLs below for including images directly in emails.
When fetched via GET this property will simply return the public URLs of the images for this product (these are the ones that are embedded in order confirmation emails to your customers, amongst other things).
When written to via POST or PUT, any image URLs you include in this list which do not already exist in Handshake (i.e. are not already attached to an existing item) will be downloaded from the internet, scaled as per the normal rules, and attached to the item.
Handshake will cache an image downloaded from a particular URL for roughly 7 days, so repeated requests using the same URLs will usually be much faster after the first time. If you want to suppress this caching behaviour (e.g. because the image at a given URL has changed and you want to force it to download again), you can pass ignoreCachedImages=1 as a query parameter to your POST or PUT request.
imageURL
Type: read-only string
Required: false
The first entry from imageURLs above. Useful when you just want access to the primary image on a particular item.
thumbnailURLs
Type: read-only list of strings
Required: false
This property provides the URLs of the 48x48 thumbnails that correspond to the images in imageURLs above. This property is readonly because you cannot upload thumbnails directly; they are auto-generated as part of the import process when you POST or PUT new values for imageURLs.
Because these are very small, they are appropriate for including images in confirmation emails, e.g.
<img src="{{ item.thumbnailURL }}" />
thumbnailURL
Type: read-only string
Required: false
The first entry from thumbnailURLs above. Useful when you just want access to the primary thumbnail on a particular item.
images
Type: read-only reference to Image
Required: false
The Images associated to this product.
pricingUnit
Type: read-only reference to Image
Required: false
The unit that is priced for sale. This might be, for instance, a 6-pack of beer.
pricingUnitPerSaleUnit
Type: read-only reference to Image
Required: false
The number of pricing units included in each of the sale units. If you are limiting customers to purchasing a case of beer, then the value will be 4.
saleUnit
Type: read-only reference to Image
Required: false
The multiple of pricing units that must be purchased. For instance, you may only allow customers to purchase a case of beer, which contains 4 6-packs.

Filters

## Filter for the item with SKU 'BAG123'
curl "https://app.handshake.com/api/latest/items?sku=BAG123"
Parameter Description
category
Type: integer
If you pass category=<objID> as a request parameter, with the objID of a Category as a filter, only items contained in that category or one of its subcategories will be returned.
manufacturer
Type: integer
If you pass manufacturer=<objID> as a request parameter, with the objID of a Manufacturer as a filter, only items that belong to that manufacturer will be returned.
order
Type: integer
If you pass order=<objID> as a request parameter, with the objID of an Order as a filter, only items that are on that order will be returned.
search
Type: string
If you pass search=<needle> as a request parameter, only items with a sku or name that contains the needle will be returned.
sku
Type: string
Filters items by an exact match on sku. When applying this filter you will get either 0 or 1 results.
pricesForCustomer
Type: integer**
If you pass pricesForCustomer=<objID> as a request parameter with the objID of a Customer, the unitPrice field in the results will return the pricing that is applicable to that customer, rather than the base unit price defined for the Item.
This isn’t so much a “filter” as a “modifier”, since it does not change which Items are returned in the response.

Recalculating positions

One of the things that our spreadsheet-based importer does is to make sure that all items imported are assigned categoryPosition values so that the catalog has a total ordering defined over it. This means that no two items share the same categoryPosition value, even if they are in different categories.

Maintaining this total ordering when you are inserting new objects through the API can be diffcult and a total pain, and to avoid this headache we added the recalculatePositions query parameter to automate this.

With any request to the items API, you can pass recalculatePositions=1 in the query string and Handshake will start a background process to recalculate all the positions for all the items in your account so that the total ordering is maintained.

A sensible approach to this would be to only pass recalculatePositions=1 with the last request to the items API when you are POSTing / PUTing multiple changes to your catalog.

Item Prices

Item prices represent how much the item in question costs.

## Items can be accessed through the API via the item prices base URL:
curl "https://app.handshake.com/api/latest/item_prices"

{
  "cdate": "2017-02-07",
  "conditionalData": {},
  "ctime": "2017-02-07T17:25:40Z",
  "ctimeOnServer": "2017-02-07T17:25:40Z",
  "entityType": "ItemPrice",
  "isAvailable": true,
  "item": "/api/latest/items/123",
  "mtime": "2017-02-07T17:25:40Z",
  "mtimeOnServer": "2017-02-07T17:25:40Z",
  "objID": 852849,
  "owner": "sample.owner@handshake.com",
  "priceList": "/api/latest/price_lists/456",
  "pricingUnit": null,
  "pricingUnitPerSaleUnit": null,
  "resource_uri": "/api/latest/item_prices/852849",
  "saleUnit": null,
  "uuid": "780fbb5a-b6b0-4035-a6aa-0382d1df279e",
  "value": "15"
}

<cdate>2017-02-07</cdate>
<conditionalData/>
<ctime>2017-02-07T17:25:40Z</ctime>
<ctimeOnServer>2017-02-07T17:25:40Z</ctimeOnServer>
<entityType>ItemPrice</entityType>
<isAvailable>true</isAvailable>
<item>/api/latest/items/123</item>
<mtime>2017-02-07T17:25:40Z</mtime>
<mtimeOnServer>2017-02-07T17:25:40Z</mtimeOnServer>
<objID>852849</objID>
<owner>sample.owner@handshake.com</owner>
<priceList>/api/latest/price_lists/456</priceList>
<pricingUnit/>
<pricingUnitPerSaleUnit/>
<resource_uri>/api/latest/item_prices/852849</resource_uri>
<saleUnit/>
<uuid>780fbb5a-b6b0-4035-a6aa-0382d1df279e</uuid>
<value>15</value>

Item prices can be accessed through the API via the item_prices base URL:

$ curl https://app.handshake.com/api/latest/item_prices

In addition to the common fields listed above, item price objects contain the following fields:

Field Description
conditionalData
Type: string
Required: false
Conditional data that relates to the item price.
isAvailable
Type: boolean
Required: true
Indicates whether the price is available for the item.
item
Type: reference to Item
Required: false
Reference to the item to which the price applies.
priceList
Type: relationship to Price List
Required: false
Reference to the price list to which this price belongs.
pricingUnit
Type: text
Required: false
The unit that is priced for sale. This might be, for instance, a 6-pack of beer.
pricingUnitPerSaleUnit
Type: number
Required: false
The number of pricing units included in each of the sale units. If you are limiting customers to purchasing a case of beer, then the value will be 4.
saleUnit
Type: text
Required: true
The multiple of pricing units that must be purchased. For instance, you may only allow customers to purchase a case of beer, which contains 4 6-packs.
value
Type: currency
Required: false
The price of the item.

Item Stock Units

Item stock units represent how much inventory is available for a given product.

## Inventory levels can be accessed through the API via the item stock unit base URL:
curl "https://app.handshake.com/api/latest/item_stock_units"

## Include the item ID to retrive the inventory for a given item:
curl "https://app.handshake.com/api/latest/item_stock_units/?item=123"
{
  "cdate": "2017-02-09",
  "ctime": "2017-02-09T16:01:32Z",
  "ctimeOnServer": "2017-02-09T16:01:32Z",
  "entityType": "ItemStockUnit",
  "isAvailable": true,
  "item": "/api/latest/items/123",
  "mtime": "2017-02-09T16:01:32Z",
  "mtimeOnServer": "2017-02-09T16:01:32Z",
  "objID": 456,
  "owner": "system",
  "resource_uri": "/api/latest/item_stock_units/456",
  "restockDate": null,
  "shelfQty": 10,
  "uuid": "68bfed09-3701-4635-97a1-e917dfcc3f82",
  "warehouse": "/api/latest/warehouses/163609",
  "warningLevelQty": 0
}
<cdate>2017-02-09</cdate>
<ctime>2017-02-09T16:01:32Z</ctime>
<ctimeOnServer>2017-02-09T16:01:32Z</ctimeOnServer>
<entityType>ItemStockUnit</entityType>
<isAvailable>true</isAvailable>
<item>/api/latest/items/123</item>
<mtime>2017-02-09T16:01:32Z</mtime>
<mtimeOnServer>2017-02-09T16:01:32Z</mtimeOnServer>
<objID>456</objID>
<owner>system</owner>
<resource_uri>/api/latest/item_stock_units/456</resource_uri>
<restockDate/>
<shelfQty>10</shelfQty>
<uuid>68bfed09-3701-4635-97a1-e917dfcc3f82</uuid>
<warehouse>/api/latest/warehouses/163609</warehouse>
<warningLevelQty>0</warningLevelQty>

Item stock units can be accessed through the API via the item_stock_units base URL:

$ curl https://app.handshake.com/api/latest/item_stock_units

In addition to the common fields listed above, item stock unit objects contain the following fields:

Field Description
isAvailable
Type: boolean
Required: true
Indicates whether the inventory is available for the item.
item
Type: relationship to Item
Required: true
Resource URI of the related item.
restockDate
Type: text
Required: false
Date new inventory is expected to be added to the inventory.
shelfQty
Type: number
Required: true
Amount of inventory available.
warehouse
Type: relationship to Warehouse
Required: true
Warehouse where the inventory is stored.
warningLevelQty
Type: number
Required: true

Item Images

Item images are the images uploaded for each item. This is aliased to the object ItemUserFile.

## Inventory levels can be accessed through the API via the item stock unit base URL:
curl "https://app.handshake.com/api/latest/item_stock_units"

## Include the item ID to retrive the inventory for a given item:
curl "https://app.handshake.com/api/latest/item_stock_units/?item=123"

{
  "attachedTo": "/api/latest/items/123",
  "caption": "",
  "categoryPosition": 0,
  "cdate": "2017-02-09",
  "ctime": "2017-02-09T18:14:46Z",
  "ctimeOnServer": "2017-02-09T18:14:46Z",
  "digest": "",
  "extension": "jpeg",
  "entityType": "ItemUserFile",
  "filename": "cU5xrRilTe2WV5QU3olA.jpeg",
  "isPublic": true,
  "mtime": "2017-02-09T18:14:47Z",
  "mtimeOnServer": "2017-02-09T18:14:47Z",
  "objID": 852895,
  "owner": "system",
  "resource_uri": "/api/latest/item_images/456",
  "size": 3159,
  "stem": "",
  "type": "image",
  "uuid": "7da1b844-57e5-490d-87f6-fccdd942a726"
}

<attachedTo>/api/latest/items/123</attachedTo>
<caption></caption>
<categoryPosition>0</categoryPosition>
<cdate>2017-02-09</cdate>
<ctime>2017-02-09T18:14:46Z</ctime>
<ctimeOnServer>2017-02-09T18:14:46Z</ctimeOnServer>
<digest></digest>
<extension>jpeg</extension>
<entityType>ItemUserFile</entityType>
<filename>cU5xrRilTe2WV5QU3olA.jpeg</filename>
<isPublic>true</isPublic>
<mtime>2017-02-09T18:14:47Z</mtime>
<mtimeOnServer>2017-02-09T18:14:47Z</mtimeOnServer>
<objID>852895</objID>
<owner>system</owner>
<resource_uri>/api/latest/item_images/456</resource_uri>
<size>3159</size>
<stem></stem>
<type>image</type>
<uuid>7da1b844-57e5-490d-87f6-fccdd942a726</uuid>

Item images can be accessed through the API via the item_images base URL:

$ curl https://app.handshake.com/api/latest/item_images

In addition to the common fields listed above, item image objects contain the following fields:

Field Description
attachedTo
Type: reference to Items
Required: true
Resource URI of the related item.
caption
Type: text
Required: no
Image caption.
digest
Type: string
Required: true
Image digest.
extension
Type: text
Required: true
Extension of the file.
filename
Type: text
Required: true
File name.
isPublic
Type: boolean
Required: true
Date new inventory is expected to be added to the inventory.
size
Type: number
Required: true
The file size of the image.
stem
Type: text
Required: true
type
Type: text
Required: true
One of image, signature, snapshot, terms, thumb_48, hero_image, css.

Categories

## Categories can be accessed through the API via the categories base URL:
curl "https://app.handshake.com/api/latest/categories"

{
    "cdate": "2011-01-18",
    "ctime": "2011-01-18T12:52:03Z",
    "entityType": "Category",
    "id": "Woodwinds",
    "manufacturer": "/api/latest/manufacturers/949",
    "mtime": "2012-06-18T17:07:40Z",
    "name": "Woodwinds",
    "objID": 958,
    "owner": "system",
    "parent": null,
    "resource_uri": "/api/latest/categories/958",
    "subType": "Item",
    "subcategories": [
        "/api/v2/categories/959",
        "/api/v2/categories/960"
    ],
    "uuid": "b549a6ad-c855-4809-a200-7b8c2157f36d"
}

<cdate>2011-01-18</cdate>
<ctime>2011-01-18T12:52:03Z</ctime>
<entityType>Category</entityType>
<id>Woodwinds</id>
<manufacturer>/api/latest/manufacturers/949</manufacturer>
<mtime>2012-06-18T17:07:40Z</mtime>
<name>Woodwinds</name>
<objID>958</objID>
<owner>system</owner>
<parent/>
<resource_uri>/api/latest/categories/958</resource_uri>
<subType>Item</subType>
<subcategories>/api/v2/categories/959</subcategories>
<subcategories>/api/v2/categories/960</subcategories>
<uuid>b549a6ad-c855-4809-a200-7b8c2157f36d</uuid>

Categories can be accessed through the API via the categories base URL:

$ curl https://app.handshake.com/api/latest/categories

In addition to the common fields listed above, category objects contain the following fields:

Field Description
name
Type: string
Required: false
The full user-visible name of this category.
id
Type: string
Required: false
The ID of this category, which is typically only ever used in bulk imports and exports.
categoryPosition
Type: integer or float
Required: true
The position of this category within its parent (or at the root of the category tree if this category has no parent).
If you provide this attribute as a float instead of an int, the API will automatically shuffle existing categories in the same parent category to accomodate you “wedging” a category between two existing ones. For example if you have three existing categories at the following positions:

  • A (5)
  • B (6)
  • C (7)

And then you POST a new category D at position 5.5, the categories will be automatically shuffled like so:

  • A (5)
  • D (6)
  • B (7)
  • C (8)
manufacturer
Type: reference to Manufacturer
Required: false
The resource URI of the Manufacturer.
parent
Type: reference to Category
Required: false
The parent of this category, or null if this category is a “root” category.
subcategories
Type: list of references to Category
Required: false
The subcategories of this category.

Filters

Parameter Description
manufacturer
Type: integer
If you pass manufacturer=<objID> as a request parameter, with the objID of a manufacturer as a filter, only categories that belong to that manufacturer will be returned. This filter only applies when you’re fetching categories with Item as the subType.

Variants

## Variants can be accessed through the API via the variants base URL:
curl "https://app.handshake.com/api/latest/variants"

{
    "barcode": "167318831223",
    "cdate": "2011-01-18",
    "ctime": "2011-01-18T17:52:04Z",
    "dimensions": [
        {
            "dimension": "Color",
            "value": "Blue"
        },
        {
            "dimension": "Size",
            "value": "30"
        }
    ],
    "entityType": "Variant",
    "item": "/api/latest/items/974",
    "mtime": "2011-12-22T22:11:31Z",
    "objID": 93015,
    "owner": "system",
    "resource_uri": "/api/latest/variants/93015",
    "sku": "M.JN.01.003",
    "unitPrice": null,
    "uuid": "0e4581c9-3a3b-4b51-af3b-544332001f40"
}

<barcode>167318831223</barcode>
<cdate>2011-01-18</cdate>
<ctime>2011-01-18T17:52:04Z</ctime>
<dimensions>
    <dimension>Color</dimension>
    <value>Blue</value>
</dimensions>
<dimensions>
    <dimension>Size</dimension>
    <value>30</value>
</dimensions>
<entityType>Variant</entityType>
<item>/api/latest/items/974</item>
<mtime>2011-12-22T22:11:31Z</mtime>
<objID>93015</objID>
<owner>system</owner>
<resource_uri>/api/latest/variants/93015</resource_uri>
<sku>M.JN.01.003</sku>
<unitPrice/>
<uuid>0e4581c9-3a3b-4b51-af3b-544332001f40</uuid>

Variants can be accessed through the API via the variants base URL:

$ curl https://app.handshake.com/api/latest/variants

In addition to the common fields listed above, variant objects contain the following fields:

Field Description
account
Type: read-only reference to Account
Required: true
Reference to the item’s account
barcode
Type: string
Required: false
categoryPosition
Type: number
Required: true
The position of this category within its parent (or at the root of the category tree if this category has no parent).
If you provide this attribute as a float instead of an int, the API will automatically shuffle existing categories in the same parent category to accomodate you “wedging” a category between two existing ones. For example if you have three existing categories at the following positions:

  • A (5)
  • B (6)
  • C (7)

And then you POST a new category D at position 5.5, the categories will be automatically shuffled like so:

  • A (5)
  • D (6)
  • B (7)
  • C (8)
.
conditionalData
Type: string
Required: false
Conditional data related to the item variant.
item
Type: reference to Item
Required: true
The Item that this Variant is connected to. This cannot be null.
hasGeneratedSKU
Type: boolean
Required: true
Indicates whether the SKU was manually entered or automatically generated.
sku
Type: string
Required: true
The SKU or “product code” of the Variant. This must be unique within your account; you cannot have two Variants with the same sku. This is required for new variants.
name
Type: string
Required: false
Name of the item.
unitPrice
Type: decimal
Required: false
The price for a single unit of this Variant. Unlike Items, this can be null, which means that the price of the Variant is assumed to be the same as the price of its item.
By default, this is the “base” unit price of the Variant, however, the pricesForCustomer query parameter (see below) can be used to cause a GET to return the pricing that is applicable to a particular Customer.
If pricesForCustomer is specified, then the value of this will never be null and will always return a real decimal value, even if that value is equal to the actual base unit price of the Item.
dimensions
Type: list of dictionaries
Required: true
A list of dictionaries, each of which represents a “dimension” of the Variant. This is required for new variants. Below is an example of the dimensions property representing a Size “2” / Color “Black” Variant:
[{"dimension": "Size", "value": "2"},{"dimension": "Color", "value": "Black"}]
For Variants of more than one dimension, the order of the dictionaries in this list is important: it determines the order in which the dimensions are presented for choice in the app.
addtionalPrices
Type: dictionary
Required: false
A dictionary mapping CustomerGroup IDs to prices specific to those customer groups.
For example, if there was a customer group with ID “UK” and the price for a variant in that customer group was 12.34, this dictionary would contain:
{'UK': "12.34",}

Filters

Parameter Description
pricesForCustomer
Type: integer
If you pass pricesForCustomer=<objID> as a request parameter with the objID of a Customer, the unitPrice field in the results will return the pricing that is applicable to that customer, rather than the base unit price defined for the Variant.
This isn’t so much a “filter” as a “modifier”, since it does not change which Variants are returned in the response.

Recalculating positions

One of the things that our spreadsheet-based importer does is to make sure that all items imported are assigned categoryPosition values so that the catalog has a total ordering defined over it. This means that no two items share the same categoryPosition value, even if they are in different categories.

Maintaining this total ordering when you are inserting new objects through the API can be diffcult and a total pain, and to avoid this headache we added the recalculatePositions query parameter to automate this.

With any request to the items API, you can pass recalculatePositions=1 in the query string and Handshake will start a background process to recalculate all the positions for all the items in your account so that the total ordering is maintained.

A sensible approach to this would be to only pass recalculatePositions=1 with the last request to the items API when you are POSTing / PUTing multiple changes to your catalog.

Variant Prices

Variant prices represent how much the variant in question costs.

## Variants can be accessed through the API via the variant prices base URL:
curl "https://app.handshake.com/api/latest/variant_prices"

{
  "cdate": "2017-02-07",
  "conditionalData": {},
  "ctime": "2017-02-07T17:25:40Z",
  "ctimeOnServer": "2017-02-07T17:25:40Z",
  "entityType": "VariantPrice",
  "isAvailable": true,
  "mtime": "2017-02-07T17:25:40Z",
  "mtimeOnServer": "2017-02-07T17:25:40Z",
  "objID": 852849,
  "owner": "sample.owner@handshake.com",
  "priceList": "/api/latest/price_lists/456",
  "pricingUnit": null,
  "pricingUnitPerSaleUnit": null,
  "resource_uri": "/api/latest/variant_prices/852849",
  "saleUnit": null,
  "uuid": "780fbb5a-b6b0-4035-a6aa-0382d1df279e",
  "value": "15",
  "variant": "/api/latest/variants/123"
}

<cdate>2017-02-07</cdate>
<conditionalData/>
<ctime>2017-02-07T17:25:40Z</ctime>
<ctimeOnServer>2017-02-07T17:25:40Z</ctimeOnServer>
<entityType>VariantPrice</entityType>
<isAvailable>true</isAvailable>
<mtime>2017-02-07T17:25:40Z</mtime>
<mtimeOnServer>2017-02-07T17:25:40Z</mtimeOnServer>
<objID>852849</objID>
<owner>sample.owner@handshake.com</owner>
<priceList>/api/latest/price_lists/456</priceList>
<pricingUnit/>
<pricingUnitPerSaleUnit/>
<resource_uri>/api/latest/variant_prices/852849</resource_uri>
<saleUnit/>
<uuid>780fbb5a-b6b0-4035-a6aa-0382d1df279e</uuid>
<value>15</value>
<variant>/api/latest/variants/123</variant>

Variant prices can be accessed through the API via the variant_prices base URL:

$ curl https://app.handshake.com/api/latest/variant_prices

In addition to the common fields listed above, variant price objects contain the following fields:

Field Description
conditionalData
Type: string
Required: false
Conditional data that relates to the variant price.
isAvailable
Type: boolean
Required: true
Indicates whether the price is available for the variant.
priceList
Type: relationship to Price List
Required: false
Reference to the price list to which this price belongs.
pricingUnit
Type: text
Required: false
The unit that is priced for sale. This might be, for instance, a 6-pack of beer.
pricingUnitPerSaleUnit
Type: number
Required: false
The number of pricing units included in each of the sale units. If you are limiting customers to purchasing a case of beer, then the value will be 4.
saleUnit
Type: text
Required: true
The multiple of pricing units that must be purchased. For instance, you may only allow customers to purchase a case of beer, which contains 4 6-packs.
value
Type: currency
Required: false
The price of the variant.
variant
Type: reference to Variant
Required: false
Reference to the variant to which the price applies.

Variant Stock Units

Variant stock units represent how much inventory is available for a given product.

## Inventory levels can be accessed through the API via the variant stock unit base URL:
curl "https://app.handshake.com/api/latest/variant_stock_units"

## Include the variant ID to retrive the inventory for a given variant:
curl "https://app.handshake.com/api/latest/variant_stock_units/?variant=123"

{
  "availableToSellQty": 10,
  "cdate": "2017-02-09",
  "ctime": "2017-02-09T16:01:32Z",
  "ctimeOnServer": "2017-02-09T16:01:32Z",
  "entityType": "VariantStockUnit",
  "isAvailable": true,
  "mtime": "2017-02-09T16:01:32Z",
  "mtimeOnServer": "2017-02-09T16:01:32Z",
  "objID": 456,
  "owner": "system",
  "resource_uri": "/api/latest/variant_stock_units/456",
  "restockDate": null,
  "shelfQty": 10,
  "variant": "/api/latest/variants/123",
  "uuid": "68bfed09-3701-4635-97a1-e917dfcc3f82",
  "warehouse": "/api/latest/warehouses/163609",
  "warningLevelQty": 0
}

<availableToSellQty>10</availableToSellQty>
<cdate>2017-02-09</cdate>
<ctime>2017-02-09T16:01:32Z</ctime>
<ctimeOnServer>2017-02-09T16:01:32Z</ctimeOnServer>
<entityType>VariantStockUnit</entityType>
<isAvailable>true</isAvailable>
<mtime>2017-02-09T16:01:32Z</mtime>
<mtimeOnServer>2017-02-09T16:01:32Z</mtimeOnServer>
<objID>456</objID>
<owner>system</owner>
<resource_uri>/api/latest/variant_stock_units/456</resource_uri>
<restockDate/>
<shelfQty>10</shelfQty>
<variant>/api/latest/variants/123</variant>
<uuid>68bfed09-3701-4635-97a1-e917dfcc3f82</uuid>
<warehouse>/api/latest/warehouses/163609</warehouse>
<warningLevelQty>0</warningLevelQty>

Variant stock units can be accessed through the API via the variant_stock_units base URL:

$ curl https://app.handshake.com/api/latest/variant_stock_units

In addition to the common fields listed above, variant stock unit objects contain the following fields:

Field Description
isAvailable
Type: boolean
Required: true
Indicates whether the inventory is available for the variant.
restockDate
Type: text
Required: false
Date new inventory is expected to be added to the inventory.
shelfQty
Type: number
Required: true
Amount of inventory available.
variant
Type: relationship to Variant
Required: true
Resource URI of the related variant.
warehouse
Type: relationship to Warehouse
Required: true
Warehouse where the inventory is stored.
warningLevelQty
Type: number
Required: true

Supply Chain Objects

Shipments

## Shipments can be accessed through the API via the shipments base URL:
curl "https://app.handshake.com/api/latest/shipments"

Shipments can be accessed through the API via the shipments base URL:

$ curl https://app.handshake.com/api/latest/shipments

In addition to the common fields listed above, shipment objects contain the following fields:

Field Description
carrier
Type: string or null
Required: false
Shipping carrier for this shipment.
delivered_at
Type: datetime or null
Required: false
ISO8061 formatted datetime.
invoice
Type: uri
Required: false
URI referencing an Invoice. See GET /api/latest/invoices/(str:uuid)
invoice_line
Type: uri
Required: false
URI referencing an Invoice Line. See GET /api/latest/invoice_lines/(str:uuid)
notes
Type: string or null
Required: false
Shipment notes.
order
Type: uri or null
Required: false
URI referencing an Order.
reference
Type: string or null
Required: false
Shipment reference.
sent_at
Type: datetime or null
Required: false
ISO8061 formatted datetime.
sent_from
Type: string or null
Required: false
sent_to
Type: string or null
Required: false
service_level
Type: string or null
Required: false
Shipment carrier service level.
tracking_link
Type: url
Required: false
Shipment tracking link.
tracking_number
Type: string or null
Required: false
Shipment tracking number.

Response JSON Object

Field Description
account
Type: string or null
Required: false
Account this object belongs to.
ctime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was created.
mtime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was last modified.
uuid
Type: string or null
Required: false
UUID identifier for this object.

Filters

Parameter Description
uuid
Type: string
UUID for the object to return.
## Fetch shipments by date created, ascending
curl "https://app.handshake.com/api/latest/shipments?order_by=ctime"

## Fetch shipments by date created, descending
curl "https://app.handshake.com/api/latest/shipments?order_by=-ctime"

## Fetch shipments by date modified, ascending
curl "https://app.handshake.com/api/latest/shipments?order_by=mtime"

## Fetch shipments by date modified, descending
curl "https://app.handshake.com/api/latest/shipments?order_by=-mtime"

## Fetch shipments by customer Filters on invoice, supports all [Relational Filters]
curl "https://app.handshake.com/api/latest/shipments?order_by=?"

## Fetch shipments by order Filters on invoice_line, supports all [Relational Filters]
curl "https://app.handshake.com/api/latest/shipments?order_by=?"

## Fetch shipments by order Filters on order, supports all [Relational Filters]
curl "https://app.handshake.com/api/latest/shipments?order_by=?"

Shipment lines

## Shipment Lines can be accessed through the API via the shipment_lines base URL:
curl "https://app.handshake.com/api/latest/shipment_lines"

Shipment Lines can be accessed through the API via the shipment_lines base URL:

$ curl https://app.handshake.com/api/latest/shipment_lines

In addition to the common fields listed above, shipment line objects contain the following fields:

Request JSON Object

Field Description
notes
Type: string or null
Required: false
order
Type: number
Required: false
Integer for ordering the lines.
shipment
Type: uri
Required: true
URI referencing a Shipment.See GET /api/latest/shipments/(str:uuid).

Response JSON Object

Field Description
account
Type: string or null
Required: false
Account this object belongs to.
ctime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was created.
mtime
Type: string or null
Required: false
ISO8061 formatted datetime of when this object was last modified.
uuid
Type: string or null
Required: false
UUID identifier for this object.

Filters

Parameter Description
uuid
Type: string
UUID for the object to return.
## Fetch shipments line item by date created, ascending
curl "https://app.handshake.com/api/latest/shipment_lines?order_by=ctime"

## Fetch shipments line item by date created, descending
curl "https://app.handshake.com/api/latest/shipment_lines?order_by=-ctime"

## Fetch shipments line item by date modified, ascending
curl "https://app.handshake.com/api/latest/shipment_lines?order_by=mtime"

## Fetch shipments line item by date modified, descending
curl "https://app.handshake.com/api/latest/shipment_lines?order_by=-mtime"

## Fetch shipments line item by customer Filters on shipment, supports all [Relational Filters]
curl "https://app.handshake.com/api/latest/shipment_lines?order_by=?"

Manufacturers

## Manufacturers can be accessed through the API via the manufacturers base URL:
curl "https://app.handshake.com/api/latest/manufacturers"

{
    "address": "/api/latest/addresses/123",
    "categoryPosition": 2,
    "cdate": "2011-01-18",
    "ctime": "2011-01-18T17:52:03Z",
    "email": "info@shortandsweet.com",
    "entityType": "Manufacturer",
    "id": "S&S",
    "logoURL": "http://c496639.r39.cf2.rackcdn.com/image/shortsweet.jpg",
    "mtime": "2011-12-22T22:11:29Z",
    "name": "Short & Sweet",
    "objID": 950,
    "owner": "Demo",
    "resource_uri": "/api/latest/manufacturers/950",
    "uuid": "567e2072-bdb9-4755-b587-ba435b3c1438"
}

<address>/api/latest/addresses/123</address>
<categoryPosition>2</categoryPosition>
<cdate>2011-01-18</cdate>
<ctime>2011-01-18T17:52:03Z</ctime>
<email>info@shortandsweet.com</email>
<entityType>Manufacturer</entityType>
<id>S&S</id>
<logoURL>http://c496639.r39.cf2.rackcdn.com/image/shortsweet.jpg</logoURL>
<mtime>2011-12-22T22:11:29Z</mtime>
<name>Short & Sweet</name>
<objID>950</objID>
<owner>Demo</owner>
<resource_uri>/api/latest/manufacturers/950</resource_uri>
<uuid>567e2072-bdb9-4755-b587-ba435b3c1438</uuid>

Manufacturers can be accessed through the API via the manufacturers base URL:

$ curl https://app.handshake.com/api/latest/manufacturers

Manufacturers are read-only through the API. There are typically so few of these that the setup can easily be done by hand.

In addition to the common fields listed above, manufacturer objects contain the following fields:

Field Description
address
Type: read-only reference to Address
Required: true
Resource URI for the address associated to the object.
categoryPosition
Type: number
Required: true
The position of this category within its parent (or at the root of the category tree if this category has no parent).
If you provide this attribute as a float instead of an int, the API will automatically shuffle existing categories in the same parent category to accomodate you “wedging” a category between two existing ones. For example if you have three existing categories at the following positions:

  • A (5)
  • B (6)
  • C (7)

And then you POST a new category D at position 5.5, the categories will be automatically shuffled like so:

  • A (5)
  • D (6)
  • B (7)
  • C (8)
name
Type: string
Required: true
The full name of this manufacturer.
id
Type: read-only string
Required: true
The ID of this manufacturer, which is typically only ever used in bulk imports and exports.
email
Type: read-only string
Required: false
The email of manufacturer.
isCompany
Type: read-only boolean
Required: true
Indicates if this manufacturer is a distinct company.
logoURL
Type: read-only string
Required: false
The publicly accessible URL for this manufacturer’s logo image. This is useful for including a logo in confirmation emails, e.g.

<img src=“{{ manufacturer.logoURL }}” />

Warehouses

Warehouses are complex tiers for managing the assignment of different prices to different customers. They reference manufacturers, and are referenced by both items and variants, as well as specific customers.

## Warehouses can be accessed through the API via the price list base URL:
curl "https://app.handshake.com/api/latest/warehouses"


{
      "address": { ... },
      "categoryPosition": 0,
      "cdate": "2017-01-23",
      "ctime": "2017-01-23T19:40:04Z",
      "ctimeOnServer": "2017-01-23T19:40:04Z",
      "entityType": "Warehouse",
      "id": "default",
      "isDefault": true,
      "mtime": "2017-01-23T19:40:04Z",
      "mtimeOnServer": "2017-01-23T19:40:04Z",
      "name": "Default Warehouse",
      "objID": 409,
      "owner": "system",
      "resource_uri": "/api/latest/warehouses/123",
      "uuid": "f01354b3-885f-4b88-8578-29b652d5496e"
}

<address>...</address>
<categoryPosition>0</categoryPosition>
<cdate>2017-01-23</cdate>
<ctime>2017-01-23T19:40:04Z</ctime>
<ctimeOnServer>2017-01-23T19:40:04Z</ctimeOnServer>
<entityType>Warehouse</entityType>
<id>default</id>
<isDefault>true</isDefault>
<mtime>2017-01-23T19:40:04Z</mtime>
<mtimeOnServer>2017-01-23T19:40:04Z</mtimeOnServer>
<name>Default Warehouse</name>
<objID>409</objID>
<owner>system</owner>
<resource_uri>/api/latest/warehouses/123</resource_uri>
<uuid>f01354b3-885f-4b88-8578-29b652d5496e</uuid>

Warehouses can be accessed through the API via the warehouses base URL:

$ curl https://app.handshake.com/api/latest/warehouses

In addition to the common fields listed above, warehouse objects contain the following fields:

Field Description
address
Type: address object
Required: true
Relationship to warehouse address.
isDefault
Type: boolean
Required: true
Indicates if the warehouse object is the default for the account.
name
Type: text
Required: true
Warehouse name.

Warehouse Addresses

## Warehouse Addresses can be accessed through the API via the warehouse addresses base URL:
curl "https://app.handshake.com/api/latest/warehouse_addresses"

{
  "cdate": "2017-01-23",
  "city": null,
  "country": null,
  "ctime": "2017-01-23T19:40:04Z",
  "ctimeOnServer": "2017-01-23T19:40:04Z",
  "entityType": "WarehouseAddress",
  "fax": null,
  "id": null,
  "mtime": "2017-01-23T19:40:04Z",
  "mtimeOnServer": "2017-01-23T19:40:04Z",
  "name": "Default Warehouse Address",
  "objID": 408,
  "owner": "system",
  "phone": null,
  "postcode": 12345,
  "resource_uri": "/api/latest/warehouse_addresses/123",
  "state": "NY",
  "street": "123 Real Street",
  "street10": null,
  "street11": null,
  "street2": null,
  "street3": null,
  "street4": null,
  "street5": null,
  "street6": null,
  "street7": null,
  "street8": null,
  "street9": null,
  "uuid": "cd2aef8b-3a26-48d6-93dd-3d926e65041c"
}

<cdate>2017-01-23</cdate>
<city/>
<country/>
<ctime>2017-01-23T19:40:04Z</ctime>
<ctimeOnServer>2017-01-23T19:40:04Z</ctimeOnServer>
<entityType>WarehouseAddress</entityType>
<fax/>
<id/>
<mtime>2017-01-23T19:40:04Z</mtime>
<mtimeOnServer>2017-01-23T19:40:04Z</mtimeOnServer>
<name>Default Warehouse Address</name>
<objID>408</objID>
<owner>system</owner>
<phone/>
<postcode>12345</postcode>
<resource_uri>/api/latest/warehouse_addresses/123</resource_uri>
<state>NY</state>
<street>123 Real Street</street>
<street10/>
<street11/>
<street2/>
<street3/>
<street4/>
<street5/>
<street6/>
<street7/>
<street8/>
<street9/>
<uuid>cd2aef8b-3a26-48d6-93dd-3d926e65041c</uuid>

Warehouse Addresses can be accessed through the API via the warehouse_addresses base URL:

$ curl https://app.handshake.com/api/latest/warehouse_addresses

Warehouse Addresses are also frequently accessed as sub-resources of warehouses.

In addition to the common fields listed above, warehouse address objects contain the following fields:

Field Description
id
Type: string
Required: false
The id of given address. Can be set as an external ID when syncing with ERP or accounting systems.
name
Type: string
Required: false
Typically used to denote the a description of a given customer location, e.g. “Mall of America”, especially if there are multiple ship-to addresses.
street
Type:string
Required: false
Street address.
street2..11
Type: string
Required: false
Street address. Note that this field will repeat to accomodate the maximum amount of street lines across all resources, not just the requested one.
city
Type: string
Required: false
City.
state
Type: string
Required: false
State.
postcode
Type: string
Required: false
Postal or zip code.
country
Type: string
Required: false
The country in which this address is located.
phone
Type: string
Required: false
Phone number.
fax
Type: string
Required: false
Fax number.

Configuration Objects

User groups

## User groups can be accessed through the API via the user_groups base URL:
curl "https://app.handshake.com/api/latest/user_groups"

{
    "cdate": "2011-01-18",
    "ctime": "2011-01-18T12:52:03Z",
    "entityType": "UserGroup",
    "id": "US",
    "isDefault": true,
    "isMaster": true
    "mtime": "2011-01-31T12:04:19Z",
    "name": "US Reps",
    "objID": 946,
    "owner": "system",
    "resource_uri": "/api/latest/customer_groups/946",
    "subcategories": ["/api/v3/user_groups/71890"]
    "uuid": "3e605828-9721-4c5a-8e80-68551a364ac0"
}

<cdate>2011-01-18</cdate>
<ctime>2011-01-18T12:52:03Z</ctime>
<entityType>UserGroup</entityType>
<id>US</id>
<isDefault>true</isDefault>
<isMaster>true</isMaster>
<mtime>2011-01-31T12:04:19Z</mtime>
<name>US Reps</name>
<objID>946</objID>
<owner>system</owner>
<subcategories type="list">
    <value>/api/v3/user_groups/71890</value>
</subcategories>
<resource_uri>/api/latest/customer_groups/946</resource_uri>
<uuid>3e605828-9721-4c5a-8e80-68551a364ac0</uuid>

User groups can be accessed through the API via the user_groups base URL:

$ curl https://app.handshake.com/api/latest/user_groups

We currently do not have write-support for user groups via the API, assuming that most users will set these up manually.

If you have a particular need for POST or PUT support for user groups, please write to us and let us know!

In addition to the common fields listed above, user group objects contain the following fields:

Field Description
name
Type: string
Required: false
The full user-visible name of this user group.
id
Type: string
Required: false
The ID of this user group, which is typically only ever used in bulk imports and exports.
isCatchAll
Type: boolean
Required: true
Is this group the one users are assigned to if they don’t fit another user group?
isDefault
Type: boolean
Required: true
Is this the default group to which users are assigned?
isMaster
Type: read-only boolean
Required: true
A boolean indicating whether or not this user group is the master group which contains all other user groups.
parent
Type: reference to UserGroup
Required: false
The resource URI UserGroup that is above this one in the hierarchy, or null if this group is the master group.
subcategories
Type: list
Required: false
List of User Group resource URIs that belong to this user group.

Config settings

## Config settings can be accessed through the API via the config_settings base URL:
curl "https://app.handshake.com/api/latest/config_settings"

{
    "apiCanRead": "2011-01-18",
    "apiCanWrite": "2011-01-18",
    "cdate": "2011-01-18",
    "ctime": "2011-01-18T12:52:03Z",
    "ctimeOnServer": "2011-12-05T16:13:21Z",
    "dataType": "bool",
    "entityType": "ConfigSetting",
    "key": "company_logoURL",
    "mtime": "2011-01-31T12:04:19Z",
    "mtimeOnServer": "2016-12-05T16:13:37Z",
    "objID": 946,
    "owner": "system",
    "resource_uri": "/api/latest/config_settings/5",
    "uuid": "3e605828-9721-4c5a-8e80-68551a364ac0",
    "value": "/mycompanylogo.png"
}

<apiCanRead>2011-01-18</apiCanRead>
<apiCanWrite>2011-01-18</apiCanWrite>
<cdate>2011-01-18</cdate>
<ctime>2011-01-18T12:52:03Z</ctime>
<ctimeOnServer>2011-12-05T16:13:21Z</ctimeOnServer>
<dataType>bool</dataType>
<entityType>ConfigSetting</entityType>
<key>company_logoURL</key>
<mtime>2011-01-31T12:04:19Z</mtime>
<mtimeOnServer>2016-12-05T16:13:37Z</mtimeOnServer>
<objID>946</objID>
<owner>system</owner>
<resource_uri>/api/latest/config_settings/5</resource_uri>
<uuid>3e605828-9721-4c5a-8e80-68551a364ac0</uuid>
<value>/mycompanylogo.png</value>

These settings are also found under the Account Settings page in Handshake. Feel free to make updates to them through the UI. Config settings can be accessed through the API via the config_settings base URL:

$ curl https://app.handshake.com/api/latest/config_settings

In addition to the common fields listed above, config setting objects contain the following fields:

Field Description
apiCanRead
Type: boolean
Required: false
The full user-visible name of this user group.
apiCanWrite
Type: boolean
Required: false
The full user-visible name of this user group.
dataType
Type: string
Required: true
One of bool, unicode, int, data, rgba, userfile, json.
key
Type: string
Required: true
One of many pre-defined values. Please reference the account settings page for a full list.
userGroup
Type: string
Required: false
The resource URI of the user group to which this configuration setting applies.
value
Type: string
Required: false
The configuration setting value.

Export Orders Schedules

## Export Orders Schedules can be accessed through the API via the export_orders_schedule base URL:
curl "https://app.handshake.com/api/latest/export_orders_schedule"

This data determines when sales orders are automatically exported from Handshake. Export Orders Schedules can be accessed through the API via the export_orders_schedule base URL:

$ curl https://app.handshake.com/api/latest/export_orders_schedule

In addition to the common fields listed above, export order schedule objects contain the following fields:

Field Description
enabled
Type: boolean
Required: true
Enabled?
exportType
Type: boolean
Required: true
Export type of object?
fileNamePath
Type: boolean
Required: false
Export file name and path.
friday
Type: boolean
Required: true
Run on Friday?
hour
Type: number
Required: false
Hour run.
includeBuyerReview
Type: boolean
Required: true
Include orders in buyer review status?
includeComplete
Type: boolean
Required: true
Include orders in complete status?
includeConfirmed
Type: boolean
Required: true
Include orders in confirmed status?
includeHoldForConfirm
Type: boolean
Required: true
Include orders in hold for confirmation status?
includeOpen
Type: boolean
Required: false
Include orders in open status?
includeProcessing
Type: boolean
Required: true
Include orders in processing status?
includeSellerReview
Type: boolean
Required: true
Include orders in seller review status?
lastRunAt
Type: datetime
Required: false
Last time the export was run.
minDate
Type: text
Required: false
Furthest date in the past to include.
minute
Type: number
Required: true
Minute run.
monday
Type: boolean
Required: true
Run on Monday?
oneOrderPerFile
Type: boolean
Required: yes
Include one order per file?
postExportStatus
Type: text
Required: false
Include post export status?
saturday
Type: boolean
Required: true
Run on Saturday?
sunday
Type: boolean
Required: true
Run on Sunday?
targetFolderName
Type: string
Required: false
Destination folder for the export.
targetURL
Type: string
Required: false
Destination URL for the export.
thursday
Type: boolean
Required: true
Run on Thursday?
wednesday
Type: boolean
Required: true
Run on Wednesday?

HTML Blocks

## HTML Blocks can be accessed through the API via the html_blocks base URL:
curl "https://app.handshake.com/api/latest/html_blocks"

Custom HTML for a specific account.. HTML Blocks can be accessed through the API via the html_blocks base URL:

$ curl https://app.handshake.com/api/latest/html_blocks

In addition to the common fields listed above, html block objects contain the following fields:

Field Description
activeUntil
Type: datetime
Required: false
Date until the HTML page is active.
body
Type: text
Required: no
HTML body.
category
Type: text
Required: false
Page category.
categoryPosition
Type: number
Required: true
data
Type: text
Required: false
HTML data.
datePublished
Type: datetime
Required: false
Date page was published.
publishStatus
Type: text
Required: true
One of unpbulished, draft, or published.
title
Type: text
Required: true
Title of report.

Product Reports

## Product Report Lines can be accessed through the API via the product_reports base URL:
curl "https://app.handshake.com/api/latest/product_reports"

Product lists that appear on Handshake Direct Mobile and Rep. Product Reports can be accessed through the API via the product_reports base URL:

$ curl https://app.handshake.com/api/latest/product_reports

In addition to the common fields listed above, product report objects contain the following fields:

Field Description
categoryPosition
Type: number
Required: true
desc
Type: text
Required: false
Report description.
filters
Type: text
Required: true
Filters for the report.
name
Type: text
Required: true
Report name.
options
Type: text
Required: true
Report options.
published
Type: boolean
Required: true
Report is published?
reportType
Type: text
Required: true
One of order_history, purchases_and_credits, period_over_period, user_defined_actionable

Product Report Lines

## Product Report Lines can be accessed through the API via the product_report_lines base URL:
curl "https://app.handshake.com/api/latest/product_report_lines"

Individual lines that appear on product reports Product Report Lines can be accessed through the API via the product_report_lines base URL:

$ curl https://app.handshake.com/api/latest/product_report_lines

In addition to the common fields listed above, product report line objects contain the following fields:

Field Description
categoryPath
Type: text
Required: true
categoryPosition
Type: number
Required: true
customer
Type: Relationship to Customer
Required: no
Relationship to customer.
data
Type: text
Required: true
Item data.
item
Type: Relationship to Item
Required: false
Relationship to item.
itemCategory
Type: relationship to Item Category
Required: false
Relationship to item category.
manufacturer
Type: relationship to Manufacturer
Required: false
Relationship to manufacturer.
overrideUnitPrice
Type: boolean
Required: true
Unit price if an override is applied.
report
Type: boolean
Required: true
Relationship to product report.
salesOrderCategory
Type: relationship to Order Category
Required: false
Relationship to order category.
shipTo
Type: relationship to Address
Required: false
Relationship to address.
variant
Type: relationship to Variant
Required: false
Relationship to variant.

Customization

Custom objects and fields

## The types endpoint provides a list of all objects and their associated properties. The example below returns the entire schema:

curl "https://app.handshake.com/api/latest/types/" 

{
  "meta": {
    "limit": 100,
    "next": null,
    "offset": 0,
    "previous": null,
    "total_count": 50
  },
  "objects": [
    { ... }
  ],
}
## To view the schema of one specific object, append the object name to the request.
## Note the required fields that are listed at the end of the request.
curl "https://app.handshake.com/api/latest/types/Address" 
{
  "account": "Demo Store",
  "ctime": "2017-02-08T16:10:22Z",
  "description": "Addresses of locations where you conduct your business.",
  "display_name": null,
  "group_id": "uuid",
  "list_uri": "/api/latest/DemoStore/addresses",
  "mtime": "2017-02-08T16:10:22Z",
  "name": "Address",
  "resource_uri": "/api/latest/types/Address",
  "schema": {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
      //The properties section contains the entire schema. For brevity, we're only showing the custom field.
      "last4": {
        "title": "Zip - Last 4",
        "type": "string"
      }
    },
    "required": [
      "account",
      "categoryPosition",
      "ctime",
      "ctimeOnServer",
      "mtime",
      "mtimeOnServer",
      "objID",
      "owner",
      "uuid"
    ],
    "type": "object"
  }
}
<account>Demo Store</account>
<ctime>2017-02-08T16:10:22Z</ctime>
<description>Addresses of locations where you conduct your business.</description>
<display_name/>
<group_id>uuid</group_id>
<list_uri>/api/latest/DemoStore/addresses</list_uri>
<mtime>2017-02-08T16:10:22Z</mtime>
<name>Address</name>
<resource_uri>/api/latest/types/Address</resource_uri>
<schema>
  <$schema>http://json-schema.org/draft-04/schema#</$schema>
  <!-- The properties setion contains the entire schema. For brevity, we're only showing the custom field. -->
  <properties>
      <last4>
          <title>Zip - Last 4</title>
          <type>string</type>
      </last4>
  </properties>
  <required>account</required>
  <required>categoryPosition</required>
  <required>ctime</required>
  <required>ctimeOnServer</required>
  <required>mtime</required>
  <required>mtimeOnServer</required>
  <required>objID</required>
  <required>owner</required>
  <required>uuid</required>
  <type>object</type>
</schema>

Custom objects allow customer-defined data to be stored in Handshake. This encompases both full-featured customer-defined objects and customer-defined extensions to Handshake’s native objects.

Custom objects can be accessed through the API via the types base URL:

$ curl https://app.handshake.com/api/latest/types

To extend a native object, create a new custom type with the same name. For instance, to add new fields to the Address object, create a custom type with the name Address.

Once a custom object has been created, the schema for the object can be defined using the types API endpoint as described below.

Schema definitions

## Schema definitions for both native and custom objects can be accessed through the API via the `types` base URL:

curl "https://app.handshake.com/api/latest/types"
{
    "group_id": "tier",
    "name": "ItemRelated",
    "description": "Something related to Item objects.",
    "schema": {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "properties": {
            "item": {
                "is_a": "/api/latest/items",
                "type": "string"
            },
            "name": {
                "type": "string"
            },
            "tier": {
                "enum": [
                    "residential",
                    "commercial",
                    "special"
                ],
                "type": "string"
            }
        },
        "type": "object"
    }
}

<group_id>tier</group_id>
<name>ItemRelated</name>
<description>Something related to Item objects.</description>
<schema>
  <$schema>http://json-schema.org/draft-04/schema#</$schema>
  <properties>
      <item>
          <is_a>/api/latest/items</is_a>
          <type>string</type>
      </item>
      <name>
          <type>string</type>
      </name>
      <tier>
          <enum>residential</enum>
          <enum>commercial</enum>
          <enum>special</enum>
          <type>string</type>
      </tier>
  </properties>
  <type>object</type>
</schema>

Schema definitions for both native and custom objects can be accessed through the API via the types base URL:

$ curl https://app.handshake.com/api/latest/types

This endpoint returns a combination of all CustomType objects for the account along with any native object schemas that have not been customized.

For example, if a custom object definition called CustomerVisitSurvey was created and no native customizations were in place this endpoint would return the single CustomerVisitSurvey along with the native schema for every customizable type. If you only want to view the custom

You can also use this endpoint to define the schema for a new custom object (using a valid JSONSchema that objects will conform to) or to extend a native object, as described below.

In addition to the common fields listed above, custom object objects contain the following fields:

Field Description
group_id
Type: string
Required: false
How objects of this type should be grouped, pass uuid to eliminate grouping.
name
Type: string
Required: false
Name for this custom type.
display_name
Type: string
Required: false
Display name to be used, can be blank.
description
Type: string
Required: false
Description of this object, can be blank or null.
schema
Type: dict
Required: false
Valid JSONSchema that objects will conform to.

Extending native objects

Almost every object in Handshake can be customized with new fields which will be unique to your account.

To customize a native object a new CustomType is created with the same name as the native object. e.g. To add new fields to SalesOrder create a CustomType with the name SalesOrder. By doing this the native object is extended with the additional fields.

When extending a native object, either the full schema or just the customizations can be sent. The full schema (native + customizations) is returned. Fields which are native have an owner attribute set to “HANDSHAKE-01134”.

Theme Configurations

The appearance of standard and custom objects and fields throughout Handshake is governed by configuration files. These configs follow a standard schema, which is documented below. This schema can be altered in order to further customize the look and feel of all Handshake products.


//The example below shows the detail view of Items on Handshake Direct Online
{
    "display_type": "detail",
    "type": "/api/latest/items",
    "title": "Item",
    "platform": "web",
    "product": "direct",
    "fields": [{
        "section": "Additional Info",
        "options": {
            "display_unreferenced_fields": true,
        },
    }, {
        "excludes": true,
        "fields": [
            "ctime",
            "ctimeOnServer",
            "externalID",
            "hasGeneratedSKU",
            "isHidden",
            "isHiddenForCustomers",
            "isImplicitlyHidden",
            "isImplicitlyHiddenForCustomers",
            "longDesc",
            "minQty",
            "mtime",
            "mtimeOnServer",
            "multQty",
            "name",
            "netDateCreated",
            "netDateCreatedOnServer",
            "netDateModified",
            "netDateModifiedLocally",
            "netModifier",
            "netObjectID",
            "netOwner",
            "objID",
            "owner",
            "pricingUnit",
            "pricingUnitPerSaleUnit",
            "realVersion",
            "saleUnit",
            "sku",
            "unitPrice"
        ],
    }]
    "related": [{
        "rel": "item",
        "href": "/api/latest/invoice_lines",
    }],
}

//The example below shows the detail view of the Shipments object on app.handshake.com
{
    "display_type": "detail",
    "type": "/api/latest/shipments",
    "title": "Shipment",
    "platform": "web",
    "product": "hub",
    "fields": [{
        "field": "reference",
        "title": "Reference",
    }, {
        "field": "order.objID",
        "title": "Order",
        "readonly": true,
        "options": {
            "href_template": "{{order.resource_uri}}",
            "href_template_language": "Handlebars",
        },
    }, {
        "field": "invoice.invoice_id",
        "title": "Invoice",
        "readonly": true,
        "options": {
            "href_template": "{{invoice.resource_uri}}",
            "href_template_language": "Handlebars",
        },
    }, {
        "field": "invoice_line",
        "title": "Invoice line",
        "readonly": true,
        "options": {
            "href_template": "{{invoice_line.resource_uri}}",
            "href_template_language": "Handlebars",
        },
    }, {
        "field": "sent_at",
        "title": "Sent at",
    }, {
        "field": "delivered_at",
        "title": "Delivered at",
    }, {
        "field": "sent_from",
        "title": "Sent from",
    }, {
        "field": "sent_to",
        "title": "Sent to",
    }, {
        "field": "carrier",
        "title": "Carrier",
    }, {
        "field": "service_level",
        "title": "Service level",
    }, {
        "field": "tracking_link",
        "title": "Tracking link",
    }, {
        "field": "tracking_number",
        "title": "Tracking number",
    }, {
        "field": "notes",
        "title": "Notes",
    }, {
        "section": "Additional Info",
        "options": {
            "display_unreferenced_fields": true,
        },
    }, {
        "excludes": true,
        "fields": [
            "account",
            "ctime",
            "mtime",
            "uuid",
        ],
    }],
}

Field Description
display_type Allowed values:
  • list - view that shows multiple entries of the object, like a search results or index page
  • detail - view of one specific instance of the object
platform Allowed values:
  • web - applies to the web interfaces
  • iOS - applies to mobile devices
product Allowed values:
  • hub - applies config to app.handshake.com
  • direct - applies to Handshake Direct Online (or Handshake Direct Mobile, if the corresponding platform is ‘iOS’)
type API endpoint where the config file applies, i.e. /api/latest/{accountID}/objects
title Display-friendly object title
createable Boolean. Determines if user should be able to create new instances of the object from the view. If true, a “Create New {object}” button will display.
scope Can be applied at the overall configuration level, section level, or field level. The scope can be determined based on object data, feature access, session data, or specific configuration settings.
sort_fields Array of field names that can be sorted on a list view.
excludes Boolean. Excludes the fields in the
fields Array of field names to be excluded from the view. Most useful for excluding audit information, like ctime and mtime.
fields Array of field objects included in the view. Not that this is separate from the above fields array.
field Unique field ID. You can get this by viewing the the raw JSON of an object on the objects page.
field.title Display-friendly field title
field.is_a Field type. Not required
field.component Type of field. Common Values:
  • GenericString
  • JSONPre
  • DateTime
  • GenericCurrency
  • ItemImage
field.readonly Boolean. True if field should not be editable.
field.options Array of properties of the field.
field.options.href_template Custom link display template.
field.options.href_template_language Templating language for the link. Supported values:
  • DjangoTemplates
  • Handlebars
field.options.field_template Custom field value display template.
field.options.field_template_language Templating language for the field Supported values:
  • DjangoTemplates
  • Handlebars
field.options.item_property
field.options.src_property
field.options.multiline: Boolean. Determines if text field should be multi-line text area.
field.options.width Integer. Determines width of image.
section Specify a display section for the fields in the view.
section.options Array of properties of the section.
section.options.display_unreferenced_fields Boolean. When true, will put all fields that are not already assigned to a secion in this section.
related Array of objects related to the current object being shown in the theme config.
related.rel Object described in the theme config. Note: not the related object.
related.href API endpoint of the related object.