API

API

RetailNext has an extensive API for users to access and modify data in the RetailNext cloud service and integrate them with other existing systems.

The API calls are REST compliant and make use of the most common HTTP methods such as GET and POST, with the data sent and received in JSON format. All requests require HTTPS connections and authentication with API keys.

This page details the most recent API methods available, while old methods are listed at Deprecated APIs.

For help with using this page, more examples, and frequently asked questions; visit Getting Started with the API.

Please review our API Implementation Considerations before building or integrating applications with the RetailNext API.

Authentication

All API endpoints are authenticated using your API token over HTTP basic auth. API tokens have a unique Access Key and Secret Key that are used during API authentication.

Subscription Admins can issue and manage API tokens for their subscription from the RetailNext cloud interface in Admin Settings > System Access Tokens. Visit System Access Tokens to learn more.

Authentication Header

--basic --user <AccessKey>:<SecretKey>

Pagination

Some API methods have paginated responses, with a default and maximum page length limit of 100 entries. These are marked in this documentation with . Queries with more items than the page length limit will have responses split across multiple pages.

206 in the response header indicates that there are additional pages for the query, while 200 means that the response is complete.

Parameters

X-Page-Length

integer

default: 100

If included, the response page length will match the specified value.

The maximum page length is 100.

X-Page-Start

integer

If included, the response will start at the specified value.

This is typically used to retrieve subsequent pages for queries that exceed the page length limit.

Example Request

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "X-Page-Length: 20" \ "https://<subscription>.api.retailnext.net/v1/<method>"

Example Response

HTTP/2 206 content-type: application/json ... x-frame-options: SAMEORIGIN x-page-next: 20 ...

Note that some API methods may respond with the UUID of the following page instead of an integer.

HTTP/2 206 content-type: application/json ... x-frame-options: SAMEORIGIN x-page-next: 2278d300-7777-11ec-87cc-4000727ce915 ...

Example Request: Subsequent Pages

The HTTP response code indicates whether a response contains all possible entries, or if you need to fetch more pages; whereby:

  • 200: OK (no additional pages)

  • 206: Partial Content

Fetch the next page by adding X-Page-Start to your original request header with a value that matches X-Page-Next from the previous response.

... -H "X-Page-Length: 20" -H "X-Page-Start: 20" \ ... "https://<subscription>.api.retailnext.net/v1/<method>"

Locations

Request Limits

Concurrent location requests are limited to 2 per customer subscription.

Query Locations

Returns locations and related fields.

POST https://<subscription>.api.retailnext.net/v2/location

v2/location has a limit of 10,000 location nodes per response, and does not support pagination.

If your query is for more than 10,000 nodes, the response header will contain the code 400 with the body {"error":"bad_request","error_detail":"too many result nodes (XXXXX), please refine your query"}.

If you expect a large response that may get trimmed by this limit, be more specific in your query (e.g. use additional filters) or consider using v1/location which supports pagination.

Example Request

This example filters for only store type locations and includes extra fields for store_id and occupancy_limit

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "Accept: application/json" -d "@request.json" \ -POST "https://<subscription>.api.retailnext.net/v2/location"

Where the request.json file contains:

{ "extra_fields": [ "store.store_id", "store.occupancy_limit" ], "where": { "and": [ { "location_types": [ "store" ] } ] } }

Example Response

