Skip to main content

Aggregate Promo Discounts (Messaging)

messagingmcp-aggregate_promos

Compute a statistic over promo discount depth, deduped by promo_id.

metric defaults to 'promo_depth' — the only aggregatable field — so it can be omitted. promo_depth_type is required (depths are unitless integers — without unit pinning the tool would mix percentages with currency amounts). Multi-buy promotions are EXCLUDED from every aggregate: their depth carries a third meaning (qualifying-item %, null for pure BOGO), so 'percentage' aggregates percentage_discount promos only and 'flat' aggregates flat_discount only. Returns a scalar value plus n_promos and n_observed (how many distinct promos contributed, and how many of those have a non-inferred row). With group_by or interval, returns a buckets array of those same shapes.

Use for "average % off", "deepest discount", "median flat amount". For counts or row-level retrieval use count_promos / list_promos.

Parameters

NameTypeRequiredConstraintsDescription
statisticstringyesStatistic to compute over distinct promotions' depth.
promo_depth_typestringyesREQUIRED. Pins the unit. 'percentage' for % off, 'flat' for currency-amount promos. Without it, percentages and currency amounts would be averaged together into a meaningless number.
metricstringnodefault: "promo_depth"Field to aggregate. Only 'promo_depth' (numeric discount value) exists, so the param can be omitted.
promo_currencystring | nullnodefault: nullISO 4217 code (e.g. GBP, USD). REQUIRED when promo_depth_type='flat' — different currencies must not be averaged. Must be omitted for 'percentage' (rejected if supplied — percentages have no currency; use regions to scope a market).
retailersstring[] | nullnodefault: nullRetailer slugs to filter by, e.g. ['zara', 'h-m']. None = all; matches any listed retailer. Call list_retailers and match the requested retailer against its retailer_name, then pass the row's retailer slug and a region it covers exactly as reported there. Slugs match exactly, so a display name or wrong case matches nothing.
regionsstring[] | nullnodefault: nullRegions to filter by, e.g. ['UK', 'US']. None = all; matches any listed region. list_retailers reports the exact region values for each retailer; use those, since regions match exactly.
start_datestring | nullnodefault: nullInclusive start of the active-date window (YYYY-MM-DD).
end_datestring | nullnodefault: nullInclusive end of the active-date window (YYYY-MM-DD).
min_depthinteger | nullnodefault: nullOptional minimum promo_depth pre-filter.
max_depthinteger | nullnodefault: nullOptional maximum promo_depth pre-filter.
has_codeboolean | nullnodefault: nullTrue = only promos with a code, False = only without, null = no filter.
include_inferredbooleannodefault: trueInclude inferred promotions (default True). False = observed only.
group_bystring | nullnodefault: nullOptional categorical bucketing. Mutually exclusive with interval. 'shoot' groups by source image to surface co-promoted bundles.
intervalstring | nullnodefault: nullOptional temporal bucketing on promotion_date. Exclusive with group_by. Rows are limited to [start_date, end_date], but bucket keys are calendar-aligned (week/month starts), so an edge bucket may be keyed before start_date and its statistic covers only the in-window part of that period.

Returns

  • On success: the stat block (or {"buckets": [...]}), with filter_echo.
  • On failure: {"error": str}.

Try it

Loading interactive widget…

Code examples

curl -s https://mcp.edited.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "x-api-key: $MCP_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "messagingmcp-aggregate_promos",
"arguments": {
"statistic": "example",
"promo_depth_type": "example",
"metric": "promo_depth",
"promo_currency": null,
"retailers": null,
"regions": null,
"start_date": null,
"end_date": null,
"min_depth": null,
"max_depth": null,
"has_code": null,
"include_inferred": true,
"group_by": null,
"interval": null
}
}
}'

Input schema

{
"type": "object",
"properties": {
"statistic": {
"description": "Statistic to compute over distinct promotions' depth.",
"enum": [
"mean",
"median",
"min",
"max"
],
"type": "string"
},
"promo_depth_type": {
"description": "REQUIRED. Pins the unit. 'percentage' for % off, 'flat' for currency-amount promos. Without it, percentages and currency amounts would be averaged together into a meaningless number.",
"enum": [
"percentage",
"flat"
],
"type": "string"
},
"metric": {
"const": "promo_depth",
"default": "promo_depth",
"description": "Field to aggregate. Only 'promo_depth' (numeric discount value) exists, so the param can be omitted.",
"type": "string"
},
"promo_currency": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO 4217 code (e.g. GBP, USD). REQUIRED when promo_depth_type='flat' — different currencies must not be averaged. Must be omitted for 'percentage' (rejected if supplied — percentages have no currency; use `regions` to scope a market)."
},
"retailers": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Retailer slugs to filter by, e.g. ['zara', 'h-m']. None = all; matches any listed retailer. Call `list_retailers` and match the requested retailer against its `retailer_name`, then pass the row's `retailer` slug and a region it covers exactly as reported there. Slugs match exactly, so a display name or wrong case matches nothing."
},
"regions": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Regions to filter by, e.g. ['UK', 'US']. None = all; matches any listed region. `list_retailers` reports the exact region values for each retailer; use those, since regions match exactly."
},
"start_date": {
"anyOf": [
{
"format": "date",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Inclusive start of the active-date window (YYYY-MM-DD)."
},
"end_date": {
"anyOf": [
{
"format": "date",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Inclusive end of the active-date window (YYYY-MM-DD)."
},
"min_depth": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional minimum promo_depth pre-filter."
},
"max_depth": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional maximum promo_depth pre-filter."
},
"has_code": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "True = only promos with a code, False = only without, null = no filter."
},
"include_inferred": {
"default": true,
"description": "Include inferred promotions (default True). False = observed only.",
"type": "boolean"
},
"group_by": {
"anyOf": [
{
"enum": [
"retailer",
"promo_type",
"region",
"shoot"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional categorical bucketing. Mutually exclusive with `interval`. 'shoot' groups by source image to surface co-promoted bundles."
},
"interval": {
"anyOf": [
{
"enum": [
"day",
"week",
"month"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Optional temporal bucketing on promotion_date. Exclusive with group_by. Rows are limited to [start_date, end_date], but bucket keys are calendar-aligned (week/month starts), so an edge bucket may be keyed before start_date and its statistic covers only the in-window part of that period."
}
},
"required": [
"statistic",
"promo_depth_type"
]
}