Shopamine RESTful API v2

Introduction

This is the documentation for Shopamine's RESTful API, version 1.

All data is transferred using JSON format.

Form of URLs

Each shop runs on its own domain name. Within that domain name, all API URLs have the prefix /api/v1/.

All API calls must be done via HTTPS. Because the large majority of shops don't have their own secure domains, this means that they must pass through on of Shopamine's HTTPS gateways, for example api.shopamine.com. So, a full URL to retrieve a list of items on www.example.com looks like this: https://api.shopamine.com/www.example.com/api/v1/items/list The common prefix will be referred to as [URL_BASE] below.

All entities use the same URL patterns for the same operations. Here is the list of operations supported on most entities:

HTTP method URL pattern Description
GET [URL_BASE]/[entity]/list Retrieves the list of entities. See also common parameters for lists. The resulting JSON object will have a single field data, containing the array of entities.
POST [URL_BASE]/[entity]/create Creates a new entity. The result will be the entity, as if retrieved from its URL by GET.
GET [URL_BASE]/[entity]/[entity_id] Retrieves data for one entity. The result is a JSON representation of the entity, as defined in sections below.
POST [URL_BASE]/[entity]/[entity_id] Updates data for one entity. The result is again the entity, as if retrieved after update by GET.
DELETE [URL_BASE]/[entity]/[entity_id] Deletes one entity. The result will be either { "status": "ok" } on success, or { "status": "failed", "error_msg": "..." } on errors.

Authentication

To call any of the API functions, you must obtain a security token. Then, you must include it in a HTTP header in all calls made to the API, as described in OAuth2 Bearer Token Usage. Here is an example of what a HTTP call might look like: GET /www.example.com/api/v1/items/list HTTP/1.1
Host: api.shopamine.com
Authorization: Bearer 8vd9n8nv9wvm195v1vmanlksdmv
The header is the only supported form of authentication, despite there being two additional modes (form-encoded body parameter, URI query parameter) described in the above-mentioned document.

A note on updates

One of the main purposes of the API is to allow synchronization of data like item prices with external software. If entire documents had to be transferred all the time, the process would be slow and brittle. To make it both easier and faster to only update a few fields, whenever an update is being made, the incoming data is merged with existing data. Fields not present in the incoming JSON document are not modified. For example, if you only wish to update an item's first price and stock amount, it is enough to do a HTTP exchange like this: POST /www.example.com/api/v1/items/123 HTTP/1.0 Host: api.shopamine.com Authorization: Bearer 8vd9n8nv9wvm195v1vmanlksdmv Content-Type: application/json Content-Length: 70 { "stock_amount": 18, "prices": { "p1": 124.99 } } This will leave all other fields intact, including other prices (if they are used). As a consequence, if you wish to delete one of the fields, you must explicitly set it to null.

Localized strings

Most strings visible to a shop's visitors are localized. In the API they are represented as JSON objects in which keys are locale identifiers (e.g. en_US) and values are the respective translations. A special locale identifier "__" is used for the default. The default must always be present and is used in all locales where a translation is missing. For single-language shops, it is recommended only the default is used. For multi-language shops, it is recommended the default is in shop owner's language, as that is what he/she will see in the administration interface. Here is an example localized string: { "__": "Chocolate cookies", "sl": "Čokoladni piškoti", "de": "Schokoladenkekse", "en_GB": "Chocolate biscuits" } Like other objects in the API, incoming localized string updates are merged with existing data. Therefore, if you wish to delete one of the translations, you must explicitly set it to null: { "__": "Apple iPhone 14", "sl": null }

Other types used

List parameters

Because some shops have very large inventories, all entity lists support/require pagination. Each entity type has a maximum page size you can use, documented in its section. The three URL parameters with which you can control retrieved data are these:
URL Parameter Description
limit Sets the maximum number of entities to retrieve. If not specified, the entity's default page size is used.
offset Sets the number of entities to skip from the beginning of the list. If not specified, it defaults to 0, meaning the first limit entities will be retrieved.
order Sets the field(s) by which the results are sorted. Multiple fields may be used, separated by commas. Each field may also be prefixed with - to reverse the order.

Entities

The following are all the entities that are currently implemented in the API.

