find_underperforming_zones
Identify ad zones with high spending but low conversions to optimize campaign performance and create blacklist candidates for PropellerAds campaigns.
Instructions
Find zones that are spending money but not converting. Useful for blacklist candidates.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID | |
| min_spend | No | Minimum spend threshold (default: $10) | |
| max_conversions | No | Maximum conversions (default: 0) | |
| date_from | No | Start date | |
| date_to | No | End date |
Implementation Reference
- src/propellerads_mcp/server.py:702-746 (handler)The handler for the 'find_underperforming_zones' tool, which filters zone statistics based on spend and conversion thresholds.
elif name == "find_underperforming_zones": zones = client.get_zone_statistics( campaign_id=args["campaign_id"], date_from=args.get("date_from"), date_to=args.get("date_to"), ) min_spend = args.get("min_spend", 10) max_conv = args.get("max_conversions", 0) underperforming = [] for z in zones: spend = z.get("spend", z.get("cost", 0)) or 0 conv = z.get("conversions", 0) or 0 if spend >= min_spend and conv <= max_conv: underperforming.append(z) if not underperforming: return f"No underperforming zones found (min spend: ${min_spend}, max conversions: {max_conv})." underperforming.sort(key=lambda x: x.get("spend", x.get("cost", 0)) or 0, reverse=True) lines = [f"# Underperforming Zones (Campaign {args['campaign_id']})\n\n"] lines.append(f"Criteria: Spend >= ${min_spend}, Conversions <= {max_conv}\n\n") lines.append("| Zone ID | Spend | Conversions | Clicks |\n") lines.append("|---------|-------|-------------|--------|\n") total_waste = 0 for z in underperforming: spend = z.get("spend", z.get("cost", 0)) or 0 total_waste += spend lines.append( f"| {z.get('zone_id')} | " f"{format_currency(spend)} | " f"{z.get('conversions', 0)} | " f"{z.get('clicks', 0)} |\n" ) lines.append(f"\n**Total wasted spend:** {format_currency(total_waste)}\n") lines.append(f"**Zones to blacklist:** {len(underperforming)}\n") zone_ids = [z.get("zone_id") for z in underperforming if z.get("zone_id")] lines.append(f"\nZone IDs: `{zone_ids}`") return "".join(lines) - Tool registration and input schema definition for 'find_underperforming_zones'.
Tool( name="find_underperforming_zones", description="Find zones that are spending money but not converting. Useful for blacklist candidates.", inputSchema={ "type": "object", "properties": { "campaign_id": {"type": "integer", "description": "Campaign ID"}, "min_spend": { "type": "number", "description": "Minimum spend threshold (default: $10)", }, "max_conversions": { "type": "integer", "description": "Maximum conversions (default: 0)", }, "date_from": {"type": "string", "description": "Start date"}, "date_to": {"type": "string", "description": "End date"}, }, "required": ["campaign_id"], }, ),