Introduction

Springboard 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 Springboard.

All URL paths are relative to an account-specific subdomain: https://{{subdomain}}.myspringboard.us/api/

Have a suggestion for a correction or improvement to our API docs? Please open an issue on GitHub.

Client Libraries

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.

OAuth

OAuth2 is a protocol that lets external applications request authorization to private details in a user's Springboard 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 contact oauth@springboardretail.com.

OAuth Flow

1.) Requesting authorization

Redirect the user to to this URL to request access to their Springboard Retail account on your behalf:

https://myspringboard.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 Springboard Retail when you registered.
scope String Required. A space delimited list of requested permissions. See Scopes.
redirect_uri String 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.

2.) Issuing an access token

If the user authorizes your app, Springboard 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://myspringboard.us/api/oauth/token

Name Type Description
client_id String Required. The client ID you received from Springboard Retail when you registered.
client_secret String Required. The client secret you received from Springboard Retail when you registered.
code String Required. The code you received as a response to Step 1

You'll receive a JSON response containing an access_token:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
  "token_type": "bearer"
}

3.) Looking up the account's hostname

Interaction with the Springboard 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://myspringboard.us/api/system/host
Authorize: Bearer {{ access_token }}

Response:

{"host": "example.myspringboard.us"}

This host value should be used to construct the base URL for future API calls for that Springboard Retail account.

4.) Using access token and host

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 }}

Scopes

Name Description
cash_drawer.open Open cash drawer
cash_drawer.close Close cash drawer
customer.manage Create and manage customers
financial.event.read View financial events
gift_card.manage Manage gift cards and adjust balances
inventory.transaction.read View inventory history
inventory.transfer.ship Ship transfers
inventory.transfer.receive Receive transfers
inventory.transfer.resolve_discrepancies Resolve transfer discrepancies
inventory.values.read View current inventory values
location.read View locations
location.manage Manage locations
payment.manage Manage payments
purchasing.order.read.pending View pending orders
purchasing.order.read.closed View closed orders
purchasing.order.read.canceled View canceled orders
purchasing.order.manage Manage orders
purchasing.receipt.read View receipts
purchasing.return.manage Manage returns
purchasing.return.read View returns
purchasing.vendor.manage Manage vendors
purchasing.vendor.read View vendors
sales.order.manage Manage sales orders
sales.ticket.manage Manage POS tickets
sales.tax.manage Manage sales tax
sales.daily_summary.read View Daily Summary
station.manage Manage stations
user.manage Manage users
reporting.read View reporting
reporting.read.group.location Group reports by location
reporting.read.group.item Group reports by item
reporting.read.group.customer Group reports by customer
reporting.read.group.date Group reports by date
reporting.read.group.payment Group reports by payment type
reporting.read.group.inventory_adjustment Group reports by inventory adjustment reason
reporting.read.group.purchasing Group reports by purchase order
reporting.read.metric Group by metric
reporting.read.metric.source_sales View source sales metrics
reporting.read.metric.beginning_inventory View beginning inventory values
reporting.read.metric.beginning_gift_card View beginning gift card balances
reporting.read.metric.ending_gift_card View ending gift card balances
reporting.read.metric.payment View payment type metrics
reporting.read.metric.sales_tax View sales tax metrics
reporting.read.metric.inventory_adjustment View inventory adjustment metrics
reporting.read.metric.purchasing View purchasing metrics
reporting.modify Modify reports
reporting.saved_reports.read View Saved Reports
cash_paid.create Create cash paid out/in transactions
shipping_method.manage Manage shipping methods
role.manage Manage roles
cash_drawer.manage Manage cash drawers
custom_field.manage Manage custom fields
customer.export Export customers
customer.merge Merge customers
customer.read View customers
financial.manage Manage financial configuration
reason_codes.manage Manage reason codes
integrations.manage Manage integrations
inventory.adjustment.manage Manage adjustments
inventory.threshold.manage Edit item reorder points and target quantity
inventory.bin.manage Update bin locations
inventory.transfer.read View transfers
inventory.transfer.recall_shipment Recall transfer shipments
inventory.counts.create Create physical counts
inventory.counts.finalize Review discrepancies and accept physical counts
inventory.vendor.read View inventory vendor information
item.manage Manage items and grids
item.view_cost View item cost and margin information
item.create_on_fly Create items on the fly
item.export Export items
item.merge Merge items
payment.read View payments
pos.manage Manage POS settings
purchasing.order.read View all orders
purchasing.order.read.open View open orders
purchasing.receipt.manage Manage receipts
purchasing.receipt.select_from_order Select receipt items from purchase order
sales.invoice.manage Create and fulfill invoices from sales orders
sales.order.view View sales orders
sales.order.edit Create and edit sales orders
sales.order.distribute Distribute sales orders
sales.order.adjust_item_price Adjust item prices on a sales order
sales.promotions.manage Manage promotions
sales.coupons.read View and redeem coupons
sales.coupons.manage Manage coupons
sales.transaction.adjust_item_price Adjust item prices in the POS
setting.manage Manage general settings
reporting.sales.read Read sales dashboard reports
reporting.read.group.sales_transaction Group reports by sales transaction
reporting.read.group.time Group reports by time
reporting.read.group.gift_card Group reports by gift card payments
reporting.read.group.inventory_transfer Group reports by inventory transfer
reporting.read.group.vendor Group reports by vendor
reporting.read.metric.source_sales_gift_cards View source sales gift cards issued metrics
reporting.read.metric.location_sales View location sales metrics
reporting.read.metric.ending_inventory View ending inventory values
reporting.read.metric.current_inventory View current inventory values
reporting.read.metric.gift_card.expire View gift card expirations
reporting.read.metric.shipping View shipping metrics
reporting.read.metric.inventory_transfer View transfer metrics
reporting.saved_reports.manage Manage Saved Reports
cash_paid.read View cash paid out/in history
payment_type.manage Manage payment types
grid_templates.manage Manage grid templates
sales_plans.manage Manage sales plans
webhooks.manage Manage Webhooks

Authentication

Accessing the Springboard 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 Springboard Retail click the name in the top right corner of the Springboard 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:

  1. Click the "Generate new token" button. This will bring you to the "New API Token" page.
  2. Type in a description for the API Token.
  3. Click the "Generate Token" button.
  4. API Token will appear. Be sure to copy your new API token now. You won’t be able to see it again.
  5. Click the "Done" button.

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 Springboard 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

Request:
require 'springboard-retail'
springboard = Springboard::Client.new(
  'https://{{subdomain}}.myspringboard.us/api',
  token: '{{token}}'
)
curl -H "Authorization: Bearer {{token}}" "https://{{subdomain}}.myspringboard.us/api/system/whoami"
Response:
true
{"id": 100001, "login": "login", "first_name": "", "last_name": ""}

Search Results

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:

  • page - which page in the results set to retrieve.
  • per_page - how many records to return in each page.

Search Results

total:
Integer

Total number of records returned by the search

pages:
Integer

The number of pages of results

results:
Array

A list of result objects

Filtering

Filtering

Collection resources can be filtered in several ways:

Full-Text Queries

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

Filters

Advanced filters use a JSON-encoded query language. This can be specified in one of two ways:

  1. Encoded as query string parameter hash (for convenience)
  2. As a JSON encoded string (for more complex queries)

In each case the value is passed via the _filter parameter or the shorthand ~ parameter. Both parameter names are equivalent.

Using query string parameters

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)

Using JSON

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)

Comparison Operators

  • $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

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.

  • Starts with: /api/items?~[custom@color][$like]=blue*
  • Ends with: /api/items?~[custom@color][$like]=*blue
  • Contains: /api/items?~[custom@color][$like]=*blue*

Logical Operators

Logical operators can be arbitrarily nested.

  • $and - Group array of nested expressions with logical AND
  • $or - Group array of nested expressions with logical OR

Custom Fields

Custom fields can be used in any filter expression with this syntax:

/api/items?~[custom@color]=blue
/api/items?~[custom@score][$gt]=100

Filtering Null Values

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)