{ "nodes": [ [ { "store_id": "50", "occupancy_limit": 50, "location_type": "store", "area": null, "uuid": "aec3dc7e-9e2c-11e5-9bb4-0e5ba9bee1b9", "parent_uuid": "22940210-f49b-11e6-944b-c0001cd87189", "name": "Caspar City Plaza", "type": "location", "archive_date": null }, { "store_id": "101", "occupancy_limit": 15, "location_type": "store", "area": null, "uuid": "86b03ba2-a117-11ea-802c-c00010892d7a", "parent_uuid": "01b1ed64-f49b-11e6-9ef8-400075388ff3", "name": "Willow Glen", "type": "location", "archive_date": null }, ... }

Extra Fields and Filtering

As in the example above, you can specify extra_fields in your query to include additional location fields that are normally not returned in responses. The supported options are as follows:

extra_field

Type

Description

extra_field

Type

Description

all

-

Expand the query to all extra fields permitted by the user’s role

store.attributes

{name}, {value}

Associated custom attributes by name and value

store.comp_start_date

YYYY-MM-DD

Store-local date. Falls back to first_traffic_date if not set (converted to store tz first)

store.first_traffic_date

YYYY-MM-DD

Store-local date. Convert UTC timestamp to store tz before extracting date

store.health_monitoring_profile_uuid

UUID

Useful for debugging HM alerting configuration

store.latitude

float32

Latitude coordinate based on validated address

store.longitude

float32

Longitude coordinate based on validated address

store.occupancy_limit

Integer

Useful for occupancy monitoring

store.override_global_store_hours

Boolean

Useful for debugging store hours discrepancies

store.pos_id

String

When using IDs for special use cases

store.pos_division_id

String

When using IDs for special use cases

store.staff_hour_id

String

When using IDs for special use cases

store.store_id

String

Store ID

store.time_zone

IANA

Timezone in IANA name format

store.validated_address

String

Validated store address

Specify where clause to filter the results. This is particularly useful when normal responses exceed the API pagination limit. The available options in where clause and their filters are:

  • location_types

    • display

    • entrance

    • fitting_room

    • other

    • store

    • region

  • node_types

    • location

    • video

    • traffic

    • pos

You can further filter locations by their archived status (boolean) and/or exact matches for custom attributes (name and value).

{ "extra_fields": [ "all" ], "where": { "and": [ { "location_types": [ "store" ] }, { "archived": false }, { "attribute": { "name": "district_manager", "value": "Smith" } } ] } }

Besides where clause, root_uuids is also available to get the list of all sub-locations/nodes under a certain location.

{ "root_uuids": ["05e54488-02f5-11eb-88c2-000025b8381c"], "where": { "and": [ { "location_types": [ "store" ] } ] } }

Create Locations

Creates sublocations and regions.

POST https://<subscription>.api.retailnext.net/v2/location/create

Parameters

name*

string

The name of the location

parent_UUID*

string

The UUID of the parent store or region

location_type*

string

Supported sublocation types: entrance, fitting_room, display, other

Supported region type: region (parent UUID must be another region)

area

integer

The area in square feet (only applicable to sublocations)

aggregate_to_parent

boolean

default: true when "entrance", false otherwise

true, false (only applicable to sublocations)

aggregate_to_store

boolean

default: true when "entrance", false otherwise

true, false (only applicable to sublocations when floor level conversion is enabled)

* required parameter

  • Creating store locations is not supported through the API

  • To create a region under the top-level parent, or the "Organization" level, you must set the parent_uuid value to that of the subscription UUID. Contact RetailNext support if you need help obtaining this value.

  • After creating a location, the API response includes the UUID of the newly created location to use in further API operations

Example Request

This example creates a new Display sublocation type within a store.

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "Accept: application/json" -d "@request.json" \ -POST "https://<subscription>.api.retailnext.net/v2/location/create"

Where the request.json file contains:

{ "name": "Front Table", "parent_uuid": "2512a786-a117-11ea-874c-8000df845ed7", "location_type": "display", "area": 53.1, "aggregate_to_parent": true, "aggregate_to_store": false }

Example Response

{ "location_type": "display", "aggregate_to_parent": true, "aggregate_to_store": false, "area": 53.1, "uuid": "fb2d8bf5-c19e-11e8-b05c-40008b55ebf7", "parent_uuid": "2512a786-a117-11ea-874c-8000df845ed7", "name": "Front Table", "type": "location", "archive_date": null }

Update Locations

Update location fields.

PUT https://<subscription>.api.retailnext.net/v2/location/<location_uuid>

Parameters

name

string

Name of location

parent_UUID

string

Moves the location beneath the specified parent location

location_type

string

Supported sublocation types: entrance, fitting_room, display, other

area

integer

Area in square feet (only applicable to stores and sublocations)

occupancy_limit

integer

Occupancy limit (only applicable to stores)

bandwidth_limit_kilobits_per_second

integer

Custom outbound bandwidth limit of a store (only applicable when global bandwidth limits are enabled)

Sending a value of 0 clears any existing custom store limit and reverts its value to the global limit.

aggregate_to_parent

boolean

true, false (only applicable to sublocations)

aggregate_to_store

boolean

true, false (only applicable to sublocations when floor level conversion is enabled)

  • Changing the location_type to or from “store” or “region” is not supported (in other words, you can only change the location_type of sublocations).

Example Request

This example updates a store by changing its name, area and occupancy limit; as well as moving it to a new parent region.

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "Accept: application/json" -d "@request.json" \ -XPUT "https://<subscription>.api.retailnext.net/v2/location/<location_uuid>"

Where the request.json file contains:

{ "name": "Willow Glen Updated", "parent_uuid": "286b1000-f8b1-11e7-9337-c0009584d333", "area": 270.8, "occupancy_limit": 20 }

Example Response

{ "occupancy_limit": 20, "location_type": "store", "area": 270.8, "uuid": "<location_uuid>", "parent_uuid": "286b1000-f8b1-11e7-9337-c0009584d333", "name": "Willow Glen Updated", "type": "location", "archive_date": null }

Updating Locations in Bulk

You can update a bulk selection of locations to a specified parameter value in certain situations.

This example updates the respective occupancy limit parameter of multiple store locations.

while IFS=, read -r site_uuid occupancy;do curl -viL --basic --user <AccessKey>:<SecreteKey> \ -XPUT "https://<subscription>.api.retailnext.net/v2/location/$site_uuid" \ -d "{\"occupancy_limit\": $occupancy}";done < ./occupancy_limit.csv

Where the occupancy_limit.csv file contains:

site_uuid, occupancy_limit 18ef3a2e-cc3f-11e6-8d5c-0000124e6871,40 ff94800e-7c5f-11e6-8056-c000704d0145,35

Point of Sale

Integrate point of sale data via API.

Request Limits

Concurrent POS upload requests are limited to 10 per customer subscription. There is also a limit of 1,200,000 transaction uploads per day per subscription. Moreover, one API request can contain up to 20 transactions, as the API is not intended to be used for bulk uploads. Refer to the Point of Sale Upload for CSV options.

Upload Transactions

POST https://<subscription>.api.retailnext.net/v1/pos/transaction

Parameters

See Point of Sale Upload for the full list of parameters. The parameters provided via the API should correspond with those configured on the Admin Settings > File Upload Configuration > POS page.

Example Request

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "Accept: application/json" -d "@request.json" \ -POST "https://<subscription>.api.retailnext.net/v1/pos/transaction"

Where the request.json file contains:

{ "transactions": [ { "store_id": "505", "receipt_number": "12737", "workstation_id": "4", "division_id": "AA01", "receipt_date_time": "2022-06-14 15:14:44", "line_items_total": 100, "transaction_total": 110, "operator_ids": [ "0000099" ], "transaction_type": "Sale", "transaction_status": "Finished", "payments": [ "cash", "discover", "gift card" ], "tax_amount": 10, "sales_associate_ids": [ "0000099" ], "currency_code": "USD", "line_items": [ { "price": 100.0, "quantity": 2, "sku": "SKU001", "description": "Item1", "discount_percentage": 20 "discount_amount": 20 } ] } ] }

Example Response

{ "transactions": [ "d507e3e0-09e3-11ed-9157-400026b643f7" ], "received_timestamp": "2022-07-22T17:29:25Z" }

Query Single Transaction Status

GET https://<subscription>.api.retailnext.net/v1/pos/transaction/status/<transaction-uuid>

Example Request

curl -viL --basic --user <AccessKey>:<SecretKey> \ -XGET "https://<subscription>.api.retailnext.net/v1/pos/transaction/status/4d7aa93f-023c-11ed-98f4-0000589072c4"

Example Response

{ "uuid": "4d7aa93f-023c-11ed-98f4-0000589072c4", "upload_time": "2022-07-12T23:42:33Z", "status": "processed", "receipt_number": "12737", "store_id": "505", "division_id": "AA01", "workstation_id": "4", "receipt_date_time": "2022-06-14 15:14:44" }

Query Multiple Transactions Status

Query the status of all transactions uploaded in the last 24 hours.

GET https://<subscription>.api.retailnext.net/v1/pos/transaction/status/

Example Request

curl -viL --basic --user <AccessKey>:<SecretKey> \ -XGET "https://<subscription>.api.retailnext.net/v1/pos/transaction/status"

Example Response

[ { "uuid": "9261b588-091e-11ed-9cad-c000ed0ebacf", "upload_time": "2022-07-21T17:57:22Z", "status": "processed", "receipt_number": "99803", "store_id": "T179", "division_id": "TH001", "workstation_id": "4", "receipt_date_time": "2022-07-19 10:23:16" }, { "uuid": "2dd0b361-092e-11ed-8be3-c00087b07a3e", "upload_time": "2022-07-21T19:49:06Z", "status": "processed", "receipt_number": "99803", "store_id": "T003", "division_id": "TH001", "workstation_id": "4", "receipt_date_time": "2022-07-19 10:23:16" }, { "uuid": "44e74195-092e-11ed-8ff8-40005dced8eb", "upload_time": "2022-07-21T19:49:44Z", "status": "processed", "receipt_number": "99001", "store_id": "T003", "division_id": "TH001", "workstation_id": "4", "receipt_date_time": "2022-07-19 10:23:16" } ]

Status API allows filtering by status and duration:

  • Append ?status=rejected or ?status=processed to get the list of all transactions by status in the past 24 hours: https://<subscription>.api.retailnext.net/v1/pos/transaction/status?status=rejected

  • Query all transactions status in a specific duration using start_time and end_time https://<subscription>.api.retailnext.net/v1/pos/transaction/status?start_time=2022-07-11T10:00:00-01:00&end_time=2022-07-11T21:59:59-01:00

  • Status and Duration filters can also be specific together in a single request: https://<subscription>.api.retailnext.net/v1/pos/transaction/status?start_time=2022-07-11T10:00:00-01:00&end_time=2022-07-11T21:59:59-01:00&status=rejected

Store Hours

Query Store Hours

Returns store hours within specified parameters.

POST https://<subscription>.api.retailnext.net/v1/storehours

Parameters

stores*

string

UUID of store location

start_date*

ISO 8601

Start date in ISO 8601 format (yyyy-mm-ddThh:mm:ssZ)

end_date*

ISO 8601

End date in ISO 8601 format (yyyy-mm-ddThh:mm:ssZ)

* required parameter

Example Request

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "Accept: application/json" -d "@request.json" \ -POST "https://<subscription>.api.retailnext.net/v1/storehours"

Where the request.json file contains:

{ "stores" : [ "aec3dc7e-9e2c-11e5-9bb4-0e5ba9bee1b9", "aec5c886-9e2c-11e5-9bb7-0e5ba9bee1b9" ], "start_date" : "2021-01-15T00:00:00Z" , "end_date" : "2021-01-22T00:00:00Z" }

Example Response

{ "result": { "aec3dc7e-9e2c-11e5-9bb4-0e5ba9bee1b9": { "2021-01-15T00:00:00Z": { "store_uuid": "aec3dc7e-9e2c-11e5-9bb4-0e5ba9bee1b9", "effective_day": "2021-01-15T00:00:00Z", "open": "2021-01-15T10:00:00Z", "close": "2021-01-15T21:00:00Z" }, ... }, "2021-01-22T00:00:00Z": { "store_uuid": "aec5c886-9e2c-11e5-9bb7-0e5ba9bee1b9", "effective_day": "2021-01-22T00:00:00Z", "open": "2021-01-22T09:00:00Z", "close": "2021-01-22T21:00:00Z" } } } }
  • The open and close timestamps in store hours query responses are always presented in the store’s local timezone, as configured in Admin Settings > Locations for a particular store. Ignore the Z i.e. UTC timezone indicator in the response for this API method.

Datamine

Query Metrics

Returns metrics within specified parameters.

POST https://<subscription>.api.retailnext.net/v2/datamine

Parameters

locations*

string

UUID of location

metrics*

string

See Metrics Glossary for API identifiers

date_ranges*

string

from and to in conjunction with additional objects.

See More Details on Date Ranges below

time_ranges*

string

from and until in hh:mm, or,

type: store_hours

group_bys*

string

time, date, location and day_of_week

See More Details on Group Bys below

* required parameter

  • Datamine API responses typically include the following indicators:

    • Ok: When querying any metric, each response entry includes an ok field. A value of true means that there was no error in serving the data, while false indicates there was an error with a further description. Errors in serving data generally relate to inadequate API token permissions or bad requests, e.g. if you’re querying metrics for a store that is not included in the Location Profile assigned to your API token.

    • Validity: When querying traffic metrics, each data point additionally includes a validity field. The possible values are: complete, incomplete and imputed, where an incomplete or imputed response means that there was a problem collecting traffic data during the queried range, e.g. power not supplied to the sensor. Learn more about traffic validation and imputing at Imputing Missing Traffic Data.

  • Response timestamps are prefixed with - or + when the store hours of a store on a given day are configured to overlap with the previous day or the following day, respectively. See Managing Store Hours for more information.

  • Responses will only include completed time intervals. For example, if a store’s local time is 09:53 at the time when a query is made for the interval 09:00 - 10:00 and grouped by 15-min, the response will be limited to the three completed time intervals: 09:00 - 09:15, 09:15 - 09:30, and 09:30 - 09:45.

Example Request

This example queries Traffic In & Out metrics for last week during store hours, with the response grouped by one day.

curl -viL --basic --user <AccessKey>:<SecretKey> \ -H "Accept: application/json" -d "@request.json" \ -POST "https://<subscription>.api.retailnext.net/v2/datamine"

Where the request.json file contains:

{ "metrics" : [ "traffic_in", "traffic_out" ], "date_ranges" : [ { "from": { "relative": { "add_weeks": -1 } }, "to": { "relative": { "base": { "name": "now" }, "truncate_to": "week" } } } ], "time_ranges" : [ { "type": "store_hours" } ], "group_bys" : [ { "group": "date", "unit": "days", "value": 1 } ], "locations" : [ "aec3dc7e-9e2c-11e5-9bb4-0e5ba9bee1b9" ], "time_zone": "America/Los_Angeles" }

Example Response

{ "ok": true, "metrics": [ { "name": "traffic_in", "ok": true, "data": [ { "value": 173, "validity": "complete", "group": { "type": "date", "from": { "gregorian": "2021-02-21", "year": 2021, "month": 1, "day": 22 }, "through": { "gregorian": "2021-02-21", "year": 2021, "month": 1, "day": 22 } }, "index": 0 }, ... ] }, { "name": "traffic_out", "ok": true, "data": [ { "value": 174, "validity": "complete", "group": { "type": "date", "from": { "gregorian": "2021-02-21", "year": 2021, "month": 1, "day": 22 }, "through": { "gregorian": "2021-02-21", "year": 2021, "month": 1, "day": 22 } }, "index": 0 }, ... ] } ] }

More Details on Date Ranges

The date_ranges parameter determines the dates from and to, respectively, for which to datamine. It also requires the use of additional objects, being:

  • name

  • gregorian

  • absolute