Introduction
The ShelfX a point of sale system for managing merchandising fixtures that allow at-the-shelf purchasing by consumers who have a ShelfX account and an associated NFC device for personal identification. The NFC identification device is associated with the consumer’s ShelfX account.
The software system provides an Application Programming Interface that can be used to build software applications that can enhance the user’s experience or the merchant’s ability to manage their business.
The ShelfX API is a RESTful JSON API. The API is divided into three components; 1) The Configuration API is used to access and update aspects of locations, fixtures, shelves, devices, and employees, 2) The Merchant API is used to access and update products, planograms, pick lists, sales reports, etc., and 3) The Xcard API is used to access and update information relating to consumers and their shopping history.
Headers
Content-Type: application/json
Accept: application/json
API Keys
API keys are assigned to employees and associated with their login. Each employee created in the Configuration application automatically is assigned an API key. By associating API keys with employees, it is possible to limit access to parts of the API based on permissions associated with the Employee Type.
The system administrator (using the master account login) can define Employee Types in Configuration. In defining a new Employee Type, the administrator can choose the Access Rights associated with that Employee Type. The a new Employee can be defined using that Employee Type and the new Employee will be assigned an API key that only allows access to parts of the system allowed by the associated Access Rights.
The Employee’s API key is displayed as part of the employee profile.
Merchant API: Xmanager
The Configuration API allows programmatic access to the ShelfX Configuration application at yourdomain.shelfx.com.
List of Objects |
---|
Products |
Product_Categories |
Product_Shelves |
Pick_Lists |
Sales_Activity |
Give_funds |
API Call Structure
The basic structure of a call is as follows:
https://[company_subdomain].xmanager.us/<object name>?account_id=<account id>&key=<account key>&[<property 1=<property 1 value>>]\*&list=true
Properties of Objects
Each merchant object has a set of properties which can be read or set using HTTP GET
and PATCH
operations respectively.
Get Products
curl "http://[company_subdomain].xmanager.us/products?key={{account_key}}&account_id={{account_id}}"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 75,
"name": "1 LB Test Item", [Product Name]
"price": "1.0", [Default Price]
"barcode": "",
"peritem": 1,
"display_line1": "",
"display_line2": "",
"display_line3": "",
"display_line4": "",
"itemWeight": "5.0",
"ordered": null,
"minOrder": null,
"inStorage": null,
"onShelves": null,
"created_at": "2013-01-31T12:54:23.000-10:00",
"updated_at": "2014-10-05T06:08:45.000-10:00",
"display_line5": "",
"SKU_Item": "02",
"price_units": "USD",
"ordered_units": "lb",
"cost": "0.0",
"boxQty": null,
"english_name": "1 LB Test",
"product_category_id": 1,
"is_service": false,
"period": 1,
"family_member_discount_percent": 0,
"days_of_week": null,
"start_time": null,
"end_time": null,
"punches": 0,
"locations": null,
"returnable_container": false,
"returnable_container_price": null,
"returnable_content_price": null,
"returnable_empty_container_weight_percentage": null,
"taxable": true,
"perishable": false,
"category2": 1,
"category3": 1,
"supplier_id": 1,
"file_name": null,
"file_type": null,
"image_data": null
},
{
"id": 29,
"name": "1OZ Test",
"price": "10.0",
"barcode": "",
"peritem": 1,
"display_line1": "1OZ Test",
"display_line2": "",
"display_line3": "",
"display_line4": "",
"itemWeight": "1.0",
"ordered": null,
"minOrder": null,
"inStorage": null,
"onShelves": null,
"created_at": "2012-05-27T05:41:08.000-10:00",
"updated_at": "2014-12-13T15:22:25.000-10:00",
"display_line5": "",
"SKU_Item": "",
"price_units": "USD",
"ordered_units": "oz",
"cost": "3.0",
"boxQty": null,
"english_name": "",
"product_category_id": 1,
"is_service": false,
"period": 1,
"family_member_discount_percent": 0,
"days_of_week": null,
"start_time": null,
"end_time": null,
"punches": 0,
"locations": null,
"returnable_container": false,
"returnable_container_price": null,
"returnable_content_price": null,
"returnable_empty_container_weight_percentage": null,
"taxable": true,
"perishable": false,
"category2": 1,
"category3": 1,
"supplier_id": 1,
"file_name": null,
"file_type": null,
"image_data": null
}, …
]
This endpoint returns json data about all the defined products.
HTTP Request
GET [company_subdomain].xmanager.us/products
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
Product Categories |
---|
id |
name |
description |
Product Shelves |
---|
id |
fixture_name |
fixture_profile |
location_id |
fixture_description |
previous_location |
door_lock_type |
synced |
swiper |
outdoor |
Xcard Services
The Xcard application is accessible at Xcard.me
Actions on Customers
Through the Merchant API, it is possible to access, take actions and get information about the Xcard accounts of your customers. Your customers are defined as consumers (Xcard account holders) who have created their Xcard account on your Xcard site, i.e. yourdomain.xcard.me, conducted purchase transactions at any of your fixtures or who have Xcards that are associated with your merchant account. You are not able to access the accounts any other Xcard account holders (consumers).
The actions allowed to be performed on your customers are:
- Find customer_id by name, email address, xcard number, or phone number
- Add funds to a customer’s Xcard account
- Charge (or deduct funds from) a customer’s Xcard account
- Get the balance of a customer’s xcard account and a list of all of that customer transactions
- Create a new customer
- Update a customer
These actions are performed by Merchant services so the basic call syntax is:
https://[company_subdomain].xmanager.us/services/<action_name>?account_id=<merchant account id>&key=<account key>[&domain=<company domain>]&[xcard_account_id=<xcard_account_id>]&[<property 1=<property 1 value>>]*
The actions and associated parameters are:
Action Name | Parameters | Property Values |
---|---|---|
find_customer | ||
add_funds_to_customer | ||
charge_customer | ||
get_customer_transations (includes customer balance) | ||
create_customer |
Each of these actions returns a JSON object with a result. The following shows examples:
Find Customer
https://[company_subdomain].xmanager.us/services/find_customer/?key={{key}}&account_id={{account_id}}&domain={{domain}}&xcard_account_id={{xcard_account_id}}&find_customer_by=name&search_key=margalit
The above command returns JSON structured like this:
{
"result": "success",
"data": {
"result": "success",
"consumer_accounts": [
{
"first_name": "Aya",
"last_name": "Margalit",
"id": 39,
"email": "x"
},
{
"first_name": "Noga",
"last_name": "Margalit",
"id": 39,
"email": "x"
},
{
"first_name": "Ran",
"last_name": "Margalit",
"id": 171,
"email": "ran@shelfx.com"
},
{
"first_name": "dror",
"last_name": "margalit",
"id": 754,
"email": "drorm@me.com"
},
{
"first_name": "DROR",
"last_name": "MARGALIT",
"id": 1013,
"email": "card_5326120380933277@shelfx.com"
},
{
"first_name": "R",
"last_name": "MARGALIT",
"id": 1060,
"email": "card_371733930071003@shelfx.com"
}
]
}
}
Get Customer Transactions
https://[company_subdomain].xmanager.us/services/get_customer_transactions/?key={{key}}&account_id={{account_id}}&domain={{domain}}&xcard_account_id={{xcard_account_id}}
The above command returns JSON structured like this:
{
"result": "success",
"data": {
"result": "found",
"balance": "421.63",
"activity": [
{
"id": 67219,
"created_at": "2014-11-12T15:48:09Z",
"title": "Purchases",
"amount2": "-4.69",
"amount": "-4.69",
"location_name": "ShelfX Demo Room",
"product_name": "20lb Ice Bag",
"first_name": "Ran",
"item_price": "4.69",
"quantity": 1,
"total_item": "4.69",
"local_date": "2014-11-12T08:48:03Z"
},
{
"id": 66443,
"created_at": "2014-11-07T20:27:45Z",
"title": "Purchases",
"amount2": "-4.69",
"amount": "-4.69",
"location_name": "ShelfX Demo Room",
"product_name": "20lb Ice Bag",
"first_name": "Ran",
"item_price": "4.69",
"quantity": 1,
"total_item": "4.69",
"local_date": "2014-11-07T13:27:44Z"
}
]
}
}
Get Merchant Transactions
https://[company_subdomain].xmanager.us/services/get_merchant_transactions/?key={{key}}&account_id={{account_id}}&domain={{domain}}&merchant_id={{customer_id}}&start_date={{start_date}}&end_date={{end_date}}
The above command returns JSON structured like this:
{
"result": "success",
"data": {
"result": "found",
"balance": "421.63",
"activity": [
{
"id": 67219,
"created_at": "2014-11-12T15:48:09Z",
"title": "Purchases",
"amount2": "-4.69",
"amount": "-4.69",
"location_name": "ShelfX Demo Room",
"product_name": "20lb Ice Bag",
"first_name": "Ran",
"item_price": "4.69",
"quantity": 1,
"total_item": "4.69",
"local_date": "2014-11-12T08:48:03Z"
},
{
"id": 66443,
"created_at": "2014-11-07T20:27:45Z",
"title": "Purchases",
"amount2": "-4.69",
"amount": "-4.69",
"location_name": "ShelfX Demo Room",
"product_name": "20lb Ice Bag",
"first_name": "Ran",
"item_price": "4.69",
"quantity": 1,
"total_item": "4.69",
"local_date": "2014-11-07T13:27:44Z"
}
]
}
}
Add funds to customer
https://[company_subdomain].xmanager.us/services/add_funds_to_customer/?key={{key}}&account_id={{account_id}}&domain={{domain}}&xcard_account_id={{xcard_account_id}}&credit_amount=1.25
The above command returns JSON structured like this:
{
"result": "success",
"data": {
"result": "success",
"message": "Transaction Successful"
}
}
Charge customer
https://[company_subdomain].xmanager.us/services/charge_customer/?key={{key}}&account_id={{account_id}}&domain={{domain}}&xcard_account_id={{xcard_account_id}}&charge_amount=1.25
The above command returns JSON structured like this:
{
"result": "success",
"data": {
"result": "success",
"message": "Transaction Successful"
}
}
Create customer
POST https://xmanager.us/services/create_customer/?account_id={{account_id}}&key={{key}}&domain={{domain}}&xcard_account_id={{xcard_account_id}}&xcard_number=17161K
The message body should contain the following
{ "customer": {"first_name":"{customer first name}", "last_name":"{customer last name}", "email":"{customer email address}", "xcard_password": "{{xcard number}}", "locale": "us-en"} }
The Xcard Number is an optional parameter in the customer json. The Xcard can be added to the account by the customer at a later time.
The customer receives a welcome email as shown below:
Thank you for activating your ShelfX card. We look forward to having you shop at our locations.
ShelfX
{
"result": "success",
"account_id": 26415,
"rfid_device_id": null
}
or
{
"result": "xcard already in use",
"error": null
}
or
{
"result": "account already exists",
"error": null
}
Update customer
POST https://xmanager.us/services/update_customer/?account_id={{account_id}}&key={{key}}&domain={{domain}}&xcard_account_id={{xcard_account_id}}
The message body should contain the following
{ "customer": {“id”: {customer_id}}, "first_name":"{new customer first name}", "last_name":"{new customer last name}", "email":"{new customer email address}" }
{
"result": "success"
}
Configuration API: Xconfig
The Configuration API allows programmatic access to the ShelfX Configuration application at yourdomain.[company_subdomain].shelfx.com.
List of Objects
- Location
- Fixture
- Device
- Shelf
- Employee
Examining the API
Use a tool like POSTMAN REST client to examine the ShelfX API. There’s also a POSTAMAN Chrome plugin available at the Google Chome webstore. When using this tool, set headers for “content-type” and “accept” to application/json.
The API will be described by examples.
API Call Structure
The basic structure of a call is as follows:
https://[your_domain].shelfx.com/<object name>?account_id=<account id>>&key=<account key>&[<property 1=<property 1 value>>[&]]*&list=true
[your_domain] is your company id.
Properties of Objects
Each configuration object has a set of properties which can be read or set using HTTP Get and Patch operations respectively.
Get locations
curl "https://demo.shelfx.com/locations/?account_id={{account_id}}&key={{account_key}}"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 24,
"name": "7-11",
"address": "",
"address2": "",
"city": "",
"state": "AK",
"zipcode": "",
"country": "United States",
"created_at": "2013-10-24T22:17:42.000-05:00",
"updated_at": "2013-10-24T22:17:42.000-05:00",
"contact_name": "",
"phone_number": "",
"store_phone": null,
"contact_mobile": "",
"contact_email": "",
"store_group": null,
"shelf_loc_style": null,
"city_tax": "0.0",
"state_tax": "0.0",
"other_tax": "0.0",
"group_id": 1,
"description": "",
"active_payment": null,
"active_login": null,
"default_language_id": 1,
"ssid": "",
"password": "",
"deleted": false,
"time_zone": "Hawaii",
"latitude": null,
"longitude": null,
"notes": "",
"test_mode": false,
"sales_tax": "0.0",
"send_alerts_to_email": "support@shelfx.com",
"allow10bis": false,
"this_is_a_warehouse": false,
"warehouse_for_supplier_id": null
},
{
"id": 21,
"name": "Alco Designs",
"address": "407 E. Redondo Beach Blvd. ",
"address2": "",
"city": "Gardena",
"state": "CA",
"zipcode": "90248",
"country": "United States",
"created_at": "2013-08-19T15:28:41.000-05:00",
"updated_at": "2014-04-20T14:50:20.000-05:00",
"contact_name": "",
"phone_number": "",
"store_phone": null,
"contact_mobile": "",
"contact_email": "",
"store_group": null,
"shelf_loc_style": null,
"city_tax": "0.0",
"state_tax": "0.0",
"other_tax": "0.0",
"group_id": 1,
"description": "",
"active_payment": null,
"active_login": null,
"default_language_id": 1,
"ssid": "AlcoNet",
"password": "1234567890",
"deleted": false,
"time_zone": "Pacific Time (US & Canada)",
"latitude": null,
"longitude": null,
"notes": "",
"test_mode": false,
"sales_tax": "0.0",
"send_alerts_to_email": "support@shelfx.com",
"allow10bis": false,
"this_is_a_warehouse": false,
"warehouse_for_supplier_id": null
},
{
"id": 27,
"name": "Alco Designs Fridge",
"address": "",
"address2": "",
"city": "",
"state": "CA",
"zipcode": "",
"country": "United States",
"created_at": "2014-04-20T17:17:55.000-05:00",
"updated_at": "2014-04-20T17:17:55.000-05:00",
"contact_name": "",
"phone_number": "",
"store_phone": null,
"contact_mobile": "",
"contact_email": "",
"store_group": null,
"shelf_loc_style": null,
"city_tax": "0.0",
"state_tax": "0.0",
"other_tax": "0.0",
"group_id": 1,
"description": "",
"active_payment": null,
"active_login": null,
"default_language_id": 1,
"ssid": "",
"password": "",
"deleted": false,
"time_zone": "Pacific Time (US & Canada)",
"latitude": null,
"longitude": null,
"notes": "",
"test_mode": false,
"sales_tax": "0.0",
"send_alerts_to_email": "support@shelfx.com",
"allow10bis": false,
"this_is_a_warehouse": false,
"warehouse_for_supplier_id": null
}, …
HTTP Request
GET https://demo.shelfx.com/locations/?account_id={{account_id}}&key={{account_key}}
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
Get fixtures
curl "https://demo.shelfx.com/fixtures?key={{account_key}}&account_id={{account_id}}"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 55,
"fixture_name": "Propane Tank Cabinet",
"fixture_profile_id": 1,
"location_id": 21,
"fixture_description": "",
"created_at": "2013-08-19T20:29:18.000Z",
"updated_at": "2014-04-21T23:34:53.000Z",
"previous_location_id": null,
"door_lock_type": 2,
"synced": true,
"swiper": 2,
"outdoor": false,
"cellular": false,
"magtek": 1,
"test_mode": false,
"is_out_of_service": false,
"out_of_service_note": null,
"take_first_pay_after": false,
"scanning": false,
"lock_sensor_position": 0
},
{
"id": 69,
"fixture_name": "Fixture",
"fixture_profile_id": 1,
"location_id": 21,
"fixture_description": null,
"created_at": "2014-09-12T17:08:22.000Z",
"updated_at": "2014-09-12T17:08:22.000Z",
"previous_location_id": null,
"door_lock_type": 3,
"synced": null,
"swiper": 2,
"outdoor": false,
"cellular": false,
"magtek": 0,
"test_mode": false,
"is_out_of_service": false,
"out_of_service_note": null,
"take_first_pay_after": false,
"scanning": false,
"lock_sensor_position": 0
}
]
HTTP Request
GET https://demo.shelfx.com/fixtures?key={{account_key}}&account_id={{account_id}}
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
Update fixture name
PATCH https://demo.shelfx.com/fixtures/55?key={{account_key}}&account_id={{account_id}}
Raw Data | Return |
---|---|
{ "fixture_name": "Candy" } | {} (malformed JSON) |
Get all fixture profiles
curl "https://demo.shelfx.com/fixture_profiles?key={{account_key}}&account_id={{account_id}}"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 1,
"name": "Beverage Fridge",
"description": "Large Coke Refrigerator",
"low_funds_threshold": "20.0",
"close_temp_thresh": 4,
"close_if_overtemp": true,
"reopen_if_undertemp": true,
"created_at": "2012-10-13T21:30:23.000Z",
"updated_at": "2014-12-13T21:16:44.000Z",
"account_id": 11,
"start_time": "2000-01-01T00:00:00Z",
"end_time": "2000-01-01T00:00:00Z",
"authorize_full_value_fixture": false
},
{
"id": 2,
"name": "Shelves",
"description": "",
"low_funds_threshold": "5.0",
"close_temp_thresh": null,
"close_if_overtemp": false,
"reopen_if_undertemp": false,
"created_at": "2012-10-17T07:27:48.000Z",
"updated_at": "2013-07-23T17:19:43.000Z",
"account_id": 11,
"start_time": "2000-01-01T00:00:00Z",
"end_time": "2000-01-01T00:00:00Z",
"authorize_full_value_fixture": false
},
{
"id": 3,
"name": "Blood Fridge",
"description": "",
"low_funds_threshold": null,
"close_temp_thresh": null,
"close_if_overtemp": false,
"reopen_if_undertemp": false,
"created_at": "2012-10-31T22:13:40.000Z",
"updated_at": "2012-10-31T22:13:40.000Z",
"account_id": 11,
"start_time": "2000-01-01T00:00:00Z",
"end_time": "2000-01-01T00:00:00Z",
"authorize_full_value_fixture": false
},
{
"id": 4,
"name": "Ice Machine",
"description": "",
"low_funds_threshold": "5.0",
"close_temp_thresh": null,
"close_if_overtemp": false,
"reopen_if_undertemp": false,
"created_at": "2013-08-26T22:23:37.000Z",
"updated_at": "2013-08-26T22:23:37.000Z",
"account_id": 11,
"start_time": "2000-01-01T00:00:00Z",
"end_time": "2000-01-01T00:00:00Z",
"authorize_full_value_fixture": false
},
{
"id": 5,
"name": "Default",
"description": "",
"low_funds_threshold": "5.0",
"close_temp_thresh": null,
"close_if_overtemp": false,
"reopen_if_undertemp": false,
"created_at": "2013-11-26T21:07:44.000Z",
"updated_at": "2013-11-26T21:07:44.000Z",
"account_id": 1,
"start_time": "2000-01-01T00:00:00Z",
"end_time": "2000-01-01T00:00:00Z",
"authorize_full_value_fixture": false
}
]
HTTP Request
GET https://demo.shelfx.com/fixture_profiles?key={{account_key}}&account_id={{account_id}}
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
Get fixture profile
curl "https://demo.shelfx.com/fixture_profiles/1?key={{account_key}}&account_id={{account_id}}"
-H "Accept: application/json"
The above command returns JSON structured like this:
{
"id": 1,
"name": "Beverage Fridge",
"description": "Large Coke Refrigerator",
"low_funds_threshold": "20.0",
"close_temp_thresh": 4,
"close_if_overtemp": true,
"reopen_if_undertemp": true,
"created_at": "2012-10-13T16:30:23.000-05:00",
"updated_at": "2014-12-13T15:16:44.000-06:00",
"account_id": 11,
"start_time": "2000-01-01T00:00:00Z",
"end_time": "2000-01-01T00:00:00Z",
"authorize_full_value_fixture": false
}
HTTP Request
GET https://demo.shelfx.com/fixture_profiles/1?key={{account_key}}&account_id={{account_id}}
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
Update fixture profile
PATCH https://demo.shelfx.com/fixture_profiles/1?key={{account_key}}&account_id={{account_id}}&location_id=1
Raw Data | Return |
---|---|
{ "name": "Beer Fridge" } | {} (malformed JSON) |
Get all devices
Get all devices at Walmart (location_id=32)
curl "https://demo.shelfx.com/devices/?key={{account_key}}&account_id={{account_id}}&location_id=32"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 44,
"serial_number": 226,
"device_type": 1, (RDU)
"has_display": null,
"has_rfid_reader": null,
"has_weight_sensors": null,
"current_temprature": "34.18",
"template": 1,
"display_line_1": null,
"display_line_2": null,
"display_line_3": null,
"display_line_4": null,
"display_line_5": null,
"has_door_lock": true,
"fixture_id": 11,
"created_at": "2012-12-26T02:28:29.000-06:00",
"updated_at": "2014-10-22T15:30:01.000-05:00",
"xbee": null,
"rfid_device_id": null,
"lastMessage": "226,700,,",
"buzzer": false,
"force_nfc": false,
"door_open": null,
"code_base": 5,
"emailed": true,
"current_temprature2": "0.0",
"auto_offset": false,
"power_reset_if_dead": false
},
{
"id": 45,
"serial_number": 188,
"device_type": 2, (SCU)
"has_display": null,
"has_rfid_reader": null,
"has_weight_sensors": null,
"current_temprature": "26.93",
"template": 1,
"display_line_1": null,
"display_line_2": null,
"display_line_3": null,
"display_line_4": null,
"display_line_5": null,
"has_door_lock": true,
"fixture_id": 11,
"created_at": "2012-12-26T02:30:04.000-06:00",
"updated_at": "2014-10-22T15:30:01.000-05:00",
"xbee": null,
"rfid_device_id": null,
"lastMessage": "188,700,,",
"buzzer": false,
"force_nfc": false,
"door_open": null,
"code_base": 5,
"emailed": true,
"current_temprature2": "24.93",
"auto_offset": false,
"power_reset_if_dead": false
}
]
HTTP Request
GET https://demo.shelfx.com/devices/?key={{account_key}}&account_id={{account_id}}&location_id=32
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
location_id | integer |
Get all shelves
Get all shelves in fixture that are associated with a given RDU
curl "https://demo.shelfx.com/shelves?account_id={{account_id}}&key={{account_key}}"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 1,
"product_id": null,
"department_id": null,
"isle": null,
"side": null,
"feet_in": null,
"feet_height": null,
"created_at": "2016-01-11T23:23:08.000+11:00",
"updated_at": "2016-02-23T10:58:25.000+11:00",
"shelf_type": "1",
"askedToRemoveOrPutback": null,
"lastValidWeight": 291,
"row": "A",
"s_column": "1",
"shelf_name": null,
"port": 1,
"device_id": 2,
"weight": 291,
"reader_id": 1,
"display_id": 1,
"tare": 142,
"pound": 377,
"fixture_id": 1,
"sensor_offset": 128,
"sensor_gain": 9,
"item_electronic_weight": 142,
"on_shelf_qty": 0,
"last_weight": 291,
"shelf_type_2": 4,
"offSessionChanges": 0,
"got_it": true,
"got_it_value": 0
},
{
"id": 2,
"product_id": null,
"department_id": null,
"isle": null,
"side": null,
"feet_in": null,
"feet_height": null,
"created_at": "2016-01-11T23:23:08.000+11:00",
"updated_at": "2016-02-23T11:02:26.000+11:00",
"shelf_type": "1",
"askedToRemoveOrPutback": null,
"lastValidWeight": 375,
"row": "A",
"s_column": "2",
"shelf_name": null,
"port": 2,
"device_id": 2,
"weight": 375,
"reader_id": 1,
"display_id": 1,
"tare": 177,
"pound": 311,
"fixture_id": 1,
"sensor_offset": 128,
"sensor_gain": 5,
"item_electronic_weight": 34,
"on_shelf_qty": 0,
"last_weight": 375,
"shelf_type_2": 4,
"offSessionChanges": 0,
"got_it": true,
"got_it_value": 0
},
...{
"id": 16,
"product_id": null,
"department_id": null,
"isle": null,
"side": null,
"feet_in": null,
"feet_height": null,
"created_at": "2016-01-11T23:23:09.000+11:00",
"updated_at": "2016-01-23T04:07:35.000+11:00",
"shelf_type": "1",
"askedToRemoveOrPutback": null,
"lastValidWeight": 0,
"row": "D",
"s_column": "4",
"shelf_name": null,
"port": 16,
"device_id": 2,
"weight": 0,
"reader_id": 1,
"display_id": 1,
"tare": 0,
"pound": 40,
"fixture_id": 1,
"sensor_offset": 130,
"sensor_gain": 5,
"item_electronic_weight": 20,
"on_shelf_qty": 0,
"last_weight": 0,
"shelf_type_2": 4,
"offSessionChanges": 0,
"got_it": true,
"got_it_value": 0
}
]
HTTP Request
GET https://demo.shelfx.com/shelves?account_id={{account_id}}&key={{account_key}}
Required Parameters
Parameter | Type |
---|---|
account_id | integer |
key | string |
Employees
Parameter | Description |
---|---|
id | object identifier |
person_id | the identifier of the person who is the employee. |
first_name | The employee’s first name. |
last_name | The employee’s last name. |
xcard_number | The employee’s Xcard number |
employee_type_id | The identifier of the employee type assigned to this employee. |
employee_id | Arbitrary string for use in identifying the employee within the company. |
account_id | identifier of the merchant account which the employee has fixture access. |
address | employee business address - not used |
address2 | employee business address line 2 - not used |
city | employee business address city - not used |
state | employee business address state - not used |
country | employee business address country - not used |
zip | employee business address zip code - not used |
contact_phone | employee contact phone - not used |
Configuration Services API
There are some miscellaneous services accessible through the configuration manager.
Unlock_Door
The unlock_door call will cause the fridge to unlock it’s door.
https://[company_subdomain].shelfx.com/services/unlock_door?account_id=<account id>>&key=<account key>&domain=<company domain>&serial=<scu serial number>
Xcard API: Consumer Accounts
You must first login to the consumer’s Xcard account using the account’s email address and password. After a successful login, a login key is returned that must be passed to subsequent operations.
Login Call
curl -H "Content-Type:application/json" -H "Accept:application/json" -d "{}"https://[company_subdomain].xcard.me/sessions/create?name={{xcard_account_email}}\&password={{xcard_account_password}}
{
"login_key": "d9d1c56b-824a-4e45-ae49-20d1da03763b"
}
HTTP Request
POST https://[company_subdomain].xcard.me/sessions/create?name={{xcard_account_email}}&password={{xcard_account_password}}
Required Parameters
Parameter | Type |
---|---|
xcard_account_email | string |
xcard_account_password | string |
List Credit Cards
[{
"id": 59059,
"card_number": "XXXXXXXXXXXXXX",
"full_string": null,
"relate_to_card": null,
"account_id": 221328,
"person_id": null,
"created_at": "2018-03-03T19:14:04.000Z",
"updated_at": "2018-07-05T14:03:17.000Z",
"expires": "04-2022",
"name_on_card": "vishal agrawal",
"cvv": "000",
"billing_address": "",
"country": "",
"city": "",
"state": "",
"zip": "",
"card_type": "1",
"default_card": true,
"nickname": null,
"processing": false,
"declined": false,
"consumer_card_type_id": null,
"vault_key": null,
"processor_id": null,
"short_card_number": "5105.....5100",
"last_user_id": null,
"enc_card_number": "Wj91dMQKy98",
"des_card_number": null,
"substitute": null,
"bic": null,
"payload": null
}]
HTTP Request
GET https://[company_subdomain].xcard.me/consumer_credit_cards?login_key={{login_key}}
curl -H "Accept:application/json" https://[company_subdomain].xcard.me/consumer_credit_cards?login_key={{login-key}}
Required Parameters
Parameter | Type |
---|---|
login_key | string |
Update Credit Card
curl -X PATCH -H "Content-Type:application/json" -H "Accept:application/json" -d "{\"consumer_credit_card\":{\"card_number\": \"4444444444444444\",\"name_on_card\": \"Ran Margalit\",\"expires\" : \"04-2023\",\"cvv\":\"123\"}}" https://[company_subdomain].xcard.me/consumer_credit_cards/{{id}}?login_key={{login_key}}
#Request
{
"consumer_credit_card":
{
"card_number": "4444444444444444",
"name_on_card": "Ran Margalit",
"expires" : "04-2023",
"cvv":"123"
}
}
}
#Response
{
"error":"Number is not a valid credit card number"
}
or
{
"result":"OK"
}
HTTP Request
POST https://[company_subdomain].xcard.me/sessions/create?name={{xcard_account_email}}&password={{xcard_account_password}}
Required Parameters
Parameter | Type |
---|---|
card_number | string |
name_on_card | string |
expires | string |
cvv | string |
Add Funds
curl -H "Content-Type:application/json" -H "Accept:application/json" -d "{\"payment_method\": \"{{id}}\",\"custom_amount\": \"5.00\" }" https://[company_subdomain].xcard.me/add_funds/add_amount/?login_key={{login_key}}
#Response
{
"status":"error",
"message":"The card was declined."
}
or
{
"status":"OK"
}
HTTP Request
POST https://[company_subdomain].xcard.me/add_funds/add_amount/?login_key={{login_key}}
Required Parameters
Parameter | Type |
---|---|
payment_method (card id) | string |
custom_amount | decimal |
Open Door
curl -H "Content-Type:application/json" -H "Accept:application/json" -d "{\"serial\": \"{{machine_serial}}\" }" https://[company_subdomain].xcard.me/vend/open/?login_key={{login_key}}
#Response
{
"result":"Fixture is offline"
}
or
{
"result":"Door is Unlocked"
}
HTTP Request
POST https://[company_subdomain].xcard.me/vend/open/?login_key={{login_key}}
Required Parameters
Parameter | Type |
---|---|
serial (serial number) | string |
Get Activity Report
curl "https://[company_subdomain].xcard.me/carts?login_key=d9d1c56b-824a-4e45-ae49-20d1da03763b"
-H "Accept: application/json"
The above command returns JSON structured like this:
{
"carts": [
{
"id": 193552,
"cname": "Walmart Innovation Lab",
"created_at": "2016-04-27T18:27:29Z",
"title": "Purchases",
"amount2": "-1.99",
"amount": "-1.99",
"location_name": "ShelfX Office",
"product_name": "Granola Bar",
"first_name": "Andrew",
"item_price": "1.99",
"quantity": 1,
"total_item": "1.99",
"tax": "0.0",
"local_date": "2016-04-27T11:27:29Z",
"transaction_type_id": 2,
"invoice_number": null
},
{
"id": 86398,
"cname": "Walmart Innovation Lab",
"created_at": "2015-02-11T22:35:35Z",
"title": "Purchases",
"amount2": "-0.75",
"amount": "-2.74",
"location_name": "ShelfX Office",
"product_name": "Orange Soda",
"first_name": "Andrew",
"item_price": "0.75",
"quantity": 1,
"total_item": "0.75",
"tax": "0.0",
"local_date": "2015-02-11T15:35:35Z",
"transaction_type_id": 2,
"invoice_number": null
},
{
"id": 86397,
"cname": "Walmart Innovation Lab",
"created_at": "2015-02-11T22:35:35Z",
"title": "Purchases",
"amount2": "-1.99",
"amount": "-2.74",
"location_name": "ShelfX Office",
"product_name": "Maruchan Instant Lunch-- Beef",
"first_name": "Andrew",
"item_price": "1.99",
"quantity": 1,
"total_item": "1.99",
"tax": "0.0",
"local_date": "2015-02-11T15:35:35Z",
"transaction_type_id": 2,
"invoice_number": null
},
{
"id": null,
"cname": null,
"created_at": "2014-05-13T16:24:36Z",
"title": "Add Funds",
"amount2": null,
"amount": "25.0",
"location_name": null,
"product_name": null,
"first_name": null,
"item_price": null,
"quantity": null,
"total_item": null,
"tax": null,
"local_date": "2014-05-13T09:24:36Z",
"transaction_type_id": 1,
"invoice_number": null
},
{
"id": null,
"cname": null,
"created_at": "2013-04-22T16:02:06Z",
"title": "Add Funds",
"amount2": null,
"amount": "12.0",
"location_name": null,
"product_name": null,
"first_name": null,
"item_price": null,
"quantity": null,
"total_item": null,
"tax": null,
"local_date": "2013-04-22T09:02:06Z",
"transaction_type_id": 1,
"invoice_number": null
}
]
}
HTTP Request
GET https://[company_subdomain].xcard.me/carts?login_key=d9d1c56b-824a-4e45-ae49-20d1da03763b
Required Parameters
Parameter | Type |
---|---|
login_key | string |
Get Payment Methods
curl "https://[company_subdomain].xcard.me/consumer_credit_cards?login_key=d9d1c56b-824a-4e45-ae49-20d1da03763b"
-H "Accept: application/json"
The above command returns JSON structured like this:
[
{
"id": 21,
"card_number": "",
"full_string": null,
"relate_to_card": null,
"account_id": 27,
"person_id": null,
"created_at": "2012-10-13T16:12:20.000-04:00",
"updated_at": "2014-05-13T12:23:13.000-04:00",
"expires": "02-2014",
"name_on_card": "Andrew D. Franklin",
"cvv": "555",
"billing_address": "3761 Moffit Ct.",
"country": "United States",
"city": "Boulder",
"state": "CO",
"zip": "80304",
"card_type": "VISA",
"default_card": false,
"nickname": "Cobwebs Visa",
"processing": false,
"declined": true,
"consumer_card_type_id": null,
"vault_key": null,
"processor_id": 1,
"short_card_number": null,
"last_user_id": null,
"enc_card_number": null,
"des_card_number": "˖"
},
{
"id": 3285,
"card_number": "",
"full_string": null,
"relate_to_card": null,
"account_id": 27,
"person_id": null,
"created_at": "2014-05-13T12:23:13.000-04:00",
"updated_at": "2016-07-20T21:26:48.000-04:00",
"expires": "07-2018",
"name_on_card": "Andrew Franklin",
"cvv": "842",
"billing_address": "3761 Moffit Ct.",
"country": "",
"city": "Boulder",
"state": "CO",
"zip": "80304",
"card_type": null,
"default_card": false,
"nickname": "Mileage Plus Explorer",
"processing": false,
"declined": false,
"consumer_card_type_id": null,
"vault_key": null,
"processor_id": 1,
"short_card_number": "42..8227",
"last_user_id": null,
"enc_card_number": "VpE3OGlrG2W",
"des_card_number": ""
}
]
HTTP Request
GET https://[company_subdomain].xcard.me/consumer_credit_cards?login_key=d9d1c56b-824a-4e45-ae49-20d1da03763b
Required Parameters
Parameter | Type |
---|---|
login_key | string |
Get Consumer Profile
curl "https://[company_subdomain].xcard.me/accounts/0?login_key=d9d1c56b-824a-4e45-ae49-20d1da03763b"
-H "Accept: application/json"
The above command returns JSON structured like this:
{
"account": {
"id": 27,
"user_name": "adfranklin49@gmail.com",
"hashed_password": null,
"salt": null,
"email": "adfranklin49@gmail.com",
"created_at": "2012-08-27T12:10:14.000-05:00",
"updated_at": "2016-08-14T10:44:42.000-05:00",
"account_type": null,
"secret_question": null,
"answer": null,
"employee_id": 4,
"first_name": "Andrew",
"last_name": "Franklin",
"reset_temp_password": false,
"master_customer_id": 107,
"accepted_tosa_ver": "3.0",
"effective_date": "2013-01-14T21:47:22.000-06:00",
"active": true,
"temp_hashed_password": null,
"temp_salt": null,
"login_with_temp": false,
"last_user_id": null,
"guarantor_id": null,
"guarantor_employee_id": null,
"guarantor_badge_info": null,
"locale": "en-us",
"cpf": null,
"login_key": "d9d1c56b-824a-4e45-ae49-20d1da03763b",
"dob": "1949-08-23",
"gender": "m",
"access_code": null,
"enabled_fingerprint": false,
"fingerDataISO": null,
"fingerDataMIN": null,
"fingerDataANSI": null
},
"consumer_account": {
"id": 8,
"account_id": 27,
"address": "3761 Moffit Court",
"address2": "",
"city": "Boulder",
"state": "CO",
"zip": "80305",
"country": 0,
"email": "adfranklin49@gmail.com",
"cell_phone": "303-810-3809",
"home_phone": null,
"balance": "107.27",
"created_at": "2012-08-27T12:10:14.000-05:00",
"updated_at": "2016-08-03T22:31:25.000-05:00",
"got_five": false,
"autoload": true,
"last_autoload_date": null,
"autoload_amount": 25,
"get_email_receipt": true,
"last_user_id": null,
"auth_amount": "0.0",
"auth_transaction_id": null,
"guarantor_code": null,
"payroll_deduction_total": "0.0",
"allowance": "0.0",
"allowance_time": 0,
"account_allowance": "0.0"
}
}
HTTP Request
GET https://[company_subdomain].xcard.me/accounts/0?login_key=d9d1c56b-824a-4e45-ae49-20d1da03763b
Required Parameters
Parameter | Type |
---|---|
login_key | string |
Events API
The ShelfX system uses the Redis Pub/Sub messaging system to distribute certain types of system events. A Redis client can subscribe to receive certain classes of events and those events will be sent to the Redis client when they occur.
Sample Code
The following code sample is used for illustrative purposes only. It should not be taken too literally, but can guide a developer in writing their own Java code to access the ShelfX API.
//Example Code to Get Shelf Inventory in a Fixture
package src.com.shelfx;
import java.util.Arrays;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
public class SampleCode {
public static void main(String[] args) throws Exception {
HttpParams httpParameters = new BasicHttpParams();
//Dcom.sun.net.ssl.checkRevocation=false
// Set the timeout in milliseconds until a connection is
// established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 30000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 30000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
try {
String url = "https://[company_subdomain].shelfx.com";
url += "/shelves/?location_id=4&account_id=11&key=cdc0756f978173c09a4f8e46949a5a28aed7990bead17abdff2747f24b7c81ff";
url+="&domain=demo";
HttpGet request = new HttpGet(url);
// request.addHeader("X",action);
request.addHeader("accept", "application/json");
HttpResponse httpResponse = httpClient.execute(request);
int code = httpResponse.getStatusLine().getStatusCode();
// Put back in list if http error
if (code == 200) {
//
System.err.println(httpResponse.getStatusLine().toString());
HttpEntity entity = httpResponse.getEntity();
String m = EntityUtils.toString(entity);
System.err.println(m);
} else {
// error?
System.err.println(httpResponse.getStatusLine().toString());
}
// handle response here...
} catch (Exception e) {
System.err.println("Sample Code:" + e.getMessage());
System.err.println("\n2");
System.err.println(e.getMessage());
System.err.println("\n3");
System.err.println(e.getLocalizedMessage());
System.err.println("\n4");
System.err.println(e.getCause());
System.err.println("\n5");
System.err.println(Arrays.toString(e.getStackTrace()));
System.err.println("\n6");
e.printStackTrace();
// handle exception here
} finally {
httpClient.getConnectionManager().shutdown();
}
}
}
Using HttpClient 4.3.3 library:
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This example demonstrates the use of the {@link ResponseHandler} to simplify
* the process of processing the HTTP response and releasing associated resources.
*/
public class APITester {
public final static void main(String[] args) throws Exception {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
String url = "https://[company_subdomain].shelfx.com";
url += "/shelves/?location_id=4&account_id=11&key=cdc0756f978173c09a4f8e46949a5a28aed7990bead17abdff2747f24b7c81ff";
url+="&domain=demo";
// Get shelf inventory for fixture with Carino device_id = 44
//System.out.println("Getting inventory for demo fixture with Carino 44");
url+="&device_id=44&serial=true"; // device_id is the Carino, serial=true means to return all shelves information
HttpGet httpget = new HttpGet(url);
httpget.addHeader("accept", "application/json");
System.out.println("Executing request " + httpget.getRequestLine());
// Create a custom response handler
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
public String handleResponse(
final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} else {
throw new ClientProtocolException("Unexpected response status: " + status);
}
}
};
String responseBody = httpclient.execute(httpget, responseHandler);
System.out.println("----------------------------------------");
System.out.println(responseBody);
// handle response here...
try {
JSONArray shelvesInfo = new JSONArray(responseBody);
for (int i = 0; i < shelvesInfo.length(); i++) {
JSONObject shelfInfo = shelvesInfo.getJSONObject(i);
System.out.printf("Shelf: %s%d\t", shelfInfo.getString("row"), shelfInfo.getInt("s_column"));
System.out.printf("Product: %20s\t", shelfInfo.getString("name"));
System.out.printf("Quantity on Shelf: %d%n", shelfInfo.getInt("on_shelf_qty"));
}
} catch (JSONException e) {
} finally {
}
} finally {
httpclient.close();
}
}
}
Errors
The ShelfX API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong. |
404 | Not Found -- The specified request could not be found. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |