
We’ve designed the elm API to give FMCG brands and third parties easier access to their key sales data. See more info below on how to fetch data from the elm API.
We work hard to keep our data fresh and accurate. Our system undergoes a daily data synchronisation process with all retailer connections to ensure that our dataset accurately reflects retroactive changes made by these retailers. This synchronisation typically covers the previous 4-7 days, depending on the specific data processing practices of each retailer.
Retailers often apply these backdated modifications to their data. Daily updates are required to ensure the most up-to-date and precise historical data, which reflects what is available on the retailer's own platform.
In practical terms, this means that if you were to retrieve sales totals for a Sunday on a Monday, the total for that Sunday may change when viewed on subsequent days such as Tuesday, Wednesday, or Thursday.
To accommodate these retailer-driven data changes effectively, we recommend including a request for data that spans approximately the last seven days in every API call. By doing so, you can ensure access to the most current information. When adding this data to your database, you can:
This ensures 100% accuracy when handling retroactive changes, avoiding potential discrepancies of up to around 1% in historical sales totals if these practices are not followed.
Which metrics a retailer can serve depends on the retailer, the level and the timeframe, and it changes over time. /list?type=metrics&retailer={retailer} is the source of truth. It returns four lists — sku_metrics, store_metrics, sku_metrics_daily and store_metrics_daily — where null means nothing is available for that combination.
Requests are lenient. A metric the retailer cannot serve is left out, the rest is returned with a 200, and the omitted names come back in the X-Elm-Omitted-Metrics response header. An unrecognised metric name is a 400, as is a request where nothing can be served.
Two limits apply to every retailer. unit_ros, value_ros, ranged_stores, stores_selling and stores_with_stock cannot be served at a daily timeframe. Store level daily data is kept for 14 days only.
This API relies on an API key for authentication. To generate/access your API key please make sure that you have admin level access to your Elm account.
To generate your API key:
Please note that API keys are sensitive pieces of information and as such should be kept secret, like a password.
Once you have your API key, you can use it for authentication by including it in the authorization header of your requests.
Headers:
Authorization: Token <your token>
This request can be used to test your connection to the API. A successful request and authorization will return {"success":true}
curl --request GET \
--url https://api.getelm.co/api/test/ \
--header 'Authorization: <your token>'
This endpoint returns a list of the retailer connections that a user has access to in their elm account. To add further retailers/customers please visit the “Manage Connections” section of your elm dashboard.
Note: the list includes all, which aggregates across retailers. all works only on /data?type=sku — the /list paths reject it.
| type required | string Value: "retailers" Example: type=retailers Returns list of available retailers |
[- "all",
- "amazon",
- "sainsburys",
- "shopify",
- "tesco"
]Returns the metrics that can be requested for a retailer, split by level and timeframe. This varies by retailer and changes over time, so read it here rather than hardcoding a list.
Each list covers one combination of level and timeframe. null means nothing is available for that combination, and requesting it returns a 400. See "Metric availability" in the introduction.
| type required | string Value: "metrics" Example: type=metrics Returns list of available metrics by retailer |
| retailer required | string Example: retailer=sainsburys Define retailer to return list of available metrics |
[- {
- "retailer": "retailer_a",
- "sku_metrics": [
- "revenue",
- "units",
- "average_price",
- "wastage"
], - "store_metrics": [
- "revenue",
- "units",
- "average_price",
- "stock"
], - "sku_metrics_daily": [
- "revenue",
- "units",
- "average_price"
], - "store_metrics_daily": null
}, - {
- "retailer": "retailer_b",
- "sku_metrics": [
- "revenue",
- "units",
- "average_price"
], - "store_metrics": null,
- "sku_metrics_daily": null,
- "store_metrics_daily": null
}
]This endpoint returns a list of the SKU codes and filter names that can be requested. To define filter names and to associate them with SKU codes please visit the "Product Settings" section of your elm dashboard.
| type required | string Value: "filters" Example: type=filters Returns list of available SKU codes and filter names by retailer |
| retailer required | string Example: retailer=sainsburys Define retailer to return list of available SKU codes and filter names |
{- "sku": [
- "1",
- "2",
- "3",
- "4"
], - "skuProductName": [
- "1 - Product 1",
- "2 - Product 2",
- "3 - Product 3",
- "4 - Product 4"
], - "filter1": [
- "IPA",
- "Lager",
- "Stout",
- "Ale"
], - "filter2": [
- "Multi-pack",
- "Single"
], - "filter3": [
- "Chocolate",
- "Vanilla",
- "Strawberry",
- "Mint"
], - "filter4": [
- "Snack",
- "Meal",
- "Dessert",
- "Drink"
], - "filter5": [
- "Low",
- "Medium",
- "High"
]
}Retrieve SKU level sales data by retailer for the selected timeframe. This is best used when looking for top level sales information, rather than requiring sales by store data.
| type required | string Value: "sku" Example: type=sku Return data at SKU level |
| retailer required | string Example: retailer=sainsburys Name of retailer to pull data from. Use Note: retailer=all applies only to SKU level data. Using retailer=all is equivalent to viewing the Sales Summary charts where retailer=sainsburys is equivalent to viewing the charts in the Sainsbury's dashboard. retailer=all supports |
| timeframe required | string Enum: "daily" "weekly" "monthly" Example: timeframe=weekly Return data by day, week or month. Note: fewer metrics are available daily than weekly, and some retailers have no daily data at all. Check |
| metric required | string Enum: "revenue" "units" "average_price" "availability" "wastage" "unit_ros" "value_ros" "ranged_stores" "stores_selling" "stores_with_stock" Example: metric=revenue Which metric(s) to return, separated by a single comma. E.g. The list above is everything this endpoint can build. What a given retailer serves depends on the retailer and timeframe, so check
|
| datefrom required | string Example: datefrom=2022-08-13 Date from which to begin pulling data in the format YYYY-MM-DD |
| dateto required | string Example: dateto=2022-10-18 Date on which to end pulling data in the format YYYY-MM-DD |
| comparison | string Enum: "period" "year" Example: comparison=period Returns an extra column for each metric selected with the value percentage change between the current period/year and the previous period/year. 'Period' refers to the value for the preceding timeframe. I.e. if the current timeframe is 'week', the 'period' value will be the value for the previous week. 'Year' refers to the value for the same timeframe in the previous year. I.e. if the current timeframe is 'week', the 'year' value will be the value for the same week in the previous year. |
| filter | string Default: "sku" Enum: "sku" "filter1" "filter2" "filter3" "filter4" "filter5" Example: filter=filter2 Define whether the results should be filtered by SKU or product filters (optional). This parameter is required if you would like to return data for a specific SKU or filter. Note: When selecting filters, the filter names will be returned in place of SKU codes. A list of available SKU codes and filter names can be accessed through the |
| viewby | string Examples:
SKU code of filter name can be used to filter data down to a specific SKU or filter. Requires the filter parameter to be set to 'sku' or a specific filter. Note: Filter names are case sensitive. |
[- {
- "week": "2022-06-12T23:00:00.000Z",
- "sku": 446677,
- "sku_product_name": "446677 productName",
- "revenue": 231
}
]Retrieve sales and other data points grouped by SKU and store ID / name. Often used where more granular data is needed, such as field team work.
Note: store level daily data is kept for 14 days only. Older daily dates return a 400. Weekly and monthly are not limited.
| type required | string Value: "store" Example: type=store Return data at store level |
| retailer required | string Example: retailer=sainsburys Name of retailer to pull data from. Use Note: retailer=all applies only to SKU level data. Using retailer=all is equivalent to viewing the Sales Summary charts where retailer=sainsburys is equivalent to viewing the charts in the Sainsbury's dashboard. retailer=all supports |
| timeframe required | string Enum: "daily" "weekly" "monthly" Example: timeframe=weekly Return data by day, week or month. Note: far fewer retailers report store level data daily than weekly. Check |
| metric required | string Enum: "revenue" "units" "average_price" "stock" "wastage" "lost_sales" Example: metric=revenue Which metric(s) to return, separated by a single comma. E.g. The list above is everything this endpoint can build. What a given retailer serves depends on the retailer and timeframe, so check |
| datefrom required | string Example: datefrom=2022-08-13 Date from which to begin pulling data in the format YYYY-MM-DD |
| dateto required | string Example: dateto=2022-10-18 Date on which to end pulling data in the format YYYY-MM-DD |
| comparison | string Enum: "period" "year" Example: comparison=period Returns an extra column for each metric selected with the value percentage change between the current period/year and the previous period/year. 'Period' refers to the value for the preceding timeframe. I.e. if the current timeframe is 'week', the 'period' value will be the value for the previous week. 'Year' refers to the value for the same timeframe in the previous year. I.e. if the current timeframe is 'week', the 'year' value will be the value for the same week in the previous year. |
| filter | string Default: "sku" Enum: "sku" "filter1" "filter2" "filter3" "filter4" "filter5" Example: filter=filter2 Define whether the results should be filtered by SKU or product filters (optional). This parameter is required if you would like to return data for a specific SKU or filter. Note: When selecting filters, the filter names will be returned in place of SKU codes. A list of available SKU codes and filter names can be accessed through the |
| viewby | string Examples:
SKU code of filter name can be used to filter data down to a specific SKU or filter. Requires the filter parameter to be set to 'sku' or a specific filter. Note: Filter names are case sensitive. |
[- {
- "week": "2022-06-12T23:00:00.000Z",
- "store_id": 4,
- "store_name": "4 London",
- "sku": 446677,
- "product_name": "productName",
- "revenue": 44
}
]This endpoint returns a list of all active actions, insights and alerts as set out in your elm account along with accompanying information by retailer for a given week. This data set is often used as the first step in a successful field visit, for example, as it outlines problem stores.
Note: Actions are refreshed weekly and so please plan your API requests accordingly. We’d recommend pulling through actions on a Tuesday.
| retailer required | string Example: retailer=sainsburys Name of retailer to pull data from. Use Note: retailer=all applies only to SKU level data. Using retailer=all is equivalent to viewing the Sales Summary charts where retailer=sainsburys is equivalent to viewing the charts in the Sainsbury's dashboard. retailer=all supports |
[- {
- "client_name": "myCompany",
- "alert_date": "2022-08-15T23:00:00.000Z",
- "sku_code": 33453,
- "sku_description": "33453 - myCompany greatProduct",
- "retailer": "tesco",
- "store_id": 1111,
- "store_description": "3322 London",
- "action": "no_sales",
- "action_description": "No sales recorded for this SKU in 4 weeks"
}
]