REST API

Clover provides a REST API for each of its supported markets:

  • US: https://api.clover.com
  • EU: https://api.eu.clover.com

In addition, there is a sandbox REST API for use with our Developer Kits and sandbox test merchants:

  • Sandbox: https://apisandbox.dev.clover.com

For the list of supported endpoints view our API Reference. These endpoints accept query parameters in the following format:

[Endpoint URI]?field=value[,additionalValues...]&[additionalQueryStrings...]

Some guidelines to follow when using the Clover REST API:

  • Clover’s APIs are only accessible via HTTPS
  • Request and response entities are always JSON
  • All API requests are protected by an OAuth2-derived access token. See OAuth 2.0 docs
  • GET queries made in-browser will also include hyperlinks to view details of each specific object, under the “href” field

Using API Tokens

Requests to the REST API require a merchant ID and an API token. The merchant ID is embedded in the URL that is used to access the Clover merchant website:

https://sandbox.dev.clover.com/home/m/[Merchant ID]

 

The API token can be retrieved via OAuth. Using OAuth is required in production, and supports CORS.

Once you have the API token and merchant ID, you can test the REST API on the command line with curl. The preferred method for accessing the API is to place the token within the “Authorizations” header under “Bearer [API Token]”.

$ curl -s https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders --header "Authorization:Bearer [API Token]" | python -mjson.tool

 

Alternately, for testing purposes you can place the API token in the request url itself, but this is discouraged in production, as it is less secure, and will not support CORS.

$ curl -s https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/items?access_token=[API Token] | python -mjson.tool

Sorting collections

Most JSON responses take the form of collections, and collections can be sorted by specifying the orderBy query parameter. Multiple fields can be specified, separated by commas.

$ curl -s https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/items?orderBy=modifiedTime,price --header "Authorization: Bearer [API Token]" | python -mjson.tool