Items [URL_BASE]/items/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this item
external_id (optional) External ID for this item (in admin it is called user code)
type The type of this item. If it is "variants", the item represents a collection of items, one of which must be selected when placing into basket. Otherwise, the item can be bought stand-alone.
name The localized name of this item.
list_desc (optional) The localized list description.
short_desc (optional) The localized short description.
long_desc (optional) The localized long description.
nodes (optional) Contains IDs of nodes to which this item belongs. They are separated by type, so each can be updated separately.
prices Contains base prices for this item. p1 is required, while the other two are optional.
discounts (optional) Contains discount rates for this item. Note that these are not percentages, so a 20% discount is represented as 0.2.
shipping_dimensions (optional) Contains the shipping dimensions for this object. weight can be present on its own, but the other three must either all be present, or none of them.
model (optional) This is the model designation for this item.
sku (optional) This is the SKU code for this item.
bar_code (optional) This is the bar code for this item.
stock_amount This is the number of items that are immediately available.
avail_in_days This is the number of days in which this item is available when out of stock.
tax_class_id This is the ID of the tax class to which this item belongs.
buyable This determines if this item can currently be bought. as_part_only means that it can be bought only as a variant of a container item.
default_buyable (optional) Determines the default buyable status for items of type variant.
I.e. if an Item with default_buyable="as_part_only" is updated with buyable = "yes" the buyable value will automatically be converted to "as_part_only"
date_updated This is the date/time at which the last change to this item was made. It updates automatically.
warranty_months (optional) This is the length of warranty for this item, in months.
variants_configuration (optional) For items with type variants, this field contains the configuration. If chooser_type is "names", the user will choose one of the variants by their respective names. If it is "specs", the user will choose by choosing relevant spec values. In that case, the specs have to be listed in chooser_specs.
images (optional) This field contains the image IDs for this item. Gallery is the list of images shown on item's page. list is the image to be used when displaying the item in lists; if missing, the first image from the gallery will be used. The variant_chooser image is used when the item is in a variant and the variant selection happens using images.
customization (optional) This field contains information about customization options for this item. There can be any number of them, and each is represented as either a choice of options (type: "choices"), or a field for the user to enter (type: "text"). price_delta is the change in price of the item, applied if the user chooses to use the option. pricing_steps determines in which order price deltas are appliced. It is useful when combining relative and absolute price deltas.
sys_tags (optional) This is a list of system tags that the item has. By default, they do nothing, but skins may use them for various purposes. For example, many skins will display some sort of a marker for items with tag "new".
seo_data (optional) This field contains SEO-related data, currently this means <meta> tags. The two most commonly used are represented directly, and there can also be any number of extra tags inside custom_meta_tags.
external_buy_settings (optional) This rarely used field is used for items that are actually bought on other sites.
extra_search_kws (optional) This field is used to enter additional search keywords that this item can be found by, in the (rare) case when they don't appear in any of the other fields.
generic_data (optional) This field can contain any extra data that doesn't fit into other fields. By default it is ignored, but custom skins can use the data in some way.
specs (optional) This field contains spec values for this item. The actual values are separate from the layout, so it's possible to update them without touching the layout. The layout itself is a recursive tree of specs and groups, the latter containing other groups and specs.

Nodes [URL_BASE]/nodes/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this node
external_id (optional) External ID for this node
type The type of this node. Nodes can switch types, but not to or from "home". There is always exactly one home page, and it also cannot be deleted.
url_key This is what goes into the URL for this node. Allowed characters are a-z, A-Z, 0-9, - and _.
parent_node_id This is the ID of the parent node for this node. All nodes, except home page, must have this set. Cycles of nodes are forbidden.
show_in_parent This field sets whether the node is considered to belong to its parent. If not, it starts a new separate sub-tree of nodes, and the parent(s) only contribute URL parts.
order_weight (optional) By default, the nodes are displayed to visitors sorted by name. When another order is desired, this field can be used. Nodes with the same order weight are still sorted by name. Nodes without an order weight come last, again sorted by name.
name This is the name of the node.
sys_tags (optional) Like with items, these can be used to tell skins that the nodes are somehow special, but don't do anything by default.
visibility This field determines whether the node is visible or not. If it is hidden, visitors can still reach it if they know the URL or if it is linked from somewhere. If it is 404, it is as if the node doesn't exist.
date_created This is the date/time at which the node was first created. Set automatically.
date_updated This is the date/time at which the node was last edited. Set automatically.
date_published (optional) This is the date/time at which the node was published. Set automatically.
image_id (optional) This is the ID of the image that represents this node.
generic_data (optional) Like with items, this field can store generic attributes, occasionally used with custom skins.
specs (optional) This field can contain a spec layout that can be then used as the template for items in this node.
seo_data (optional) This field contains SEO-related data, currently this means <meta> tags. The two most commonly used are represented directly, and there can also be any number of extra tags inside custom_meta_tags.
filters (optional) This field contains settings about which filters are available when looking at items in this node. Each filter can be one of the predefined ones (price, brand, category), or it can be a filter based on a spec. In the latter case, it's ID must be set.
sort_orders (optional) This field contains settings about which sort orders are available to visitors when looking at items in this node. It is similar to filters, except that directions allowed must also be specified.