Filtering with references to other fields

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)

Embedding

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"
  }
}

Reporting

Reporting API

GET /api/reporting/analyzer

Params

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

Metrics

Source Sales

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

Location Sales

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

Beginning Inventory

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

Ending Inventory

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

Shipping

Supported groups: locations.*

  • shipping.net_shipping_income

Payments

Supported groups: locations.*, payments.*, credit_card_payments.*

  • payment.payment_type_count
  • payment.credit_card_type_count
  • payment.payments_received
  • payment.refunds
  • payment.net_payments

Groups

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

  • item.public_id
  • item.description
  • item.custom@*key*

Customer

  • customer.public_id
  • customer.first_name
  • customer.last_name
  • customer.email
  • customer.custom@*key*

Location

  • location.public_id
  • location.name

Date

  • 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
  • time.hour

Payment

  • payment.type

Credit Card Payment

  • credit_card_payment.type

Inventory

Inventory APIs control everything related to items in the system, their inventory values, adjusting inventory, and transfering inventory between locations

Items

The items resource exposes the ability to create and modify items in the Springboard Retail system. The vast majority of item APIs make use of the item record type:

Item

id:
integer (required)
public_id:
text

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.

metadata:
text

a placeholder for custom data (deprecated)

cost:
numeric(10,2) (required)

The default cost of purchasing this item

price:
numeric(10,2) (required)

The default sales price

description:
text

A short description of the item.

long_description:
text

A long description of the item

custom:
hash

An object that acts as a container for custom values defined in Springboard Retail as well as any arbitrary values stored by integrations or custom applications.

active:
Boolean

Whether or not this record is currently active and being used

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

financial_class_id:
integer

The id of the financial class this item belongs to.

import_batch_id:
integer

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.

primary_vendor_id:
integer

The id for the primary vendor record that supplies this item.

Item Example:
{
  "id": 105515,
  "cost": 10.17,
  "price": 74.16,
  "financial_class_id": 101485,
  "import_batch_id": 100122,
  "primary_vendor_id": 104349
}

Create an item

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"cost":46.58,"price":17.59}' "https://{{subdomain}}.myspringboard.us/api/items"
springboard["items"]
  .post({"cost"=>74.75, "price"=>11.02})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/items/162616

Retrieve an item

GET /api/items/{{item_id}}

Items are retrieved from the Springboard 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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/items/{{item_id}}"
springboard["items/{{item_id}}"].get.body
Response:
{
  "id": 104607,
  "cost": 95.47,
  "price": 24.48,
  "financial_class_id": 106398,
  "import_batch_id": 100891,
  "primary_vendor_id": 102138
}
{"id"=>100629,
 "cost"=>56.66,
 "price"=>16.85,
 "financial_class_id"=>102220,
 "import_batch_id"=>105331,
 "primary_vendor_id"=>104490}

Update an item

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"cost":71.39,"price":94.67,"financial_class_id":100436,"import_batch_id":102466,"primary_vendor_id":100254}' "https://{{subdomain}}.myspringboard.us/api/items/102427"
springboard["items/{{item_id}}"]
  .put(my_item_object)
  .status
Response:
# ...
# Status: 200 OK
# ...

# No Content
=> 200

Search items

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/items/?per_page=1"
springboard["items"].query(per_page: 1).get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 101846,
      "cost": 80.33,
      "price": 86.77,
      "financial_class_id": 106409,
      "import_batch_id": 103493,
      "primary_vendor_id": 103579
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>102399,
    "cost"=>20.71,
    "price"=>51.83,
    "financial_class_id"=>103799,
    "import_batch_id"=>102887,
    "primary_vendor_id"=>107258},
   "..."]}

Merge duplicate items

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"slave_ids":[100002,100003]}' "https://{{subdomain}}.myspringboard.us/api/items/{{item_id}}/merges"
springboard["items/{{item_id}}/merges"]
  .post({"slave_ids"=>[100002, 100003]})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/items/140931/merges/123534

Item grids

The items resource exposes the ability to create and modify items in the Springboard Retail system. The vast majority of item grids APIs make use of the item record type:

Item grid

id:
integer (required)
metadata:
text

a placeholder for custom data

description:
text (required)

A short description of the item.

long_description:
text

A long description of the item

item_cost:
numeric(10,2)

The default cost of purchasing this item

item_price:
numeric(10,2)

The default sales price

item_original_price:
numeric(10,2)

The original sales price

item_custom:
hash

An object that acts as a container for custom values defined in Springboard Retail as well as any arbitrary values stored by integrations or custom applications.

active:
Boolean

Whether or not this record is currently active and being used

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

item_financial_class_id:
integer

The id of the financial class this item belongs to.

item_primary_vendor_id:
integer

The id for the primary vendor record that supplies this item.

Item grid Example:
{
  "id": 109180,
  "item_cost": 83.26,
  "item_price": 23.96,
  "item_original_price": 74.26,
  "item_financial_class_id": 101365,
  "item_primary_vendor_id": 102472
}

Create an item grid

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/item_grids"
springboard["item_grids"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/item_grids/114252

Retrieve an item grid

GET /api/item_grids/{{item_grid_id}}

Item grids are retrieved from the Springboard 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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/item_grids/{{item_grid_id}}"
springboard["item_grids/{{item_grid_id}}"]
  .get.body
Response:
{
  "id": 100180,
  "item_cost": 60.76,
  "item_price": 69.63,
  "item_original_price": 27.95,
  "item_financial_class_id": 102423,
  "item_primary_vendor_id": 109711
}
{"id"=>104868,
 "item_cost"=>75.45,
 "item_price"=>29.59,
 "item_original_price"=>50.83,
 "item_financial_class_id"=>101289,
 "item_primary_vendor_id"=>109872}

Update an item grid

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"item_cost":46.62,"item_price":76.86,"item_original_price":76.06,"item_financial_class_id":107584,"item_primary_vendor_id":103972}' "https://{{subdomain}}.myspringboard.us/api/item/grids/103683"
springboard["item_grids/{{item_grid_id}}"]
  .put(my_item_grid_object)
  .status
Response:
# ...
# Status: 200 OK
# ...

# No Content
=> 200

Search item grids

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/item_grids/?per_page=1"
springboard["item_grids"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 105049,
      "item_cost": 87.99,
      "item_price": 43.65,
      "item_original_price": 64.9,
      "item_financial_class_id": 103287,
      "item_primary_vendor_id": 107160
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>102512,
    "item_cost"=>22.34,
    "item_price"=>76.93,
    "item_original_price"=>26.94,
    "item_financial_class_id"=>103937,
    "item_primary_vendor_id"=>101795},
   "..."]}

Inventory Values

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.

Retrieve inventory values by item

GET /api/inventory/values

Inventory values are retrieved via a GET request to /api/inventory/values.

Request:
springboard[:inventory][:values].query(group: [:location_id]).get.body
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/inventory/values?group\[\]=item_id&per_page=2"
Response:
{"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
      }
   ]
}

Inventory Transactions

Springboard 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:

Inventory Transaction

id:
integer (required)

The unique identifier for a transaction

item_id:
integer (required)

the item id whose inventory was altered.

unit_cost:
numeric(10,2) (required)

the per-item cost for the items altered in this transaction

location_id:
integer (required)

the id of the location whose inventory is being altered

delta_qty:
numeric(10,2)

the change in quantity

delta_qty_on_po:
numeric(10,2)

the change in quantity pending on a purchase order

delta_qty_committed:
numeric(10,2)

the change in quantity committed to a sale

delta_qty_in_transit:
numeric

the change in quantity being transferred between stores

created_at:
DateTime

The date and time that this record was created

Inventory Transaction Example:
{
  "id": 109796,
  "item_id": 106078,
  "unit_cost": 56.9,
  "location_id": 106100,
  "delta_qty": 51.96,
  "delta_qty_on_po": 41.6,
  "delta_qty_committed": 12.77
}

Search inventory transactions

GET /api/inventory/transactions

Searching and filtering inventory transactions is done via a simple GET request to /api/inventory/transactions.

Request:
springboard[:inventory][:transactions].query(per_page: 2).get.body
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/inventory/transactions?per_page=2"
Response:
{
  "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
    }
  ]
}

Sales

Sales APIs expose the ability to manage customers, sales orders, and promotions as well as exposing APIs to retrieve information about sales tickets, cash paid transactions, and sales history data.

Tickets

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.

Sales Ticket

id:
integer (required)
metadata:
text
type:
text (required)
customer_id:
integer
source_location_id:
integer
sales_rep:
text
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

public_id:
text
station_id:
integer
parent_transaction_id:
integer
recalculate:
boolean
status:
text
order_id:
integer
total:
numeric(10,2)
created_by_user_id:
integer
completed_at:
DateTime

The date and time that this ticket was completed

affect_inventory:
boolean

Whether or not the ticket should affect inventory on completion

Sales ItemLine

id:
integer (required)
type:
text (required)
sales_transaction_id:
integer
description:
text
value:
numeric(10,2)
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

qty:
numeric(10,2)
adjusted_unit_price:
numeric(10,2)
unit_cost:
numeric(10,2)
original_unit_price:
numeric(10,2)
item_id:
integer (required)
action_id:
text
shipping_line_id:
integer
item_line_id:
integer
sales_transaction_line_id:
integer
address_id:
integer
shipping_method_id:
integer
manually_added:
boolean
reason_codes:
text
lookup_id:
integer
customer_id:
integer
loyalty_points:
integer
order_line_id:
integer
address_revision_id:
integer
order_discount_id:
integer
gift_card_id:
integer
tax_rule_id:
integer

Payment

A payment for use in a sales transaction

id:
integer (required)
type:
text (required)

The payment type. Valid options: "CashPayment", "CreditCardPayment", "CheckPayment", "CustomPayment", "ExternalPayment"

status:
text

The payment's current status indicating whether or not it has been captured.

amount:
numeric(10,2) (required)

The amount of money to pay.

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Sales Ticket Example:
{
  "id": 101387,
  "customer_id": 104081,
  "source_location_id": 106747,
  "station_id": 103669,
  "parent_transaction_id": 100356,
  "order_id": 100001,
  "total": 36.89,
  "created_by_user_id": 100454,
  "completed_at": "2013-08-05T09:22:24-04:00"
}
Sales ItemLine Example:
{
  "id": 109168,
  "type": "ItemLine",
  "sales_transaction_id": 105873,
  "value": 19.37,
  "qty": 4.0,
  "adjusted_unit_price": 98.36,
  "unit_cost": 74.19,
  "original_unit_price": 69.43,
  "item_id": 100001,
  "shipping_line_id": 108084,
  "item_line_id": 109452,
  "sales_transaction_line_id": 102923,
  "address_id": 101054,
  "shipping_method_id": 109372,
  "lookup_id": 105250,
  "customer_id": 101224,
  "loyalty_points": 100924,
  "order_line_id": 106162,
  "address_revision_id": 106012,
  "order_discount_id": 107165,
  "gift_card_id": 109779,
  "tax_rule_id": 101348
}
Payment Example:
{
  "id": 105210,
  "type": "CashPayment",
  "amount": 70.06
}

Create a ticket

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/sales/tickets"
springboard["sales/tickets"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/tickets/139214

Retrieve a ticket

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/sales/tickets/{{ticket_id}}"
springboard["sales/tickets/{{ticket_id}}"]
  .get.body
Response:
{
  "id": 102890,
  "customer_id": 100924,
  "source_location_id": 107393,
  "station_id": 105398,
  "parent_transaction_id": 107818,
  "order_id": 105818,
  "total": 33.66,
  "created_by_user_id": 102306,
  "completed_at": "2013-08-05T09:22:24-04:00"
}
{"id"=>107740,
 "customer_id"=>100560,
 "source_location_id"=>109445,
 "station_id"=>105336,
 "parent_transaction_id"=>100467,
 "order_id"=>101916,
 "total"=>31.15,
 "created_by_user_id"=>102512,
 "completed_at"=>"2013-08-05T09:22:24-04:00"}

Retrieve a ticket's lines

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 item
  • TaxLine - Sales tax charge or refund
  • DiscountLine - Discount to another type of line
  • ShippingLine - Shipping charge, discount or refund

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/sales/tickets/{{ticket_id}}/lines/?per_page=1"
springboard["sales/tickets/{{ticket_id}}/lines"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 108313,
      "type": "ItemLine",
      "sales_transaction_id": 103873,
      "value": 45.89,
      "qty": 4.0,
      "adjusted_unit_price": 16.99,
      "unit_cost": 63.27,
      "original_unit_price": 20.36,
      "item_id": 100001,
      "shipping_line_id": 106853,
      "item_line_id": 103357,
      "sales_transaction_line_id": 103569,
      "address_id": 100430,
      "shipping_method_id": 104912,
      "lookup_id": 109835,
      "customer_id": 105020,
      "loyalty_points": 106768,
      "order_line_id": 101356,
      "address_revision_id": 105815,
      "order_discount_id": 107277,
      "gift_card_id": 107187,
      "tax_rule_id": 103450
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>108402,
    "type"=>"ItemLine",
    "sales_transaction_id"=>104205,
    "value"=>97.25,
    "qty"=>4.0,
    "adjusted_unit_price"=>72.44,
    "unit_cost"=>13.07,
    "original_unit_price"=>75.74,
    "item_id"=>100001,
    "shipping_line_id"=>102327,
    "item_line_id"=>101102,
    "sales_transaction_line_id"=>106220,
    "address_id"=>105993,
    "shipping_method_id"=>108702,
    "lookup_id"=>106659,
    "customer_id"=>102974,
    "loyalty_points"=>103378,
    "order_line_id"=>108648,
    "address_revision_id"=>103905,
    "order_discount_id"=>100734,
    "gift_card_id"=>109413,
    "tax_rule_id"=>100116},
   "..."]}

Add an item line to a ticket

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"ItemLine","item_id":100001}' "https://{{subdomain}}.myspringboard.us/api/sales/tickets/{{ticket_id}}/item_lines"
springboard["sales/tickets/{{ticket_id}}/item_lines"]
  .post({"type"=>"ItemLine", "item_id"=>100001})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/tickets/113570/item_lines/120393

Add a payment to a ticket

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"CashPayment","amount":16.28}' "https://{{subdomain}}.myspringboard.us/api/sales/tickets/{{ticket_id}}/payments"
springboard["sales/tickets/{{ticket_id}}/payments"]
  .post({"type"=>"CashPayment", "amount"=>80.62})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/tickets/146091/payments/181819

Add a coupon to a ticket

PUT /api/sales/tickets/{{ticket_id}}

Adds a coupon to the ticket. See the coupon data type for more details.

Request:
springboard[: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}}.myspringboard.us/api/sales/tickets/403993"
Response:
200 # success!
# ...
# Status: 200 OK
# ...

# No Content.

Update a ticket

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.

Request:
springboard[: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}}.myspringboard.us/api/sales/tickets/403993"
Response:
200 # success!
# ...
# Status: 200 OK
# ...

# No Content.

Search tickets

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/sales/tickets/?per_page=1"
springboard["sales/tickets"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 106287,
      "customer_id": 107034,
      "source_location_id": 102496,
      "station_id": 108251,
      "parent_transaction_id": 105304,
      "order_id": 104760,
      "total": 55.11,
      "created_by_user_id": 106383,
      "completed_at": "2013-08-05T09:22:24-04:00"
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>107789,
    "customer_id"=>104548,
    "source_location_id"=>101268,
    "station_id"=>103815,
    "parent_transaction_id"=>107004,
    "order_id"=>108890,
    "total"=>24.36,
    "created_by_user_id"=>101209,
    "completed_at"=>"2013-08-05T09:22:24-04:00"},
   "..."]}

Orders

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

Sales Order

id:
integer (required)
customer_id:
integer (required)
station_id:
integer
source_location_id:
integer (required)
status:
text

