Skip to main content

Connect with Aqurate via RESTful API

⏳Duration: 60 minutes
🎚️ Complexity: high

📌 Prerequisites

1. An Aqurate account (get it at aqurate.ai)

2. An active subscription with Aqurate Personalize

☝️ All data is pushed to Aqurate using our RESTful API. Exact documentation here.

1. Authentication 👩‍✈️

To push your shop data to Aqurate, you need to generate an API key on the API Keys page. You can choose the Shop via API preset, or generate a custom key with the scope: write:input_tables

When making API calls, use the generated API key for the X-Auth-Token parameter.

⚠️ Keep your API keys safe, as they can be used to access the data in your Aqurate account. For your security, API keys can only be viewed once. If you lose an API key, you can easily revoke it and generate a new one.

💡If you want to use the same API key to retrieve product recommendations, also enable the read:item_recs and read:user_recs scope. More details on the how-to guide.

2. The API endpoint for sending the data 📥

When making API calls, please use the POST /input/{table} endpoint. You can find it in the API Documentation here. The expected data structure is detailed under point 4 below.

⚠️ Please note that the /input/{table} endpoint has a rate limit of 1 request per second. We recommend implementing a delay and a retry mechanism.

3. The required data types 📋

The data model for computing Aqurate Personalize includes the tables below. However, not all tables and columns are mandatory.

Table

Details

Required

The orders and their customers.

Yes

The line items corresponding to the orders.

Yes

The items and their details.

Yes

The items and their corresponding attributes

No

The mapping of items into categories.

Yes

The mapping of categories.

Yes

The current stock level for all available items.

Yes

The email addresses of customers

Only required for recommendations via email.

4. The tables and structures ䷦

Orders (orders)

Field name

Details

Type

Required

order_id

The unique identifier of the order.

String

Yes

customer_id

The unique identifier of the customer.

String

Yes

order_date

The date and time at which the order was placed by the customer. The format is ISO 8601 in UTC.

Timestamp

Yes

order_status

The status of the order. Accepted values are: 'processing', 'completed', 'returned', 'canceled’

String

Yes

storefront

The storefront where the order was placed (e.g. shop.com, shop.de, Amazon.com, Physical retail, etc.)

String

No

Line Items (line_items)

Field name

Details

Type

Required

order_id

The unique identifier of the order.

String

Yes

product_id

The unique identifier of the item.

String

Yes

sku
​

The SKU number of the item.

String

quantity

The quantity of items.

Float

Yes

price_per_unit

The price of one item. Should be the same type (net/gross) as the price field in the Items table.

Float

Yes

Items (items)

Field name

Details

Type

Required Personalize

Required Search

product_id

The unique identifier of the item.

String

Yes

Yes

item_parent_id

The unique identifier of the parent item.

String

sku

The SKU number of the item.

String

Yes

name

The display name of the item.

String

Yes

Yes

description

The description of the item.

String

Yes

brand

The name of the item’s brand.

String

Yes

price

The final sale price of the item. Should be the same type (net/gross) as the price field in the Line Items table.

Float

Yes

Yes

price_old

The base price of the item, before discounts.

Float

Yes

currency

The 3-letter currency denomination (e.g. EUR, RON, USD, HUF)

String

Yes

stock_status

Availability status of the product eg, in_stock, out_of_stock, preorder

String

Yes

photo_url

The URL of the main product picture.

String

Yes

Yes

image_srcset

Comma-separated list of image URLs with width descriptors, used to populate the HTML srcset attribute for responsive image loading eg, url?class=240 240w, url?class=320 320w, ...

String

Yes

sizes

Media condition string mapped to viewport breakpoints, used to populate the HTML sizes attribute so the browser picks the right srcset entry eg, (min-width: 1024px) 25vw, ...

String

Yes

item_uri

The item’s publicly accessible URL.

String

Yes

Yes

is_active

1 or 0, depending on whether the item is currently listed on the shop’s website.

Boolean

Yes

Yes

created_at

The date and time at which the item was created. The format is ISO 8601 in UTC.

Timestamp

Yes

Yes

Custom Item Attributes (custom_item_attributes)

Field name

Details

Type

Required

product_id

The unique identifier of the item.

String

Yes

attributes

List of attribute objects of the item.

Each object consists of two keys:

  • "attribute_name" (type: String)

  • "attribute_values" (type: List)

The values within "attribute_values" should be consistent across type.

List

No

Item Categories (item_categories)

Field name

Details

Type

Required

product_id

The unique identifier of the item.

String

Yes

category_id

The unique identifier of the category of the item.

String

Yes

is_primary

To be used when a primary category is defined for the item. For example, an item in "shoes" and "bestsellers" would have the main category "shoes".

Boolean

Yes

⚠️ One item can be in multiple categories. This table is not unique at row level on product_id, but on the combination of product_id and category_id.

Categories (categories)

Field name

Details

Type

Required

main_category_id

The unique identifier of the main category.

String

Yes

main_category

The name of the main category.

String

Yes

subcategory_1_id

The unique identifier of the first-level subcategory.

String

subcategory_1

The name of the first-level subcategory.

String

subcategory_2_id

The unique identifier of the second-level subcategory.

String

subcategory_2

The name of the second-level subcategory.

String

subcategory_3_id

The unique identifier of the third-level subcategory.

String

subcategory_3

The name of the third-level subcategory.

String

subcategory_4_id

The unique identifier of the fourth-level subcategory.

String

subcategory_4

The name of the fourth-level subcategory.

String

Stock (stock)

Field name

Details

Type

Required

product_id

The unique identifier of the item.

String

Yes

stock_quantity

The number of units in stock.

String

Yes

stock_type

One of "own", "dropshipping", " at_supplier".

String

Customers (customers)

This table is optional. It is only needed to send recommendations via email.

Field name

Details

Type

Required

customer_id

The unique identifier of the customer.

String

Yes

email

The email of the customer.

String

Yes

5. Scheduling the API calls 🕒

5.1 First upload

For the initial training of the AI model, we recommend sending up to 4 years of historical data.

5.2 Daily runs

The AI model is trained every 24 hours, so we recommend sending updated data every 24 hours, too.

The system always focuses on the latest entry for each entity.

Example:

Let's take an item with the product_id '67.' To determine whether this product is currently available on the webpage, we review the recent uploads and narrow down to the most recent update involving the product identified by ID '67.' If, in this update, the 'is_active' attribute was marked as 'true,' we consider the item active. This determination remains valid until the product is modified through a new API call to the 'items' table, at which point the 'is_active' field is set to 'false'.

5.3 Rate limit and retry logic

The /input/{table} endpoint has a rate limit of 1 request per second and 5000 requests per day.

We are doing our best to always provide enough server capacity to handle all incoming requests. But due to unexpected spikes, it is possible that a small number of requests will result in a server error.

We recommend implementing a delay and a retry mechanism.

To ensure all data reaches us, please retry requests that fail with status codes 429 or greater than 499. However, retries should not replace proper rate-limiting; it's important to time your requests accordingly. Additionally, you can batch up to 1000 rows of data in a single request to reduce the number of requests you need to make.

Did this answer your question?