{
    "elements": [
        {
            "code": "",
            "defaultTaxRates": false,
            "hidden": false,
            "id": "V33H8XGTZCKNP",
            "isRevenue": true,
            "name": "Item Use",
            "price": 100,
            "priceType": "PER_UNIT",
            "unitName": "hr"
        },
        {
            "code": "",
            "defaultTaxRates": false,
            "hidden": false,
            "id": "EWKZEMNCBQQ9Y",
            "isRevenue": true,
            "name": "Nontax Item",
            "price": 100,
            "priceType": "FIXED",
            "unitName": "oz"
        },
...

 

The default sort order is by creation time, descending, but you can manually order by ascending or descending by inputting %20ASC or %20DESC, respectively.

$ curl -s https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/items?orderBy=modifiedTime%20ASC --header "Authorization: Bearer [API Token]" | python -mjson.tool

{
  "elements": [ {
      "id": "1CF022RN5TGDM",
      "hidden": false,
      "name": "Pizza Slice",
      "price": 250,
      "priceType": "FIXED",
      "defaultTaxRates": true,
      "cost": 0,
      "isRevenue": true
    }, {
      "id": "SNGFTY41642NY",
      "hidden": false,
      "name": "Pork Rice Bowl with House Salad",
      "price": 1200,
      "priceType": "FIXED",
      "defaultTaxRates": true,
      "cost": 0,
      "isRevenue": true,
      "stockCount": 3
    },
...

Filtering collections

Collections can be filtered with the filter query parameter. The filter parameter supports standard comparison operations, such as =, >=, !=, etc. Multiple filterparams are specified with multiple &filter=params.

$ curl -s "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders?filter=clientCreatedTime>=[unix-time]&filter=clientCreatedTime<=[unix-time]" --header "Authorization: Bearer [API Token]" | python -mjson.tool

You can see what parameters are filterable for a given method in the API Reference.

$ curl -s "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders?filter=total>1000&filter=payType!=FULL" --header "Authorization: Bearer [API Token]" | python -mjson.tool

{
    "elements": [
        {
            "clientCreatedTime": 1401286267000,
            "createdTime": 1401286268000,
            "currency": "USD",
            "employee": {
                "id": "QT0DES4CXR572"
            },
            "groupLineItems": true,
            "href": "https://sandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders/8WAD6KV8D90KR",
            "id": "8WAD6KV8D90KR",
            "isVat": false,
            "manualTransaction": false,
            "modifiedTime": 1401286463000,
            "payType": "SPLIT_CUSTOM",
            "state": "locked",
            "taxRemoved": false,
            "testMode": false,
            "total": 5293
        },
        {
            "clientCreatedTime": 1400106245000,
            "createdTime": 1400106245000,
            "currency": "USD",
            "employee": {
                "id": "QT0DES4CXR572"
            },
            "groupLineItems": true,
            "href": "https://sandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders/0S0JJYG231462",
            "id": "0S0JJYG231462",
            "isVat": false,
            "manualTransaction": false,
            "modifiedTime": 1400106366000,
            "payType": "SPLIT_CUSTOM",
            "state": "locked",
            "taxRemoved": false,
            "testMode": false,
            "total": 2829
        }
    ],
    "href": "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders?filter=total%3E1000&filter=payType!%3DFULL&limit=100"
}

Pagination

The offset and limit query parameters can be used to page through larger results. The default limit is 100 elements, and the hard limit is 1000.

$ curl -s "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders?offset=10&limit=1" --header "Authorization: Bearer [API Token]" | python -mjson.tool
{
    "elements": [
        {
            "clientCreatedTime": 1403294602000,
            "createdTime": 1403294602000,
            "currency": "USD",
            "employee": {
                "id": "5PYBJET35969W"
            },
            "groupLineItems": true,
            "href": "https://sandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders/6Z3JQ98FQ8B40",
            "id": "6Z3JQ98FQ8B40",
            "isVat": false,
            "manualTransaction": false,
            "modifiedTime": 1403295698000,
            "state": "open",
            "taxRemoved": false,
            "testMode": false,
            "total": 1743
        }
    ],
    "href": "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders?offset=10&limit=1"
}

Field expansion

Fields can be expanded with the expand query parameter. You can see what parameters are expandable for a given method in the API Reference.

Example:

$ curl -s "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/items/[Item ID]?expand=categories" --header "Authorization: Bearer [API Token]" | python -mjson.tool

{
    "id": "Z0EPYQ2R5TQ5Y",
    "hidden": false,
    "name": "Bangers and Mash",
    "alternateName": "",
    "code": "024463061095",
    "price": 150,
    "priceType": "FIXED",
    "defaultTaxRates": true,
    "unitName": "",
    "isRevenue": true,
    "categories": {
        "elements": [
            {
                "id": "MHH9XR2YXZ4T4",
                "name": "Food",
                "sortOrder": "0"
            }
        ]
    }
}

 

Multiple parameters can be expanded by using a comma:

IMPORTANT

Please limit expansions to maximum of 3 per API call to allow us to continually provide quick API response times and reduce undue load.

$ curl -s "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/items/[Item ID]?expand=tags%2Ccategories" --header "Authorization: Bearer [API Token]" | python -mjson.tool

{
    "cost": 0,
    "defaultTaxRates": true,
    "hidden": false,
    "id": "AK5ESN5YR8YWY",
    "isRevenue": true,
    "modifiedTime": 1432671908000,
    "name": "Pizza",
    "price": 1499,
    "priceType": "FIXED",
    "tags": {
        "elements": [
            {
                "id": "HYQ5Z74KS9E6W",
                "name": "Hot"
            }
        ]
    },
    "categories": {
        "elements": [
            {
                "id": "1JZPWY014VPEP",
                "name": "Italian",
                "sortOrder": 1
            },
            {
                "id": "0AJNZP04JXB4G",
                "name": "From the Oven",
                "sortOrder": 0
            }
        ]
    }
}

 

Two levels of fields can be expanded by specifying a dotted field path:

$ curl -s "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders/[Order ID]?expand=lineItems.taxRates" --header "Authorization: Bearer [API Token]" | python -mjson.tool

...
{
    "clientCreatedTime": "1389389735000",
    "createdTime": "1389389736000",
    "employee": "id",
    "groupLineItems": "true",
    "id": "QGSS9P64219CM",
    "lineItems": {
        "elements": [
            {
                "createdTime": "1389389734000",
                "id": "VGQRH14DBR7JC",
                "name": "Bangers and Mash",
                "price": "1000",
                "printed": "true",
                "taxRates": {
                    "elements": [
                        {
                            "id": "VSA19B84VG1GT",
                            "isDefault": "true",
                            "name": "VAT",
                            "rate": "1500000"
                        },
                        {
                            "id": "BTHZCAXV6Z5R8",
                            "isDefault": "true",
                            "name": "Zero Tax",
                            "rate": "0"
                        }
                    ]
                }
            }
        ]
    },
    "manualTransaction": "false",
    "payType": "FULL",
    "state": "locked",
    "taxRemoved": "false",
    "total": "1000"
}
...

Inventory Stock

The quantity field holds an item’s stock, and is found by expanding itemStock when viewing items. Note that this field can only be updated throughv3/merchants/[Merchant ID]/item_stocks endpoints, which are shown in the new API Reference. The field supports whole or decimal numbers, both positive and negative.

$ cat /tmp/item_stock.json
{
   "quantity": 160.5
}

$ curl -s -X POST "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/item_stock/[Item ID]" --header "Authorization: Bearer [API Token]" --data "[Content from item_stock.json" | python -mjson.tool

{
  "item": {
    "id": "3Z29BX6C013XC"
  },
  "stockCount": 161,
  "quantity": 160.5
}

 

Stock count is a deprecated field that will always display quantity rounded to the nearest whole number. As a result, its use is discouraged.

Object associations

Many-to-many associations between objects require their own endpoints. For example, if you want to add an item to a category, we require that you create the item, create the category, and then use an object association call to link the two. We support object associations with the following calls:

  • /v3/merchants/[Merchant ID]/category_items: category to an item (see API Reference)
  • /v3/merchants/[Merchant ID]/item_modifier_groups: modifier group to an item (see API Reference)
  • /v3/merchants/[Merchant ID]/tax_rate_items: tax rate to an item (see API Reference)
  • /v3/merchants/[Merchant ID]/tag_items: label to an item (see API Reference)

Example: Category Items

To create an association, POST a tuple of the two object IDs to the association endpoint.

$ cat /tmp/category_items.json
{
  "elements": [
    { "category": {"id": "Y906VJJHTNCVW"}, "item": {"id": "7PARQ2Z2G0336"}}
  ]
}

$ curl -s -X POST "https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/category_items" --header "Authorization: Bearer [API Token]" -H "Content-Type: application/json" --data "[Content from category_items.json]"

 

To create multiple associations in one call, POST a list of tuples. This sample associates three items with two categories:

{
  "elements": [
      { "item": {"id": "ABWN2X43EXJN8"}, "category": {"id": "J615DCVPX97JG"} },
      { "item": {"id": "ABWN2X43EXJN8"}, "category": {"id": "PBRT27S9JBSK8"} },
      { "item": {"id": "F1RBG5MKD3SQR"}, "category": {"id": "J615DCVPX97JG"} },
      { "item": {"id": "F1RBG5MKD3SQR"}, "category": {"id": "PBRT27S9JBSK8"} },
      { "item": {"id": "S9230FJR93DFJ"}, "category": {"id": "J615DCVPX97JG"} },
      { "item": {"id": "S9230FJR93DFJ"}, "category": {"id": "PBRT27S9JBSK8"} }
  ]
}

 

To remove the association, send a POST with ?delete=true appended to the URL, along with the same payload. To remove all categories from an item, use a payload with the item and no category:

{
  "elements": [
    { "item": {"id": "7PARQ2Z2G0336"}}
  ]
}

Displaying null fields

To have a response display all possible fields, you can append return_null_fields=true to your query.

$ curl -s https://apisandbox.dev.clover.com/v3/merchants/[Merchant ID]/orders/[Order ID]?return_null_fields=true  --header "Authorization:Bearer [API Token]" | python -mjson.tool

{
   "id": "[Order ID]",
   "currency": "USD",
   "employee": {
      "id": "0YN6A3WJ5BEZJ"
   },
   "total": 152,
   "title": "5",
   "note": null,
   "orderType": {
       "id": "2ZPZHQG2Z64NM",
       "labelKey": null,
       "label": null,
       "taxable": null,
       "isDefault": null,
       "isDeleted": null
   },
   "taxRemoved": false,
   "isVat": false,
   "state": "locked",
   "manualTransaction": true,
   "groupLineItems": true,
   "testMode": false,
   "payType": null,
   "createdTime": 1373613867000,
   "clientCreatedTime": 1373613795000,
   "modifiedTime": 1373613868000,
   "serviceCharge": null
}