Product Catalog

Our product catalog API unlocks the ability to send high-performing journeys such as back in stock, low inventory, and price drop. It also lets you segment your customers and branch journeys using product data.

  • Create high performing journeys, such as back in stock, low inventory, and price drop.
  • Segment customers based on their past browsing, add to cart, and purchasing activity using product data such as name, category, tag, price, and other attributes.
  • Branch journeys based on product attributes or inventory, such as only sending a message if the product is in stock.

Attentive also has several integrations with popular e-commerce platforms that sync product data to Attentive. These are available in the Integrations tab.

Important note for testing/QA

When you're testing journeys that use product catalog data (like price drop, back in stock, or low inventory), we strongly recommend adding a Wait step of at least one hour as the very first step in the journey. This initial wait step allows sufficient time for our system to process changes to your product catalog.

An initial wait step is generally not necessary for your actual live journeys. In most non-testing scenarios, subscribers will enter the journey after catalog updates have already been processed.

When testing back in stock journeys specifically, keep in mind that back in stock journeys are triggered when availableForPurchase is false, not when inventoryQuantity is 0 (or less than the threshold amount if you're using inventory thresholds).

How to Get Started

  1. Create an Attentive app to get an api key
  2. Review the authentication workflow
  3. Read through the product catalog file format you'll need to generate to send us your product catalog.
  4. Either use the sample script below to send us the file(s) you've generated, or implement something similar.
  5. By default, validateOnly will be set to true when initiating the upload, in order for you to develop without
    saving the catalog Attentive side. Once you're ready for production, go ahead and set validateOnly to false.
  6. Once the file has been uploaded, contact your CSM to confirm that the data quality is high enough for the Attentive product data features to be enabled.

Sample CLI Utility Script

Feel free to reuse and adapt this Python3 script to send Attentive the catalog files you've generated.

import argparse
import requests  # you may need to install this https://docs.python-requests.org/en/latest/user/install/
import json
import time

from distutils.util import strtobool


API_KEY = ''  # Set this
API_BASE_URL = 'https://api.attentivemobile.com'
STATUS_INTERVAL = 10


def initiate_catalog_upload(validate_only, api_key):
    post_url = API_BASE_URL + '/v1/product-catalog/uploads'
    r = requests.post(
        post_url,
        json={'validateOnly': validate_only},
        headers={'Authorization': 'Bearer ' + api_key},
    )
    assert r.status_code == 200, "Are you sure your api key is correct?"
    resp = r.json()
    return resp['uploadId'], resp['uploadUrl']


def print_errors(errors):
    print("Validation Errors:")
    for error in errors:
        print(json.dumps(error))


def wait_for_validation(upload_id, validate_only, api_key, counter):
    """
    The file at this point should now be queued up and we are awaiting validation. If there are any
    validation errors, we'll print them out from here. You may want to integrate your own more
    advanced monitoring.
    """
    time.sleep(STATUS_INTERVAL)
    get_url = API_BASE_URL + '/v1/product-catalog/uploads/' + upload_id
    r = requests.get(get_url, headers={'Authorization': 'Bearer ' + api_key}).json()
    if r['errors']:
        # Consider implementing alerting over here
        print_errors(r['errors'])
    if r['status'] == 'validated':
        return
    # waiting approximately an hour before giving up. Totally up to you how long, but Attentive should
    # rarely be behind an hour behind in processing
    if counter == 360:
        print("Giving up on waiting for validation for " + upload_id)
        return

    wait_for_validation(upload_id, validate_only, api_key, counter + 1)


def upload_catalog(filepath, validate_only, api_key):
    upload_id, upload_url = initiate_catalog_upload(validate_only, api_key)
    with open(filepath, 'rb') as f:
        r = requests.put(upload_url, data=f)
        assert r.status_code == 200, 'Unexpected issue uploading'
    wait_for_validation(upload_id, validate_only, api_key, 0)
    return upload_id


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='CLI utility script to demonstrate and assist in sending your generated product catalog to Attentive via its API'
    )
    parser.add_argument('filepath', help='Path to your catalog file')
    parser.add_argument(
        '--validateOnly',
        default=True,
        dest='validate_only',
        type=lambda x: bool(strtobool(x)),
        help='Boolean flag to choose whether or not Attentive should only validate the file for correctness only or not. '
        'Defaults to True to prevent saving invalid data during development. Set to False when everything passes without errors.',
    )
    parser.add_argument(
        '--apiKey',
        dest='api_key',
        help='You can pass the API Key in here as an argument or set it in the API_KEY variable at the top of this file',
    )
    args = parser.parse_args()

    key = args.api_key or API_KEY
    assert key, (
        'Please either pass in the apiKey argument to this script, or '
        'update the API_KEY variable at the top of this file to authenticate to Attentive'
    )
    id = upload_catalog(args.filepath, args.validate_only, key)

Product catalog file format

You can use the Product Catalog API to provide Attentive with your entire product catalog
programmatically in order to segment or branch on different product attributes to send more
targeted SMS messages. It also unlocks other unique product features (e.g. Back In-Stock Journeys).

In order to use the Product Catalog API, you must first provide Attentive with your full or
partial product catalog as a ndjson format file to be HTTP file uploaded to a specified URL. Each
line in the file represents a full product, as described in the sample below
. This article
outlines the structure of each product/row, as well as the definitions of each object and field.

Top-level product
{
   "name": string, *
   "id": string, *
   "description": string,
   "brand": string,
   "link": string, *
   "lastUpdated": timestamp, *
   "categories": Array<string>,
   "tags": Array<string>,
   "productOptions": Array<ProductOption>,
   "images": Array<Image>,
   "attributes": Array<Attribute>
   "variants": Array<Variant> *,
   "collections": Array<String>
}

Product Option
{
   "name": string, *
   "position": int, *
   "values": Array<string> *
}

Image
{
   "position": int,
   "alt": string,
   "src": string, *
   "width": int,
   "height": int,
   "variantIds": Array<string>
}

Attribute
{
   "name": string, *
   "value": string *
}

Variant
{
   "name": string, * full name
   "id": string, *
   "position": int,
   "prices": Array<Price>,
   "availableForPurchase": boolean, *
   "inventoryQuantity": int,
   "productOptionValues": Array<ProductOptionValue>,
   "link": string, *
   "lastUpdated": timestamp, *
   "attributes": Array<Attribute>
}

Product Option Value
{
   "productOptionName": string, *
   "value": string *
}

Price
{
   "currencyCode": string, *
   "amount": string, *
   "compareAtPrice": string,
}

Definition of terms

Product

Products are the goods that you are selling on your website. For example, it can be a t-shirt
or a pair of shoes. This is the root JSON object on each line and is inherently required.

FieldDescriptionTypeRequired
idThis is your product ID and the field we key off of. It must be unique across your catalog. You need this unique ID to make any updates to the product by uploading your product with the same id. The maximum length of the ID is 256 characters.stringRequired
nameThe name of your product. Note that this is how it appears in messages. The maximum length of the name is 256 characters.stringRequired
descriptionA short description of your product. The maximum length of the description is 1024 characters.stringOptional
brandBrand for your product. Maximum length of brand is 256 characters.stringOptional
linkThe link to your product's detail page online. Maximum length of link is 2048 characters. (http(s) required)stringRequired
lastUpdatedThe date and time (in UTC) of when your product was last updated.timestampRequired
categoriesOne or more categories in your taxonomy associated with this product. You can specify up to ten categories per product and each category can be up to 64 characters long.Array<string>Optional
tagsOne or more tags that are associated with and used to categorize this product. You can specify up to 50 tags per product and each tag can be up to 64 characters long.Array<string>Optional
productOptionsSee Product Option. Up to 10 ProductOptions are allowed per product and up to 100 values are allowed per option.Array<ProductOption>Optional
imagesSee Image. Up to 250 images are allowed per product.Array<Image>Optional
attributesSee Attribute. Up to 100 attributes are allowed per product.Array<Attribute>Optional
variantsSee Variant. Up to 100 variants are allowed per product.Array<Variant>Required
collectionsThe grouping of products that this product belongs to. Up to 20 collections per product are allowed.Array<string>Optional

Variant

A variant can be added to a Product to represent one version of a product with several options.
The Product has a variant for every possible combination of its options. Following the example
in Product, a variant is a size small and color black. An order can begin fulfillment once a
variant is selected. Each product must have at least one variant

FieldDescriptionTypeRequired
idThis is your variant ID and the field we key off of. It must be unique across your catalog. You need this unique ID to make any updates to the product by uploading your variant with the same id. The maximum length of the ID is 256 characters.stringRequired
nameThe name of this variant. Note that this is how it appears in messages to your subscribers. The maximum length of the name is 256 characters.stringRequired
positionThe order in which this variant appears among all the other variants that belong to this product. The variant with the lowest number is the default variant. This value must be greater than or equal to 0.intOptional
linkThe link to your variant's detail page online. If there is no link for your variant, you can use your product link. The maximum length of the link is 2048 characters. (http(s) required)stringRequired
pricesSee PriceArray<Price>Required
availableForPurchaseIs this variant still being sold?booleanRequired
inventoryQuantityThe amount of the variant available before the variant is out of stock.intOptional
productOptionValuesThe combination of options that this variant represents for the product. See Product Options section for details.Array<ProductOption>Optional
attributesSee Attribute. Up to 100 Variants allowed.Array<Attribute>Optional
lastUpdatedThe date and time (in UTC) of when your product or variant was last updated.timestampRequired

Product Option

Product options are the dimensions or choices that a customer has to select to add a variant
to their cart. Following our previous Product example above with the t-shirt, the
customer needs to select the size and color they want. In this example, size and color are the
product options.

FieldDescriptionTypeRequired
nameThe name/title of this product option. Up to 256 characters longstringRequired
positionThe order in which this option appears among all the other options. The option with the lowest number is first in the order. This value must be greater than or equal to 0.intRequired
valuesThe different possible values for this product option. Up to 256 characters long for each value.Array<string>Required

Product Option Value

Product option values are the unique product option selections associated with a given variant.
These are contextualized within the Variant object.

FieldDescriptionTypeRequired
productOptionNameThe product option namestringRequired
valueThe selection or value for this variantstringRequired

Attribute

Generic key/value data for products/variants that can be used for categorizing.

FieldDescriptionTypeRequired
nameThe attribute name. Up to 64 characters long.stringRequired
valueThe attribute value. Up to 256 characters long.stringRequired

Image

Data for the images associated with your products and variants that can be used for Attentive product
messaging and experiences.

FieldDescriptionTypeRequired
srcThe URL to the image (http(s) required).stringRequired
altThe alt text for the image. This is used as a back up in case an image can't be displayed and standard on the web. Up to 512 characters allowed.stringOptional
widthThe width of the image in pixelsintOptional
heightThe height of the image in pixelsintOptional
variantIdsThe list of variant IDs this image applies to. Each id must match the ID of the field of one of the variants.Array<string>Optional
positionThe order in which images are considered for a product or variant. The image with the lowest position will be the default image. In other words, ascending order. Defaults to 0.intOptional

Price

A price associated with the variant. You may have more than one price and currency associated
with a variant. In those cases, Attentive will likely choose the lowest available price in
messaging experiences.

FieldDescriptionTypeRequired
currencyCodeThis follows the three letter currency codes (e.g. USD). For more info, see ISO-4217.stringRequired
amountThe price amountstringRequired
compareAtPriceThis is another price field, and use of this field implies the variant is on sale. This is the price buyers compare against to evaluate how good a sale is. Example: "The price was but now is ! Get it while it lasts"stringOptional

Formatted example of one product

The below example is formatted in json to clearly show the object schema. The file you pass to the API should be in ndjson format.

{
  "name": "Nasa T-Shirt",
  "id": "PD-123",
  "description": "A very popular T-Shirt",
  "brand": "NASA",
  "link": "https://www.google.com",
  "lastUpdated": "2021-10-05T18:08:28+00:00",
  "categories": ["Shirts"],
  "tags": ["Summer Sale", "Space"],
  "productOptions": [
    {"name": "Color", "position": 0, "values": ["Blue", "Black"]},
    {"name": "Size", "position": 1, "values": ["Small", "Medium", "Large"]}
  ],
  "images": [
    {"src": "https://www.google.com", "alt": "Picture of Nasa T-Shirt in Blue", "position": 0, "height": 250, "width": 400, "variantIds": ["VD-234"]},
    {"src": "https://www.google.com", "alt": "Another Picture of Nasa T-Shirt in Black", "position": 0, "height": 250, "width": 400, "variantIds": ["VD-235", "VD-236"]}
  ],
  "attributes": [{"name": "Fabric", "value": "Cotton"}],
  "variants": [
    {
      "name": "Nasa T-Shirt - Blue - Small",
      "id": "VD-234",
      "position": 0,
      "prices": [
        {"currencyCode": "USD", "amount": "10.00"}
      ],
      "availableForPurchase": true,
      "productOptionValues": [
        {"productOptionName": "Color", "value": "Blue"},
        {"productOptionName": "Size", "value": "Small"}
      ],
      "link": "https://www.google.com",
      "lastUpdated": "2021-10-05T18:08:28+00:00"
    },
    {
      "name": "Nasa T-Shirt - Black - Medium",
      "id": "VD-235",
      "position": 1,
      "prices": [
        {"currencyCode": "USD", "amount": "10.00"}
      ],
      "availableForPurchase": true,
      "productOptionValues": [
        {"productOptionName": "Color", "value": "Black"},
        {"productOptionName": "Size", "value": "Medium"}
      ],
      "link": "https://www.google.com",
      "lastUpdated": "2021-10-05T18:08:28+00:00"
    },
    {
      "name": "Nasa T-Shirt - Black - Large",
      "id": "VD-236",
      "position": 2,
      "prices": [
        {"currencyCode": "USD", "amount": "10.00"}
      ],
      "availableForPurchase": true,
      "productOptionValues": [
        {"productOptionName": "Color", "value": "Black"},
        {"productOptionName": "Size", "value": "Large"}
      ],
      "link": "https://www.google.com",
      "lastUpdated": "2021-10-05T18:08:28+00:00"
    }
  ]
}

Development Workflow Tips

  • As you're developing your code to generate this catalog file for Attentive, it's helpful to
    validate your generated files without any side effects on Attentive. To do that, please set
    the validateOnly boolean to true when calling /product-catalog/uploads. Please note
    your file is not immediately processed once the upload compeletes, but you can check the
    status of your upload with the same endpoint.
  • The cadence of uploading your catalog to Attentive is up to you. A daily job works great for most
    of our users, but we'd prefer we limit it to no more than every few hours if you're sending us
    your entire catalog on every upload. However, if you would like to send us "delta uploads"
    (only products/variants which have changed since your last upload), please feel free to be more
    liberal with your cadence. If we find there are upload frequency issues, we'll be sure to reach
    out.
  • If you have any questions as to how to map your catalog to the Attentive format above,
    please reach out to your client strategy partner at Attentive.

File Upload Limits

  • All files need to be UTF-8 encoded.
  • 2GB maximum file size
  • 4mb maximum line/product size
  • 500k line/product limit per file