The status of the order. Valid options: "pending", "open", "canceled", "closed"

sales_rep:
text
recalculate:
boolean
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

shipping_method_id:
integer
shipping_charge:
numeric(10,2)
billing_address_id:
integer
shipping_address_id:
integer

Sales OrderLine

id:
integer (required)
item_id:
integer (required)
description:
text
qty:
numeric(10,2) (required)
adjusted_unit_price:
numeric(10,2)
original_unit_price:
numeric(10,2)
unit_cost:
numeric(10,2)
total_tax:
numeric(10,2)

Extended tax amount to collect for the line

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

qty_open:
numeric(10,2)
qty_invoiced:
numeric(10,2)
order_id:
integer
ship_from_location_id:
integer
discounts:
array

List of Sales OrderLineDiscount to be applied

Sales OrderPayment

A payment for use in a sales order

id:
integer (required)
type:
text (required)

The payment type. Valid options: "CashPayment", "CreditCardPayment", "CheckPayment", "CustomPayment", "ExternalPayment"

status:
text

The payment's current status indicating whether or not it has been captured.

deposit:
boolean (required)

If true, the funds are captured immediately. Otherwise funds are captured when fulfilling the order.

amount:
numeric(10,2) (required)

The amount of money to pay.

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Sales Order Example:
{
  "id": 101027,
  "customer_id": 109324,
  "station_id": 108045,
  "source_location_id": 102614,
  "status": "pending",
  "shipping_method_id": 108314,
  "shipping_charge": 70.29,
  "billing_address_id": 108158,
  "shipping_address_id": 102083
}
Sales OrderLine Example:
{
  "id": 105905,
  "item_id": 104184,
  "qty": 2.0,
  "adjusted_unit_price": 41.72,
  "original_unit_price": 72.73,
  "unit_cost": 11.44,
  "total_tax": 12.5,
  "qty_open": 41.0,
  "qty_invoiced": 58.58,
  "order_id": 105416,
  "ship_from_location_id": 103010,
  "discounts": [
    {
      "description": "Discount",
      "amount": 12.34
    }
  ]
}
Sales OrderPayment Example:
{
  "id": 105806,
  "type": "CashPayment",
  "deposit": true,
  "amount": 27.8
}

Create an order

POST /api/sales/orders

Creating sales orders requires you to have a customer_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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"customer_id":104646,"source_location_id":105259}' "https://{{subdomain}}.myspringboard.us/api/sales/orders"
springboard["sales/orders"]
  .post({"customer_id"=>103448, "source_location_id"=>104536})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/orders/116492

Retrieve an order

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/sales/orders/{{order_id}}"
springboard["sales/orders/{{order_id}}"].get.body
Response:
{
  "id": 100377,
  "customer_id": 100065,
  "station_id": 102615,
  "source_location_id": 108856,
  "status": "pending",
  "shipping_method_id": 101394,
  "shipping_charge": 94.68,
  "billing_address_id": 102646,
  "shipping_address_id": 105054
}
{"id"=>102545,
 "customer_id"=>107678,
 "station_id"=>103902,
 "source_location_id"=>103114,
 "status"=>"pending",
 "shipping_method_id"=>106153,
 "shipping_charge"=>14.01,
 "billing_address_id"=>102682,
 "shipping_address_id"=>101993}

Add an item to an order

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":104541,"qty":2.0}' "https://{{subdomain}}.myspringboard.us/api/sales/orders/{{order_id}}/lines"
springboard["sales/orders/{{order_id}}/lines"]
  .post({"item_id"=>107865, "qty"=>2.0})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/orders/136220/lines/189366

Add an item to an order with discounts

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":104603,"qty":2.0,"discounts":[{"description":"Discount","amount":12.34}]}' "https://{{subdomain}}.myspringboard.us/api/sales/orders/{{order_id}}/lines"
springboard["sales/orders/{{order_id}}/lines"]
  .post({"item_id"=>104169, "qty"=>2.0, "discounts"=>[{"description"=>"Discount", "amount"=>12.34}]})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/orders/144217/lines/143006

Retrieve an orders's lines

GET /api/sales/order/{{order_id}}/lines

A sales order has zero or more associated item lines.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/sales/order/{{order_id}}/lines/?per_page=1"
springboard["sales/order/{{order_id}}/lines"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 107922,
      "item_id": 106486,
      "qty": 2.0,
      "adjusted_unit_price": 35.01,
      "original_unit_price": 83.27,
      "unit_cost": 84.66,
      "total_tax": 12.5,
      "qty_open": 67.41,
      "qty_invoiced": 24.69,
      "order_id": 101987,
      "ship_from_location_id": 101264,
      "discounts": [
        {
          "description": "Discount",
          "amount": 12.34
        }
      ]
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>108384,
    "item_id"=>103254,
    "qty"=>2.0,
    "adjusted_unit_price"=>44.16,
    "original_unit_price"=>59.66,
    "unit_cost"=>87.82,
    "total_tax"=>12.5,
    "qty_open"=>27.33,
    "qty_invoiced"=>22.59,
    "order_id"=>108836,
    "ship_from_location_id"=>105651,
    "discounts"=>[{"description"=>"Discount", "amount"=>12.34}]},
   "..."]}

Distribute an item line on an order

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

Request:
springboard[: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}}.myspringboard.us/api/sales/orders/403993/lines/135225"
Response:
200 # success!
# ...
# Status: 200 OK
# ...

Add shipping to an order

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.

Request:
springboard[: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}}.myspringboard.us/api/sales/orders/403993/"
Response:
200 # success!
# ...
# Status: 200 OK
# ...

Add a payment to an order

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"type":"CashPayment","deposit":true,"amount":28.34}' "https://{{subdomain}}.myspringboard.us/api/sales/orders/{{order_id}}/payments"
springboard["sales/orders/{{order_id}}/payments"]
  .post({"type"=>"CashPayment", "deposit"=>true, "amount"=>48.34})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/orders/138795/payments/196488

Update an order

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

Request:
springboard[:sales][:orders][403992].put(status: 'open').status
curl -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"status":"open"}' "https://{{subdomain}}.myspringboard.us/api/sales/orders/403993"
Response:
200 # success!
# ...
# Status: 200 OK
# ...

Search orders

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/sales/orders/?per_page=1"
springboard["sales/orders"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 106773,
      "customer_id": 102620,
      "station_id": 108699,
      "source_location_id": 109442,
      "status": "pending",
      "shipping_method_id": 104442,
      "shipping_charge": 38.99,
      "billing_address_id": 100282,
      "shipping_address_id": 107619
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>103041,
    "customer_id"=>102429,
    "station_id"=>102787,
    "source_location_id"=>104318,
    "status"=>"pending",
    "shipping_method_id"=>109272,
    "shipping_charge"=>16.79,
    "billing_address_id"=>104228,
    "shipping_address_id"=>101390},
   "..."]}

Invoices

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

Sales Invoice

id:
integer (required)
metadata:
text
type:
text (required)
customer_id:
integer
source_location_id:
integer
sales_rep:
text
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

public_id:
text
station_id:
integer
parent_transaction_id:
integer
recalculate:
boolean
status:
text
order_id:
integer
total:
numeric(10,2)
created_by_user_id:
integer
Sales Invoice Example:
{
  "id": 104347,
  "customer_id": 104349,
  "source_location_id": 106996,
  "station_id": 102337,
  "parent_transaction_id": 103738,
  "order_id": 106447,
  "total": 73.53,
  "created_by_user_id": 102029
}