Specs [URL_BASE]/specs/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this spec
external_id (optional) External ID for this spec
type This is the type of this spec. numeric and numeric_discrete are interchangeable, the only difference is how they are displayed when used in filters. For specs of type choice, see more information below.
name The localized name of this spec.
description (optional) A description, useful for administrators, when multiple unrelated specs have the same name (for example, "Capacity" might refer to a hard drive or to a barrel).
unit (optional) The unit of measurement, used for numeric specs.

Choices

Specs of type choices each have a corresponding list of the actual choices. They are accessed with the following URL patterns:
HTTP method URL pattern Description
GET [URL_BASE]/specs/[spec_id]/choices/list Retrieves the list of choices. See also common parameters for lists
POST [URL_BASE]/specs/[spec_id]/choices/create Creates a new choice
GET [URL_BASE]/specs/[spec_id]/choices/[choice_id] Retrieves data for one choice.
POST [URL_BASE]/specs/[spec_id]/choices/[choice_id] Updates data for one choice.
DELETE [URL_BASE]/specs/[spec_id]/choices/[choice_id] Deletes one choice
List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this choice
external_id (optional) External ID for this choice
value This is the localized textual value visitors will see.
order_weight (optional) By default, choices are sorted by value. If another order is required, this field can be used.

Users [URL_BASE]/users/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this user
email The e-mail address of this user
name (optional) The name of this user.
nickname (optional) The nickname of this user.
date_created The date/time at which the user was created. Set automatically.
user_type_id (optional) The ID of the user type of this user.

Addresses

Each user can have a number of addresses associated with him, used in checkout. Addresses, once created, cannot be changed or deleted. They are accessed with the following URL patterns:
HTTP method URL pattern Description
GET [URL_BASE]/users/[user_id]/addresses/list Retrieves the list of addresses. See also common parameters for lists
POST [URL_BASE]/users/[user_id]/addresses/create Creates a new address
GET [URL_BASE]/users/[user_id]/addresses/[address_id] Retrieves data for one address.
List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this address
name The name of the person.
company (optional) The company name.
street_addr_1 First line of street address.
street_addr_2 (optional) The second line of street address.
postal_code The postal code of this address.
city The city of this address
state_code (optional) The code of the state, in countries which have states.
country_code The 2-letter country code.
tax_code (optional) The tax code (e.g. VAT number in EU)
phone (optional) The phone number to call when issues arise.
deleted Signifies whether the user has deleted this address from his list of addresses.

Contract Prices

Each user can have a number of contract prices associated with him. Each contract prices correspond of one item with the final customer price and the discount given. The price must be already calculated, the discount value is meant to be shown on the item on the shop (if needed). The contract prices can be created, read, updated and deleted.

To use the Contract Prices API you need to contact support as is not enabled by default!

HTTP method URL pattern Description
GET [URL_BASE]/users/[user_id]/contract_prices/list Retrieves the list of the contract prices. See also common parameters for lists
POST [URL_BASE]/users/[user_id]/contract_prices/create Creates a new contract price
POST [URL_BASE]/users/[user_id]/contract_prices/delete Delete an existing contract price
POST [URL_BASE]/users/[user_id]/contract_prices/deleteAll Delete all contract prices for the selected user
List parameters:

Sample object:

Note: it's required to send a data object with an array of values, also when sending a single contract price Expand

Field descriptions:
Field Description
item_id Shopamine's ID number for this item. [1]
item_sku This is the SKU code for this item. [1]
item_bar This is the bar code for this item. [1]
item_external_id The external ID of this item. [1]
price_base (optional) Contract final price for the item/user combination.
discount_rate (optional) Discount rate (%) associated to this item/user combination
sync_name (optional) Your integration name or additional info for this price

