Heartland Retail provides a full-featured REST API to users. The API can be used to fetch data, integrate with other products, or build custom applications on top of the POS.
All URL paths are relative to an account-specific subdomain: https://{{subdomain}}.retail.heartland.us/api/
Have a suggestion for a correction or improvement to our API docs? Please open an issue on GitHub.
Here are some client libraries to make interacting with our API easier:
Don't see your language? You can still interact with our API using a general purpose HTTP library.
Want your client library listed here? Open an issue on GitHub.
Heartland Retail provides limited API support for software developers.
Before submitting a support request, please ensure you have inspected the response body from your request to see if any details were returned that may point you towards the underlying issue. We also recommend checking your request body against the API documentation to ensure all values are filled out as required by that endpoint.
If you are unable to self-service your issue, you can submit a support request
OAuth2 is a protocol that lets external applications request authorization to private details in a user's Heartland Retail account without getting their password. OAuth tokens can be limited to specific data (see Scopes), and can be revoked by users at any time. You'll need to register your application before getting started.
A registered app is assigned a unique Client ID and Client Secret which will be used in the OAuth flow. The Client Secret should not be shared.
To register your application please submit a request.
Redirect the user to to this URL to request access to their Heartland Retail account on your behalf:
https://retail.heartland.us/oauth/authorize
The following values should be passed as query string parameters:
Name | Type | Description |
---|---|---|
client_id | String | Required. The client ID you received from Heartland Retail when you registered. |
scope | String | Required. A space delimited list of requested permissions. See Scopes. |
redirect_uri | String | Required. The URL in your app where users will be sent after authorization. |
state | String | Random string to be passed back upon completion. It is used to protect against cross-site request forgery attacks. |
If the user authorizes your app, Heartland Retail will redirect back to your specified redirect_uri
with a temporary code in a code GET parameter, as well as a state
parameter if you provided one in the previous step. If the states don't match, the request may have been created by a third party and you should abort the process.
Exchange this for an access token:
GET https://retail.heartland.us/api/oauth/token
Name | Type | Description |
---|---|---|
client_id | String | Required. The client ID you received from Heartland Retail when you registered. |
client_secret | String | Required. The client secret you received from Heartland Retail when you registered. |
code | String | Required. The code you received as a response to Step 1 |
grant_type | String | Required. The grant type of this flow is authorization_code |
redirect_uri | String | Required. The URL you passed in Step 1 |
You'll receive a JSON response containing an access_token
:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
"token_type": "bearer"
}
Interaction with the Heartland Retail API is always done through a hostname particular to each company's account. After receiving the access_token
for the account you need to perform a one time lookup of the account's hostname.
To receive the account's host send a request with the received access_token
to the following URL:
GET https://retail.heartland.us/api/system/host
Authorize: Bearer {{ access_token }}
Response:
{"host": "example.retail.heartland.us"}
This host
value should be used to construct the base URL for future API calls for that Heartland Retail account.
The access token allows you to make requests to the API on a behalf of a user. All requests must be performed using the host
retrieved from the previous step.
GET https://{{ host }}/api/system/whoami
Authorize: Bearer {{ access_token }}
Name | Description |
---|---|
cash_drawer.close |
Close cash drawer |
cash_drawer.manage |
Manage cash drawers |
cash_drawer.open |
Open cash drawer |
cash_paid.create |
Create cash paid out/in transactions |
cash_paid.read |
View cash paid out/in history |
custom_field.manage |
Manage custom fields |
customer.export |
Export customers |
customer.manage |
Create and manage customers |
customer.merge |
Merge customers |
customer.read |
View customers |
financial.event.read |
View financial events |
financial.manage |
Manage financial configuration |
gift_card.manage |
Manage gift cards and adjust balances |
grid_templates.manage |
Manage grid templates |
integrations.manage |
Manage integrations |
inventory.adjustment.manage |
Manage adjustments |
inventory.adjustment.read |
View adjustments |
inventory.bin.manage |
Update bin locations |
inventory.counts.create |
Create physical counts |
inventory.counts.finalize |
Review discrepancies and accept physical counts |
inventory.counts.acknowledge_discrepancies |
Acknowledge discrepant counts |
inventory.threshold.manage |
Edit item reorder points and target quantity |
inventory.transaction.read |
View inventory history |
inventory.transfer.read |
View transfers |
inventory.transfer.recall_shipment |
Recall transfer shipments |
inventory.transfer.receive |
Receive transfers |
inventory.transfer.resolve_discrepancies |
Resolve transfer discrepancies |
inventory.transfer.select_from_shipment |
Select receipt items from transfer shipment |
inventory.transfer.ship |
Ship transfers |
inventory.values.read |
View current inventory values |
inventory.vendor.read |
View inventory vendor information |
item.create_on_fly |
Create items on the fly |
item.export |
Export items |
item.manage |
Manage items and grids |
item.merge |
Merge items |
item.view_cost |
View item cost and margin information |
location.manage |
Manage locations |
location.read |
View locations |
payment.manage |
Manage payments |
payment.read |
View payments |
payment_type.manage |
Manage payment types |
pos.manage |
Manage POS settings |
purchasing.order.manage |
Manage orders |
purchasing.order.read.canceled |
View canceled orders |
purchasing.order.read.closed |
View closed orders |
purchasing.order.read.open |
View open orders |
purchasing.order.read.pending |
View pending orders |
purchasing.order.read |
View all orders |
purchasing.receipt.manage |
Manage receipts |
purchasing.receipt.read |
View receipts |
purchasing.receipt.select_from_order |
Select receipt items from purchase order |
purchasing.receipt.acknowledge_unauthorized_quantities |
Acknowledge unauthorized receipt quantities |
purchasing.return.manage |
Manage returns |
purchasing.return.read |
View returns |
purchasing.vendor.manage |
Manage vendors |
purchasing.vendor.read |
View vendors |
reason_codes.manage |
Manage reason codes |
reporting.modify |
Reporting Analysis |
reporting.read.group.custom_payment |
Group reports by custom payment type |
reporting.read.group.customer |
Group reports by customer |
reporting.read.group.date |
Group reports by date |
reporting.read.group.gift_card |
Group reports by gift card payments |
reporting.read.group.inventory_adjustment |
Group reports by inventory adjustment reason |
reporting.read.group.inventory_transfer |
Group reports by inventory transfer |
reporting.read.group.item |
Group reports by item |
reporting.read.group.location |
Group reports by location |
reporting.read.group.payment |
Group reports by payment type |
reporting.read.group.promotion_name |
Group reports by promotion name |
reporting.read.group.purchasing |
Group reports by purchase order |
reporting.read.group.sales_transaction |
Group reports by sales transaction |
reporting.read.group.tax_rule |
Group reports by tax rule |
reporting.read.group.time |
Group reports by time |
reporting.read.group.vendor |
Group reports by vendor |
reporting.read.group |
Group reports |
reporting.read.metric.beginning_gift_card |
View beginning gift card balances |
reporting.read.metric.beginning_inventory |
View beginning inventory values |
reporting.read.metric.current_inventory |
View current inventory values |
reporting.read.metric.ending_gift_card |
View ending gift card balances |
reporting.read.metric.ending_inventory |
View ending inventory values |
reporting.read.metric.gift_cards_expired |
View gift card expirations |
reporting.read.metric.inventory_adjustment |
View inventory adjustment metrics |
reporting.read.metric.inventory_transfer |
View transfer metrics |
reporting.read.metric.location_sales_gift_cards |
View location sales gift cards issued metrics |
reporting.read.metric.location_sales |
View location sales metrics |
reporting.read.metric.payment |
View payment type metrics |
reporting.read.metric.purchasing |
View purchasing metrics |
reporting.read.metric.sales_tax |
View sales tax metrics |
reporting.read.metric.shipping |
View shipping metrics |
reporting.read.metric.source_sales_gift_cards |
View source sales gift cards issued metrics |
reporting.read.metric.source_sales |
View source sales metrics |
reporting.read.metric |
Group by metric |
reporting.read |
View reporting |
reporting.sales.read |
Read sales dashboard reports |
reporting.saved_reports.manage |
Manage Saved Reports |
reporting.saved_reports.read |
View Saved Reports |
role.manage |
Manage roles |
sales.coupons.manage |
Manage coupons |
sales.coupons.read |
View and redeem coupons |
sales.daily_summary.read |
View Daily Summary |
sales.invoice.manage |
Create and fulfill invoices from sales orders |
sales.order.adjust_item_price |
Adjust item prices on a sales order |
sales.order.distribute |
Distribute sales orders |
sales.order.edit |
Create and edit sales orders |
sales.order.manage |
Manage sales orders |
sales.order.view |
View sales orders |
sales.pos.adjust_tax_amount |
Adjust tax amount in the POS |
sales.promotions.manage |
Manage promotions |
sales.tax.manage |
Manage sales tax |
sales.ticket.manage |
Manage POS tickets |
sales.transaction.adjust_item_price |
Adjust item prices in the POS |
sales_plans.manage |
Manage sales plans |
setting.manage |
Manage general settings |
shipping_method.manage |
Manage shipping methods |
station.manage |
Manage stations |
user.manage |
Manage users |
ui_extensions.manage |
Manage UI extensions |
webhooks.manage |
Manage Webhooks |
pos_pre_complete_webhooks.manage |
Add or remove POS Pre Complete Webhooks |
Accessing the Heartland Retail API requires a secret API token. You can manage your API keys in the API Tokens page. To access the API Tokens page in Heartland Retail click the name in the top right corner of the Heartland Retail dashboard. A drop down menu will open, you can now click "my account" to bring you to your account page. Then click "API" to bring you to API Tokens page.
Generating an API Token:
Each HTTP request to the API should include an Authorization header with the API token. Example:
curl -H "Authorization: Bearer {{token}}"
Permissions
Each user in Heartland Retail is assigned a role. These roles have configurable permissions. It is important to note that once you are authenticated your API calls will be limited to the set of actions allowed by your permissions.
If you are making API requests and getting 401 Unauthorized
responses you
may want to check your permissions via GET /api/system/whoami
require 'heartland-retail'
client = HeartlandRetail::Client.new(
'https://{{subdomain}}.retail.heartland.us/api',
token: '{{token}}'
)
curl -H "Authorization: Bearer {{token}}" "https://{{subdomain}}.retail.heartland.us/api/system/whoami"
true
{"id": 100001, "login": "login", "first_name": "", "last_name": ""}
Search results objects are simple wrappers around result sets that indicate the total number of records that match the request, the number of pages available, and an array containing the results for the current page.
There are two query parameters that alter how what is returned in via search results:
Collection resources can be filtered in several ways:
Full text queries perform fuzzy searching across all indexed text fields (which fields exactly varies by collection). Partial word matches are support from the beginning of a term.
/api/items?query=big+blue+thing
/api/items?query=startswi
Advanced filters use a JSON-encoded query language. This can be specified in one of two ways:
In each case the value is passed via the _filter
parameter or the shorthand ~
parameter. Both parameter names are equivalent.
Queries up to a certain level of complexity can be expressed directly as query string parameters. This is useful for constructing ad-hoc queries in a browser:
/api/items?~[price][$gt]=100&~[price][$lt]=200
Resulting pseudo-SQL:
(price > 100 AND price < 100)
For arbitrarily complex queries it is recommended that the filters be encoded as a JSON string.
Here is an example of a complex query using nested logical operators and multiple comparison operators:
JSON:
{
"$or": [
{"price": {"$gte": 10, "$lte": 20}},
{"price": 0},
{"$and": [
{"cost": 0},
{"updated_at": {"$gt": "2012-01-01"}}
]}
],
"active": true,
"tax_category": {"$in": ["c1", "c2", "c3"]}
}
URL-encoded:
/api/items?_filter[]=%7B%22$or%22:[%7B%22price%22:%7B%22$gte%22:10,%22$lte%22:20%7D%7D,%7B%22price%22:0%7D,%7B%22$and%22:[%7B%22cost%22:0%7D,%7B%22updated_at%22:%7B%22$gt%22:%222012-01-01%22%7D%7D]%7D],%22tax_category%22:%7B%22$in%22:[%22c1%22,%22c2%22,%22c3%22]%7D,%22active%22:true%7D
Resulting pseudo-SQL:
(
((price >= 10) AND (price <= 20))
OR (price = 0)
OR ((cost = 0) AND (updated_at > '2012-01-01'))
)
AND (tax_category IN ('c1', 'c2', 'c3'))
AND (active IS TRUE)
$eq
- Equals$neq
- Not equals$in
- In array$nin
- Not in array$gt
- Greater than$gte
- Greater than or equals$lt
- Less than$lte
- Less than or equals$like
- Like (see Like Queries)Like queries use *
as a wildcard. The wildcard character must be specified somewhere to get partial match behavior. If no wildcard is specified, $like
behaves as $eq
. Like queries are case insensitive.
/api/items?~[custom@color][$like]=blue*
/api/items?~[custom@color][$like]=*blue
/api/items?~[custom@color][$like]=*blue*
Logical operators can be arbitrarily nested.
$and
- Group array of nested expressions with logical AND$or
- Group array of nested expressions with logical ORCustom fields can be used in any filter expression with this syntax:
/api/items?~[custom@color]=blue
/api/items?~[custom@score][$gt]=100
Checking for null
or non-null
values can be done using the $eq
/$neq
operators and the JSON syntax:
{
"custom@category": {"$eq": null},
"description": {"$neq": null}
}
Resulting pseudo-SQL:
(custom@category IS NULL) AND (description IS NOT NULL)
To compare fields to other fields rather than literal values use a string with the field name wrapped in double curly-braces (e.g. {{field_name}}
).
{
"qty_shipped": {"$gt": "{{qty_received}}"}
}
Resulting pseudo-SQL:
(qty_shipped > qty_received)
It is possible to embed the contents of associated objects in an API response
using one or more _include[]
query string parameters.
For example, to retrieve an object that has a my_object_id
property (or any property ending in _id
), you can embed the
related my_object
data like this:
GET /api/some-resource/1234?_include[]=my_object
The response will look something like this:
{
"id": 1234,
"my_object_id": 5678,
"my_object": {
"id": 5678,
"description": "Object Description"
}
}
GET /api/reporting/analyzer
metrics[]
(required)An array of metrics to include in the output (see Metrics section). Must specify at least one.
groups[]
(optional)An array of dimension fields to group by (see Groups section).
start_date
(optional), end_date
(optional)An ISO 8601 formatted date string (date only, no time). This is used as the start/end date for any metric that has a date dimension.
sales.filters
, item.filters
, location.filters
(optional)A JSON filter expression (see Filtering doc for syntax) to filter the item, location, or sale records to include when computing metrics.
subtotal
(optional, default: false)If set to true
, the response will include rows for subtotals at each grouping level (see groups[]
). Setting to true
without specifying any groups[]
will result in an error.
Each result object will include an additional subtotal_level
property. Its value will be null
for each non-subtotal result. For the subtotals, its value will be an integer corresponding to the index in the groups[]
param array.
For example, given the following groups:
location.name
, item.custom@group
, item.custom@category
These would be the corresponding subtotal_level
property values:
Subtotal Groups | Subtotal Level |
---|---|
location.name, item.custom@group | 2 |
location.name | 1 |
Grand Total | 0 |
Supported groups: item.*
, location.*
, customer.*
, date.*
, time.*
source_sales.net_sales
source_sales.net_qty_sold
source_sales.net_markdowns
source_sales.net_margin
source_sales.net_margin_ratio
source_sales.gross_sales
source_sales.gross_qty_sold
source_sales.gross_returns
source_sales.gross_qty_returned
source_sales.transaction_count
source_sales.customer_count
source_sales.item_count
Supported groups: item.*
, location.*
, customer.*
, date.*
, time.*
location_sales.sellthrough
location_sales.inventory_turn
location_sales.net_sales
location_sales.net_qty_sold
location_sales.net_markdowns
location_sales.net_margin
location_sales.net_margin_ratio
location_sales.gross_sales
location_sales.gross_qty_sold
location_sales.gross_returns
location_sales.gross_qty_returned
location_sales.transaction_count
location_sales.customer_count
location_sales.item_count
Supported groups: item.*
, location.*
Required params: start_date
beginning_inventory.qty_owned
beginning_inventory.cost_owned
beginning_inventory.price_owned
beginning_inventory.qty_on_po
beginning_inventory.price_on_po
beginning_inventory.qty_committed
beginning_inventory.cost_committed
beginning_inventory.price_committed
beginning_inventory.qty_in_transit
beginning_inventory.cost_in_transit
beginning_inventory.price_in_transit
beginning_inventory.qty_on_hand
beginning_inventory.cost_on_hand
beginning_inventory.price_on_hand
beginning_inventory.qty_available
beginning_inventory.cost_available
beginning_inventory.price_available
Supported groups: item.*
, location.*
Required params: end_date
ending_inventory.qty_owned
ending_inventory.cost_owned
ending_inventory.price_owned
ending_inventory.qty_on_po
ending_inventory.price_on_po
ending_inventory.qty_committed
ending_inventory.cost_committed
ending_inventory.price_committed
ending_inventory.qty_in_transit
ending_inventory.cost_in_transit
ending_inventory.price_in_transit
ending_inventory.qty_on_hand
ending_inventory.cost_on_hand
ending_inventory.price_on_hand
ending_inventory.qty_available
ending_inventory.cost_available
ending_inventory.price_available
Supported groups: locations.*
shipping.net_shipping_income
Supported groups: locations.*
, payments.*
, credit_card_payments.*
payment.payment_type_count
payment.credit_card_type_count
payment.payments_received
payment.refunds
payment.net_payments
NOTE: Some metric/group combinations are invalid. See the metric sections for a list of supported grouping levels. An invalid combination of metrics and groups will result in an error. For example, it's not possible to compute inventory values grouped by customer since inventory levels inherently have no customer dimension.
item.public_id
item.description
item.custom@*key*
customer.public_id
customer.first_name
customer.last_name
customer.email
customer.custom@*key*
location.public_id
location.name
date.date
date.year
date.month_of_year
date.month_of_year_name
date.week_of_year
date.week_of_year_name
date.day_of_week
date.day_of_week_name
time.time
time.hour
payment.type
credit_card_payment.type
In Heartland Retail you have the ability to create custom fields for most record types that allow you to store information in a way that makes sense for your business.
Custom fields are referenced on their corresponding group_id
record via the
key
value. You can interact with custom fields on the individual record two different ways.
To update custom field values individually, such as to only update a single custom
field value. The sytnax for that is {"custom@field_key":"Value"}
. That will only touch
the one custom fields you specify.
The other option is to update all custom field values at once. You can do this
with {"custom":{"field_key":"Value"}}
. It is important to note that this is an absolute
value, so any existing custom field values that are not included in this request body
will be removed.
For example if you have an item
custom field with the name "Style Name" and
the key style_name
, you would update that fields value on the item record with PUT /api/item/<item_id>
with the request body {"custom@style_name":"Cool New Style"}
. This will then show "Cool New Style" in
the "Style Name" field for that item record.
Most record types are able to have custom fields that can be used to store any data you would like on that record. The request body for custom fields varies slightly depending on the record type the custom field exists on.
All custom field records have this common base definition:
The record type that this custom field should be displayed on
item
, customer
, financial.account
, inventory.transfer
, item.vendor
, location
, payment.check
, payment_type.
, purchasing.order
, purchasing.receipt
, purchasing.return
, purchasing.vendor
, sales.order
, sales.transaction
, sales.transaction.line_item
This will be the internally referenced name for the custom field. The key of the custom field must match with the key in the custom hash on the record type for the data that you want displayed. You can specify a key, or allow it to be auto-generated as a normalized unique value based on the custom field name.
The display name of the custom field that will show up in the UI. If no key is specified then this will also be what the custom field key is based on.
Whether or not this record is currently active and being used
If true, this custom field must have a unique value on each record. If this is an item group custom field, having the value set to unique allows the value to be used as a lookup such as from a printed barcode/UPC.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Specifies if this is a text field or a picklist
list
, text
This field is required if the validation_type is list, otherwise it is not used. It can accept an array of strings or a JSON string representing an array of values.
Auto-generated validation list based on validation_options
Custom key/value information stored about this custom field. This is where additional parameters specific to the custom field group are stored.
{
"id": 109391,
"group_id": "item",
"key": "style_name",
"name": "Style Name",
"validation_type": "text",
"validation_options": "["Value 1","Value 2","Value 3"]",
"valid_list_values": [
"Value 1",
"Value 2",
"Value 3"
]
}
POST /api/custom_fields
Custom fields are created by POSTing a custom field record containing the required
attributes to the /api/custom_fields
resource. When successful, the response
headers will contain a Location header that indicates the url at which
the newly created custom field can be found. The custom field's unique id will be the
last portion of that URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"group_id":"item","name":"Style Name"}' "https://{{subdomain}}.retail.heartland.us/api/custom_fields"
client["custom_fields"]
.post({"group_id"=>"item", "name"=>"Style Name"})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/custom_fields/146697
GET /api/custom_fields/{{custom_field_id}}
Custom fields are retrieved from the Heartland Retail API via their unique id. The id can be found via searches or from the Location header in a Create Custom Field response.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/custom_fields/{{custom_field_id}}"
client["custom_fields/{{custom_field_id}}"]
.get.body
{
"id": 102350,
"group_id": "item",
"key": "style_name",
"name": "Style Name",
"validation_type": "text",
"validation_options": "["Value 1","Value 2","Value 3"]",
"valid_list_values": [
"Value 1",
"Value 2",
"Value 3"
]
}
{"id"=>104467,
"group_id"=>"item",
"key"=>"style_name",
"name"=>"Style Name",
"validation_type"=>"text",
"validation_options"=>"["Value 1","Value 2","Value 3"]",
"valid_list_values"=>["Value 1", "Value 2", "Value 3"]}
PUT /api/custom_fields/{{custom_field_id}}
Custom Fields can be edited by PUTting a custom field record containing a valid subset of custom field attributes to the custom field's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"group_id":"item","name":"Style Name","validation_type":"text","validation_options":"["Value 1","Value 2","Value 3"]"}' "https://{{subdomain}}.retail.heartland.us/api/custom_fields/{{custom_field_id}}"
client["custom_fields/{{custom_field_id}}"]
.put(my_custom_field_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/custom_fields
Custom fields can be searched by GETting the root of the custom field resource
/api/custom_fields
. This API call will result in a search result record
containing zero or more custom field records in the values
attribute. See
Search Results for more information on search
results.
Custom fields can be filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/custom_fields/?per_page=1"
client["custom_fields"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100653,
"group_id": "item",
"key": "style_name",
"name": "Style Name",
"validation_type": "text",
"validation_options": "["Value 1","Value 2","Value 3"]",
"valid_list_values": [
"Value 1",
"Value 2",
"Value 3"
]
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>108353,
"group_id"=>"item",
"key"=>"style_name",
"name"=>"Style Name",
"validation_type"=>"text",
"validation_options"=>"["Value 1","Value 2","Value 3"]",
"valid_list_values"=>["Value 1", "Value 2", "Value 3"]},
"..."]}
A adjustment set is a record of items that have been or will be adjusted.
pending
, complete
, canceled
The user who created this record
The most recent user who updated this record
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The user who created this record
The most recent user who updated this record
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 104773,
"adjustment_reason_id": 105174,
"location_id": 100250,
"created_by_user_id": 103327,
"updated_by_user_id": 103563
}
{
"id": 100436,
"adjustment_set_id": 109384,
"item_id": 105781,
"qty": 101545,
"unit_cost": 68.18,
"created_by_user_id": 109372,
"updated_by_user_id": 100170
}
POST /api/inventory/adjustment_sets
Creating an adjustment set requires an adjustment reason id and a location id. The location id is used to determine where the adjustment set will be applied.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"adjustment_reason_id":103563,"location_id":104753}' "https://{{subdomain}}.retail.heartland.us/api/inventory/adjustment_sets"
client["inventory/adjustment_sets"]
.post({"adjustment_reason_id"=>105315, "location_id"=>105995})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/inventory/adjustment_sets/158234
GET /api/inventory/adjustment_sets/{{adjustment_set_id}}
An adjustment set is retrieved using its unique identifier. This identifier
can be found by searching for adjustment sets, from references in other records, or
from the Location
header returned in response to the creation of a new
adjustment set.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/adjustment_sets/{{adjustment_set_id}}"
client["inventory/adjustment_sets/{{adjustment_set_id}}"]
.get.body
{
"id": 104377,
"adjustment_reason_id": 105724,
"location_id": 101112,
"created_by_user_id": 105085,
"updated_by_user_id": 101892
}
{"id"=>102987,
"adjustment_reason_id"=>101575,
"location_id"=>109428,
"created_by_user_id"=>102472,
"updated_by_user_id"=>106325}
PUT /api/inventory/adjustment_sets/{{adjustment_set_id}}
Adjustment sets can be edited by PUTting a record containing a valid subset of adjustment set attributes to the adjustment sets resource URL. To complete an adjustment set, you will just need to set the status to "complete"
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"adjustment_reason_id":101972,"location_id":108911}' "https://{{subdomain}}.retail.heartland.us/api/inventory/adjustment_sets/{{adjustment_set_id}}"
client["inventory/adjustment_sets/{{adjustment_set_id}}"]
.put(my_inventory_adjustment_set_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/inventory/adjustment_sets/{{adjustment_set_id}}/lines
An adjustment set has zero or more associated lines.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/adjustment_sets/{{adjustment_set_id}}/lines/?per_page=1"
client["inventory/adjustment_sets/{{adjustment_set_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100505,
"adjustment_set_id": 106843,
"item_id": 103581,
"qty": 102581,
"unit_cost": 65.28,
"created_by_user_id": 103126,
"updated_by_user_id": 107416
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>105320,
"adjustment_set_id"=>104528,
"item_id"=>101063,
"qty"=>101004,
"unit_cost"=>89.43,
"created_by_user_id"=>103098,
"updated_by_user_id"=>109626},
"..."]}
POST /api/inventory/adjustment_sets/{{adjustment_set_id}}/lines
Adds an item with the given qty to the adjustment set. This method can also be used to increment the quantity of an existing item line.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"adjustment_set_id":103785,"item_id":105990,"qty":107872,"unit_cost":77.76}' "https://{{subdomain}}.retail.heartland.us/api/inventory/adjustment_sets/{{adjustment_set_id}}/lines"
client["inventory/adjustment_sets/{{adjustment_set_id}}/lines"]
.post({"adjustment_set_id"=>101275, "item_id"=>106185, "qty"=>105069, "unit_cost"=>91.63})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/inventory/adjustment_sets/197048/lines/175826
GET /api/inventory/adjustment_sets
Adjustment sets can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/adjustment_sets/?per_page=1"
client["inventory/adjustment_sets"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 109199,
"adjustment_reason_id": 102767,
"location_id": 107181,
"created_by_user_id": 103938,
"updated_by_user_id": 104509
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103036,
"adjustment_reason_id"=>100506,
"location_id"=>107513,
"created_by_user_id"=>101137,
"updated_by_user_id"=>101935},
"..."]}
The items resource exposes the ability to create and modify items in the Heartland Retail system. The vast majority of item APIs make use of the item record type:
The unique public identifier for this item. This can be used to provide your own naming scheme to your inventory. Items can be searched for using this value.
a placeholder for custom data (deprecated)
The default cost of purchasing this item
The default sales price
A short description of the item.
A long description of the item
An object that acts as a container for custom values defined in Heartland Retail as well as any arbitrary values stored by integrations or custom applications.
Whether or not this record is currently active and being used
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The id of the financial class this item belongs to.
The weight of the tem
The width of the item
The height of the item
The depth of the item
If this item was imported or modified by an import this attribute references the import batch that brought this item into the system or updated it most recently.
The id for the primary vendor record that supplies this item.
{
"id": 106762,
"cost": 92.34,
"price": 83.65,
"financial_class_id": 109859,
"import_batch_id": 101752,
"primary_vendor_id": 107425
}
POST /api/items
Items are created by POSTing an item record containing the required
attributes to the /api/items
resource. When successful, the response
headers will contain a Location header that indicates the url at which
the newly created item can be found. The item's unique id will be the
last portion of that URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"cost":61.77,"price":28.04}' "https://{{subdomain}}.retail.heartland.us/api/items"
client["items"]
.post({"cost"=>28.99, "price"=>66.5})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/items/163735
GET /api/items/{{item_id}}
Items are retrieved from the Heartland Retail API via their unique id. The id can be found via searches, references from other records, or from the Location header in a Create Item response.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/items/{{item_id}}"
client["items/{{item_id}}"].get.body
{
"id": 102390,
"cost": 95.85,
"price": 27.71,
"financial_class_id": 103803,
"import_batch_id": 100259,
"primary_vendor_id": 104520
}
{"id"=>106656,
"cost"=>96.67,
"price"=>24.5,
"financial_class_id"=>106534,
"import_batch_id"=>103670,
"primary_vendor_id"=>108335}
PUT /api/items/{{item_id}}
Items can be edited by PUTting an item record containing a valid subset of item attributes to the item's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"cost":56.99,"price":55.55,"financial_class_id":100739,"import_batch_id":102831,"primary_vendor_id":105868}' "https://{{subdomain}}.retail.heartland.us/api/items/{{item_id}}"
client["items/{{item_id}}"]
.put(my_item_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/items
Items can be searched by GETting the root of the items resource /api/items
.
This API call will result in a search result record containing zero or more
item records in the values
attribute. See
Search Results for more information on search
results.
Items can be filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/items/?per_page=1"
client["items"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 103096,
"cost": 86.78,
"price": 15.3,
"financial_class_id": 105749,
"import_batch_id": 109261,
"primary_vendor_id": 107067
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100671,
"cost"=>39.39,
"price"=>91.49,
"financial_class_id"=>109594,
"import_batch_id"=>104722,
"primary_vendor_id"=>104684},
"..."]}
POST /api/items/{{item_id}}/merges
If you have duplicate items and would like to combine them into one item you can do so using the merges API. This will combine their open inventory quantities, inventory histories, and sales histories.
The base item specified in the URL is considered the "master" item. Include an array of slave_ids
in the
request body. These "slave" items will be deleted after having their data combined into the master.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"slave_ids":[100002,100003]}' "https://{{subdomain}}.retail.heartland.us/api/items/{{item_id}}/merges"
client["items/{{item_id}}/merges"]
.post({"slave_ids"=>[100002, 100003]})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/items/182227/merges/155936
The items resource exposes the ability to create and modify items in the Heartland Retail system. The vast majority of item grids APIs make use of the item record type:
a placeholder for custom data
A short description of the item.
A long description of the item
The default cost of purchasing this item
The default sales price
The original sales price
An object that acts as a container for custom values defined in Heartland Retail as well as any arbitrary values stored by integrations or custom applications.
Whether or not this record is currently active and being used
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The id of the financial class this item belongs to.
The id for the primary vendor record that supplies this item.
{
"id": 102757,
"item_cost": 86.11,
"item_price": 89.79,
"item_original_price": 80.5,
"item_financial_class_id": 108297,
"item_primary_vendor_id": 108225
}
POST /api/item_grids
Item grids are created by POSTing an item grid record containing the required
attributes to the /api/item_grids
resource. When successful, the response
headers will contain a Location header that indicates the url at which
the newly created item grid can be found. The item grid's unique id will be the
last portion of that URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/item_grids"
client["item_grids"].post({}).headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/item_grids/111213
GET /api/item_grids/{{item_grid_id}}
Item grids are retrieved from the Heartland Retail API via their unique id. The id can be found via searches, references from other records, or from the Location header in a Create Item grid response.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/item_grids/{{item_grid_id}}"
client["item_grids/{{item_grid_id}}"].get.body
{
"id": 100883,
"item_cost": 39.51,
"item_price": 40.06,
"item_original_price": 13.38,
"item_financial_class_id": 101476,
"item_primary_vendor_id": 105496
}
{"id"=>109016,
"item_cost"=>41.36,
"item_price"=>42.0,
"item_original_price"=>91.03,
"item_financial_class_id"=>101214,
"item_primary_vendor_id"=>107091}
PUT /api/item_grids/{{item_grid_id}}
Item grids can be edited by PUTting an item grid record containing a valid subset of item grid attributes to the item grid's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"item_cost":73.77,"item_price":28.62,"item_original_price":15.25,"item_financial_class_id":103636,"item_primary_vendor_id":103732}' "https://{{subdomain}}.retail.heartland.us/api/item_grids/{{item_grid_id}}"
client["item_grids/{{item_grid_id}}"]
.put(my_item_grid_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/item_grids
Item grids can be searched by GETting the root of the item grids resource /api/item_grids
.
This API call will result in a search result record containing zero or more
item grid records in the values
attribute. See
Search Results for more information on search
results.
Item grids can be filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/item_grids/?per_page=1"
client["item_grids"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 102484,
"item_cost": 78.92,
"item_price": 30.59,
"item_original_price": 31.23,
"item_financial_class_id": 107095,
"item_primary_vendor_id": 105626
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103048,
"item_cost"=>40.4,
"item_price"=>98.73,
"item_original_price"=>63.69,
"item_financial_class_id"=>109073,
"item_primary_vendor_id"=>100803},
"..."]}
The inventory values API allows you to retrieve real-time inventory values from across your business. This API uses our advanced filtering capabilities to let you filter and group the data however you like.
GET /api/inventory/values
This will return the total combined inventory values for all items and locations.
You can optionally pass the query parameter group[]=location_id
to get the
totals by location.
client[:inventory][:values].get.body
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/values"
{
"total"=>1,
"pages"=>1,
"results"=>[
{
"qty"=>4205.0,
"qty_on_hand"=>4205.0,
"qty_committed"=>61.0,
"qty_on_po"=>2781.0,
"qty_in_transit"=>55.0,
"qty_available"=>4089.0,
"unit_cost"=>9.95,
"qty_contributed_to_unit_cost"=>4205.0
}
]
}
{
"results": [
{
"qty": 4205.0,
"qty_on_hand": 4205.0,
"qty_committed": 61.0,
"qty_on_po": 2781.0,
"qty_in_transit": 55.0,
"qty_available": 4089.0,
"unit_cost": 9.95,
"qty_contributed_to_unit_cost": 4205.0
}
],
"total": 1,
"pages": 1
}
GET /api/inventory/values
Inventory values are retrieved via a GET
request to
/api/inventory/values
with the query parameter group[]=item_id
. A result is
returned for each item that has an inventory history. Items that have never been
received, adjusted, counted, sold, or returned will not be present as all values
are implicitly 0.
You can also optionally pass the query parameter group[]=location_id
to return
the item totals broken down by location.
Another optional query parameter is exclude_empty_locations=true
and this will
only return a result for locations with at least one inventory value that is not 0.
client[:inventory][:values].query(group: [:item_id]).get.body
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/values?group[]=item_id&per_page=2"
{
"total"=>19611,
"pages"=>9806,
"results"=>[
{
"qty"=>1880.0,
"qty_on_hand"=>1880.0,
"qty_committed"=>7.0,
"qty_on_po"=>19.0,
"qty_in_transit"=>9.0,
"qty_available"=>1873.0,
"unit_cost"=>10.25,
"item_id"=>68033
},
{
"qty"=>112.0,
"qty_on_hand"=>112.0,
"qty_committed"=>0.0,
"qty_on_po"=>8.0,
"qty_in_transit"=>0.0,
"qty_available"=>112.0,
"unit_cost"=>24.93017857142857,
"item_id"=>68034
}
]
}
{
"total":19611,
"pages":9806,
"results":[
{
"qty":1880.0,
"qty_on_hand":1880.0,
"qty_committed":7.0,
"qty_on_po":19.0,
"qty_in_transit":9.0,
"qty_available":1873.0,
"unit_cost":10.2494840425531915,
"item_id":68033
},
{
"qty":112.0,
"qty_on_hand":112.0,
"qty_committed":0.0,
"qty_on_po":8.0,
"qty_in_transit":0.0,
"qty_available":112.0,
"unit_cost":24.9301785714285714,
"item_id":68034
}
]
}
GET /api/inventory/values
You can retrieve the current inventory values for a single item via a GET
request to
/api/inventory/values
with the query parameters group[]=item_id
, group[]=location_id
, and item_id=100001
. This request will only work if all 3 parameters are passed.
You can use the optional query parameter exclude_empty_locations=true
to only return
a result for locations with at least one inventory value that is not 0.
client[:inventory][:values].query(group: [:item_id, :location_id], item_id: 100001).get.body
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/values?group[]=item_id&group[]=location_id&item_id=100001&per_page=2"
{
"total"=>19611,
"pages"=>9806,
"results"=>[
{
"qty"=>25.0,
"qty_on_hand"=>25.0,
"qty_committed"=>7.0,
"qty_on_po"=>19.0,
"qty_in_transit"=>9.0,
"qty_available"=>18.0,
"unit_cost"=>10.25,
"item_id"=>100001,
"location_id"=>100001
},
{
"qty"=>112.0,
"qty_on_hand"=>112.0,
"qty_committed"=>0.0,
"qty_on_po"=>8.0,
"qty_in_transit"=>0.0,
"qty_available"=>112.0,
"unit_cost"=>10.25,
"item_id"=>100001,
"location_id"=>100002
}
]
}
{
"total":19611,
"pages":9806,
"results":[
{
"qty": 25.0,
"qty_on_hand": 25.0,
"qty_committed": 7.0,
"qty_on_po": 19.0,
"qty_in_transit": 9.0,
"qty_available": 18.0,
"unit_cost": 10.25,
"item_id": 100001,
"location_id": 100001
},
{
"qty": 112.0,
"qty_on_hand": 112.0,
"qty_committed": 0.0,
"qty_on_po": 8.0,
"qty_in_transit": 0.0,
"qty_available": 112.0,
"unit_cost": 10.25,
"item_id": 100001,
"location_id": 100002
}
]
}
Heartland Retail creates a record whenever any type of inventory transaction takes place. The Inventory Transactions API allows you to access these records.
Inventory transaction APIs work with the inventory transaction record type:
The unique identifier for a transaction
the item id whose inventory was altered.
the per-item cost for the items altered in this transaction
the id of the location whose inventory is being altered
the change in quantity
the change in quantity pending on a purchase order
the change in quantity committed to a sale
the change in quantity being transferred between stores
The date and time that this record was created (in ISO8601 format)
{
"id": 109306,
"item_id": 103912,
"unit_cost": 63.49,
"location_id": 107279,
"delta_qty": 40.56,
"delta_qty_on_po": 33.25,
"delta_qty_committed": 42.81
}
GET /api/inventory/transactions
Searching and filtering inventory transactions is done via a
GET
request to /api/inventory/transactions
.
client[:inventory][:transactions].query(per_page: 2).get.body
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transactions?per_page=2"
{
"total"=>119,
"pages"=>60,
"results"=>
[
{
"id"=>100001,
"item_id"=>100001,
"unit_cost"=>45.0,
"created_at"=>"2013-08-05T09:43:55-04:00",
"delta_qty"=>-1.0,
"delta_qty_on_po"=>nil,
"delta_qty_committed"=>nil,
"delta_qty_in_transit"=>nil,
"location_id"=>100001
},
{
"id"=>100002,
"item_id"=>100003,
"unit_cost"=>7.0,
"created_at"=>"2013-08-06T08:20:13-04:00",
"delta_qty"=>-1.0,
"delta_qty_on_po"=>nil,
"delta_qty_committed"=>nil,
"delta_qty_in_transit"=>nil,
"location_id"=>100001
}
]
}
{
"total": 119,
"pages": 60,
"results": [
{
"id": 100001,
"item_id": 100001,
"unit_cost": 45.0,
"created_at": "2013-08-05T09:43:55-04:00",
"delta_qty": -1.0,
"delta_qty_on_po": null,
"delta_qty_committed": null,
"delta_qty_in_transit": null,
"location_id": 100001
},
{
"id": 100002,
"item_id": 100003,
"unit_cost": 7.0,
"created_at": "2013-08-06T08:20:13-04:00",
"delta_qty": -1.0,
"delta_qty_on_po": null,
"delta_qty_committed": null,
"delta_qty_in_transit": null,
"location_id": 100001
}
]
}
The inventory transfers resource exposes the ability to create and modify inventory transfers in the Heartland Retail system.
There are two common flows for Inventory Transfers:
Create Transfer => Add Transfer Lines => Mark as shipped => Select received Lines => Mark as received => Complete
Alternatively you can create an Inventory Transfer Request first:
Create Transfer Request => Add Requested Lines => Mark as requested => Select shipped Lines => Mark as shipped => Select received Lines => Mark as received => Complete
The vast majority of inventory transfer APIs make use of the inventory transfer record type:
The id of the transfer record
Status of the transfer
The id of the location from which items are shipped
The id of the location to which items are shipped
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The id of the last user who updated the transfer
The timestamp when the transfer was shipped
The id of the user who shipped the transfer
The timestamp when the transfer was received
The id of the user who received the transfer
Total quantity of items shipped
Total quantity of items received
Total quantity of items lost
Custom field values
Total quantity of items requested (for Transfer Requests)
Due Date for Transfer Requests
The id of purchasing receipt that initiated the Transfer Request
Total quantity of items discrepant (the difference between qtyreceived and qtyshipped)
Whether the transfer is overdue to be received or not
Whether the transfer is overdue to be picked or not
An expected format to update one or more transfer lines.
A collection of one or more lines entries.
If true
then any existing transfer lines will be updated
The column to update (only when all_selected
is true
)
The column name to update to (only when all_selected
is true
)
{
"id": 106022,
"status": "in_transit",
"from_location_id": 105736,
"to_location_id": 107891,
"created_by_user_id": 109189,
"updated_by_user_id": 106072,
"shipped_by_user_id": 109889,
"received_by_user_id": 108123,
"total_qty_shipped": 56.6,
"total_qty_received": 75.67,
"total_qty_lost": 46.41,
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
},
"total_qty_requested": 31.47,
"purchasing_receipt_id": 108705,
"total_qty_discrepant": 72.75
}
{
"transfer_lines": {
"123": "{ 'qty_received' => 5 }",
"321": "{ 'qty_received' => 2 }"
},
"column_name": "qty_received",
"source_column_name": "qty_shipped"
}
GET /api/inventory/transfers
Inventory Transfers can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/?per_page=1"
client["inventory/transfers"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 108152,
"status": "in_transit",
"from_location_id": 107288,
"to_location_id": 108813,
"created_by_user_id": 107663,
"updated_by_user_id": 101745,
"shipped_by_user_id": 108826,
"received_by_user_id": 100645,
"total_qty_shipped": 98.76,
"total_qty_received": 81.32,
"total_qty_lost": 90.49,
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
},
"total_qty_requested": 32.67,
"purchasing_receipt_id": 102566,
"total_qty_discrepant": 97.85
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103569,
"status"=>"in_transit",
"from_location_id"=>100143,
"to_location_id"=>109977,
"created_by_user_id"=>100706,
"updated_by_user_id"=>107870,
"shipped_by_user_id"=>105596,
"received_by_user_id"=>104819,
"total_qty_shipped"=>76.7,
"total_qty_received"=>62.6,
"total_qty_lost"=>74.4,
"custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"},
"total_qty_requested"=>14.37,
"purchasing_receipt_id"=>100216,
"total_qty_discrepant"=>20.99},
"..."]}
GET /api/inventory/transfers/{{transfer_id}}
Inventory Transfers can be fetched by GETting the inventory transfer's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}"
client["inventory/transfers/{{transfer_id}}"]
.get.body
{
"id": 103999,
"status": "in_transit",
"from_location_id": 106319,
"to_location_id": 104224,
"created_by_user_id": 105141,
"updated_by_user_id": 102477,
"shipped_by_user_id": 107091,
"received_by_user_id": 105995,
"total_qty_shipped": 32.76,
"total_qty_received": 54.51,
"total_qty_lost": 10.17,
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
},
"total_qty_requested": 16.06,
"purchasing_receipt_id": 104549,
"total_qty_discrepant": 73.35
}
{"id"=>104403,
"status"=>"in_transit",
"from_location_id"=>109871,
"to_location_id"=>102203,
"created_by_user_id"=>105239,
"updated_by_user_id"=>101452,
"shipped_by_user_id"=>103125,
"received_by_user_id"=>101063,
"total_qty_shipped"=>61.88,
"total_qty_received"=>19.05,
"total_qty_lost"=>82.64,
"custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"},
"total_qty_requested"=>67.25,
"purchasing_receipt_id"=>109488,
"total_qty_discrepant"=>51.87}
POST /api/inventory/transfers
Inventory Transfers are created by POSTing a inventory transfer record containing
the required attributes to the /api/inventory/transfers
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"status":"in_transit"}' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers"
client["inventory/transfers"]
.post({ "from_location_id"=>"123", "to_location_id"=>"321" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/inventory/transfers/197764
PUT /api/inventory/transfers/{{transfer_id}}
Inventory Transfers can be edited by PUTting an inventory transfer record containing a valid subset of inventory transfer attributes to the inventory transfer's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"status":"in_transit","from_location_id":103100,"to_location_id":109899,"created_by_user_id":105256,"updated_by_user_id":103199,"shipped_by_user_id":103640,"received_by_user_id":102920,"total_qty_shipped":64.16,"total_qty_received":64.22,"total_qty_lost":28.02,"custom":{"custom1":"Custom value 1","custom2":"Custom value 2"},"total_qty_requested":70.86,"purchasing_receipt_id":107130,"total_qty_discrepant":85.77}' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}"
client["inventory/transfers/{{transfer_id}}"]
.put(my_inventory_transfer_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/inventory/transfers/{{transfer_id}}/lines
Inventory Transfer Lines can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines/?per_page=1"
client["inventory/transfers/{{transfer_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100357,
"transfer_id": 107408,
"item_id": 103783,
"qty_shipped": 86.0,
"qty_received": 42.92,
"qty_lost": 68.33,
"unit_cost": 50.1,
"qty_discrepant": 90.25,
"qty_over": 94.13,
"qty_short": 82.08,
"created_by_user_id": 109314,
"updated_by_user_id": 101250,
"qty_requested": 75.12
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>106195,
"transfer_id"=>103279,
"item_id"=>101312,
"qty_shipped"=>88.64,
"qty_received"=>86.23,
"qty_lost"=>94.5,
"unit_cost"=>68.58,
"qty_discrepant"=>22.39,
"qty_over"=>39.04,
"qty_short"=>15.14,
"created_by_user_id"=>105986,
"updated_by_user_id"=>104010,
"qty_requested"=>53.33},
"..."]}
GET /api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}
Inventory Transfer Lines can be fetched by GETting the inventory transfer line's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}"
client["inventory/transfers/{{transfer_id}}/lines/{{line_id}}"]
.get.body
{
"id": 104092,
"transfer_id": 100664,
"item_id": 103213,
"qty_shipped": 48.27,
"qty_received": 53.8,
"qty_lost": 66.64,
"unit_cost": 49.04,
"qty_discrepant": 56.13,
"qty_over": 38.01,
"qty_short": 68.04,
"created_by_user_id": 105496,
"updated_by_user_id": 105355,
"qty_requested": 24.82
}
{"id"=>109060,
"transfer_id"=>100224,
"item_id"=>106610,
"qty_shipped"=>49.19,
"qty_received"=>45.9,
"qty_lost"=>54.92,
"unit_cost"=>84.63,
"qty_discrepant"=>71.31,
"qty_over"=>37.32,
"qty_short"=>21.57,
"created_by_user_id"=>101311,
"updated_by_user_id"=>101197,
"qty_requested"=>52.41}
POST /api/inventory/transfers/{{transfer_id}}/lines
Inventory Transfer Lines are created by POSTing a inventory transfer line record
containing the required attributes to the /api/inventory/transfers/{{transfer_id}}/lines
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"transfer_id":107643,"qty_shipped":35.78,"qty_received":77.45,"qty_lost":18.56,"unit_cost":61.2,"qty_discrepant":40.7,"qty_over":15.51,"qty_short":48.49,"qty_requested":53.11}' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines"
client["inventory/transfers/{{transfer_id}}/lines"]
.post({ "item_id"=>"123", "qty_shipped"=>"5" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/inventory/transfers/175492/lines/132494
PUT /api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}
Inventory Transfer Lines can be edited by PUTting an inventory transfer line record containing a valid subset of inventory transfer line attributes to the inventory transfer line's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"transfer_id":109937,"item_id":103010,"qty_shipped":38.23,"qty_received":44.35,"qty_lost":94.72,"unit_cost":34.28,"qty_discrepant":22.4,"qty_over":90.32,"qty_short":64.17,"created_by_user_id":104617,"updated_by_user_id":103567,"qty_requested":69.57}' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}"
client["inventory/transfers/{{transfer_id}}/lines/{{line_id}}"]
.put(my_inventory_transfer_line_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
PUT /api/inventory/transfers/{{transfer_id}}/lines
Inventory Transfer Lines can be edited in bulk by PUTting an inventory transfer line record containing a valid subset of inventory transfer line attributes and providing the list of transfer line ids to update to the inventory transfer lines resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"transfer_id":102691,"item_id":107950,"qty_shipped":84.83,"qty_received":23.55,"qty_lost":98.82,"unit_cost":74.22,"qty_discrepant":37.45,"qty_over":61.17,"qty_short":97.76,"created_by_user_id":107088,"updated_by_user_id":107958,"qty_requested":82.05}' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines"
client["inventory/transfers/{{transfer_id}}/lines"]
.put(my_inventory_transfer_line_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
DELETE /api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}
Inventory Transfer Lines can be deleted by sending a DELETE request to the inventory transfer line's resource URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}"
client["inventory/transfers/{{transfer_id}}/lines/{{line_id}}"]
.delete.status
200
200
DELETE /api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}
Inventory Transfer Lines can be deleted in bulk by sending a DELETE request with transfer line ids to the to the transfer lines resource URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/lines/{{line_id}}"
client["inventory/transfers/{{transfer_id}}/lines/{{line_id}}"]
.delete.status
200
200
GET /api/inventory/transfers/{{transfer_id}}/transfer_lines
This endpoint exposes Inventory Transfer Lines with embedded items for each line.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/transfer_lines/?per_page=1"
client["inventory/transfers/{{transfer_id}}/transfer_lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 103427,
"transfer_id": 104077,
"item_id": 107546,
"qty_shipped": 61.69,
"qty_received": 19.95,
"qty_lost": 26.72,
"unit_cost": 90.71,
"qty_discrepant": 81.44,
"qty_over": 88.95,
"qty_short": 71.98,
"created_by_user_id": 108741,
"updated_by_user_id": 109327,
"qty_requested": 42.13
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>104911,
"transfer_id"=>109745,
"item_id"=>108429,
"qty_shipped"=>90.81,
"qty_received"=>42.0,
"qty_lost"=>66.34,
"unit_cost"=>77.02,
"qty_discrepant"=>34.26,
"qty_over"=>54.42,
"qty_short"=>48.86,
"created_by_user_id"=>101890,
"updated_by_user_id"=>107683,
"qty_requested"=>25.47},
"..."]}
PUT /api/inventory/transfers/{{transfer_id}}/transfer_lines
Inventory Transfer Lines can be updated in bulk by PUTting a specifically crafted collection where keys are transfer lines ids, and values are updates.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"transfer_lines":{"123":"{ 'qty_received' => 5 }","321":"{ 'qty_received' => 2 }"},"column_name":"qty_received","source_column_name":"qty_shipped"}' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/transfer_lines"
client["inventory/transfers/{{transfer_id}}/transfer_lines"]
.post({ "transfer_lines"=>{ "123"=>{"qty_received"=>5}, "321"=>{"qty_received"=>6}, } })
.get.body
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/inventory/transfers/{{transfer_id}}/events
Inventory Transfer Events can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/events/?per_page=1"
client["inventory/transfers/{{transfer_id}}/events"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 108573,
"transfer_id": 105081,
"created_by_user_id": 109645,
"updated_by_user_id": 106431,
"local_created_at": "2013-08-05T07:22:24-04:00",
"local_updated_at": "2013-08-05T07:22:38-04:00",
"total_delta_qty_shipped": 75.74,
"total_delta_qty_received": 24.2,
"total_delta_qty_lost": 82.46,
"total_qty_created": 97.76,
"total_qty_added": 30.88
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103877,
"transfer_id"=>100327,
"created_by_user_id"=>106651,
"updated_by_user_id"=>104105,
"local_created_at"=>"2013-08-05T07:22:24-04:00",
"local_updated_at"=>"2013-08-05T07:22:38-04:00",
"total_delta_qty_shipped"=>13.04,
"total_delta_qty_received"=>93.5,
"total_delta_qty_lost"=>88.11,
"total_qty_created"=>96.63,
"total_qty_added"=>69.48},
"..."]}
GET /api/inventory/transfers/{{transfer_id}}/events/{{event_id}}
Inventory Transfer Events can be fetched by GETting the inventory transfer event's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/events/{{event_id}}"
client["inventory/transfers/{{transfer_id}}/events/{{event_id}}"]
.get.body
{
"id": 102111,
"transfer_id": 109356,
"created_by_user_id": 108259,
"updated_by_user_id": 102885,
"local_created_at": "2013-08-05T07:22:24-04:00",
"local_updated_at": "2013-08-05T07:22:38-04:00",
"total_delta_qty_shipped": 23.28,
"total_delta_qty_received": 79.01,
"total_delta_qty_lost": 52.52,
"total_qty_created": 16.21,
"total_qty_added": 18.38
}
{"id"=>104456,
"transfer_id"=>108525,
"created_by_user_id"=>102258,
"updated_by_user_id"=>108357,
"local_created_at"=>"2013-08-05T07:22:24-04:00",
"local_updated_at"=>"2013-08-05T07:22:38-04:00",
"total_delta_qty_shipped"=>94.98,
"total_delta_qty_received"=>92.41,
"total_delta_qty_lost"=>73.33,
"total_qty_created"=>18.95,
"total_qty_added"=>57.99}
GET /api/inventory/transfers/{{transfer_id}}/event_lines
Inventory Transfer Event Lines can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/event_lines/?per_page=1"
client["inventory/transfers/{{transfer_id}}/event_lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 101322,
"event_id": 102129,
"transfer_line_id": 104985,
"delta_qty_shipped": 81.16,
"delta_qty_received": 97.58,
"delta_qty_lost": 19.5,
"adjustment_reason_id": 107907,
"adjustment_id": 102821,
"local_created_at": "2013-08-05T07:22:24-04:00",
"local_updated_at": "2013-08-05T07:22:38-04:00",
"qty_created": 70.1,
"qty_added": 25.54
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>109680,
"event_id"=>106765,
"transfer_line_id"=>108609,
"delta_qty_shipped"=>86.44,
"delta_qty_received"=>50.13,
"delta_qty_lost"=>99.12,
"adjustment_reason_id"=>107709,
"adjustment_id"=>107526,
"local_created_at"=>"2013-08-05T07:22:24-04:00",
"local_updated_at"=>"2013-08-05T07:22:38-04:00",
"qty_created"=>88.84,
"qty_added"=>16.87},
"..."]}
GET /api/inventory/transfers/{{transfer_id}}/event_lines/{{line_id}}
Inventory Transfer Event Lines can be fetched by GETting the inventory transfer event line's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/event_lines/{{line_id}}"
client["inventory/transfers/{{transfer_id}}/event_lines/{{line_id}}"]
.get.body
{
"id": 103872,
"event_id": 105604,
"transfer_line_id": 103550,
"delta_qty_shipped": 82.03,
"delta_qty_received": 46.57,
"delta_qty_lost": 94.41,
"adjustment_reason_id": 102486,
"adjustment_id": 101596,
"local_created_at": "2013-08-05T07:22:24-04:00",
"local_updated_at": "2013-08-05T07:22:38-04:00",
"qty_created": 76.51,
"qty_added": 25.31
}
{"id"=>108671,
"event_id"=>102894,
"transfer_line_id"=>100026,
"delta_qty_shipped"=>82.92,
"delta_qty_received"=>56.73,
"delta_qty_lost"=>41.8,
"adjustment_reason_id"=>105974,
"adjustment_id"=>104382,
"local_created_at"=>"2013-08-05T07:22:24-04:00",
"local_updated_at"=>"2013-08-05T07:22:38-04:00",
"qty_created"=>18.89,
"qty_added"=>45.78}
GET /api/inventory/transfers/{{transfer_id}}/events/{{event_id}}/lines
Inventory Transfer Event Lines can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/events/{{event_id}}/lines/?per_page=1"
client["inventory/transfers/{{transfer_id}}/events/{{event_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 106297,
"event_id": 103153,
"transfer_line_id": 107191,
"delta_qty_shipped": 24.36,
"delta_qty_received": 31.85,
"delta_qty_lost": 95.2,
"adjustment_reason_id": 104470,
"adjustment_id": 106915,
"local_created_at": "2013-08-05T07:22:24-04:00",
"local_updated_at": "2013-08-05T07:22:38-04:00",
"qty_created": 93.63,
"qty_added": 11.17
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>108608,
"event_id"=>101837,
"transfer_line_id"=>103306,
"delta_qty_shipped"=>65.4,
"delta_qty_received"=>90.78,
"delta_qty_lost"=>31.15,
"adjustment_reason_id"=>107262,
"adjustment_id"=>104197,
"local_created_at"=>"2013-08-05T07:22:24-04:00",
"local_updated_at"=>"2013-08-05T07:22:38-04:00",
"qty_created"=>49.36,
"qty_added"=>86.19},
"..."]}
GET /api/inventory/transfers/{{transfer_id}}/events/{{event_id}}/lines/{{line_id}}
Inventory Transfer Event Lines can be fetched by GETting the inventory transfer event line's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/events/{{event_id}}/lines/{{line_id}}"
client["inventory/transfers/{{transfer_id}}/events/{{event_id}}/lines/{{line_id}}"]
.get.body
{
"id": 101489,
"event_id": 103475,
"transfer_line_id": 101429,
"delta_qty_shipped": 27.97,
"delta_qty_received": 36.23,
"delta_qty_lost": 10.01,
"adjustment_reason_id": 105951,
"adjustment_id": 104236,
"local_created_at": "2013-08-05T07:22:24-04:00",
"local_updated_at": "2013-08-05T07:22:38-04:00",
"qty_created": 45.89,
"qty_added": 79.8
}
{"id"=>109703,
"event_id"=>105890,
"transfer_line_id"=>105875,
"delta_qty_shipped"=>89.47,
"delta_qty_received"=>31.08,
"delta_qty_lost"=>21.39,
"adjustment_reason_id"=>104351,
"adjustment_id"=>103654,
"local_created_at"=>"2013-08-05T07:22:24-04:00",
"local_updated_at"=>"2013-08-05T07:22:38-04:00",
"qty_created"=>69.02,
"qty_added"=>52.09}
POST /api/inventory/transfers/{{transfer_id}}/shipments
Inventory Transfers Shipments are created by POSTing a inventory transfer shipment record containing the required attributes to the shipments resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d 'TBD' "https://{{subdomain}}.retail.heartland.us/api/inventory/transfers/{{transfer_id}}/shipments"
client["inventory/transfers/{{transfer_id}}/shipments"]
.post(TBD)
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/inventory/transfers/188013/shipments/164724
A sales ticket is a record that a POS sale, return, or exchange transaction.
Sales ticket APIs expose the ability to create, retrieve, update, and search for sales tickets. The sales ticket APIs make use of the sales ticket record.
In order to complete a ticket it must have payments sufficient to cover its balance.
Ticket
, Return
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
When set to false, we do not calculate and apply any promotion, coupon, or tax rules
Current status of the transaction
incomplete
, complete
, void
The user who created this record
An object that acts as a container for custom values defined in Heartland Retail as well as any arbitrary values stored by integrations or custom applications.
The date and time that this ticket was created with the location timezone applied
The date and time that this ticket was last updated with the location timezone applied
Internal store for custom data.
The most recent user who updated this record
The date and time that this ticket was completed
Whether or not the ticket should affect inventory on completion. Must be set during ticket creation
ID of coupon to apply to the ticket
An array of user IDs to be used as sales reps for this ticket
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
A payment for use in a sales transaction
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The payment's current status indicating whether or not it has been captured.
pending
, complete
, voided
The amount of money to pay.
The user friendly payment description
Object containing the details received from the payment gateway
The payment type
Payments::CashPayment
, Payments::CreditCardPayment
, Payments::CheckPayment
, Payments::CustomPayment
, Payments::ExternalPayment
, Payments::GiftCardPayment
The display name for the credit card holder on credit card payments
Set to true to capture payment immediately, when set to false it captures payment on transaction complete
The amount of money that has been paid
Payment reference ID
{
"id": 107451,
"type": "Ticket",
"customer_id": 101941,
"source_location_id": 105855,
"station_id": 108578,
"parent_transaction_id": 105696,
"status": "incomplete",
"total": 38.9,
"created_by_user_id": 108051,
"local_created_at": "2013-08-05T09:22:24-04:00",
"local_updated_at": "2013-08-05T09:22:24-04:00",
"updated_by_user_id": 108730,
"completed_at": "2013-08-05T09:22:24-04:00",
"coupon_id": 108194,
"sales_rep_ids": [
100002,
100003
]
}
{
"id": 109908,
"type": "ItemLine",
"sales_transaction_id": 103163,
"value": 31.87,
"qty": 4.0,
"adjusted_unit_price": 42.04,
"unit_cost": 74.64,
"original_unit_price": 43.22,
"item_id": 100001,
"shipping_line_id": 101606,
"item_line_id": 107509,
"sales_transaction_line_id": 104011,
"address_id": 101235,
"shipping_method_id": 102120,
"lookup_id": 108560,
"customer_id": 109354,
"loyalty_points": 109872,
"order_line_id": 109523,
"address_revision_id": 108975,
"order_discount_id": 108911,
"gift_card_id": 106099,
"tax_rule_id": 104421
}
{
"id": 109661,
"sales_transaction_id": 100445,
"payment_id": 107032,
"sales_order_payment_id": 105706,
"amount": 14.26,
"description": "Cash",
"gateway_id": 105671,
"type": "Payments::CashPayment",
"credit_card_id": 105046,
"deposit_payment_id": 103439,
"cardholder_name": "John Doe",
"active": true,
"amount_tendered": 35.49,
"gateway_connection_id": 103483
}
POST /api/sales/tickets
Creating a sales ticket requires a station_id
. The station_id
is used to determine
which location's inventory to alter as a result of the sales ticket.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"Ticket"}' "https://{{subdomain}}.retail.heartland.us/api/sales/tickets"
client["sales/tickets"]
.post({"type"=>"Ticket"})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/tickets/159871
GET /api/sales/tickets/{{ticket_id}}
A sales ticket is retrieved using its unique identifiers. This identifier
can be found by searching for tickets, from references in other records, or
from the Location
header returned in response to the creation of a new
sales tickets.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/{{ticket_id}}"
client["sales/tickets/{{ticket_id}}"].get.body
{
"id": 101737,
"type": "Ticket",
"customer_id": 101255,
"source_location_id": 102068,
"station_id": 100406,
"parent_transaction_id": 103564,
"status": "incomplete",
"total": 93.65,
"created_by_user_id": 100906,
"local_created_at": "2013-08-05T09:22:24-04:00",
"local_updated_at": "2013-08-05T09:22:24-04:00",
"updated_by_user_id": 101753,
"completed_at": "2013-08-05T09:22:24-04:00",
"coupon_id": 106576,
"sales_rep_ids": [
100002,
100003
]
}
{"id"=>103379,
"type"=>"Ticket",
"customer_id"=>109040,
"source_location_id"=>109460,
"station_id"=>101613,
"parent_transaction_id"=>108142,
"status"=>"incomplete",
"total"=>22.89,
"created_by_user_id"=>106877,
"local_created_at"=>"2013-08-05T09:22:24-04:00",
"local_updated_at"=>"2013-08-05T09:22:24-04:00",
"updated_by_user_id"=>105773,
"completed_at"=>"2013-08-05T09:22:24-04:00",
"coupon_id"=>109683,
"sales_rep_ids"=>[100002, 100003]}
GET /api/sales/tickets/{{ticket_id}}/lines
A sales ticket has zero or more associated lines. Lines can be any of the following types:
ItemLine
- The sale or return of an itemTaxLine
- Sales tax charge or refundDiscountLine
- Discount to another type of lineShippingLine
- Shipping charge, discount or refundcurl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/{{ticket_id}}/lines/?per_page=1"
client["sales/tickets/{{ticket_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 102640,
"type": "ItemLine",
"sales_transaction_id": 102622,
"value": 77.05,
"qty": 4.0,
"adjusted_unit_price": 62.08,
"unit_cost": 86.4,
"original_unit_price": 74.26,
"item_id": 100001,
"shipping_line_id": 106563,
"item_line_id": 106808,
"sales_transaction_line_id": 108596,
"address_id": 104273,
"shipping_method_id": 104950,
"lookup_id": 101607,
"customer_id": 107882,
"loyalty_points": 107174,
"order_line_id": 105477,
"address_revision_id": 100151,
"order_discount_id": 102100,
"gift_card_id": 100563,
"tax_rule_id": 107957
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>101072,
"type"=>"ItemLine",
"sales_transaction_id"=>109608,
"value"=>54.79,
"qty"=>4.0,
"adjusted_unit_price"=>48.82,
"unit_cost"=>57.7,
"original_unit_price"=>34.45,
"item_id"=>100001,
"shipping_line_id"=>106511,
"item_line_id"=>106299,
"sales_transaction_line_id"=>109680,
"address_id"=>103680,
"shipping_method_id"=>104479,
"lookup_id"=>100239,
"customer_id"=>109644,
"loyalty_points"=>109547,
"order_line_id"=>102172,
"address_revision_id"=>107650,
"order_discount_id"=>109811,
"gift_card_id"=>105778,
"tax_rule_id"=>108903},
"..."]}
POST /api/sales/tickets/{{ticket_id}}/item_lines
An item line indicates the sale or return of an item. This method can also be used to modify the quantity of an existing item line. Tickets are limited to 500 item lines per ticket. Attempting to add more than that will return an error.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"ItemLine","item_id":100001}' "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/{{ticket_id}}/item_lines"
client["sales/tickets/{{ticket_id}}/item_lines"]
.post({"type"=>"ItemLine", "item_id"=>100001})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/tickets/134253/item_lines/119327
POST /api/sales/tickets/{{ticket_id}}/payments
Adds a payment with the given amount and method to the ticket. See the payment data type for more details.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"amount":89.52,"type":"Payments::CashPayment","amount_tendered":64.48}' "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/{{ticket_id}}/payments"
client["sales/tickets/{{ticket_id}}/payments"]
.post({"amount"=>15.39, "type"=>"Payments::CashPayment", "amount_tendered"=>63.89})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/tickets/195530/payments/172877
PUT /api/sales/tickets/{{ticket_id}}
Adds a coupon to the ticket. See the coupon data type for more details.
client[:sales][:tickets][403992].put(coupon_id: 1).status
curl -v -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"coupon_id":"1"}' "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/403993"
200 # success!
# ...
# Status: 200 OK
# ...
# No Content.
PUT /api/sales/tickets/{{ticket_id}}
A sales ticket can be modified by sending a PUT
request to the record's
unique URL. The contents of the request must contain a valid subset of
sales ticket record attribute. You can pass completed_at
to set the
specific completion date and time for the ticket (for example in the past).
A sales ticket also accepts the affect_inventory
flag that if set to
false
can be used to not perform inventory adjustment on ticket
completion.
client[:sales][:tickets][403992].put(status: 'void').status
curl -v -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"status":"void"}' "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/403993"
200 # success!
# ...
# Status: 200 OK
# ...
# No Content.
GET /api/sales/tickets
Sales tickets can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/tickets/?per_page=1"
client["sales/tickets"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 106332,
"type": "Ticket",
"customer_id": 107260,
"source_location_id": 106327,
"station_id": 108326,
"parent_transaction_id": 104381,
"status": "incomplete",
"total": 66.03,
"created_by_user_id": 100282,
"local_created_at": "2013-08-05T09:22:24-04:00",
"local_updated_at": "2013-08-05T09:22:24-04:00",
"updated_by_user_id": 105996,
"completed_at": "2013-08-05T09:22:24-04:00",
"coupon_id": 105170,
"sales_rep_ids": [
100002,
100003
]
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>106809,
"type"=>"Ticket",
"customer_id"=>105855,
"source_location_id"=>104204,
"station_id"=>102603,
"parent_transaction_id"=>101268,
"status"=>"incomplete",
"total"=>74.63,
"created_by_user_id"=>101019,
"local_created_at"=>"2013-08-05T09:22:24-04:00",
"local_updated_at"=>"2013-08-05T09:22:24-04:00",
"updated_by_user_id"=>102627,
"completed_at"=>"2013-08-05T09:22:24-04:00",
"coupon_id"=>108486,
"sales_rep_ids"=>[100002, 100003]},
"..."]}
A sales order is a record that documents an order placed by a customer. Sales orders are typically used for future pickup of items, special orders, or ecommerce orders. This record holds the items, sales prices, shipping method/fee, and the payment information for the order. (For POS sales transactions, see Tickets)
A sales order has four statuses; Pending, Open, Canceled, Closed. While an order is pending, no inventory for items on the order has been committed. Before an order can be moved to the Open status, you must have sufficent payments added to the order as well as a valid shipping/billing address. You can cancel an order as long as it does not have any completed invoices against it. Once all items on the order have been successfully invoiced, the order is automatically transitioned to Closed.
Sales order APIs expose the ability to create, retrieve, update, and search for sales orders. The sales order APIs make use of the sales order record
The status of the order. Valid options: "pending", "open", "canceled", "closed"
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
List of gift cards to add to the order
Extended tax amount to collect for the line
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
List of Sales OrderLineDiscount to be applied
A payment for use in a sales order
The payment type. Valid options: "CashPayment", "CreditCardPayment", "CheckPayment", "CustomPayment", "ExternalPayment"
The payment's current status indicating whether or not it has been captured.
If true, the funds are captured immediately. Otherwise funds are captured when fulfilling the order.
The amount of money to pay.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 102919,
"customer_id": 106930,
"station_id": 106221,
"source_location_id": 100502,
"status": "pending",
"shipping_method_id": 102218,
"shipping_charge": 53.75,
"billing_address_id": 101830,
"shipping_address_id": 109513,
"gift_cards": [
{
"number": "GIFT-CARD-NUMBER",
"value": 12.34
}
]
}
{
"id": 106418,
"item_id": 104158,
"qty": 2.0,
"adjusted_unit_price": 35.85,
"original_unit_price": 33.08,
"unit_cost": 48.59,
"total_tax": 12.5,
"qty_open": 84.72,
"qty_invoiced": 52.1,
"order_id": 104292,
"ship_from_location_id": 106887,
"discounts": [
{
"description": "Discount",
"amount": 12.34
}
]
}
{
"id": 104973,
"type": "CashPayment",
"deposit": true,
"amount": 56.63
}
POST /api/sales/orders
Creating sales orders requires you to have a customer_id
, a station_id
and a source_location_id
.
The customer_id
is used to determine which customers is placing the order. And the
source location_id
is which location will be credited for the sale once the order
has been invoiced.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"customer_id":109174,"station_id":105110,"source_location_id":103446}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders"
client["sales/orders"]
.post({"customer_id"=>106323, "station_id"=>107876, "source_location_id"=>103715})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/orders/188773
GET /api/sales/orders/{{order_id}}
A sales order is retrieved using its unique identifiers. This identifier
can be found by searching for orders, from references in other records, or
from the Location
header returned in response to the creation of a new
sales order.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/orders/{{order_id}}"
client["sales/orders/{{order_id}}"].get.body
{
"id": 103890,
"customer_id": 100950,
"station_id": 102039,
"source_location_id": 102023,
"status": "pending",
"shipping_method_id": 106394,
"shipping_charge": 18.57,
"billing_address_id": 105875,
"shipping_address_id": 103805,
"gift_cards": [
{
"number": "GIFT-CARD-NUMBER",
"value": 12.34
}
]
}
{"id"=>105576,
"customer_id"=>106494,
"station_id"=>102418,
"source_location_id"=>103316,
"status"=>"pending",
"shipping_method_id"=>109647,
"shipping_charge"=>97.02,
"billing_address_id"=>109642,
"shipping_address_id"=>101147,
"gift_cards"=>[{"number"=>"GIFT-CARD-NUMBER", "value"=>12.34}]}
POST /api/sales/orders/{{order_id}}/lines
An item line indicates the sale or return of an item. This method can also be used to modify the quantity of an existing item line.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":100438,"qty":2.0}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders/{{order_id}}/lines"
client["sales/orders/{{order_id}}/lines"]
.post({"item_id"=>100579, "qty"=>2.0})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/orders/138895/lines/198575
POST /api/sales/orders/{{order_id}}/lines
It's possible to embed order line discounts when adding an item to an order. This will make the price of the line drop the amount specified by the sum of discounts.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":102708,"qty":2.0,"discounts":[{"description":"Discount","amount":12.34}]}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders/{{order_id}}/lines"
client["sales/orders/{{order_id}}/lines"]
.post({"item_id"=>102732, "qty"=>2.0, "discounts"=>[{"description"=>"Discount", "amount"=>12.34}]})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/orders/134172/lines/165013
GET /api/sales/orders/{{order_id}}/lines
A sales order has zero or more associated item lines.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/orders/{{order_id}}/lines/?per_page=1"
client["sales/orders/{{order_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 105908,
"item_id": 102499,
"qty": 2.0,
"adjusted_unit_price": 29.17,
"original_unit_price": 48.77,
"unit_cost": 23.47,
"total_tax": 12.5,
"qty_open": 73.41,
"qty_invoiced": 52.22,
"order_id": 106179,
"ship_from_location_id": 107233,
"discounts": [
{
"description": "Discount",
"amount": 12.34
}
]
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>108726,
"item_id"=>105081,
"qty"=>2.0,
"adjusted_unit_price"=>71.95,
"original_unit_price"=>97.53,
"unit_cost"=>82.1,
"total_tax"=>12.5,
"qty_open"=>45.71,
"qty_invoiced"=>27.92,
"order_id"=>109765,
"ship_from_location_id"=>100395,
"discounts"=>[{"description"=>"Discount", "amount"=>12.34}]},
"..."]}
PUT /api/sales/orders/{{order_id}}/lines/{{line_id}}
Distributing an item line designates the location that item will be fulfilled from.
You must specify the ship_from_location_id
client[:sales][:orders][403992][:lines][135225].put(ship_from_location_id: '100002')
curl -v -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"ship_from_location_id":"100002"}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders/403993/lines/135225"
200 # success!
# ...
# Status: 200 OK
# ...
PUT /api/sales/orders/{{order_id}}/
A sales order can record a shipping method and amount to charge for the shipment.
To add a shipping method you need the shipping_method_id
and the shipping_charge_amount
.
client[:sales][:orders][403992].put(shipping_method_id: 100003, shipping_charge: 22.00)
curl -v -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"shipping_charge":100002,"shipping_method_id":22.00}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders/403993/"
200 # success!
# ...
# Status: 200 OK
# ...
POST /api/sales/orders/{{order_id}}/payments
Adds a payment with the given amount and method to the order. See the payment data type for more details. A sales order stores the payment information to be captured either immediately or upon shipment of the order (fulling the invoice). There must be sufficent payments added to the order before it can be moved to the Open status.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"CashPayment","deposit":true,"amount":23.27}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders/{{order_id}}/payments"
client["sales/orders/{{order_id}}/payments"]
.post({"type"=>"CashPayment", "deposit"=>true, "amount"=>17.18})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/orders/165414/payments/172187
PUT /api/sales/orders/{{order_id}}
A sales order can be modified by sending a PUT
request to the record's
unique URL. The contents of the request must contain a valid subset of
sales order record attribute
client[:sales][:orders][403992].put(status: 'open').status
curl -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"status":"open"}' "https://{{subdomain}}.retail.heartland.us/api/sales/orders/403993"
200 # success!
# ...
# Status: 200 OK
# ...
GET /api/sales/orders
Sales orders can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/orders/?per_page=1"
client["sales/orders"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 101997,
"customer_id": 101991,
"station_id": 101469,
"source_location_id": 108922,
"status": "pending",
"shipping_method_id": 109662,
"shipping_charge": 81.06,
"billing_address_id": 100872,
"shipping_address_id": 106258,
"gift_cards": [
{
"number": "GIFT-CARD-NUMBER",
"value": 12.34
}
]
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100262,
"customer_id"=>100643,
"station_id"=>106693,
"source_location_id"=>104366,
"status"=>"pending",
"shipping_method_id"=>102033,
"shipping_charge"=>48.02,
"billing_address_id"=>100397,
"shipping_address_id"=>102905,
"gift_cards"=>[{"number"=>"GIFT-CARD-NUMBER", "value"=>12.34}]},
"..."]}
A sales invoice is a record that documents the full or partial fulfillment of a sales order. (For POS sales transactions, see Tickets)
Sales invoice APIs expose the ability to create, retrieve, update, and search for sales invoices. The sales invoice APIs make use of the sales invoice record
Invoice
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
When set to false, we do not calculate and apply any promotion, coupon, or tax rules
Current status of the transaction
incomplete
, complete
, void
An object that acts as a container for custom values defined in Heartland Retail as well as any arbitrary values stored by integrations or custom applications.
The date and time that this ticket was completed
Whether or not the ticket should affect inventory on completion. Must be set during ticket creation
ID of customer address used for billing
{
"id": 104734,
"type": "Invoice",
"customer_id": 103394,
"source_location_id": 101092,
"station_id": 105226,
"status": "incomplete",
"order_id": 103857,
"completed_at": "2013-08-05T09:22:24-04:00",
"billing_address_id": 103096
}
POST /api/sales/invoices
Creating sales invoices requires you to have a station id and a sales order id. The station id is used to determine which location's inventory to alter as a result of the sales invoice and the order id is used to determine what should be invoiced and which customer should receive it.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"Invoice"}' "https://{{subdomain}}.retail.heartland.us/api/sales/invoices"
client["sales/invoices"]
.post({"type"=>"Invoice"})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/invoices/11480
GET /api/sales/invoices/{{invoice_id}}
A sales invoice is retrieved using its unique identifiers. This identifier
can be found by searching for invoices, from references in other records, or
from the Location
header returned in response to the creation of a new
sales invoices.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/invoices/{{invoice_id}}"
client["sales/invoices/{{invoice_id}}"].get.body
{
"id": 101502,
"type": "Invoice",
"customer_id": 101111,
"source_location_id": 105486,
"station_id": 101369,
"status": "incomplete",
"order_id": 100287,
"completed_at": "2013-08-05T09:22:24-04:00",
"billing_address_id": 100406
}
{"id"=>109721,
"type"=>"Invoice",
"customer_id"=>105948,
"source_location_id"=>102544,
"station_id"=>105476,
"status"=>"incomplete",
"order_id"=>106065,
"completed_at"=>"2013-08-05T09:22:24-04:00",
"billing_address_id"=>108774}
GET /api/sales/invoices/{{invoice_id}}/lines
A sales invoice has zero or more associated lines. Lines can be any of the following types:
ItemLine
- The sale or return of an itemTaxLine
- Sales tax charge or refundDiscountLine
- Discount to another type of lineShippingLine
- Shipping charge, discount or refundcurl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/invoices/{{invoice_id}}/lines/?per_page=1"
client["sales/invoices/{{invoice_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 109292,
"type": "ItemLine",
"sales_transaction_id": 100396,
"value": 39.18,
"qty": 4.0,
"adjusted_unit_price": 25.37,
"unit_cost": 71.95,
"original_unit_price": 65.23,
"item_id": 100001,
"shipping_line_id": 106041,
"item_line_id": 102039,
"sales_transaction_line_id": 102381,
"address_id": 102174,
"shipping_method_id": 104295,
"lookup_id": 101995,
"customer_id": 106886,
"loyalty_points": 100753,
"order_line_id": 107926,
"address_revision_id": 109196,
"order_discount_id": 109208,
"gift_card_id": 108571,
"tax_rule_id": 100447
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>104827,
"type"=>"ItemLine",
"sales_transaction_id"=>103823,
"value"=>99.51,
"qty"=>4.0,
"adjusted_unit_price"=>37.65,
"unit_cost"=>88.09,
"original_unit_price"=>82.0,
"item_id"=>100001,
"shipping_line_id"=>107357,
"item_line_id"=>100748,
"sales_transaction_line_id"=>103055,
"address_id"=>103794,
"shipping_method_id"=>102991,
"lookup_id"=>109918,
"customer_id"=>102732,
"loyalty_points"=>104089,
"order_line_id"=>105271,
"address_revision_id"=>100016,
"order_discount_id"=>105383,
"gift_card_id"=>107871,
"tax_rule_id"=>106113},
"..."]}
PUT /api/sales/invoices/{{invoice_id}}
A sales invoice can be modified by sending a PUT
request to the record's
unique URL. The contents of the request must contain a valid subset of
sales invoice record attribute
client[:sales][:invoices][403992].put(status: 'void').status
curl -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"status":"void"}' "https://{{subdomain}}.retail.heartland.us/api/sales/invoices/403993"
200 # success!
# ...
# Status: 200 OK
# ...
# No Content.
GET /api/sales/invoices
Sales invoices can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/invoices/?per_page=1"
client["sales/invoices"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 103292,
"type": "Invoice",
"customer_id": 109265,
"source_location_id": 101188,
"station_id": 109810,
"status": "incomplete",
"order_id": 109354,
"completed_at": "2013-08-05T09:22:24-04:00",
"billing_address_id": 104464
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100725,
"type"=>"Invoice",
"customer_id"=>102418,
"source_location_id"=>104073,
"station_id"=>101744,
"status"=>"incomplete",
"order_id"=>109956,
"completed_at"=>"2013-08-05T09:22:24-04:00",
"billing_address_id"=>100512},
"..."]}
Customer APIs expose the ability to create, retrieve, update, and search for customers. The customer APIs make use of the customer record.
Unique ID string
First name
Last name
Email address
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
ID of default address record
ID of address record used for shipping
ID of address record used for billing
Whether or not this record is currently active and being used
Custom field values
ID of batch if this record was created as part of an import batch
Full name
Address record for primary address
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
If the country is set to 'US' then 2 letter state acronym required
Set to 2 letter country acronym. Set value to anything other than 'US' to use a non standard state/postal_code
If the country is set to 'US' then a 5 digit ZIP or ZIP+4 code is required
Custom field values
{
"id": 109030,
"first_name": "Walter",
"last_name": "White",
"email": "walter@example.com",
"address_id": 107505,
"shipping_address_id": 109690,
"billing_address_id": 102454,
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
},
"customer_import_batch_id": 105084,
"name": "Walter White",
"loyalty_points_balance": 108966,
"loyalty_points_total": 103754
}
{
"id": 100497,
"address_id": 108800,
"current_revision_id": 107538,
"first_name": "Bruce",
"last_name": "Wayne",
"line_1": "1007 Mountain Drive",
"city": "Gotham",
"state": "NJ",
"phone": "212-555-5555",
"country": "US",
"postal_code": "10025",
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
}
}
POST /api/customers
To create a customer you must specify at least a first name or a last name. Only one of those two values is actually required.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"first_name":"Walter"}' "https://{{subdomain}}.retail.heartland.us/api/customers"
client["customers"]
.post({"first_name"=>"Walter"})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/customers/199537
GET /api/customers/{{customer_id}}
A Customer is retrieved using its unique identifiers. This identifier
can be found by searching for customers, from references in other records, or
from the Location
header returned in response to the creation of a new
customer.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}"
client["customers/{{customer_id}}"].get.body
{
"id": 103293,
"first_name": "Walter",
"last_name": "White",
"email": "walter@example.com",
"address_id": 102597,
"shipping_address_id": 104241,
"billing_address_id": 104051,
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
},
"customer_import_batch_id": 109037,
"name": "Walter White",
"loyalty_points_balance": 100696,
"loyalty_points_total": 103456
}
{"id"=>105547,
"first_name"=>"Walter",
"last_name"=>"White",
"email"=>"walter@example.com",
"address_id"=>102359,
"shipping_address_id"=>100265,
"billing_address_id"=>107601,
"custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"},
"customer_import_batch_id"=>103162,
"name"=>"Walter White",
"loyalty_points_balance"=>100424,
"loyalty_points_total"=>105546}
PUT /api/customers/{{customer_id}}
A customer can be modified by sending a PUT
request to the record's
unique URL. The contents of the request must contain a valid subset of
customer record attribute
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"first_name":"Walter","last_name":"White","email":"walter@example.com","address_id":101946,"shipping_address_id":103887,"billing_address_id":100790,"custom":{"custom1":"Custom value 1","custom2":"Custom value 2"},"name":"Walter White"}' "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}"
client["customers/{{customer_id}}"]
.put(my_customer_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/customers
Customers can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/customers/?per_page=1"
client["customers"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 108657,
"first_name": "Walter",
"last_name": "White",
"email": "walter@example.com",
"address_id": 103117,
"shipping_address_id": 102726,
"billing_address_id": 109410,
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
},
"customer_import_batch_id": 101377,
"name": "Walter White",
"loyalty_points_balance": 109782,
"loyalty_points_total": 101860
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103821,
"first_name"=>"Walter",
"last_name"=>"White",
"email"=>"walter@example.com",
"address_id"=>102754,
"shipping_address_id"=>105795,
"billing_address_id"=>105808,
"custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"},
"customer_import_batch_id"=>104726,
"name"=>"Walter White",
"loyalty_points_balance"=>109347,
"loyalty_points_total"=>106917},
"..."]}
POST /api/customers/{{customer_id}}/merges
If you have duplicate customers and would like to combine them into one customer you can do so using the merges API. This will combine their sales history and customer data.
The base customer specified in the URL is considered the "master" customer. Include an array of slave_ids
in the
request body. These "slave" customers will be deleted after having their data combined into the master.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"slave_ids":[100002,100003]}' "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}/merges"
client["customers/{{customer_id}}/merges"]
.post({"slave_ids"=>[100002, 100003]})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/customers/161110/merges/18282
POST /api/customers/{{customer_id}}/addresses
You are able to create multiple addresses per customer each with their own address_id
that can be used
to specify the customer's address preferences.
To assign an address to be the default, billing, or shipping address you must create or retrieve an
address to get the address_id
which can then be used to update the customer record. By specifying the
address_id
when updating the customer, you are able to set the default address. You are also able to specify
a shipping_address_id
or a billing_address_id
to set the default specific address type for use in a sales order.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}/addresses"
client["customers/{{customer_id}}/addresses"]
.post({})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/customers/174146/addresses/195660
GET /api/customers/{{customer_id}}/addresses
You can retrieve all addresses currently attached to a customer by using the
customer's unique identifier. This identifier can be found by searching for
customers, from references in other records, or from the Location
header
returned in response to the creation of a new customer.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}/addresses"
client["customers/{{customer_id}}/addresses"]
.get.body
{
"id": 102418,
"address_id": 108726,
"current_revision_id": 100039,
"first_name": "Bruce",
"last_name": "Wayne",
"line_1": "1007 Mountain Drive",
"city": "Gotham",
"state": "NJ",
"phone": "212-555-5555",
"country": "US",
"postal_code": "10025",
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
}
}
{"id"=>100053,
"address_id"=>100925,
"current_revision_id"=>106908,
"first_name"=>"Bruce",
"last_name"=>"Wayne",
"line_1"=>"1007 Mountain Drive",
"city"=>"Gotham",
"state"=>"NJ",
"phone"=>"212-555-5555",
"country"=>"US",
"postal_code"=>"10025",
"custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"}}
GET /api/customers/{{customer_id}}/addresses/{{address_id}}
An address is retrieved using its unique identifier. This identifier
can be found by searching for all addresses attached to a customer, from references
in other records, or from the Location
header returned in response to the creation
of a new address.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}/addresses/{{address_id}}"
client["customers/{{customer_id}}/addresses/{{address_id}}"]
.get.body
{
"id": 102641,
"address_id": 101051,
"current_revision_id": 106558,
"first_name": "Bruce",
"last_name": "Wayne",
"line_1": "1007 Mountain Drive",
"city": "Gotham",
"state": "NJ",
"phone": "212-555-5555",
"country": "US",
"postal_code": "10025",
"custom": {
"custom1": "Custom value 1",
"custom2": "Custom value 2"
}
}
{"id"=>104256,
"address_id"=>101226,
"current_revision_id"=>103664,
"first_name"=>"Bruce",
"last_name"=>"Wayne",
"line_1"=>"1007 Mountain Drive",
"city"=>"Gotham",
"state"=>"NJ",
"phone"=>"212-555-5555",
"country"=>"US",
"postal_code"=>"10025",
"custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"}}
PUT /api/customers/{{customer_id}}/addresses/{{address_id}}
An address can be modified by sending a PUT
request to the record's
unique URL. The contents of the request must contain a valid subset of
address record attributes
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"first_name":"Bruce","last_name":"Wayne","line_1":"1007 Mountain Drive","city":"Gotham","state":"NJ","phone":"212-555-5555","country":"US","postal_code":"10025","custom":{"custom1":"Custom value 1","custom2":"Custom value 2"}}' "https://{{subdomain}}.retail.heartland.us/api/customers/{{customer_id}}/addresses/{{address_id}}"
client["customers/{{customer_id}}/addresses/{{address_id}}"]
.put(my_address_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
The tax jurisdictions resource exposes the ability to create and modify tax jurisdictions in the Heartland Retail system.
The id of the tax jurisdiction
The name of the tax jurisdiction
The type of the tax jurisdiction (either StateJurisdiction or PostalCodeJurisdiction)
The postal codes of the tax jurisdiction (for PostalCodeJurisdiction)
{
"id": 100757,
"name": "MA",
"type": "StateJurisdiction",
"country": "US",
"state": "MA"
}
GET /api/sales/tax_jurisdictions
Tax Jurisdictions can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_jurisdictions/?per_page=1"
client["sales/tax_jurisdictions"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 103764,
"name": "MA",
"type": "StateJurisdiction",
"country": "US",
"state": "MA"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100741,
"name"=>"MA",
"type"=>"StateJurisdiction",
"country"=>"US",
"state"=>"MA"},
"..."]}
GET /api/sales/tax_jurisdictions/{{jurisdiction_id}}
Tax Jurisdictions can be fetched by GETting the tax jurisdiction's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_jurisdictions/{{jurisdiction_id}}"
client["sales/tax_jurisdictions/{{jurisdiction_id}}"]
.get.body
{
"id": 103039,
"name": "MA",
"type": "StateJurisdiction",
"country": "US",
"state": "MA"
}
{"id"=>103809,
"name"=>"MA",
"type"=>"StateJurisdiction",
"country"=>"US",
"state"=>"MA"}
POST /api/sales/tax_jurisdictions
Tax Jurisdictions are created by POSTing a tax jurisdiction record containing
the required attributes to the /api/sales/tax_jurisdictions
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/sales/tax_jurisdictions"
client["sales/tax_jurisdictions"]
.post({ "name"=>"MA", "type"=>"StateJurisdiction", "country"=>"US", "state"=>"MA" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/tax_jurisdictions/149344
PUT /api/sales/tax_jurisdictions/{{jurisdiction_id}}
Tax Jurisdictions can be edited in bulk by PUTting a tax jurisdiction record containing a valid subset of tax jurisdiction attributes to the tax jurisdiction's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"name":"MA","type":"StateJurisdiction","country":"US","state":"MA"}' "https://{{subdomain}}.retail.heartland.us/api/sales/tax_jurisdictions/{{jurisdiction_id}}"
client["sales/tax_jurisdictions/{{jurisdiction_id}}"]
.put(my_tax_jurisdiction_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
DELETE /api/sales/tax_jurisdictions/{{jurisdiction_id}}
Tax Jurisdictions can be deleted by sending a DELETE request to the tax jurisdiction's resource URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_jurisdictions/{{jurisdiction_id}}"
client["sales/tax_jurisdictions/{{jurisdiction_id}}"]
.delete.status
200
200
The tax rules resource exposes the ability to create and modify tax rules in the Heartland Retail system.
The id of the tax rule record
The name of the tax rule
Tax percentage for "Percentage"-based tax or flat amount for "Flat Per Item"
Whether or not a certain price must be reached before tax is applied
Financial account that you map to will be the account that is credited/debited when the journal entries are synced to a connected financial system.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Which tax jurisdiction the rule is attributed to (globally if not set)
The type of the tax rule (either PercentageRule or FlatPerItemRule)
Whether items should not be taxed if they are above a certain price
Whether or not to tax the amount below the minimum_price
Whether or not tax rule is archived
Apply the rule only to particular customers (JSON-serialized)
Apply the rule only to particular items (JSON-serialized)
Whether the tax rule is configured in financial system correctly or not
{
"id": 101158,
"minimum_price": 18.18,
"liability_account_id": 104358,
"jurisdiction_id": 107137,
"maximum_price": 41.12,
"customer_filter": "{"$and":[{"custom@taxed":{"$eq":"true"}}]}",
"item_filter": "{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}"
}
GET /api/sales/tax_rules
Tax Rules can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules/?per_page=1"
client["sales/tax_rules"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 105820,
"minimum_price": 28.36,
"liability_account_id": 101661,
"jurisdiction_id": 100980,
"maximum_price": 14.85,
"customer_filter": "{"$and":[{"custom@taxed":{"$eq":"true"}}]}",
"item_filter": "{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>104078,
"minimum_price"=>25.46,
"liability_account_id"=>105442,
"jurisdiction_id"=>100474,
"maximum_price"=>12.54,
"customer_filter"=>"{"$and":[{"custom@taxed":{"$eq":"true"}}]}",
"item_filter"=>
"{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}"},
"..."]}
GET /api/sales/tax_rules/{{rule_id}}
Tax Rules can be fetched by GETting the tax rule's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules/{{rule_id}}"
client["sales/tax_rules/{{rule_id}}"].get.body
{
"id": 102375,
"minimum_price": 57.82,
"liability_account_id": 107330,
"jurisdiction_id": 104881,
"maximum_price": 29.08,
"customer_filter": "{"$and":[{"custom@taxed":{"$eq":"true"}}]}",
"item_filter": "{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}"
}
{"id"=>105117,
"minimum_price"=>40.56,
"liability_account_id"=>100208,
"jurisdiction_id"=>105315,
"maximum_price"=>15.95,
"customer_filter"=>"{"$and":[{"custom@taxed":{"$eq":"true"}}]}",
"item_filter"=>
"{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}"}
POST /api/sales/tax_rules
Tax Rules are created by POSTing a tax rule record containing
the required attributes to the /api/sales/tax_rules
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules"
client["sales/tax_rules"]
.post({ "name"=>"CA Sales Tax", "amount"=>"50", "item_filter"=>"{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/sales/tax_rules/117162
PUT /api/sales/tax_rules/{{rule_id}}
Tax Rules can be edited by PUTting a tax rule record containing a valid subset of tax rule attributes and providing the list of tax rules ids to update to the tax rules resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"minimum_price":18.22,"liability_account_id":106510,"jurisdiction_id":104852,"maximum_price":92.24,"customer_filter":"{"$and":[{"custom@taxed":{"$eq":"true"}}]}","item_filter":"{"$and":[{"custom@tax_category":{"$eq":"CLOTHING"}}]}"}' "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules/{{rule_id}}"
client["sales/tax_rules/{{rule_id}}"]
.put(my_tax_rule_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
PUT /api/sales/tax_rules
Tax Rules can be edited in bulk by PUTting a tax rule record containing a valid subset of tax rule attributes to the tax rule's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"transfer_id":102886,"item_id":103791,"qty_shipped":50.2,"qty_received":89.4,"qty_lost":87.42,"unit_cost":88.81,"qty_discrepant":65.88,"qty_over":51.34,"qty_short":93.61,"created_by_user_id":103883,"updated_by_user_id":101885,"qty_requested":62.13}' "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules"
client["sales/tax_rules"]
.put(my_inventory_transfer_line_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
DELETE /api/sales/tax_rules/{{rule_id}}
Tax Rules can be deleted by sending a DELETE request to the tax rule's resource URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules/{{rule_id}}"
client["sales/tax_rules/{{rule_id}}"]
.delete.status
200
200
DELETE /api/sales/tax_rules
Tax Rules can be deleted in bulk by sending a DELETE request with tax rules ids to the tax rules resource URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/sales/tax_rules"
client["sales/tax_rules"].delete.status
200
200
Heartland Retail includes a powerful rules-based promotion system. There are two ways to define promotions that can be used to apply discounts and special offers to a sale transaction: Promotion Rules and Coupons.
Promotion Rules and Coupons are each similarly structured and based on the concept of conditions and actions. This part of the documentation will focus on the similarities between these two promotions. For information about the specifics of each, see their respective sections.
Conditions determine whether the given promotion's actions should be applied to the
current sales transaction. These are transaction-level conditions specified in the
condition_definition
field.
Be careful not to confuse these with item-level conditions which some actions
support. If your promotion needs to target only certain items but should apply
to any transaction then you do not need to specify a condition_definition
.
Actions define the effects the promotion will have on the sales transaction. A
promotion must have one or more actions. Each action has a type
which
determines the effect on the transaction. Actions may have additional parameters
depending on the type.
See Action Types for a list of available types and their parameters.
Here's an example of a promotion rule. This rule would apply an employee discount of 30% off the original price of any item except those whose primary vendor's ID is 100003. This rule only applies if sales transaction has customer associated and that customer's "Is Employee" custom field is set to "Yes".
{
"id": 1,
"name": "Employee Discount",
"start_at": "2015-01-21 00:00:00",
"end_at": null,
"rank": 1,
"condition_definition": {
"$and": [
{
"customer.custom.is_employee": {
"$eq": "Yes"
}
}
]
},
"action_definition": [
{
"type": "DiscountItem",
"params": {
"discount": 0.3,
"discount_type": "percent",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": {
"$neq": "100003"
}
}
]
},
"item_price_attribute": "original_price"
},
"id": "8e5fd952-a186-11e4-8eee-bc764e2061ef"
}
],
"archived?": true,
"disabled?": false,
"created_at": "2015-01-21T15:59:07+00:00",
"updated_at": "2015-01-21T16:02:08+00:00"
}
The promotion rules resource exposes the ability to create, retrieve, search, update and delete promotion rules in the Heartland Retail system.
A promotion rule is considered active if it is not archived, not disabled and the current date and time is within start_at
and end_at
.
See Filtering for details on the filter expression syntax of condition_definition
.
The promotion rule APIs make use of the promotion rule record type:
A promotion rule is a record that represents a rule used in processing promotions and pricing.
The name of this promotion.
The date and time this promotion starts.
The date and time this promotion ends.
It determines the order in which promotions are applied. Promotions are applied from lowest to highest rank.
Whether or not the promotion is archived.
Whether or not the promotion is disabled.
A filter expression.
A filter expression.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 102389,
"rank": 101112,
"Promotion Action Definition": {
"type": "DiscountItem",
"params": {
"discount": 5,
"discount_type": "amount",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": "100001"
}
]
}
}
},
"Promotion Condition Definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
}
POST /api/promotion_rules
Promotion rules are created by POSTing a promotion rule record containing
at least the required attributes to the /api/promotion_rules
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/promotion_rules"
client["promotion_rules"]
.post({})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/promotion_rules/117771
GET /api/promotion_rules/{{promotion_rule_id}}
Promotion rules are retrieved via their unique id. The id can be found via a search.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/promotion_rules/{{promotion_rule_id}}"
client["promotion_rules/{{promotion_rule_id}}"]
.get.body
{
"id": 101334,
"rank": 107634,
"Promotion Action Definition": {
"type": "DiscountItem",
"params": {
"discount": 5,
"discount_type": "amount",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": "100001"
}
]
}
}
},
"Promotion Condition Definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
}
{"id"=>104851,
"rank"=>101674,
"Promotion Action Definition"=>
{"type"=>"DiscountItem",
"params"=>
{"discount"=>5,
"discount_type"=>"amount",
"item_price_attribute"=>"price",
"item_conditions"=>
{"$and"=>[{"item_line.item_primary_vendor_id"=>"100001"}]}}},
"Promotion Condition Definition"=>
{"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}}
GET /api/promotion_rules
Promotion rules can be searched by GETting the root of the promotion rules resource. This API call will result in a search result record containing zero or more promotion rule records in the results attribute. See Search Results for more information on search results.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/promotion_rules/?per_page=1"
client["promotion_rules"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 104291,
"rank": 103134,
"Promotion Action Definition": {
"type": "DiscountItem",
"params": {
"discount": 5,
"discount_type": "amount",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": "100001"
}
]
}
}
},
"Promotion Condition Definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100921,
"rank"=>105122,
"Promotion Action Definition"=>
{"type"=>"DiscountItem",
"params"=>
{"discount"=>5,
"discount_type"=>"amount",
"item_price_attribute"=>"price",
"item_conditions"=>
{"$and"=>[{"item_line.item_primary_vendor_id"=>"100001"}]}}},
"Promotion Condition Definition"=>
{"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}},
"..."]}
PUT /api/promotion_rules/{{promotion_rule_id}}
Promotion rules can be edited by PUTting a promotion rule record containing a valid subset of promotion rule attributes to the promotion rule's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"rank":105466,"Promotion Action Definition":{"type":"DiscountItem","params":{"discount":5,"discount_type":"amount","item_price_attribute":"price","item_conditions":{"$and":[{"item_line.item_primary_vendor_id":"100001"}]}}},"Promotion Condition Definition":{"$and":[{"customer.customer.rewards_level":{"$eq":"gold"}}]}}' "https://{{subdomain}}.retail.heartland.us/api/promotion_rules/{{promotion_rule_id}}"
client["promotion_rules/{{promotion_rule_id}}"]
.put(my_promotion_rule_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
DELETE /api/promotion_rules/{{promotion_rule_id}}
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/promotion_rules/{{promotion_rule_id}}"
client["promotion_rules/{{promotion_rule_id}}"]
.delete.status
200
200
The Coupons resource exposes the ability to create, retrieve, search, update and delete Coupons in the Heartland Retail system.
A coupon is considered active if it is not archived, not disabled and the current date and time is within start_at
and end_at
.
See Filtering for details on the filter expression syntax of condition_definition
.
The coupon APIs make use of the coupon record type:
A coupon is a record that represents a rule used in processing coupons and pricing.
The name of this coupon.
The code of this coupon.
The date and time this coupon starts.
The date and time this coupon ends.
Whether or not the coupon is archived.
Whether or not the coupon is disabled.
A filter expression.
A filter expression.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 1,
"name": "name",
"code": "10new",
"Promotion Action Definition": {
"type": "DiscountItem",
"params": {
"discount": 5,
"discount_type": "amount",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": "100001"
}
]
}
}
},
"Promotion Condition Definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
}
POST /api/coupons
Coupons are created by POSTing a coupon record containing
at least the required attributes to the /api/coupons
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"name":"name","code":"10new"}' "https://{{subdomain}}.retail.heartland.us/api/coupons"
client["coupons"]
.post({"name"=>"name", "code"=>"10new"}))
.get.body
# ...
# Status: 201 Created
# ...
# No Content
{"id"=>1, "name"=>"name", "code"=>"10new"}
GET /api/coupons/{{coupon_id}}
Coupons are retrieved via their unique id. The id can be found via a search.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/coupons/{{coupon_id}}"
client["coupons/{{coupon_id}}"].get.body
{
"id": 103608,
"name": "name",
"code": "10new",
"Promotion Action Definition": {
"type": "DiscountItem",
"params": {
"discount": 5,
"discount_type": "amount",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": "100001"
}
]
}
}
},
"Promotion Condition Definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
}
{"id"=>1,
"name"=>"name",
"code"=>"10new",
"Promotion Action Definition"=>
{"type"=>"DiscountItem",
"params"=>
{"discount"=>5,
"discount_type"=>"amount",
"item_price_attribute"=>"price",
"item_conditions"=>
{"$and"=>[{"item_line.item_primary_vendor_id"=>"100001"}]}}},
"Promotion Condition Definition"=>
{"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}}
GET /api/coupons
Coupons can be searched by GETting the root of the Coupons resource. This API call will result in a search result record containing zero or more coupon records in the results attribute. See Search Results for more information on search results.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/coupons/?per_page=1"
client["coupons"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 1,
"name": "name",
"code": "10new",
"Promotion Action Definition": {
"type": "DiscountItem",
"params": {
"discount": 5,
"discount_type": "amount",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.item_primary_vendor_id": "100001"
}
]
}
}
},
"Promotion Condition Definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>1,
"name"=>"name",
"code"=>"10new",
"Promotion Action Definition"=>
{"type"=>"DiscountItem",
"params"=>
{"discount"=>5,
"discount_type"=>"amount",
"item_price_attribute"=>"price",
"item_conditions"=>
{"$and"=>[{"item_line.item_primary_vendor_id"=>"100001"}]}}},
"Promotion Condition Definition"=>
{"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}},
"..."]}
PUT /api/coupons/{{coupon_id}}
Coupons can be edited by PUTting a coupon record containing a valid subset of coupon attributes to the coupon's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"name":"name","code":"10new","Promotion Action Definition":{"type":"DiscountItem","params":{"discount":5,"discount_type":"amount","item_price_attribute":"price","item_conditions":{"$and":[{"item_line.item_primary_vendor_id":"100001"}]}}},"Promotion Condition Definition":{"$and":[{"customer.customer.rewards_level":{"$eq":"gold"}}]}}' "https://{{subdomain}}.retail.heartland.us/api/coupons/{{coupon_id}}"
client["coupons/{{coupon_id}}"]
.put({"name"=>"name", "code"=>"10new"})
.get.body
# ...
# Status: 200 OK
# ...
# No Content
{"id"=>1, "name"=>"name", "code"=>"10new"}
DELETE /api/coupons/{{coupon_id}}
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/coupons/{{coupon_id}}"
client["coupons/{{coupon_id}}"].delete.status
200
200
The following promotion action types may be used to specify promotion behaviors on either Promotion Rules or Coupons. See Promotions for usage details.
Applies the given discount to item lines on the transaction that match the given
item_conditions
. If item_conditions
are not specified, applies to any item.
Must be DiscountItem
Amount of the discount. The value here is dependent upon the discount_type
.
If discount_type
is percent
value should be the percent off divided by 100 (e.g. 25% off = 0.25).
If discount_type
is amount
value should be the amount to subtract from the item's unit price. (e.g. $12.34 off = 12.34)
If discount_type
is fixed_price
value should be the amount to use as the item's unit price (e.g. $12.34 per item = 12.34)
The type of discount to apply to the matching items. See discount
for more details.
Valid options are amount
, percent
, and fixed_price
.
The date and time this promotion starts.
Which items on the transaction should receive the discount. See filtering docs for more details. If omitted, discount will apply to any item.
Applies the given discount to the transaction.
Must be DiscountSubtotal
Amount of the discount. The value here is dependent upon the discount_type
.
If discount_type
is percent
value should be the percent off divided by 100 (e.g. 25% off = 0.25).
If discount_type
is amount
value should be the amount to subtract from the item's unit price. (e.g. $12.34 off = 12.34)
The type of discount to apply to transaction. See discount
for more details.
Valid options are amount
, percent
.
{
"type": "DiscountItem",
"discount": 0.25,
"discount_type": "percent",
"item_price_attribute": "price",
"item_conditions": {
"$and": [
{
"item_line.price": {
"$gt": 100
}
}
]
}
}
{
"type": "DiscountSubtotal",
"discount": 0.25,
"discount_type": "percent"
}
A location represents a place where sales and inventory transactions can occur. This can be a physical store or it can represent a virtual store like an e-commerce site.
Location APIs make use of the location record type:
A location represents a physical space where sales transactions can take place.
unique identifier for the record
custom key/value information stored about this location
The name of the location
The unique identifier for the address record associated with this location
a unique identifier provided by the user for the purpose of coding information
unique identifier for the current revision of the address associated with this location
Whether or not this record is currently active and being used
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
unique identifier for the timezone record
The user who created this record
The most recent user who updated this record
Unique identifier for the location
An object that acts as a container for custom values defined in Heartland Retail as well as any arbitrary values stored by integrations or custom applications.
unique identifier for the price list record
key/value information stored about this locations settings
Whether the location has a credit card processor configured or not
{
"id": 100001,
"name": "Boston",
"address_id": 100004,
"public_id": "BOS",
"address_revision_id": 100016,
"timezone_identifier_id": 1,
"created_by_user_id": 106126,
"updated_by_user_id": 105157,
"uuid": "d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id": 1,
"credit_cards_configured": "false"
}
GET /api/locations
Search for and list locations
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/locations/?per_page=1"
client["locations"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100001,
"name": "Boston",
"address_id": 100004,
"public_id": "BOS",
"address_revision_id": 100016,
"timezone_identifier_id": 1,
"created_by_user_id": 105820,
"updated_by_user_id": 107811,
"uuid": "d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id": 1,
"credit_cards_configured": "false"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100001,
"name"=>"Boston",
"address_id"=>100004,
"public_id"=>"BOS",
"address_revision_id"=>100016,
"timezone_identifier_id"=>1,
"created_by_user_id"=>108675,
"updated_by_user_id"=>103334,
"uuid"=>"d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id"=>1,
"credit_cards_configured"=>"false"},
"..."]}
A purchase order is a record of items that have been or will be ordered from a vendor.
In order to complete a purchase order, it must have a receipt against it for all items on order.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 106686,
"vendor_id": 104254,
"created_by_user_id": 104199,
"receive_at_location_id": 100631,
"total_qty": 57.69,
"total_cost": 11.08,
"total_price": 30.79,
"total_received_qty": 58.46,
"total_received_cost": 58.4,
"total_received_price": 82.72,
"total_open_qty": 98.44,
"total_open_cost": 98.83,
"total_open_price": 77.35,
"po_import_batch_id": 104576
}
{
"id": 102246,
"item_id": 100842,
"order_id": 105896,
"qty": 41.39,
"unit_cost": 88.38,
"qty_received": 103166
}
POST /api/purchasing/orders
Creating a purchase order requires a vendor and the location id. The location id is used to determine where the order will be received.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"vendor_id":107068,"receive_at_location_id":101771}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/orders"
client["purchasing/orders"]
.post({"vendor_id"=>101978, "receive_at_location_id"=>104575})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/orders/161747
GET /api/purchasing/orders/{{purchase_order_id}}
A purchase order is retrieved using its unique identifier. This identifier
can be found by searching for purchase orders, from references in other records, or
from the Location
header returned in response to the creation of a new
purchase order.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/orders/{{purchase_order_id}}"
client["purchasing/orders/{{purchase_order_id}}"]
.get.body
{
"id": 100732,
"vendor_id": 101968,
"created_by_user_id": 102676,
"receive_at_location_id": 102365,
"total_qty": 89.91,
"total_cost": 18.32,
"total_price": 59.1,
"total_received_qty": 73.1,
"total_received_cost": 74.52,
"total_received_price": 55.68,
"total_open_qty": 62.57,
"total_open_cost": 36.72,
"total_open_price": 17.65,
"po_import_batch_id": 109767
}
{"id"=>106525,
"vendor_id"=>102581,
"created_by_user_id"=>100793,
"receive_at_location_id"=>103680,
"total_qty"=>97.56,
"total_cost"=>68.27,
"total_price"=>73.01,
"total_received_qty"=>61.1,
"total_received_cost"=>23.32,
"total_received_price"=>68.83,
"total_open_qty"=>84.31,
"total_open_cost"=>18.97,
"total_open_price"=>23.62,
"po_import_batch_id"=>104450}
GET /api/purchasing/orders/{{purchase_order_id}}/lines
A purchase order has zero or more associated lines.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/orders/{{purchase_order_id}}/lines/?per_page=1"
client["purchasing/orders/{{purchase_order_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 104104,
"item_id": 108894,
"order_id": 107935,
"qty": 28.83,
"unit_cost": 68.8,
"qty_received": 103595
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>102785,
"item_id"=>105680,
"order_id"=>101460,
"qty"=>29.4,
"unit_cost"=>58.8,
"qty_received"=>105108},
"..."]}
POST /api/purchasing/orders/{{purchase_order_id}}/lines
Adds an item with the given qty to the purchase order. This method can also be used to increment the quantity of an existing item line.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":101104,"order_id":109311,"qty":99.97,"unit_cost":54.86,"qty_received":100168}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/orders/{{purchase_order_id}}/lines"
client["purchasing/orders/{{purchase_order_id}}/lines"]
.post({"item_id"=>106774, "order_id"=>100350, "qty"=>67.42, "unit_cost"=>22.78, "qty_received"=>100063})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/orders/155054/lines/138184
A purchase receipt is a record that documents the full or partial fulfillment of a purchase order. (For purchase orders, see Purchase Order)
Purchasing receipt APIs expose the ability to create, retrieve, and update receipts.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 101252,
"order_id": 107809
}
{
"id": 105400,
"item_id": 102281,
"qty": 88.15,
"unit_cost": 99.88,
"receipt_id": 102809,
"order_line_id": 101756
}
POST /api/purchasing/receipts
Creating a purchase receipt requires a vendor and the location id. The location id is used to determine where the inventory is being received.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/receipts"
client["purchasing/receipts"]
.post({})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/receipts/110626
GET /api/purchasing/receipts/{{purchase_receipt_id}}
A receipt is retrieved using its unique identifier. This identifier
can be found by searching for receipts, from references in other records, or
from the Location
header returned in response to the creation of a new
purchase order.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/receipts/{{purchase_receipt_id}}"
client["purchasing/receipts/{{purchase_receipt_id}}"]
.get.body
{
"id": 104017,
"order_id": 102574
}
{"id"=>101836, "order_id"=>106370}
GET /api/purchasing/receipts/{{purchase_receipt_id}}/lines
A receipt has zero or more associated lines.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/receipts/{{purchase_receipt_id}}/lines/?per_page=1"
client["purchasing/receipts/{{purchase_receipt_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 104126,
"item_id": 107316,
"qty": 44.52,
"unit_cost": 34.23,
"receipt_id": 107281,
"order_line_id": 102629
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>109762,
"item_id"=>100539,
"qty"=>97.69,
"unit_cost"=>40.64,
"receipt_id"=>100315,
"order_line_id"=>104847},
"..."]}
POST /api/purchasing/receipts/{{purchase_receipt_id}}/lines
Adds an item with the given qty to the receipt. This method can also be used to modify the quantity of an existing item line.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":101665,"qty":13.08,"receipt_id":105874}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/receipts/{{purchase_receipt_id}}/lines"
client["purchasing/receipts/{{purchase_receipt_id}}/lines"]
.post({"item_id"=>107901, "qty"=>83.82, "receipt_id"=>107890})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/receipts/16499/lines/114680
A purchase return is a record of an item that has been or will be returned to a vendor.
Purchase return APIs expose the ability to create, retrieve, and update returns.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 107662,
"order_id": 103773
}
{
"id": 104194,
"item_id": 102658,
"qty": 80.06,
"unit_cost": 56.96,
"receipt_id": 106031,
"order_line_id": 109863
}
POST /api/purchasing/returns
Creating a purchase return requires a vendor and the location id. The location id is used to determine where the inventory is coming from.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"vendor_id":105062,"return_from_location_id":101872}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/returns"
client["purchasing/returns"]
.post({"vendor_id"=>106171, "return_from_location_id"=>105041})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/returns/199364
GET /api/purchasing/returns/{{purchase_return_id}}
A purchase return is retrieved using its unique identifier. This identifier
can be found by searching for purchase return, from references in other records, or
from the Location
header returned in response to the creation of a new
purchase return.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/returns/{{purchase_return_id}}"
client["purchasing/returns/{{purchase_return_id}}"]
.get.body
{
"id": 103610,
"vendor_id": 105281,
"return_from_location_id": 106405
}
{"id"=>107304, "vendor_id"=>109608, "return_from_location_id"=>100034}
GET /api/purchasing/returns/{{purchase_return_id}}/lines
A purchase return has zero or more associated lines.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/returns/{{purchase_return_id}}/lines/?per_page=1"
client["purchasing/returns/{{purchase_return_id}}/lines"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 106485,
"item_id": 109916,
"return_id": 106263,
"qty": 57.72,
"unit_cost": 73.37
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>104587,
"item_id"=>101338,
"return_id"=>103332,
"qty"=>20.46,
"unit_cost"=>48.47},
"..."]}
POST /api/purchasing/returns/{{purchase_return_id}}/lines
Adds an item with the given qty to the purchase return. This method can also be used to modify the quantity of an existing item line.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":101317,"return_id":109625,"qty":69.65,"unit_cost":85.25}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/returns/{{purchase_return_id}}/lines"
client["purchasing/returns/{{purchase_return_id}}/lines"]
.post({"item_id"=>101846, "return_id"=>106529, "qty"=>32.66, "unit_cost"=>22.3})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/returns/131494/lines/125332
The purchase vendor resource exposes the ability to create and modify purchase vendors in the Heartland Retail system.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Whether or not this record is currently active and being used
{
"id": 107855,
"address_id": 104057,
"vendor_import_batch_id": 108638
}
POST /api/purchasing/vendors
Purchase vendors are created by POSTing a purchase vendor record containing
the required attributes to the /api/purchasing/vendors
resource.
When successful, the response headers will contain a Location header that
indicates the url at which the newly created purchase vendor can be found.
The vendor's unique id will be the last portion of that URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/vendors"
client["purchasing/vendors"]
.post({})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/purchasing/vendors/17246
GET /api/purchasing/vendors/{{vendor_id}}
Purchase vendors are retrieved from the Heartland Retail API via their unique id. The id can be found via searches, references from other records, or from the Location header in a Create Purchase Vendor response.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/vendors/{{vendor_id}}"
client["purchasing/vendors/{{vendor_id}}"]
.get.body
{
"id": 101299,
"address_id": 106071,
"vendor_import_batch_id": 100922
}
{"id"=>105475, "address_id"=>109094, "vendor_import_batch_id"=>105639}
PUT /api/purchasing/vendors/{{vendor_id}}
Purchase vendors can be edited by PUTting a purchase vendor record containing a valid subset of purchase vendor attributes to the purchase vendor's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"address_id":104433,"vendor_import_batch_id":100817}' "https://{{subdomain}}.retail.heartland.us/api/purchasing/vendors/{{vendor_id}}"
client["purchasing/vendors/{{vendor_id}}"]
.put(my_purchasing_vendor_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/purchasing/vendors
Purchase vendors can be searched by GETting the root of the purchase vendors
resource /api/purchasing/vendors
. This API call will result in a search result
record containing zero or more purchase vendor records in the values
attribute. See Search Results for more information on search
results.
Purchase vendors can be filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/purchasing/vendors/?per_page=1"
client["purchasing/vendors"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 107326,
"address_id": 109379,
"vendor_import_batch_id": 100380
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>105672, "address_id"=>107081, "vendor_import_batch_id"=>101656},
"..."]}
Webhooks are limited to 10 URLs per event. Attempting to register more than that will return an error indicating which event(s) exceed the limit.
Webhooks retry once per hour for up to 72 hours. A webhook is considered successful when the handler returns a 200 status code.
The webhook APIs make use of the webhook record type:
The user who created this record
The most recent user who updated this record
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 108908,
"url": "http://example.org",
"created_by_user_id": 104399,
"updated_by_user_id": 108007
}
POST /api/webhooks
Webhooks are created by POSTing a webhook record containing
at least the required attributes to the /api/webhooks
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"url":"http://example.org"}' "https://{{subdomain}}.retail.heartland.us/api/webhooks"
client["webhooks"]
.post({"url"=>"http://example.com", "events"=>["webhook_registered"]}))
.get.body
# ...
# Status: 201 Created
# ...
# No Content
{"id"=>1, "url"=>"http://example.com", "events"=>["webhook_registered"]}
GET /api/webhooks/{{webhook_id}}
Webhooks are retrieved via their unique id. The id can be found via a search.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/webhooks/{{webhook_id}}"
client["webhooks/{{webhook_id}}"].get.body
{
"id": 103784,
"url": "http://example.org",
"created_by_user_id": 107277,
"updated_by_user_id": 108222
}
{"id"=>102748,
"url"=>"http://example.org",
"created_by_user_id"=>106740,
"updated_by_user_id"=>101533}
GET /api/webhooks
Webhooks can be searched by GETting the root of the Webhooks resource. This API call will result in a search result record containing zero or more webhook records in the results attribute. See Search Results for more information on search results.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/webhooks/?per_page=1"
client["webhooks"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 103315,
"url": "http://example.org",
"created_by_user_id": 105076,
"updated_by_user_id": 105121
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>107304,
"url"=>"http://example.org",
"created_by_user_id"=>108648,
"updated_by_user_id"=>109293},
"..."]}
PUT /api/webhooks/{{webhook_id}}
Webhooks can be edited by PUTting a webhook record containing a valid subset of webhook attributes to the webhook's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"url":"http://example.org"}' "https://{{subdomain}}.retail.heartland.us/api/webhooks/{{webhook_id}}"
client["webhooks/{{webhook_id}}"]
.put(my_webhook_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
DELETE /api/webhooks/{{webhook_id}}
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/webhooks/{{webhook_id}}"
client["webhooks/{{webhook_id}}"].delete.status
200
200
Occurs whenever a webhook is created.
Payload:
{
"webhook": {
"id": 1234,
"url": "https://example.com/target",
"events": [
"customer_created",
"customer_merged"
]
}
}
Occurs whenever a customer is created. Describes a customer.
Payload:
{
"id": 1,
"first_name": "First Name",
"last_name": "Last Name",
...
}
Occurs whenever a customer has changed. Describes a customer.
Payload:
{
"id": 1,
"first_name": "First Name",
"last_name": "Last Name",
...
}
Occurs whenever customers have merged.
Payload:
{
"old_customer_ids": [1, 2, 3, 4],
"new_customer_id": 5
}
Occurs whenever a customer has been selected in sale transaction. Describes a customer and a sale transaction.
Payload:
{
"customer": {
"id": 1,
"first_name": "First Name",
"last_name": "Last Name",
...
},
"sales_transaction": {
"id": 101388,
"customer_id": 102262,
"source_location_id": 103683,
"station_id": 108059,
"parent_transaction_id": 108668,
"order_id": 103520,
"total": 22.81,
"created_by_user_id": 107176
...
}
}
Occurs whenever sale transaction is completed. Describes a sale transaction.
Payload:
{
"id": 101388,
"customer_id": 102262,
"source_location_id": 103683,
"station_id": 108059,
"parent_transaction_id": 108668,
"order_id": 103520,
"total": 22.81,
"created_by_user_id": 107176
...
}
Occurs whenever item is created. Describes an item.
Payload:
{
"id": 108162,
"cost": 92.68,
"price": 47.01,
"financial_class_id": 103307,
"import_batch_id": 103994,
"primary_vendor_id": 108158,
...
}
Occurs whenever item has changed. Describes an item.
Payload:
{
"id": 108162,
"cost": 92.68,
"price": 47.01,
"financial_class_id": 103307,
"import_batch_id": 103994,
"primary_vendor_id": 108158,
...
}
### purchasing_vendor_created
Occurs whenever purchasing vendor is created. Describes a [purchase vendor](#resource-purchase_vendor).
Payload:
```json
{
"id": 103504,
"address_id": 104772,
"vendor_import_batch_id": 103806,
...
}
Occurs whenever purchasing vendor has changed. Describes a purchase vendor.
Payload:
{
"id": 103504,
"address_id": 104772,
"vendor_import_batch_id": 103806,
...
}
Occurs whenever promotion rule is created. Describes a promotion rule.
Payload:
{
"id": 105928,
"rank": 102965,
"action_definition": [
{
"type": "DiscountSubtotal",
"params": {
"discount": 20,
"discount_type": "amount"
}
}
],
"condition_definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
}
Occurs whenever promotion rule has changed. Describes a promotion rule.
Payload:
{
"id": 105928,
"rank": 102965,
"action_definition": [
{
"type": "DiscountSubtotal",
"params": {
"discount": 20,
"discount_type": "amount"
}
}
],
"condition_definition": {
"$and": [
{
"customer.customer.rewards_level": {
"$eq": "gold"
}
}
]
}
}
Traffic counters recognize shapes and count them as visitors. These counters can be set up on the entrances to the store or within the store. Traffic counters represent devices that could be assigned to locations.
Location of the traffic counter
Counter name
Original device name (coming from integrations)
Is this a store entrance traffic counter?
If not the entrance, the name of the zone
An object that acts as a container for any arbitrary values stored by integrations or custom applications.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 101942,
"location_id": 105638
}
POST /api/traffic_counters
Creating a traffic counter requires a name
, original_name
(could be
the same as name
), entrance
and zone
. If you pass the location_id
,
the counter will be assigned to the location.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/traffic_counters"
client["traffic_counters"]
.post({})
.headers['Location']
# ...
# Status: 201 Created
# ...
# No Content
/api/traffic_counters/162508
PUT /api/traffic_counters/{{counter_id}}
A traffic counter can be modified by sending a PUT
request to the record's
unique URL. The contents of the request must contain a valid subset of
traffic counter record attribute.
client[:traffic_counters][123].put(name: 'Boston').status
curl -v -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"name":"Boston"}' "https://{{subdomain}}.retail.heartland.us/api/traffic_counters/123"
200 # success!
# ...
# Status: 200 OK
# ...
# No Content.
GET /api/traffic_counters
Traffic counters can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/traffic_counters/?per_page=1"
client["traffic_counters"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 106475,
"location_id": 103027
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>[{"id"=>107127, "location_id"=>108936}, "..."]}
A traffic count is number of visitors for the given counter and datetime.
Location of the traffic counter
Counter name
Original device name (coming from integrations)
Is this a store entrance traffic counter?
If not the entrance, the name of the zone
An object that acts as a container for any arbitrary values stored by integrations or custom applications.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
{
"id": 104643,
"location_id": 100797
}
PUT /api/traffic_counts
Creating a traffic count requires a traffic_counter_id
, datetime
and
value
.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"traffic_counter_id":107497,"value":107215,"year":107761,"month":103197,"week":106035,"hour":103872,"date_id":108150,"time_id":102232}' "https://{{subdomain}}.retail.heartland.us/api/traffic_counts"
client["traffic_counts"]
.put(my_traffic_count_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/traffic_counts/{{count_id}}
A traffic count is retrieved using its unique identifier. This identifier can be found by searching for counts, from references in other records, or from the response to the creation of a new count.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/traffic_counts/{{count_id}}"
client["traffic_counts/{{count_id}}"].get.body
{
"id": 101328,
"traffic_counter_id": 107367,
"value": 108371,
"year": 108632,
"month": 108398,
"week": 106206,
"hour": 100489,
"date_id": 107796,
"time_id": 105527
}
{"id"=>107750,
"traffic_counter_id"=>106963,
"value"=>101626,
"year"=>100920,
"month"=>108327,
"week"=>109397,
"hour"=>102410,
"date_id"=>103395,
"time_id"=>105905}
GET /api/traffic_counts
Traffic counts can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/traffic_counts/?per_page=1"
client["traffic_counts"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100348,
"traffic_counter_id": 100741,
"value": 108141,
"year": 108777,
"month": 103939,
"week": 107073,
"hour": 107850,
"date_id": 102730,
"time_id": 103739
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103338,
"traffic_counter_id"=>108037,
"value"=>104698,
"year"=>103457,
"month"=>109393,
"week"=>105575,
"hour"=>108691,
"date_id"=>104658,
"time_id"=>106465},
"..."]}
GET /api/permissions
Permissions can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/permissions/?per_page=1"
client["permissions"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": "role.manage",
"description": "Authorize users to manage roles records"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>"role.manage",
"description"=>"Authorize users to manage roles records"},
"..."]}
A role is a collection of permissions with a name assigned to one or more users, and subscribed to one or more alert types.
The ID of the role record
The name of the role
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Count of users with the role
{
"id": 107314,
"users_count": 106274
}
GET /api/roles
Roles can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/roles/?per_page=1"
client["roles"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 106007,
"users_count": 102181
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>[{"id"=>100672, "users_count"=>108155}, "..."]}
POST /api/roles
Roles are created by POSTing a role record containing the required
attributes to the /api/roles
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/roles"
client["roles"]
.post({ "name"=>"Sales Associate" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/roles/156700
PUT /api/roles/{{role_id}}
Roles can be edited by PUTting a role record containing a valid subset of role attributes to the role's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"users_count":105537}' "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}"
client["roles/{{role_id}}"]
.put(my_role_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/roles/{{role_id}}
Roles can be fetched by GETting the role's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}"
client["roles/{{role_id}}"].get.body
{
"id": 104802,
"users_count": 101826
}
{"id"=>108758, "users_count"=>108833}
DELETE /api/roles/{{role_id}}
Roles can be deleted by sending a DELETE request the role's resource URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}"
client["roles/{{role_id}}"].delete.status
200
200
A role can authorize one ore more permissions and be assigned to one or multiple users. For more information on permissions see Permissions.
{
"id": "role.manage",
"description": "Authorize users to manage roles records"
}
GET /api/roles/{{role_id}}/permissions
Roles permissions can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/permissions/?per_page=1"
client["roles/{{role_id}}/permissions"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": "role.manage",
"description": "Authorize users to manage roles records"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>"role.manage",
"description"=>"Authorize users to manage roles records"},
"..."]}
PUT /api/roles/{{role_id}}/permissions
Permissions can be added to roles by PUTing their IDs to the role's permissions resource.
client["roles/123/permissions"].post({ "permission_ids"=>["customer.read", "role.manage"], "enabled"=>"true" }).get.body
curl -v -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"permission_ids"=>["customer.read", "role.manage"], "enabled"=>"true"}' "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/permissions"
204 # No Content
# ...
# Status: 204 No Content
# ...
# No Content.
GET /api/roles/{{role_id}}/permissions/{{permission_id}}
Role permissions can be fetched by GETting the role permission's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/permissions/{{permission_id}}"
client["roles/{{role_id}}/permissions/{{permission_id}}"]
.get.body
{
"id": 101482,
"description": "Authorize users to manage roles records"
}
{"id"=>"role.manage", "description"=>"Authorize users to manage roles records"}
DELETE /api/roles/{{role_id}}/permissions/{{permission_id}}
Remove a permission from the role by sending a DELETE request to the role permission's URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/permissions/{{permission_id}}"
client["roles/{{role_id}}/permissions/{{permission_id}}"]
.delete.status
200
200
A role can be subscribed to one or more alert types. All users with the role will see alert types their roles are subscribed to.
{
"id": 107264,
"type": "SalesOrdersDistributableAlertType",
"description": "Distributable Sales Orders",
"category": "sales"
}
GET /api/roles/{{role_id}}/alert_types
Roles alert types can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/alert_types/?per_page=1"
client["roles/{{role_id}}/alert_types"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 108942,
"type": "SalesOrdersDistributableAlertType",
"description": "Distributable Sales Orders",
"category": "sales"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>107324,
"type"=>"SalesOrdersDistributableAlertType",
"description"=>"Distributable Sales Orders",
"category"=>"sales"},
"..."]}
POST /api/roles/{{role_id}}/alert_types
Alert types can be added to roles by POSTing their IDs to the role's alert types resource.
When successful, the response headers will contain a Location header that indicates the url at which the newly created alert subscription can be found. The alert subscription's unique id will be the last portion of that URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/alert_types"
client["roles/123/alert_types"]
.post({ "alert_type_id"=>"321" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/roles/150501/alert_types/180534
GET /api/roles/{{role_id}}/alert_types/{{alert_type_id}}
Role alert type can be fetched by GETting the role alert type's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/alert_types/{{alert_type_id}}"
client["roles/{{role_id}}/alert_types/{{alert_type_id}}"]
.get.body
{
"id": 104224,
"type": "SalesOrdersDistributableAlertType",
"description": "Distributable Sales Orders",
"category": "sales"
}
{"id"=>102973,
"type"=>"SalesOrdersDistributableAlertType",
"description"=>"Distributable Sales Orders",
"category"=>"sales"}
DELETE /api/roles/{{role_id}}/alert_types/{{alert_type_id}}
Alert types can be removed from roles by sending a DELETE request to the role alert type's resource.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/alert_types/{{alert_type_id}}"
client["roles/{{role_id}}/alert_types/{{alert_type_id}}"]
.delete.status
200
200
A role can be assigned to one or more users. For more information on managing users see Users.
The ID of the user record
The unique username for the user
First name of the user
Last name of the user
Email address
Phone number
The date and time that this record was created (in ISO8601 format)
The unique public identifier for the user
Whether the user has access to all locations or not
Whether or not this record is currently active and being used
The date and time that this record was last updated (in ISO8601 format)
Whether the user is admin or not
Whether the user is account owner or not
(Deprecated) Whether the user is account admin or not
The UUID of the user record
Whether the user is a sales representative or not
First name and Last name of the user (or login if they are not set)
{
"id": 101422
}
GET /api/roles/{{role_id}}/users
Roles users can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/users/?per_page=1"
client["roles/{{role_id}}/users"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 101461
},
"..."
]
}
{"total"=>42, "pages"=>5, "results"=>[{"id"=>103947}, "..."]}
POST /api/roles/{{role_id}}/users
Users can be added to roles by POSTing their IDs to the role's users resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/users"
client["roles/123/users"]
.post({ "users"=>["222","333"] })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/roles/159775/users/133740
DELETE /api/roles/{{role_id}}/users
Users can be removed from roles by sending a DELETE request with their IDs to the role users resource.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/roles/{{role_id}}/users"
client["roles/{{role_id}}/users"].delete.status
200
200
A user is a record storing information about end users of the system. Users can't be deleted because they are tied to other resources across the application. However, they can be marked as inactive when necessary.
The ID of the user record
The unique username for the user
First name of the user
Last name of the user
Email address
Phone number
The date and time that this record was created (in ISO8601 format)
The unique public identifier for the user
Whether the user has access to all locations or not
Whether or not this record is currently active and being used
The date and time that this record was last updated (in ISO8601 format)
Whether the user is admin or not
Whether the user is account owner or not
(Deprecated) Whether the user is account admin or not
The UUID of the user record
Whether the user is a sales representative or not
First name and Last name of the user (or login if they are not set)
{
"id": 105077
}
GET /api/users
Users can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/users/?per_page=1"
client["users"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 104612
},
"..."
]
}
{"total"=>42, "pages"=>5, "results"=>[{"id"=>101536}, "..."]}
POST /api/users
Users are created by POSTing a user record containing the required
attributes to the /api/users
resource. The password is required and
stored encrypted in the database.
When successful, the response headers will contain a Location header that indicates the url at which the newly created user can be found. The user's unique id will be the last portion of that URL.
You can also optionally set the users roles and locations with the create
user request.
To set roles, you can include role_ids
with an array of Role ID's, or
include is_admin
with true
as the value to grant the user full admin access.
To set locations, you can pass location_ids
with an array of Location ID's,
or include all_locations
with true
as the value to give the user access
to all locations.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/users"
client["users"]
.post({ "first_name"=>"John", "last_name"=>"Doe", "login"=>"johndoe", "email"=>"john@doe.com", "password"=>"password1", "sales_rep"=>"true", "role_ids"=>["111","222"], "location_ids"=>["1111","2222"] })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/users/126817
PUT /api/users/{{user_id}}
Users can be edited by PUTting a user record containing a valid subset of user attributes to the user's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}"
client["users/{{user_id}}"]
.put(my_user_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
PUT /api/users/profile
Update the current user profile by PUTting a user record containing a valid subset of user attributes to the /profile resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/users/profile"
client["users/profile"].put(my_user_object).status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/users/{{user_id}}
Users can be fetched by GETting the user's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}"
client["users/{{user_id}}"].get.body
{
"id": 102394
}
{"id"=>108893}
A user has one or more roles assigned to it. Each role grants at least one permission. For more information on managing roles see Roles.
The ID of the role record
The name of the role
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Count of users with the role
{
"id": 108662,
"users_count": 101013
}
{
"id": 100993,
"role_id": 104426,
"user_id": 101014
}
GET /api/users/{{user_id}}/roles
Users roles can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/roles/?per_page=1"
client["users/{{user_id}}/roles"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100410,
"users_count": 106490
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>[{"id"=>103920, "users_count"=>106542}, "..."]}
POST /api/users/{{user_id}}/roles
Users can be granted roles by POSTing them to the user's roles resource.
When successful, the response headers will contain a Location header that indicates the url at which the newly created role can be found. The role's unique id will be the last portion of that URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/roles"
client["users/123/roles"]
.post({ "role_id"=>"321" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/users/190948/roles/151626
GET /api/users/{{user_id}}/roles/{{role_id}}
User roles can be fetched by GETting the user role's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/roles/{{role_id}}"
client["users/{{user_id}}/roles/{{role_id}}"]
.get.body
{
"id": 101721,
"users_count": 102050
}
{"id"=>109481, "users_count"=>106613}
DELETE /api/users/{{user_id}}/roles/{{role_id}}
Remove a role from the user by sending a DELETE request to the user location's URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/roles/{{role_id}}"
client["users/{{user_id}}/roles/{{role_id}}"]
.delete.status
200
200
GET /api/users/{{user_id}}/permissions
Users permissions can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/permissions/?per_page=1"
client["users/{{user_id}}/permissions"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100405,
"role_id": 108896,
"user_id": 101264
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>[{"id"=>105642, "role_id"=>108865, "user_id"=>107366}, "..."]}
A user can have access to one or more locations. Only data attributed to those locations is accessible by the user. For more information on managing locations see Locations.
A location represents a physical space where sales transactions can take place.
unique identifier for the record
custom key/value information stored about this location
The name of the location
The unique identifier for the address record associated with this location
a unique identifier provided by the user for the purpose of coding information
unique identifier for the current revision of the address associated with this location
Whether or not this record is currently active and being used
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
unique identifier for the timezone record
The user who created this record
The most recent user who updated this record
Unique identifier for the location
An object that acts as a container for custom values defined in Heartland Retail as well as any arbitrary values stored by integrations or custom applications.
unique identifier for the price list record
key/value information stored about this locations settings
Whether the location has a credit card processor configured or not
{
"id": 100001,
"name": "Boston",
"address_id": 100004,
"public_id": "BOS",
"address_revision_id": 100016,
"timezone_identifier_id": 1,
"created_by_user_id": 108278,
"updated_by_user_id": 100307,
"uuid": "d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id": 1,
"credit_cards_configured": "false"
}
GET /api/users/{{user_id}}/locations
Users locations can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/locations/?per_page=1"
client["users/{{user_id}}/locations"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 100001,
"name": "Boston",
"address_id": 100004,
"public_id": "BOS",
"address_revision_id": 100016,
"timezone_identifier_id": 1,
"created_by_user_id": 105672,
"updated_by_user_id": 109808,
"uuid": "d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id": 1,
"credit_cards_configured": "false"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>100001,
"name"=>"Boston",
"address_id"=>100004,
"public_id"=>"BOS",
"address_revision_id"=>100016,
"timezone_identifier_id"=>1,
"created_by_user_id"=>103749,
"updated_by_user_id"=>107335,
"uuid"=>"d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id"=>1,
"credit_cards_configured"=>"false"},
"..."]}
GET /api/users/{{user_id}}/locations/{{location_id}}
User locations can be fetched by GETting the user location's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/locations/{{location_id}}"
client["users/{{user_id}}/locations/{{location_id}}"]
.get.body
{
"id": 103713,
"name": "Boston",
"address_id": 100004,
"public_id": "BOS",
"address_revision_id": 100016,
"timezone_identifier_id": 1,
"created_by_user_id": 104562,
"updated_by_user_id": 105360,
"uuid": "d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id": 1,
"credit_cards_configured": "false"
}
{"id"=>100001,
"name"=>"Boston",
"address_id"=>100004,
"public_id"=>"BOS",
"address_revision_id"=>100016,
"timezone_identifier_id"=>1,
"created_by_user_id"=>101948,
"updated_by_user_id"=>107243,
"uuid"=>"d0a77755-ddfb-4276-a523-afc7bb959b2d",
"price_list_id"=>1,
"credit_cards_configured"=>"false"}
POST /api/users/{{user_id}}/locations
Users can be granted access to locations by POSTing them to the user's locations resource.
When successful, the response headers will contain a Location header that indicates the url at which the newly created user location can be found. The user location's unique id will be the last portion of that URL.
If you want to grant access to all locations update the user record with
all_locations=true
flag instead.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"name":"Boston"}' "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/locations"
client["users/123/locations"]
.post({ "location_id"=>"321" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/users/168272/locations/174293
DELETE /api/users/{{user_id}}/locations/{{location_id}}
Remove access to a location from the user by sending a DELETE request to the user location's URL.
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/locations/{{location_id}}"
client["users/{{user_id}}/locations/{{location_id}}"]
.delete.status
200
200
Alerts represents the events that require the user's attention. Each alert is marked with a color to represent its severity: green, yellow, red.
Type of the alert
The severity of the alert. Can be red, yellow or green
Human-readable message of the alert
Additional information related to the alert
Count of times the alert has been triggered
{
"count": 100215
}
GET /api/users/{{user_id}}/alerts
Users alerts can be fetched by querying the user alerts' URL and providing
the location_id
parameter.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/users/{{user_id}}/alerts/?per_page=1"
client["users/{{user_id}}/alerts"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"count": 103440
},
"..."
]
}
{"total"=>42, "pages"=>5, "results"=>[{"count"=>107215}, "..."]}
A payment type is a record storing information about payment method.
Payment Type APIs make use of the payment_type
record type:
The unique public identifier for this payment type. This can be used to provide your own naming scheme to your payment types.
Name of the payment type
Financial account that you map to will be the account that is debited/credited when the journal entries are synced to a connected financial system.
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Kind of the payment type (PaymentType by default or GiftCardPaymentType for gift card payments)
PaymentType
, GiftCardPaymentType
Description of the payment type
Name of the custom fields group
Key of the payment type
Whether the payment type is accepted on sales order or not
Whether the payment amounts of this type should be defaulted to balance due or not
Whether the payment type is builtin or not
Whether or not this record is currently active and being used
Processing type of the payment type (either manual, webhooks, heartland, or big_commerce). Manual means that the payment is processed with Heartland Retail.
manual
, webhooks
, heartland
, big_commerce
URL to check the balance for webhooks payment types
URL to capture payments for webhooks payment types
URL to refund payments for webhooks payment types
URL to void payments for webhooks payment types
Financial account that you map to will be the account that is credited/debited when the journal entries are synced to a connected financial system.
Maximum amount of allowed refund for the payment type
Whether the payment type is configured in financial system correctly or not
(Only for gift card payment types) Financial account that you map to will be the account that is credited/debited when the journal entries of gift card adjustments are synced to a connected financial system.
{
"id": 105613,
"public_id": "cash",
"name": "Cash",
"payment_account_id": 108735,
"kind": "PaymentType",
"description": "Cash",
"custom_field_group": "payment_type.cash",
"key": "cash",
"deposit_account_id": 104389,
"max_refund_amount": 12.54,
"expiration_account_id": 103029
}
GET /api/payment_types
Payment Types can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/payment_types/?per_page=1"
client["payment_types"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 109457,
"public_id": "cash",
"name": "Cash",
"payment_account_id": 105744,
"kind": "PaymentType",
"description": "Cash",
"custom_field_group": "payment_type.cash",
"key": "cash",
"deposit_account_id": 100219,
"max_refund_amount": 16.2,
"expiration_account_id": 104222
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>104498,
"public_id"=>"cash",
"name"=>"Cash",
"payment_account_id"=>108244,
"kind"=>"PaymentType",
"description"=>"Cash",
"custom_field_group"=>"payment_type.cash",
"key"=>"cash",
"deposit_account_id"=>103810,
"max_refund_amount"=>94.78,
"expiration_account_id"=>107253},
"..."]}
POST /api/payment_types
Payment types are created by POSTing a payment type record containing the required
attributes to the /api/payment_types
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"name":"Cash"}' "https://{{subdomain}}.retail.heartland.us/api/payment_types"
client["payment_types"]
.post({ "name"=>"Custom Payment Type" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/payment_types/186755
PUT /api/payment_types/{{payment_type_id}}
Payment types can be edited by PUTting a payment type record containing a valid subset of payment type attributes to the payment type's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"public_id":"cash","name":"Cash","payment_account_id":102349,"kind":"PaymentType","description":"Cash","deposit_account_id":107937,"max_refund_amount":18.38,"expiration_account_id":102942}' "https://{{subdomain}}.retail.heartland.us/api/payment_types/{{payment_type_id}}"
client["payment_types/{{payment_type_id}}"]
.put(my_payment_type_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
GET /api/payment_types/{{payment_type_id}}
Payment types can be fetched by GETting the payment type's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/payment_types/{{payment_type_id}}"
client["payment_types/{{payment_type_id}}"]
.get.body
{
"id": 104894,
"public_id": "cash",
"name": "Cash",
"payment_account_id": 100133,
"kind": "PaymentType",
"description": "Cash",
"custom_field_group": "payment_type.cash",
"key": "cash",
"deposit_account_id": 106648,
"max_refund_amount": 77.57,
"expiration_account_id": 107014
}
{"id"=>109583,
"public_id"=>"cash",
"name"=>"Cash",
"payment_account_id"=>109370,
"kind"=>"PaymentType",
"description"=>"Cash",
"custom_field_group"=>"payment_type.cash",
"key"=>"cash",
"deposit_account_id"=>101542,
"max_refund_amount"=>29.83,
"expiration_account_id"=>103422}
The shipping methods resource exposes the ability to create and modify shipping methods in the Heartland Retail system.
The id of the shipping method record
Custom key/value information stored about this shipping method
The name of the shipping method
Whether or not this record is currently active and being used
Financial account that you map to will be the account that is debited/credited when the journal entries are synced to a connected financial system.
The cost of the shipping method that will be charged to the customer when this shipping method is applied to a Sales Order (if no amount is specified on the order)
Whether the shipping method is configured in financial system correctly or not
{
"id": 107998,
"name": "USPS",
"income_account_id": 102126,
"amount": 9.99
}
GET /api/shipping/methods
Shipping Methods can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/shipping/methods/?per_page=1"
client["shipping/methods"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 102829,
"name": "USPS",
"income_account_id": 104683,
"amount": 9.99
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>109914, "name"=>"USPS", "income_account_id"=>106255, "amount"=>9.99},
"..."]}
GET /api/shipping/methods/{{method_id}}
Shipping Methods can be fetched by GETting the shipping method's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/shipping/methods/{{method_id}}"
client["shipping/methods/{{method_id}}"].get.body
{
"id": 101412,
"name": "USPS",
"income_account_id": 101421,
"amount": 9.99
}
{"id"=>103288, "name"=>"USPS", "income_account_id"=>104881, "amount"=>9.99}
POST /api/shipping/methods
Shipping Methods are created by POSTing a shipping method record containing
the required attributes to the /api/shipping/methods
resource.
The amount specified on a shipping method is the default amount if no amount is specified on the order.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"name":"USPS","amount":9.99}' "https://{{subdomain}}.retail.heartland.us/api/shipping/methods"
client["shipping/methods"]
.post({ "name"=>"USPS", "amount"=>"50" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/shipping/methods/157898
PUT /api/shipping/methods/{{method_id}}
Shipping Methods can be edited by PUTting an shipping method record containing a valid subset of shipping method attributes to the shipping method's resource URL.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"name":"USPS","income_account_id":102821,"amount":9.99}' "https://{{subdomain}}.retail.heartland.us/api/shipping/methods/{{method_id}}"
client["shipping/methods/{{method_id}}"]
.put(my_shipping_method_object)
.status
# ...
# Status: 200 OK
# ...
# No Content
=> 200
The id of the adjustment record
The name of the reason
The description of the reason
Financial account that you map to will be the account that is credited/debited when the journal entries are synced to a connected financial system.
Whether or not this record is currently active and being used
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
Whether the reason is builtin or not
Whether the reason is configured in financial system correctly or not
{
"id": 102679,
"account_id": 102751
}
GET /api/reason_codes/gift_card_adjustment_reasons
Gift Card Adjustment Reasons can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/reason_codes/gift_card_adjustment_reasons/?per_page=1"
client["reason_codes/gift_card_adjustment_reasons"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 102703,
"account_id": 104640
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>[{"id"=>105613, "account_id"=>101925}, "..."]}
The gift cards resource exposes the ability to create and modify gift cards in the Heartland Retail system.
The id of the gift card record
The number of the gift card (case insensitive alphanumeric with no special characters)
The date and time that this record was created (in ISO8601 format)
The date and time that this record was last updated (in ISO8601 format)
The date after which the gift card may no longer be used
The uuid of the gift card record
The current balance of the gift card
{
"id": 105402,
"number": "GC12345",
"expires_at": "2025-08-05"
}
GET /api/gift_cards
Gift Cards can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/gift_cards/?per_page=1"
client["gift_cards"].query(per_page: 1).get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 103564,
"number": "GC12345",
"expires_at": "2025-08-05"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>107472, "number"=>"GC12345", "expires_at"=>"2025-08-05"}, "..."]}
GET /api/gift_cards/{{gift_card_number}}
Gift Cards can be fetched by GETting the gift card number's URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/gift_cards/{{gift_card_number}}"
client["gift_cards/{{gift_card_number}}"].get.body
{
"id": 100207,
"number": "GC12345",
"expires_at": "2025-08-05"
}
{"id"=>108894, "number"=>"GC12345", "expires_at"=>"2025-08-05"}
POST /api/gift_cards
Gift Cards are created by POSTing a gift card record containing the required
attributes to the /api/gift_cards
resource.
When successful, the response headers will contain a Location header that indicates the url at which the newly created gift card can be found. The gift card's unique number will be the last portion of that URL.
For more information on available adjustment reasons see Gift Card Adjustment Reasons.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"number":"GC12345"}' "https://{{subdomain}}.retail.heartland.us/api/gift_cards"
client["gift_cards"]
.post({ "number"=>"GC123456", "reason_id"=>"1", "expires_at"=>"2025-08-05" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/gift_cards/181844
The adjustments resource exposes the ability to modify a gift card balance without a sales transaction.
For more information on available adjustment reasons see Gift Card Adjustment Reasons.
The id of the adjustment record
The id of the gift card record
The id of the Reason Code record
The id of the user that created the adjustment
The amount of the adjustment
The date and time that this record was created (in ISO8601 format)
The date and time that this record was created in the location timezone (in ISO8601 format)
Gift Card Number
{
"id": 101985,
"gift_card_id": 107271,
"reason_id": 107962,
"created_by_user_id": 103027,
"delta_balance": 21.87,
"local_created_at": "2013-08-05T07:22:24-04:00"
}
GET /api/gift_card/adjustments
Gift Card Adjustments can be searched for, filtered and sorted by any of their properties. For more information on filtering search results see Filtering.
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.retail.heartland.us/api/gift_card/adjustments/?per_page=1"
client["gift_card/adjustments"]
.query(per_page: 1)
.get.body
{
"total": 42,
"pages": 5,
"results": [
{
"id": 104537,
"gift_card_id": 104371,
"reason_id": 100217,
"created_by_user_id": 104734,
"delta_balance": 95.55,
"local_created_at": "2013-08-05T07:22:24-04:00"
},
"..."
]
}
{"total"=>42,
"pages"=>5,
"results"=>
[{"id"=>103895,
"gift_card_id"=>101688,
"reason_id"=>101351,
"created_by_user_id"=>103753,
"delta_balance"=>53.02,
"local_created_at"=>"2013-08-05T07:22:24-04:00"},
"..."]}
GET /api/gift_card/adjustments/{{adjustment_id}}
Gift Card Adjustments can be fetched by GETting the gift card adjustment's resource URL.
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.retail.heartland.us/api/gift_card/adjustments/{{adjustment_id}}"
client["gift_card/adjustments/{{adjustment_id}}"]
.get.body
{
"id": 104818,
"gift_card_id": 103959,
"reason_id": 109905,
"created_by_user_id": 101258,
"delta_balance": 74.56,
"local_created_at": "2013-08-05T07:22:24-04:00"
}
{"id"=>106939,
"gift_card_id"=>105503,
"reason_id"=>106499,
"created_by_user_id"=>102443,
"delta_balance"=>44.08,
"local_created_at"=>"2013-08-05T07:22:24-04:00"}
POST /api/gift_card/adjustments
Gift Card Adjustments are created by POSTing a gift card adjustment record containing
the required attributes to the /api/gift_card/adjustments
resource.
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"gift_card_id":105659,"reason_id":105425,"delta_balance":84.55}' "https://{{subdomain}}.retail.heartland.us/api/gift_card/adjustments"
client["gift_card/adjustments"]
.post({ "gift_card_id"=>"123456", "delta_balance"=>"50", "reason_id"=>"1" })
.get.body
# ...
# Status: 201 Created
# ...
# No Content
/api/gift_card/adjustments/139025