Create an invoice

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/sales/invoices"
springboard["sales/invoices"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/sales/invoices/166444

Retrieve an invoice

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/sales/invoices/{{invoice_id}}"
springboard["sales/invoices/{{invoice_id}}"]
  .get.body
Response:
{
  "id": 101656,
  "customer_id": 105488,
  "source_location_id": 100848,
  "station_id": 104641,
  "parent_transaction_id": 101340,
  "order_id": 105519,
  "total": 38.43,
  "created_by_user_id": 101621
}
{"id"=>105536,
 "customer_id"=>107422,
 "source_location_id"=>108645,
 "station_id"=>101188,
 "parent_transaction_id"=>107192,
 "order_id"=>106869,
 "total"=>31.33,
 "created_by_user_id"=>103049}

Retrieve an invoice's lines

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 item
  • TaxLine - Sales tax charge or refund
  • DiscountLine - Discount to another type of line
  • ShippingLine - Shipping charge, discount or refund

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/sales/invoices/{{invoice_id}}/lines/?per_page=1"
springboard["sales/invoices/{{invoice_id}}/lines"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 101777,
      "type": "ItemLine",
      "sales_transaction_id": 100926,
      "value": 79.81,
      "qty": 4.0,
      "adjusted_unit_price": 13.08,
      "unit_cost": 12.36,
      "original_unit_price": 84.1,
      "item_id": 100001,
      "shipping_line_id": 107800,
      "item_line_id": 108344,
      "sales_transaction_line_id": 102494,
      "address_id": 105002,
      "shipping_method_id": 106636,
      "lookup_id": 109975,
      "customer_id": 106094,
      "loyalty_points": 105993,
      "order_line_id": 108572,
      "address_revision_id": 100066,
      "order_discount_id": 107174,
      "gift_card_id": 105640,
      "tax_rule_id": 103915
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>102256,
    "type"=>"ItemLine",
    "sales_transaction_id"=>108983,
    "value"=>60.78,
    "qty"=>4.0,
    "adjusted_unit_price"=>79.43,
    "unit_cost"=>47.28,
    "original_unit_price"=>29.73,
    "item_id"=>100001,
    "shipping_line_id"=>102769,
    "item_line_id"=>102032,
    "sales_transaction_line_id"=>106793,
    "address_id"=>108565,
    "shipping_method_id"=>108305,
    "lookup_id"=>107329,
    "customer_id"=>104672,
    "loyalty_points"=>106086,
    "order_line_id"=>109345,
    "address_revision_id"=>104785,
    "order_discount_id"=>103177,
    "gift_card_id"=>100420,
    "tax_rule_id"=>105454},
   "..."]}

Update an invoice

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

Request:
springboard[:sales][:invoices][403992].put(status: 'void').status
curl -H "Authorization: Bearer {{Token}}" -X PUT -H "Content-Type: application/json" -d '{"status":"void"}' "https://{{subdomain}}.myspringboard.us/api/sales/invoices/403993"
Response:
200 # success!
# ...
# Status: 200 OK
# ...

# No Content.

Search invoices

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/sales/invoices/?per_page=1"
springboard["sales/invoices"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 104405,
      "customer_id": 101188,
      "source_location_id": 101755,
      "station_id": 106707,
      "parent_transaction_id": 105045,
      "order_id": 102892,
      "total": 83.48,
      "created_by_user_id": 106850
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>103383,
    "customer_id"=>106251,
    "source_location_id"=>104076,
    "station_id"=>109672,
    "parent_transaction_id"=>107883,
    "order_id"=>109105,
    "total"=>42.81,
    "created_by_user_id"=>108254},
   "..."]}

Customers

Customer APIs expose the ability to create, retrieve, update, and search for customers. The customer APIs make use of the customer record.

Customer

id:
integer (required)
public_id:
text

Unique ID string

first_name:
text

First name

last_name:
text

Last name

email:
text

Email address

address_id:
integer

ID of default address record

shipping_address_id:
integer

ID of address record used for shipping

billing_address_id:
integer

ID of address record used for billing

active:
Boolean

Whether or not this record is currently active and being used

customer_import_batch_id:
integer

ID of batch if this record was created as part of an import batch

custom:
object

Custom field values

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Address

id:
integer
address_id:
integer
current_revision_id:
integer
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

type:
text
first_name:
text
last_name:
text
line_1:
text
line_2:
text
city:
text
state:
text

If the country is set to 'US' then 2 letter state acronym required

phone:
text
country:
text

Set to 2 letter country acronym. Set value to anything other than 'US' to use a non standard state/postal_code

postal_code:
text

If the country is set to 'US' then a 5 digit ZIP or ZIP+4 code is required

custom:
object

Custom field values

Customer Example:
{
  "id": 108633,
  "first_name": "Walter",
  "last_name": "White",
  "email": "walter@example.com",
  "address_id": 106478,
  "shipping_address_id": 103040,
  "billing_address_id": 101491,
  "customer_import_batch_id": 100281,
  "custom": {
    "custom1": "Custom value 1",
    "custom2": "Custom value 2"
  }
}
Address Example:
{
  "id": 108880,
  "address_id": 104512,
  "current_revision_id": 106529,
  "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"
  }
}

Create a customer

POST /api/customers

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/customers"
springboard["customers"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/customers/144561

Retrieve a customer

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/customers/{{customer_id}}"
springboard["customers/{{customer_id}}"].get.body
Response:
{
  "id": 103199,
  "first_name": "Walter",
  "last_name": "White",
  "email": "walter@example.com",
  "address_id": 100917,
  "shipping_address_id": 102770,
  "billing_address_id": 105866,
  "customer_import_batch_id": 104409,
  "custom": {
    "custom1": "Custom value 1",
    "custom2": "Custom value 2"
  }
}
{"id"=>108887,
 "first_name"=>"Walter",
 "last_name"=>"White",
 "email"=>"walter@example.com",
 "address_id"=>101318,
 "shipping_address_id"=>100532,
 "billing_address_id"=>105361,
 "customer_import_batch_id"=>106591,
 "custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"}}

Update a customer

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

Request:
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":100045,"shipping_address_id":101889,"billing_address_id":109605,"customer_import_batch_id":105996,"custom":{"custom1":"Custom value 1","custom2":"Custom value 2"}}' "https://{{subdomain}}.myspringboard.us/api/customers/101320"
springboard["customers/{{customer_id}}"]
  .put(my_customer_object)
  .status
Response:
# ...
# Status: 200 OK
# ...

# No Content
=> 200

Search customers

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/customers/?per_page=1"
springboard["customers"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 105796,
      "first_name": "Walter",
      "last_name": "White",
      "email": "walter@example.com",
      "address_id": 109074,
      "shipping_address_id": 108566,
      "billing_address_id": 104837,
      "customer_import_batch_id": 102404,
      "custom": {
        "custom1": "Custom value 1",
        "custom2": "Custom value 2"
      }
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>102791,
    "first_name"=>"Walter",
    "last_name"=>"White",
    "email"=>"walter@example.com",
    "address_id"=>103410,
    "shipping_address_id"=>101174,
    "billing_address_id"=>100337,
    "customer_import_batch_id"=>102938,
    "custom"=>{"custom1"=>"Custom value 1", "custom2"=>"Custom value 2"}},
   "..."]}

Merge duplicate customers

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"slave_ids":[100002,100003]}' "https://{{subdomain}}.myspringboard.us/api/customers/{{customer_id}}/merges"
springboard["customers/{{customer_id}}/merges"]
  .post({"slave_ids"=>[100002, 100003]})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/customers/115212/merges/173046

Create an address

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/customers/{{customer_id}}/addresses"
springboard["customers/{{customer_id}}/addresses"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/customers/139343/addresses/1324

Retrieve all addresses

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/customers/{{customer_id}}/addresses"
springboard["customers/{{customer_id}}/addresses"]
  .get.body
Response:
{
  "id": 103497,
  "address_id": 108681,
  "current_revision_id": 100791,
  "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"=>102859,
 "address_id"=>104387,
 "current_revision_id"=>101859,
 "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"}}

Retrieve an address

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/customers/{{customer_id}}/addresses/{{address_id}}"
springboard["customers/{{customer_id}}/addresses/{{address_id}}"]
  .get.body
Response:
{
  "id": 100619,
  "address_id": 101548,
  "current_revision_id": 104131,
  "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"=>104633,
 "address_id"=>100102,
 "current_revision_id"=>109707,
 "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"}}