[1] At least one code must be included, otherwise the api call will fail!

External Prices Service

When internal capabilities are not enough (typically this happens with B2B stores which have customer-specific rules and contracts to follow), Shopamine has the ability to obtain prices from an external web service in real-time. To use this capability you should implement a HTTP-accessible service which will receive queries from Shopamine as they are needed, and which should respond with price data for the given query.

The incoming query will contain the user's email address and a number of item IDs together with quantities of interest (usually the quantity will be 1, but when in basket and in checkout the quantity might be bigger). The incoming item ID can be either "external_id" or "sku" from the rest of the API, configurable in Shopamine. Quantities will always be integers.

There are two ways in which the query can be encoded, either as parameters in the URL, or as a JSON document. The latter is probably slightly more robust, but also probably a bit harder to implement. Which way is used is configurable in Shopamine.

URL query format

If the query is in the URL, you have four choices:

  1. The entire query is in one parameter, and you can configure the separator between items and between an item's ID and quantity. For example, it the separators are , and : respectively, a query for three SKUs might look like this:

    http://.../getUserPrices?user=john@example.com&items=SKU0001:1,SKU0015:1,SKU0451:12

    You specify the URL, both parameter names (user and items in the example) and the separators in configuration.

  2. The query includes one parameter for each item. The parameter name is always the same or can include a counter, and there is a separator between the item's ID and quantity. For example, if separator is : and a counter is included, the query from above would instead look like this:

    http://.../getUserPrices?email=john@example.com&item1=SKU0001:1&item2=SKU0015:1&item3=SKU0451:12

    For something PHP-like, it would probably be easier if there was no counter and the parameter name included brackets instead:

    http://.../getUserPrices.php?who=john@example.com&item[]=SKU0001:1&item[]=SKU0015:1&item[]=SKU0451:12

    Again, you can specify the URL, both parameter names, whether to include a counter or not and the separator in configuration.

  3. The query includes two parameters for each item. One contains the item's ID and the other its quantity. You can include counters or not. With a counter, the query might look like this:

    http://.../prices?user=john@example.com&item1=SKU0001&qty1=1&item2=SKU0015&qty2=1&item3=SKU0451&qty3=12
  4. The last option is to have the item's ID be the parameter name and the quantity its value:

    http://.../getPrices?_email=john@example.com&SKU0001=1&SKU0015=1&SKU0451=12

To Shopamine they are all the same. You should choose the one which you find the easiest to implement in your system of choice. If you're using any of the separator-based modes (the first two), you should choose a separator which will not conflict with any characters in item IDs.

JSON query format

If you'd prefer to receive queries in JSON format, that is also an option. Shopamine will make a POST request to an URL of your choice with contents like this example:

{ "v": 1, "user_email": "john@example.com", "query": { "SKU0001": 1, "SKU0015": 1, "SKU0451": 12 } }

The "v" field contains the version, which will currently always be 1. If a richer query format will eventually be introduced, it will be of a different version and we plan to support version 1 indefinitely.

Response format

The response expected is basically a table of data, with one line per item. For encoding efficiency, it is simply an JSON array of arrays, with some metainfo in the envelope document to describe what the table actually contains. For example, here's a simple response to the above query:

{ "v": 1, "currency": "EUR", "columns": [ "id", "base_price", "final_price" ], "data: [ [ "SKU0001", 180.0, 155.0 ], [ "SKU0015", 12.0, 12.0 ], [ "SKU0451", 75.0, 44.5 ] ] }

We currently support the following columns:

The response must include "id", and at least one of "base_price" or "final_price". If "discount_rate" is included it will be taken into account. If not, it will be computed from "base_price" and "final_price" if both are present, and assumed to be 0 otherwise.

The recommended combinations of fields are these (in order of preference):

The prices returned should always be for one item, regardless of the quantity in the query. They should also not include any taxes. Future versions may allow returning prices for total quantities and with taxes included.

Currently, the response must be in the shop's base currency, in EU that's typically EUR.

Error responses

If the user is not recognized or has no special prices, please simply return this:

{ "v": 1 }

In that case (and also for items not included in the returned data) the user will be shown the default prices configured in Shopamine.

On the other hand, if some error occurs, please return a response like this:

{ "error": "...", "public_error": "..." }

If public_error is present, it will be shown to the user as-is. Otherwise he will be shown a generic error message.

Any/both of the errors will be logged in the shop's logs to help resolve problems.

Other considerations

The response should include a header Content-Type: application/json. The charset used must be UTF-8.

The request can be done either via HTTP or HTTPS. HTTP is considerably faster, so provides a better user experience, but obviously it is less secure. If the pricing information is considered very sensitive, HTTPS should be used instead.

The request can be done without authentication, or by any of these authentication methods:

For queries involving many items using URL parameters, several HTTP requests will be made so that the URLs are not too long. The default limit is 2000 total characters.

If JSON queries are used, there will usually be only one request per page view containing all the items.

User types [URL_BASE]/user_types/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this user type
name The name of this user type.
sys_tags (optional) The list of system tags skins can use for special handling of this user type.
pricing_settings (optional) If this user type uses different pricing settings than the shop's default, the settings will be here.

Purchases [URL_BASE]/purchases/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this purchase
external_id (optional) The external ID of this purchase.
user_id The ID of the user that made this purchase.
shipping_address_id (optional) The shipping address for this purchase. Will not be present on purchases that only have virtual goods or on purchases which have no shipping.
billing_address_id (optional) The billing address for this purchase. Will not be present on purchases that only contain free items.
date_bought The date/time at which the purchase was made.
status The status of the order.
items Contains the list of items that were bought in this purchase. container_item_id is only present with variants. customization is only present with items that have customization; when so, the values are stored under values, and configuration contains the snapshot of the item's settings when the purchase was made.
shipping (optional) Contains information about shipping for this purchase. Some types of shipping will calculate how the items should be distributed into parcels, but most do not. type and name serve as a snapshot of the shipping's settings at the time the purchase was made.
payment (optional) Contains information on the payment method for this purchase.
user_notes (optional) There are the user's comments when he made the purchase.
system_notes (optional) If Shopamine had anything to say about this purchase (usually related to billing), it will be stored here.
items_total This field contains the total cost of all the items in this purchase, excluding shipping and billing costs.
grand_total This field contains the grand total for this purchase, including items, shipping and billing costs.
tax_conf_snapshot This field contains a snapshot of the relevant tax computation settings that were used with this purchase.

All purchase-related prices and costs are stored as so-called complex prices. You will likely only use a field or two, but they are there for audit purposes.

Complex price field description
value The final value, with taxes and discounts applied.
currency The currency of this price.
base This is the base price, before taxes and discounts.
base_with_discounts This is the base price, with discounts applied, but without taxes.
base_with_taxes This is the base price with taxes, but without discounts.
discounts_applied This field lists all the discounts that were applied to this price. The default discount has discount_id of 0.
taxes_applied This field lists all the taxes that were applied to this price. It should be used in combination with purchase's tax_conf_snapshot, rather than with current shop's settings.

Tax classes [URL_BASE]/tax_classes/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this tax class
name The name of this tax class.
external_id (optional) The external ID of this tax class.

Images [URL_BASE]/images/...

List parameters:

Sample object:
Expand
Field descriptions:
Field Description
id Shopamine's ID number for this tax class
media_type The media type of this image.
width The width of the image in pixels.
height The height of the image in pixels.
title The localized title of this image.
description The localized description of this image.
md5_hash The MD5 hash of this image's file's contents. Used for preventing duplicates.

Images cannot be changed once uploaded, except for their title and description. They can be uploaded either directly, using data URLs, or fetched from an external server, using HTTP/S or FTP. For FTP, if username and password are required, you can provide them directly in the URL.

Web Hooks

Shopamine can send notification to an external app via a webhook call on specified entity create, change and delete.
The entire Shopamine entity is sent as a POST entity or the entity Id is added to the called url.
The webhook call is fire and forget, shopamine will not retry to call the provided url if the first one fails.

Purchase Web Hook

Purchase ID as an URL query parameter

Your provided endpoint is called with an additional parameter purchase_id
For example: https://www.example.com/your/path?purchase_id=123

Entire Purchase JSON entity

The purchase JSON entity will be added as a POST entity when calling your url: https://www.example.com/your/path.

Calling the webhook on specific status change

Firing the webhook call can be restricted on specific Purchase status, see the purchase sample object - status

Contents