Update an address

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

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"address_id":105593,"current_revision_id":104412,"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}}.myspringboard.us/api/addresss/101231"
springboard["customers/{{customer_id}}/addresses/{{address_id}}"]
  .put(my_address_object)
  .status
Response:
# ...
# Status: 200 OK
# ...

# No Content
=> 200

Promotions

Springboard 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

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

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.

Example

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"
}

Promotion Rules

The promotion rules resource exposes the ability to create, retrieve, search, update and delete promotion rules in the Springboard 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:

Promotion Rule

A promotion rule is a record that represents a rule used in processing promotions and pricing.

id:
integer (required)
name:
text (required)

The name of this promotion.

start_at:
DateTime

The date and time this promotion starts.

end_at:
DateTime

The date and time this promotion ends.

rank:
integer

It determines the order in which promotions are applied. Promotions are applied from lowest to highest rank.

archived:
Boolean

Whether or not the promotion is archived.

disabled:
Boolean

Whether or not the promotion is disabled.

action_definition:
Array<Promotion Action Definition>

An array of actions (i.e. things to do) if the promotion's conditions are satisfied. For example discount an item, give an item away for free, etc.

condition_definition:
Promotion Condition Definition

A filter expression.

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Promotion Rule Example:
{
  "id": 105742,
  "rank": 103930,
  "action_definition": [
    {
      "type": "DiscountSubtotal",
      "params": {
        "discount": 20,
        "discount_type": "amount"
      }
    }
  ],
  "condition_definition": {
    "$and": [
      {
        "customer.customer.rewards_level": {
          "$eq": "gold"
        }
      }
    ]
  }
}

Create a promotion rule

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/promotion_rules"
springboard["promotion_rules"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/promotion_rules/19199

Retrieve a promotion rule

GET /api/promotion_rules/{{promotion_rule_id}}

Promotion rules are retrieved via their unique id. The id can be found via a search.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/promotion_rules/{{promotion_rule_id}}"
springboard["promotion_rules/{{promotion_rule_id}}"]
  .get.body
Response:
{
  "id": 104413,
  "rank": 101831,
  "action_definition": [
    {
      "type": "DiscountSubtotal",
      "params": {
        "discount": 20,
        "discount_type": "amount"
      }
    }
  ],
  "condition_definition": {
    "$and": [
      {
        "customer.customer.rewards_level": {
          "$eq": "gold"
        }
      }
    ]
  }
}
{"id"=>100630,
 "rank"=>109358,
 "action_definition"=>
  [{"type"=>"DiscountSubtotal",
    "params"=>{"discount"=>20, "discount_type"=>"amount"}}],
 "condition_definition"=>
  {"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}}

Search promotion rules

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/promotion_rules/?per_page=1"
springboard["promotion_rules"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 109347,
      "rank": 101587,
      "action_definition": [
        {
          "type": "DiscountSubtotal",
          "params": {
            "discount": 20,
            "discount_type": "amount"
          }
        }
      ],
      "condition_definition": {
        "$and": [
          {
            "customer.customer.rewards_level": {
              "$eq": "gold"
            }
          }
        ]
      }
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>109825,
    "rank"=>108546,
    "action_definition"=>
     [{"type"=>"DiscountSubtotal",
       "params"=>{"discount"=>20, "discount_type"=>"amount"}}],
    "condition_definition"=>
     {"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}},
   "..."]}

Update a promotion rule

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"rank":105112,"action_definition":[{"type":"DiscountSubtotal","params":{"discount":20,"discount_type":"amount"}}],"condition_definition":{"$and":[{"customer.customer.rewards_level":{"$eq":"gold"}}]}}' "https://{{subdomain}}.myspringboard.us/api/promotion/rules/103562"
springboard["promotion_rules/{{promotion_rule_id}}"]
  .put(my_promotion_rule_object)
  .status
Response:
# ...
# Status: 200 OK
# ...

# No Content
=> 200

Delete a promotion rule

DELETE /api/promotion_rules/{{promotion_rule_id}}

Request:
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/promotion_rules/{{promotion_rule_id}}"
springboard["promotion_rules/{{promotion_rule_id}}"]
  .delete.status
Response:
200
200

Coupons

The Coupons resource exposes the ability to create, retrieve, search, update and delete Coupons in the Springboard 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:

Coupon

A coupon is a record that represents a rule used in processing coupons and pricing.

id:
integer (required)
name:
text (required)

The name of this coupon.

code:
text (required)

The code of this coupon.

start_at:
DateTime

The date and time this coupon starts.

end_at:
DateTime

The date and time this coupon ends.

archived:
Boolean

Whether or not the coupon is archived.

disabled:
Boolean

Whether or not the coupon is disabled.

action_definition:
Array<Promotion Action Definition>

An array of actions (i.e. things to do) if the promotion's conditions are satisfied. For example discount an item, give an item away for free, etc.

condition_definition:
Promotion Condition Definition

A filter expression.

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Coupon Example:
{
  "id": 1,
  "name": "name",
  "code": "10new",
  "action_definition": [
    {
      "type": "DiscountSubtotal",
      "params": {
        "discount": 20,
        "discount_type": "amount"
      }
    }
  ],
  "condition_definition": {
    "$and": [
      {
        "customer.customer.rewards_level": {
          "$eq": "gold"
        }
      }
    ]
  }
}

Create a coupon

POST /api/coupons

Coupons are created by POSTing a coupon record containing at least the required attributes to the /api/coupons resource.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"name":"name","code":"10new"}' "https://{{subdomain}}.myspringboard.us/api/coupons"
springboard["coupons"]
  .post({"name"=>"name", "code"=>"10new"}))
  .get.body
Response:
# ...
# Status: 201 Created
# ...

# No Content
{"id"=>1, "name"=>"name", "code"=>"10new"}

Retrieve a coupon

GET /api/coupons/{{coupon_id}}

Coupons are retrieved via their unique id. The id can be found via a search.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/coupons/{{coupon_id}}"
springboard["coupons/{{coupon_id}}"].get.body
Response:
{
  "id": 102622,
  "name": "name",
  "code": "10new",
  "action_definition": [
    {
      "type": "DiscountSubtotal",
      "params": {
        "discount": 20,
        "discount_type": "amount"
      }
    }
  ],
  "condition_definition": {
    "$and": [
      {
        "customer.customer.rewards_level": {
          "$eq": "gold"
        }
      }
    ]
  }
}
{"id"=>1,
 "name"=>"name",
 "code"=>"10new",
 "action_definition"=>
  [{"type"=>"DiscountSubtotal",
    "params"=>{"discount"=>20, "discount_type"=>"amount"}}],
 "condition_definition"=>
  {"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}}

Search Coupons

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/coupons/?per_page=1"
springboard["coupons"].query(per_page: 1).get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 1,
      "name": "name",
      "code": "10new",
      "action_definition": [
        {
          "type": "DiscountSubtotal",
          "params": {
            "discount": 20,
            "discount_type": "amount"
          }
        }
      ],
      "condition_definition": {
        "$and": [
          {
            "customer.customer.rewards_level": {
              "$eq": "gold"
            }
          }
        ]
      }
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>1,
    "name"=>"name",
    "code"=>"10new",
    "action_definition"=>
     [{"type"=>"DiscountSubtotal",
       "params"=>{"discount"=>20, "discount_type"=>"amount"}}],
    "condition_definition"=>
     {"$and"=>[{"customer.customer.rewards_level"=>{"$eq"=>"gold"}}]}},
   "..."]}

Update a coupon

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"name":"name","code":"10new","action_definition":[{"type":"DiscountSubtotal","params":{"discount":20,"discount_type":"amount"}}],"condition_definition":{"$and":[{"customer.customer.rewards_level":{"$eq":"gold"}}]}}' "https://{{subdomain}}.myspringboard.us/api/coupons/101854"
springboard["coupons/{{coupon_id}}"]
  .put({"name"=>"name", "code"=>"10new"})
  .get.body
Response:
# ...
# Status: 200 OK
# ...

# No Content
{"id"=>1, "name"=>"name", "code"=>"10new"}

Delete a coupon

DELETE /api/coupons/{{coupon_id}}

Request:
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/coupons/{{coupon_id}}"
springboard["coupons/{{coupon_id}}"].delete.status
Response:
200
200

Action Types

The following promotion action types may be used to specify promotion behaviors on either Promotion Rules or Coupons. See Promotions for usage details.

DiscountItem

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.

type:
text (required)

Must be DiscountItem

discount:
float (required)

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)

discount_type:
string (required)

The type of discount to apply to the matching items. See discount for more details. Valid options are amount, percent, and fixed_price.

item_price_attribute:
string

The date and time this promotion starts.

item_conditions:
Filter Expression

Which items on the transaction should receive the discount. See filtering docs for more details. If omitted, discount will apply to any item.

DiscountSubtotal

Applies the given discount to the transaction.

type:
text (required)

Must be DiscountSubtotal

discount:
float (required)

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)

discount_type:
string (required)

The type of discount to apply to transaction. See discount for more details. Valid options are amount, percent.

DiscountItem Example:
{
  "type": "DiscountItem",
  "discount": 0.25,
  "discount_type": "percent",
  "item_price_attribute": "price",
  "item_conditions": {
    "$and": [
      {
        "item_line.price": {
          "$gt": 100
        }
      }
    ]
  }
}
DiscountSubtotal Example:
{
  "type": "DiscountSubtotal",
  "discount": 0.25,
  "discount_type": "percent"
}

Locations

Location related resources include physical locations, POS stations, and cash drawers

Locations

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:

Location

A location represents a physical space where sales transactions can take place.

id:
Integer

unique identifier for the record

metadata:
Object

custom key/value information stored about this location

name:
String (required)

The name of the location

public_id:
String

a unique identifier provided by the user for the purpose of coding information

address_id:
Integer

The unique identifier for the address record associated with this location

address_revision_id:
Integer

unique identifier for the current revision of the address associated with this location

active:
Boolean

Whether or not this record is currently active and being used

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Location Example:
{
  "id": 100001,
  "name": "Boston",
  "public_id": "BOS",
  "address_id": 100004,
  "address_revision_id": 100016
}

Search locations

GET /api/locations

Search for and list locations

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/locations/?per_page=1"
springboard["locations"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 100001,
      "name": "Boston",
      "public_id": "BOS",
      "address_id": 100004,
      "address_revision_id": 100016
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>100001,
    "name"=>"Boston",
    "public_id"=>"BOS",
    "address_id"=>100004,
    "address_revision_id"=>100016},
   "..."]}

Purchasing

Purchasing APIs expose the ability to manage purchase orders, receipts, and returns.

Purchase Order

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.

Purchasing Order

id:
integer (required)
public_id:
text
status:
text (required)
start_shipments_at:
Date
end_shipments_at:
Date
vendor_id:
integer (required)
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

created_by_user_id:
integer
description:
text
receive_at_location_id:
integer (required)
custom:
object
total_qty:
numeric(10,2)
total_cost:
numeric(10,2)
total_price:
numeric(10,2)
total_received_qty:
numeric(10,2)
total_received_cost:
numeric(10,2)
total_received_price:
numeric(10,2)
total_open_qty:
numeric(10,2)
total_open_cost:
numeric(10,2)
total_open_price:
numeric(10,2)
initial_margin_ratio:
numeric
po_import_batch_id:
integer

Purchasing OrderLine

id:
integer (required)
item_id:
integer (required)
order_id:
integer (required)
qty:
numeric(10,2) (required)
unit_cost:
numeric(10,2) (required)
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

qty_received:
integer (required)
received_cost:
numeric
open_cost:
numeric
qty_expected:
numeric
status:
text
Purchasing Order Example:
{
  "id": 102944,
  "vendor_id": 106053,
  "created_by_user_id": 108149,
  "receive_at_location_id": 101537,
  "total_qty": 93.05,
  "total_cost": 84.56,
  "total_price": 43.27,
  "total_received_qty": 36.33,
  "total_received_cost": 82.8,
  "total_received_price": 87.41,
  "total_open_qty": 76.11,
  "total_open_cost": 78.07,
  "total_open_price": 42.77,
  "po_import_batch_id": 106011
}
Purchasing OrderLine Example:
{
  "id": 104477,
  "item_id": 101657,
  "order_id": 100631,
  "qty": 41.72,
  "unit_cost": 71.87,
  "qty_received": 105870
}

Create an order

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"vendor_id":104876,"receive_at_location_id":108296}' "https://{{subdomain}}.myspringboard.us/api/purchasing/orders"
springboard["purchasing/orders"]
  .post({"vendor_id"=>100361, "receive_at_location_id"=>107956})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/purchasing/orders/181010

Retrieve an order

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/purchasing/orders/{{purchase_order_id}}"
springboard["purchasing/orders/{{purchase_order_id}}"]
  .get.body
Response:
{
  "id": 100527,
  "vendor_id": 106748,
  "created_by_user_id": 108649,
  "receive_at_location_id": 100077,
  "total_qty": 53.74,
  "total_cost": 98.7,
  "total_price": 62.11,
  "total_received_qty": 50.4,
  "total_received_cost": 84.68,
  "total_received_price": 78.64,
  "total_open_qty": 11.34,
  "total_open_cost": 96.42,
  "total_open_price": 91.84,
  "po_import_batch_id": 101890
}
{"id"=>103822,
 "vendor_id"=>103338,
 "created_by_user_id"=>102580,
 "receive_at_location_id"=>101188,
 "total_qty"=>98.79,
 "total_cost"=>75.22,
 "total_price"=>72.15,
 "total_received_qty"=>85.1,
 "total_received_cost"=>16.93,
 "total_received_price"=>37.41,
 "total_open_qty"=>49.99,
 "total_open_cost"=>41.58,
 "total_open_price"=>27.21,
 "po_import_batch_id"=>101161}

Retrieve an orders's lines

GET /api/purchasing/orders/{{purchase_order_id}}/lines

A purchase order has zero or more associated lines.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/purchasing/orders/{{purchase_order_id}}/lines/?per_page=1"
springboard["purchasing/orders/{{purchase_order_id}}/lines"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 108617,
      "item_id": 103390,
      "order_id": 101861,
      "qty": 44.21,
      "unit_cost": 68.97,
      "qty_received": 101432
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>103292,
    "item_id"=>106225,
    "order_id"=>108698,
    "qty"=>29.54,
    "unit_cost"=>42.41,
    "qty_received"=>108429},
   "..."]}

Add an item to an order

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":109321,"order_id":102379,"qty":94.11,"unit_cost":66.8,"qty_received":106344}' "https://{{subdomain}}.myspringboard.us/api/purchasing/orders/{{purchase_order_id}}/lines"
springboard["purchasing/orders/{{purchase_order_id}}/lines"]
  .post({"item_id"=>107823, "order_id"=>109276, "qty"=>72.91, "unit_cost"=>43.12, "qty_received"=>103621})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/purchasing/orders/125113/lines/199581

Purchase Receipt

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.

Purchasing Receipt

id:
integer (required)
status:
text (required)
order_id:
integer
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

custom:
object
public_id:
text

Purchasing ReceiptLine

id:
integer (required)
item_id:
integer (required)
qty:
numeric(10,2) (required)
unit_cost:
numeric(10,2)
receipt_id:
integer (required)
order_line_id:
integer
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

qty_expected:
numeric
qty_unauthorized:
numeric
Purchasing Receipt Example:
{
  "id": 104628,
  "order_id": 107911
}
Purchasing ReceiptLine Example:
{
  "id": 108648,
  "item_id": 109925,
  "qty": 62.61,
  "unit_cost": 95.54,
  "receipt_id": 106668,
  "order_line_id": 101498
}

Create a receipt

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{}' "https://{{subdomain}}.myspringboard.us/api/purchasing/receipts"
springboard["purchasing/receipts"]
  .post({})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/purchasing/receipts/121901

Retrieve a receipt

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/purchasing/receipts/{{purchase_receipt_id}}"
springboard["purchasing/receipts/{{purchase_receipt_id}}"]
  .get.body
Response:
{
  "id": 102896,
  "order_id": 103508
}
{"id"=>101224, "order_id"=>106929}

Retrieve a receipt's lines

GET /api/purchasing/receipts/{{purchase_receipt_id}}/lines

A receipt has zero or more associated lines.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/purchasing/receipts/{{purchase_receipt_id}}/lines/?per_page=1"
springboard["purchasing/receipts/{{purchase_receipt_id}}/lines"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 109850,
      "item_id": 104053,
      "qty": 38.25,
      "unit_cost": 37.35,
      "receipt_id": 101800,
      "order_line_id": 104993
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>103672,
    "item_id"=>107480,
    "qty"=>36.37,
    "unit_cost"=>45.81,
    "receipt_id"=>105191,
    "order_line_id"=>108151},
   "..."]}

Add an item to a receipt

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":108483,"qty":50.76,"receipt_id":104242}' "https://{{subdomain}}.myspringboard.us/api/purchasing/receipts/{{purchase_receipt_id}}/lines"
springboard["purchasing/receipts/{{purchase_receipt_id}}/lines"]
  .post({"item_id"=>108029, "qty"=>73.42, "receipt_id"=>106040})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/purchasing/receipts/186579/lines/174496

Purchase Return

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.

Purchasing Receipt

id:
integer (required)
status:
text (required)
order_id:
integer
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

custom:
object
public_id:
text

Purchasing ReceiptLine

id:
integer (required)
item_id:
integer (required)
qty:
numeric(10,2) (required)
unit_cost:
numeric(10,2)
receipt_id:
integer (required)
order_line_id:
integer
created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

qty_expected:
numeric
qty_unauthorized:
numeric
Purchasing Receipt Example:
{
  "id": 107146,
  "order_id": 105343
}
Purchasing ReceiptLine Example:
{
  "id": 104210,
  "item_id": 105381,
  "qty": 11.2,
  "unit_cost": 17.45,
  "receipt_id": 109435,
  "order_line_id": 103696
}

Create a return

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"vendor_id":100509,"return_from_location_id":107748}' "https://{{subdomain}}.myspringboard.us/api/purchasing/returns"
springboard["purchasing/returns"]
  .post({"vendor_id"=>108610, "return_from_location_id"=>109809})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/purchasing/returns/170313

Retrieve a return

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/purchasing/returns/{{purchase_return_id}}"
springboard["purchasing/returns/{{purchase_return_id}}"]
  .get.body
Response:
{
  "id": 100942,
  "vendor_id": 101522,
  "return_from_location_id": 107562
}
{"id"=>108323, "vendor_id"=>105842, "return_from_location_id"=>104564}

Retrieve a return's lines

GET /api/purchasing/returns/{{purchase_return_id}}/lines

A purchase return has zero or more associated lines.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/purchasing/returns/{{purchase_return_id}}/lines/?per_page=1"
springboard["purchasing/returns/{{purchase_return_id}}/lines"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 107936,
      "item_id": 107149,
      "return_id": 106216,
      "qty": 49.18,
      "unit_cost": 44.56
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>100956,
    "item_id"=>106481,
    "return_id"=>109399,
    "qty"=>42.01,
    "unit_cost"=>78.26},
   "..."]}

Add an item to a return

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"item_id":101288,"return_id":102744,"qty":83.22,"unit_cost":98.54}' "https://{{subdomain}}.myspringboard.us/api/purchasing/returns/{{purchase_return_id}}/lines"
springboard["purchasing/returns/{{purchase_return_id}}/lines"]
  .post({"item_id"=>105686, "return_id"=>107534, "qty"=>65.84, "unit_cost"=>29.51})
  .headers['Location']
Response:
# ...
# Status: 201 Created
# ...

# No Content
/api/purchasing/returns/168628/lines/190867

Webhooks

The Webhooks resource exposes the ability to create, retrieve, search, update and delete Webhook in the Springboard Retail system.

Webhooks

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:

Webhook

id:
integer (required)
url:
string (required)
events:
array (required)

available events

created_by_user_id:
Integer

The user who created this record

updated_by_user_id:
Integer

The user who updated this record

created_at:
DateTime

The date and time that this record was created

updated_at:
DateTime

The date and time that this record was last updated

Webhook Example:
{
  "id": 102317,
  "url": "http://example.org",
  "created_by_user_id": 101280,
  "updated_by_user_id": 102736
}

Create a webhook

POST /api/webhooks

Webhooks are created by POSTing a webhook record containing at least the required attributes to the /api/webhooks resource.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -w "%{http_code}" -d '{"url":"http://example.org"}' "https://{{subdomain}}.myspringboard.us/api/webhooks"
springboard["webhooks"]
  .post({"url"=>"http://example.com", "events"=>["webhook_registered"]}))
  .get.body
Response:
# ...
# Status: 201 Created
# ...

# No Content
{"id"=>1, "url"=>"http://example.com", "events"=>["webhook_registered"]}

Retrieve a webhook

GET /api/webhooks/{{webhook_id}}

Webhooks are retrieved via their unique id. The id can be found via a search.

Request:
curl -H "Authorization: Bearer {{Token}}" -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/webhooks/{{webhook_id}}"
springboard["webhooks/{{webhook_id}}"].get.body
Response:
{
  "id": 102415,
  "url": "http://example.org",
  "created_by_user_id": 101233,
  "updated_by_user_id": 103616
}
{"id"=>100654,
 "url"=>"http://example.org",
 "created_by_user_id"=>106821,
 "updated_by_user_id"=>108162}

Search Webhooks

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.

Request:
curl -H "Authorization: Bearer {{Token}}" "https://{{subdomain}}.myspringboard.us/api/webhooks/?per_page=1"
springboard["webhooks"]
  .query(per_page: 1)
  .get.body
Response:
{
  "total": 42,
  "pages": 5,
  "results": [
    {
      "id": 103489,
      "url": "http://example.org",
      "created_by_user_id": 105327,
      "updated_by_user_id": 100821
    },
    "..."
  ]
}
{"total"=>42,
 "pages"=>5,
 "results"=>
  [{"id"=>108090,
    "url"=>"http://example.org",
    "created_by_user_id"=>106137,
    "updated_by_user_id"=>109490},
   "..."]}

Update a webhook

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.

Request:
curl -H "Authorization: Bearer {{Token}}" -H "Content-Type: application/json" -X PUT -w "%{http_code}" -d '{"url":"http://example.org","created_by_user_id":102300,"updated_by_user_id":109447}' "https://{{subdomain}}.myspringboard.us/api/webhooks/101834"
springboard["webhooks/{{webhook_id}}"]
  .put(my_webhook_object)
  .status
Response:
# ...
# Status: 200 OK
# ...

# No Content
=> 200

Delete a webhook

DELETE /api/webhooks/{{webhook_id}}

Request:
curl -H "Authorization: Bearer {{Token}}" -X DELETE -w "%{http_code}" "https://{{subdomain}}.myspringboard.us/api/webhooks/{{webhook_id}}"
springboard["webhooks/{{webhook_id}}"]
  .delete.status
Response:
200
200

Events

webhook_registered

Occurs whenever a webhook is created.

Payload:

{
  "webhook": {
    "id": 1234,
    "url": "https://example.com/target",
    "events": [
      "customer_created",
      "customer_merged"
    ]
  }
}

customer_created

Occurs whenever a customer is created. Describes a customer.

Payload:

{
  "id": 1,
  "first_name": "First Name",
  "last_name": "Last Name",
  ...
}

customer_updated

Occurs whenever a customer has changed. Describes a customer.

Payload:

{
  "id": 1,
  "first_name": "First Name",
  "last_name": "Last Name",
  ...
}

customer_merged

Occurs whenever customers have merged.

Payload:

{
  "old_customer_ids": [1, 2, 3, 4],
  "new_customer_id": 5
}

sales_transaction_customer_selected

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
    ...
  }
}

sales_transaction_completed

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
  ...
}