# Glued API Reference > Machine-readable documentation for AI agents and LLMs. > Human-readable version: https://glued.me/api-docs ## Overview Glued is an ad intelligence platform for Meta and Google Ads. This API exposes 18 tools via the MCP (Model Context Protocol) over Streamable HTTP. - Base URL: https://api.glued.me/ - Protocol: JSON-RPC 2.0 - Authentication: Bearer token (API keys start with `glued_`) --- ## Authentication All requests are HTTP POST to https://api.glued.me/ with these headers: ``` Authorization: Bearer glued_YOUR_API_KEY Content-Type: application/json Accept: application/json, text/event-stream X-Glued-Client: my-agent ``` Request body (JSON-RPC 2.0 envelope): ```json { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "TOOL_NAME", "arguments": { } }, "id": 1 } ``` Response arrives as a Server-Sent Events stream. Parse the actual data from: ``` result["content"][0]["text"] → JSON string, parse with json.loads() ``` Python helper: ```python import httpx, json API_KEY = "glued_YOUR_API_KEY" def call_tool(name: str, arguments: dict) -> dict: response = httpx.post( "https://api.glued.me/", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", "Accept": "application/json, text/event-stream", "X-Glued-Client": "my-agent", }, json={"jsonrpc": "2.0", "method": "tools/call", "params": {"name": name, "arguments": arguments}, "id": 1}, timeout=30, ) for line in response.text.splitlines(): if line.startswith("data:"): payload = json.loads(line[5:]) return json.loads(payload["result"]["content"][0]["text"]) raise ValueError("No data event in response") ``` --- ## Tools There are 21 tools. Free tools have no credit cost. Paid analytics tools consume credits based on the number of ad accounts: `max(1, floor(ad_accounts / 10))` per call. Exceptions: `scrape_meta_ads_library` costs 5 credits per query; campaign management tools (`create_meta_campaign`, `create_meta_adset`, `upload_meta_ads`, `duplicate_meta_campaign_or_adset`, `set_meta_campaign_status`, `update_meta_campaign_budget`) cost 1 credit flat per action. Shopify tools (`query_shopify_report`, `get_shopify_revenue_summary`) cost max(1, store_count) credits per call. **Recommended call order for a new agent:** 1. `list_workspaces` → get workspace_id values 2. `list_ad_accounts` → confirm which accounts are active (and their platform) 3. For Meta analytics: use `query_ad_report`, `query_ad_hourly`, `query_campaign_hourly`, etc. 4. For Google Ads analytics: use `query_google_ads_report` or `query_google_ads_campaign_hourly` 5. For Shopify revenue: `list_shopify_stores` → `query_shopify_report` or `get_shopify_revenue_summary` 6. For comments: `list_pages` → `query_page_comments` 7. For campaign management: `create_meta_campaign` → `create_meta_adset` → `upload_meta_ads` --- ### Tool: list_workspaces Tier: FREE — no credits consumed Description: Returns every workspace accessible by the API key, along with connected Meta ad accounts. Always call this first to obtain workspace_id values required by all other tools. Parameters: none Returns: - workspaces (array) - workspace_id (string) — use this in all other tool calls, e.g. "ws_07e80aa1060e" - name (string) — human-readable workspace name - currency (string) — currency code for all monetary values, e.g. "USD", "HKD" - ad_accounts (array) - account_id (string) — Meta ad account ID, e.g. "act_565702975911434" - name (string) — ad account display name - platform (string) — always "meta" Example call: ```python result = call_tool("list_workspaces", {}) workspace_id = result["workspaces"][0]["workspace_id"] currency = result["workspaces"][0]["currency"] ``` Example response: ```json { "workspaces": [ { "workspace_id": "ws_07e80aa1060e", "name": "My Brand Analytics", "currency": "USD", "ad_accounts": [ { "account_id": "act_565702975911434", "name": "Brand Campaigns", "platform": "meta" } ] } ] } ``` --- ### Tool: list_ad_accounts Tier: FREE — no credits consumed Description: Returns all ad accounts (Meta and Google Ads) connected to a workspace with their status. Use account_id values to filter analytics queries to specific accounts. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces Returns: - ad_accounts (array) - account_id (string) — Meta: "act_..." format; Google Ads: numeric customer ID - account_name (string) — display name - platform (string) — "meta" or "google_ads" - status (string) — Meta: "active"/"paused"/"revoked"; Google Ads: "ENABLED"/"PAUSED" Example call: ```python result = call_tool("list_ad_accounts", {"workspace_id": "ws_07e80aa1060e"}) active = [a for a in result["ad_accounts"] if a["status"] == "active"] ``` --- ### Tool: query_ad_report Tier: PAID — credits: max(1, floor(ad_accounts / 10)) per call Description: Core analytics tool. Query Meta ad performance grouped by any dimension with flexible metrics and date ranges. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — one of: today, yesterday, last_7_days, last_14_days, last_30_days, this_month, last_month, this_quarter, custom - group_by (string, REQUIRED) — one of: account, campaign, ad, creative, landing_page, headline, copy. Use "account" for one aggregated row per ad account. - metrics (array of strings, REQUIRED) — one or more of: spend, impressions, clicks, ctr, cpc, cpm, roas, revenue, conversions, cpa, video_views, reach, frequency, landing_page_views, purchase_count, cost_per_landing_page_view - sort_metric (string, optional) — metric to sort by; defaults to first metric - sort_direction (string, optional) — "asc" or "desc"; default "desc" - limit (integer, optional) — max rows 1-500; default 50 - account_ids (array of strings, optional) — filter to specific account IDs - start_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - end_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - include_breakdowns (boolean, optional) — when true and group_by is "creative", adds platform and demographic breakdowns; default false Returns: - rows (array) — one row per grouped entity - entity_id (string) - entity_name (string) - entity_type (string) — "campaign", "ad_set", "ad", etc. - account_id (string) - metrics (object) — keys match requested metrics, e.g. {spend, roas, clicks, ctr} - spend (number) — in workspace currency - roas (number) — revenue / spend - ctr (number) — decimal, e.g. 0.019 means 1.9% - status (string) — ACTIVE, PAUSED, etc. - metadata (object) — objective, bidStrategy, dailyBudget, etc. - totals (object) — summed metrics across all rows - meta (object) - date_range (object) — {start: "YYYY-MM-DD", end: "YYYY-MM-DD", preset: string} - group_by (string) - row_count (integer) - currency (string) Example call — top campaigns by spend last 7 days: ```python result = call_tool("query_ad_report", { "workspace_id": "ws_07e80aa1060e", "date_range": "last_7_days", "group_by": "campaign", "metrics": ["spend", "roas", "clicks", "ctr"], "sort_metric": "spend", "limit": 10, }) for row in result["rows"]: m = row["metrics"] print(f"{row['entity_name']}: spend={m['spend']} roas={m['roas']:.2f}") ``` --- ### Tool: get_workspace_dashboard Tier: PAID — credits: max(1, floor(ad_accounts / 10)) per call Description: Multi-source workspace performance overview — returns per-source spend, revenue, and profit for all connected platforms (Meta Ads, Google Ads, Shopify) across today, yesterday, and last 7 days. Also includes Meta campaign-level data. Ideal for cross-platform daily briefings or automated digests. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces Returns: - workspace_id (string) - currency (string) - sources (array) — one entry per connected platform - source_id (string) — "meta" | "google_ads" | "shopify" - name (string) — display name e.g. "Meta Ads" - today (object) — {spend, revenue, profit} - yesterday (object) — {spend, revenue, profit} - last7 (object) — {spend, revenue, profit} - top_spend_account_id (string|null) — null for Shopify - currency (string) - campaigns (array) — Meta campaign-level data - campaign_id (string), campaign_name (string) - account_id (string) — numeric ad account ID (no "act_" prefix) - account_name (string), daily_budget (number) - today / yesterday / last7 (object) — {spend, revenue, roas} - last_synced_at (string) — ISO 8601 timestamp - cache_info (object) — {source: "fresh"|"warm"|"hot", age_seconds: number|null} Example call: ```python result = call_tool("get_workspace_dashboard", {"workspace_id": "ws_07e80aa1060e"}) for src in result.get("sources", []): print(f"{src['name']} today spend={src['today']['spend']} revenue={src['today']['revenue']}") ``` --- ### Tool: get_google_ads_dashboard_summary Tier: PAID — credits: max(1, floor(google_ads_accounts / 10)) per call Description: Google Ads spend and revenue summary across today, yesterday, and last 7 days, summed across all connected customer accounts. Returns null if Google Ads is not connected. Use this for Google-Ads-specific lookups; for a full cross-platform overview use get_workspace_dashboard. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces Returns a single SourceMetrics object: - source_id (string) — "google_ads" - name (string) — "Google Ads" - today / yesterday / last7 (object) — {spend, revenue, profit} - top_spend_account_id (string|null) — customer ID with highest spend in last 7 days - currency (string) — workspace currency Example call: ```python result = call_tool("get_google_ads_dashboard_summary", {"workspace_id": "ws_07e80aa1060e"}) if result.get("result") is None: print("Google Ads not connected") else: print(f"Today spend: {result['today']['spend']} revenue: {result['today']['revenue']}") ``` --- ### Tool: get_top_assets Tier: PAID — credits: max(1, floor(ad_accounts / 10)) per call Description: Returns top 5 creatives, headlines, copy bodies, and landing page URLs ranked by spend. Use for creative recommendations or identifying what to scale. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - account_id (string, optional) — specific account ID, or "all" (default) to automatically use the top-spend account Returns: - account_id (string) - account_name (string) - currency (string) - creatives (array, top 5 by spend) - image_hash (string) - asset_url (string) — CDN URL to the creative image - thumbnail_url (string) - asset_type (string) — "image" or "video" - metrics (object) — {spend, impressions, roas, ctr} - headlines (array, top 5 by spend) - text (string) — headline text - metrics (object) — {spend, impressions, roas, ctr} - copy (array, top 5 by spend) - text (string) — full body copy text - metrics (object) — {spend, impressions, roas, ctr} - landing_pages (array, top 5 by spend) - text (string) — landing page URL - metrics (object) — {spend, impressions, roas, ctr} - fetched_at (string) — ISO 8601 timestamp Example call: ```python result = call_tool("get_top_assets", { "workspace_id": "ws_07e80aa1060e", "account_id": "all", }) print("Top headline:", result["headlines"][0]["text"]) best_roas = max(result["creatives"], key=lambda c: c["metrics"]["roas"]) print("Best ROAS creative:", best_roas["asset_url"]) ``` --- ### Tool: query_campaign_hourly Tier: PAID — credits: max(1, floor(ad_accounts / 10)) per call Description: Hour-by-hour performance breakdown per campaign. Use today or yesterday for true hourly resolution. Good for identifying peak delivery hours and pacing issues. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — same options as query_ad_report; use "today" or "yesterday" for actual hourly data - metrics (array of strings, optional) — same options as query_ad_report; default: spend, impressions, clicks, ctr, cpc, reach, frequency - campaign_ids (array of strings, optional) — filter to specific campaign IDs - account_ids (array of strings, optional) — filter to specific account IDs - start_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - end_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" Returns: - rows (array) — one entry per campaign - campaignId (string) - campaignName (string) - hours (array) — one entry per hour of day - hour (integer) — 0-23 in workspace timezone - metrics (object) — metric values for this hour - totals (object) — summed metrics for this campaign across the date range Example call: ```python result = call_tool("query_campaign_hourly", { "workspace_id": "ws_07e80aa1060e", "date_range": "yesterday", "metrics": ["spend", "impressions", "clicks"], }) for row in result["rows"]: peak = max(row["hours"], key=lambda h: h["metrics"].get("spend", 0)) print(f"{row['campaignName']} — peak hour: {peak['hour']}:00") ``` --- ### Tool: scrape_meta_ads_library Tier: PAID — credits: 5 per page_id or search_keyword (non-refundable) Rate limit: 1 call per 5 minutes Description: Scrapes active ads from Meta Ads Library. Returns up to 50 ads per query sorted by impressions. Two modes: scrape a specific brand by page ID, or search any topic by keyword. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - mode (string, REQUIRED) — "page_id" or "search_keyword" - page_ids (array of strings, conditional) — REQUIRED when mode is "page_id"; each Facebook page ID costs 5 credits - search_keywords (array of strings, conditional) — REQUIRED when mode is "search_keyword"; each keyword costs 5 credits - impression_duration_days (integer, optional) — filter to ads active in last N days; options: 7, 14, 21, 28; default: 7 Returns: - success (boolean) - total_queries (integer) — number of page IDs or keywords queried - credits_consumed (integer) — 5 × total_queries - results (array) — one entry per query - query_type (string) — "page_id" or "search_keyword" - query_value (string) — the page ID or keyword queried - ads_found (integer) — number of ads returned - ads (array) - ad_archive_id (string) — unique Meta Ads Library ID - rank (integer) — rank by impressions; 1 is highest - image_url (string) — direct URL to the ad creative - display_format (string) — "IMAGE", "VIDEO", "CAROUSEL", etc. - runtime_days (integer) — days this ad has been running - is_active (boolean) - platforms (array of strings) — e.g. ["facebook", "instagram"] - page_name (string) — brand page name - title (string) — ad headline - cta_text (string) — call-to-action text, e.g. "Shop Now" - ad_library_link (string) — URL to view in Meta Ads Library - scraped_at (string) — ISO 8601 timestamp Example call — search by keyword: ```python result = call_tool("scrape_meta_ads_library", { "workspace_id": "ws_07e80aa1060e", "mode": "search_keyword", "search_keywords": ["protein powder"], "impression_duration_days": 7, }) print(f"Credits used: {result['credits_consumed']}") for ad in result["results"][0]["ads"][:5]: print(f"[{ad['rank']}] {ad['title']} — {ad['runtime_days']} days — {ad['cta_text']}") ``` Example call — scrape by page ID: ```python result = call_tool("scrape_meta_ads_library", { "workspace_id": "ws_07e80aa1060e", "mode": "page_id", "page_ids": ["123456789"], }) ``` --- ### Tool: list_pages Tier: FREE — no credits consumed Description: List Facebook/Instagram pages connected to a workspace. Use before calling query_page_comments to discover which page IDs are available. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces Returns: - pages (array) - page_id (string) — Facebook page ID - page_name (string) — display name - has_instagram (boolean) — whether an Instagram account is linked - instagram_username (string) — Instagram username if linked, else null - total_count (integer) Example call: ```python result = call_tool("list_pages", {"workspace_id": "ws_07e80aa1060e"}) for p in result["pages"]: print(p["page_id"], p["page_name"]) ``` --- ### Tool: query_page_comments Tier: PAID — credits: max(1, floor(ad_accounts / 10)) per call — charged per page call Description: Query Facebook/Instagram comments from organic posts and paid ads. Use for sentiment analysis, feedback monitoring, or identifying objections in ad comments. How pagination works: The first call (page=1) fetches all comments from the Meta API and caches the full dataset server-side for 5 minutes. Subsequent page calls (page=2, 3, ...) are served instantly from cache — no repeated Meta API calls. Complete your pagination loop within 5 minutes to stay within the cache window. If the cache expires mid-loop, the next call will re-fetch from Meta automatically. Use limit=50 to minimize calls and total credit cost. Avoid very small limits like 5 or 10 — they create unnecessary round-trips and increase total credits spent. Expected response times: Page 1 (live Meta fetch): at least 3 minutes. For large workspaces with 60+ ad accounts or 40+ pages this can reach 4–5 minutes. Pages 2+ are significantly faster. Do NOT set hard-coded timeouts on any page call — if the connection is cut before the response completes, the agent receives no data and may behave unexpectedly. Let every call complete naturally. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_preset (string, REQUIRED) — one of: today, yesterday, last_7_days, last_14_days, last_30_days, this_month, last_month - platform (string, optional) — "facebook" or "instagram"; default both - source (string, optional) — "organic" or "ad"; default both - page_ids (array of strings, optional) — filter to specific page IDs from list_pages - limit (integer, optional) — comments per page 1-100; default 25; recommended 50 - page (integer, optional) — page number starting at 1; increment until has_more is false; complete the loop within 5 minutes; default 1 Returns: - comments (array) — comments for the current page - comment_id (string) - message (string) — full comment text - commenter_name (string) — or "Anonymous" - created_time (string) — ISO 8601 - platform (string) — "facebook" or "instagram" - source (string) — "ad" or "organic" - permalink (string) — direct link to comment - page_id (string) - page_name (string) - returned_count (integer) — comments in this page - total_count (integer) — total comments across all pages (before filters) - filtered_count (integer) — total comments after applying filters - page (integer) — current page number - total_pages (integer) — total number of pages available - has_more (boolean) — true if more pages exist; call again with page+1 - credits_used (integer) — charged per page call independently Example call — paginate through all ad comments: ```python # Page 1 fetches from Meta API and caches server-side for 5 minutes. # Pages 2+ are served from cache — complete the loop within 5 minutes. # Use limit=50 to minimize calls and credit cost. all_comments = [] page = 1 while True: result = call_tool("query_page_comments", { "workspace_id": "ws_07e80aa1060e", "date_preset": "last_7_days", "source": "ad", "platform": "instagram", "limit": 50, "page": page, }) all_comments.extend(result["comments"]) if not result["has_more"]: break page += 1 print(f"Fetched {len(all_comments)} comments across {page} pages") for c in all_comments: print(f"[{c['platform']}] {c['commenter_name']}: {c['message'][:80]}") ``` --- ### Tool: query_ad_hourly Tier: PAID — credits: max(1, floor(ad_accounts / 10)) per call Description: Meta Ads only. Ad-level metrics with optional hourly time-of-day breakdown. Use start_time/end_time to slice a specific intraday window. Best used with "today" or "yesterday". Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — same options as query_ad_report - metrics (array of strings, optional) — same options as query_ad_report; default: spend, impressions, clicks, ctr, cpc - account_ids (array of strings, optional) — filter to specific Meta account IDs - start_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - end_date (string, optional) — YYYY-MM-DD; must equal start_date with time window - start_time (string, optional) — HH:MM 24h format (e.g. "00:00"); single-day only - end_time (string, optional) — HH:MM 24h format, exclusive (e.g. "12:00") - limit (integer, optional) — max ad rows 1-500; default 50 - sort_metric (string, optional) — metric to sort by - sort_direction (string, optional) — "asc" or "desc"; default "desc" Returns: same shape as query_ad_report — rows with entity_id, entity_name, metrics, plus hourly buckets in ad_time when time window is specified. Example call — early spend per ad until noon: ```python result = call_tool("query_ad_hourly", { "workspace_id": "ws_07e80aa1060e", "date_range": "today", "metrics": ["spend", "impressions", "clicks"], "start_time": "00:00", "end_time": "12:00", }) ``` --- ### Tool: query_google_ads_report Tier: PAID — credits: max(1, floor(google_ads_accounts / 10)) per call Description: Google Ads only. For Meta data use query_ad_report instead. Primary tool for all Google Ads analytics — campaigns, ad groups, ads, landing pages, headlines, descriptions, and image/video creatives. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — same options as query_ad_report - group_by (string, REQUIRED) — campaign, ad_set, ad, landing_page, headline, copy, creative Note: headline and copy only support metrics=["impressions"] - metrics (array of strings, optional) — spend, impressions, clicks, ctr, cpc, conversions, conversions_value, roas, cpa Default: spend, impressions, clicks, conversions IMPORTANT: "revenue" is Meta-only and will return an error if passed here. - sort_metric (string, optional) — metric to sort by - sort_direction (string, optional) — "asc" or "desc"; default "desc" - limit (integer, optional) — max rows 1-500; default 50 - account_ids (array of strings, optional) — Google Ads customer IDs (digits only, no dashes) - start_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - end_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - filters (array of objects, optional) — e.g. [{"field": "status", "operator": "equals", "value": "ENABLED"}] Returns: same shape as query_ad_report — rows, totals, meta with currency and row_count. meta.warnings lists any excluded campaign types (e.g. for group_by="creative"). Example call — top Google Ads campaigns: ```python result = call_tool("query_google_ads_report", { "workspace_id": "ws_07e80aa1060e", "date_range": "last_7_days", "group_by": "campaign", "metrics": ["spend", "clicks", "conversions", "roas"], "limit": 10, }) ``` --- ### Tool: query_google_ads_campaign_hourly Tier: PAID — credits: max(1, floor(google_ads_accounts / 10)) per call Description: Google Ads only. Hourly time-series metrics for campaigns or ad groups. Works with any date range. For a 7-day range each campaign gets up to 7×24=168 hourly buckets. Only campaign and ad_set support hourly breakdown in the Google Ads API. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — any preset or "custom" - group_by (string, optional) — "campaign" (default) or "ad_set" - metrics (array of strings, optional) — same as query_google_ads_report; default: spend, impressions, clicks, conversions - campaign_ids (array of strings, optional) — filter to specific campaign IDs - ad_group_ids (array of strings, optional) — filter to specific ad group IDs - account_ids (array of strings, optional) — Google Ads customer IDs (digits only) - start_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - end_date (string, optional) — YYYY-MM-DD; only when date_range is "custom" - start_time (string, optional) — HH:MM 24h format; narrow to hour window; single-day only - end_time (string, optional) — HH:MM 24h format, exclusive; pair with start_time Returns: - rows (array) — one per campaign or ad group - entity_id, entity_name, entity_type, account_id - ad_time (array) — hourly buckets sorted chronologically - date (string) — YYYY-MM-DD in workspace timezone - hourWindow (string) — e.g. "09:00:00 - 09:59:59" in workspace timezone NOTE: camelCase here — Meta's query_ad_hourly uses snake_case hour_window instead - metrics (object) — metric values for this hour - metrics (object) — totals summed from hourly buckets - meta.timezone (string) — workspace timezone used for hour labels Example call: ```python result = call_tool("query_google_ads_campaign_hourly", { "workspace_id": "ws_07e80aa1060e", "date_range": "yesterday", "group_by": "campaign", "metrics": ["spend", "clicks", "conversions"], }) for row in result["rows"]: peak = max(row["ad_time"], key=lambda h: h["metrics"].get("spend", 0)) print(f"{row['entity_name']} peak: {peak['hourWindow']}") ``` --- ### Tool: list_shopify_stores Tier: FREE — no credits consumed Description: Returns metadata for all Shopify stores connected to a workspace. Use the shop_domain values in query_shopify_report and get_shopify_revenue_summary. Call this first to discover available stores and their native currencies. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces Returns: - stores (array) - shop_domain (string) — Shopify store domain, e.g. "my-store.myshopify.com" - shop_name (string) — human-readable store name - currency (string) — store's native currency code - store_timezone (string) — store timezone - plan_name (string) — Shopify plan - store_id (string) — internal identifier - count (integer) — number of connected stores Example call: ```python result = call_tool("list_shopify_stores", {"workspace_id": "ws_07e80aa1060e"}) for store in result["stores"]: print(f"{store['shop_name']} — {store['shop_domain']} ({store['currency']})") ``` --- ### Tool: query_shopify_report Tier: PAID — credits: max(1, number of connected Shopify stores) per call Description: Query Shopify store data with flexible grouping. Always returns all 6 metrics regardless of group_by — no metrics parameter needed or accepted. Use list_shopify_stores first to get available shop_domain values. NOTE: Unlike query_ad_report or query_google_ads_report, there is NO metrics parameter. All 6 metrics are always returned in every response. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — today, yesterday, last_7_days, last_14_days, last_30_days, this_month, last_month, this_quarter, custom - group_by (string, REQUIRED) — "day", "product", or "customer" - shop_domain (string, optional) — e.g. "my-store.myshopify.com"; from list_shopify_stores. Omit to use the first connected store. - start_date (string, optional) — YYYY-MM-DD; required when date_range="custom" - end_date (string, optional) — YYYY-MM-DD; required when date_range="custom" - display_currency (string, optional) — ISO currency code to convert revenue into - limit (integer, optional) — max rows for group_by="product" (1–500, default 50) All 6 metrics always present in every row: - revenue — net revenue after discounts and refunds - gross_sales — subtotal before discounts (line item price × qty) - discounts — total discount amount applied - orders — number of qualifying orders - units_sold — total units sold (populated for group_by="product"; 0 otherwise) - aov — average order value (revenue / orders) Row identifier field by group_by: - day → date (YYYY-MM-DD) — one row per calendar day - product → product (name) — sorted by revenue desc; units_sold populated - customer → customer_type ("new" or "returning") — always 2 rows Top-level response fields: - rows (array) — one row per group_by period/product/customer - shop (string) — store display name - shop_domain (string) — store domain e.g. "my-brand.myshopify.com" - [6 metrics as top-level fields on each row — see above] - meta.group_by (string) — the group_by used - meta.date_range (object) — {start, end} ISO-8601 bounds - meta.row_count (integer) — total rows returned Example call — top products last 30 days: ```python result = call_tool("query_shopify_report", { "workspace_id": "ws_07e80aa1060e", "date_range": "last_30_days", "group_by": "product", "limit": 10, }) for row in result["rows"]: print(f"{row['product']}: revenue=${row['revenue']:.2f}, aov=${row['aov']:.2f}, units={row['units_sold']}") ``` --- ### Tool: get_shopify_revenue_summary Tier: PAID — credits: max(1, number of connected Shopify stores) per call Description: Get aggregate total revenue and order count for a Shopify store. Only counts paid/partially-paid/authorized orders — test and cancelled orders excluded. Use when the user asks for a single revenue total (e.g. "What was my revenue last month?"). For day-by-day or product breakdowns use query_shopify_report instead. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - date_range (string, REQUIRED) — same options as query_shopify_report - start_date (string, optional) — YYYY-MM-DD; required when date_range="custom" - end_date (string, optional) — YYYY-MM-DD; required when date_range="custom" - display_currency (string, optional) — ISO currency code to convert revenue into Returns: - total_revenue (number) — aggregate revenue for the period - total_orders (integer) — number of qualifying orders - raw_order_count (integer) — total fetched orders before filtering - stores_queried (integer) — number of Shopify stores included in the summary - currency (string) — currency of revenue figures - start / end (string) — ISO-8601 date bounds - timezone (string) — timezone used for date boundaries Example call: ```python result = call_tool("get_shopify_revenue_summary", { "workspace_id": "ws_07e80aa1060e", "date_range": "last_30_days", }) print(f"Revenue: {result['currency']} {result['total_revenue']:.2f} from {result['total_orders']} orders") ``` --- ### Tool: create_meta_campaign Tier: PAID — 1 credit flat per campaign created Description: Create a PAUSED Meta campaign. Always created as PAUSED — activate manually in Ads Manager or via set_meta_campaign_status. Multi-step protocol: call with only workspace_id first to get account list, then collect all inputs and show a confirmation summary before creating. Parameters: - workspace_id (string, REQUIRED) — from list_workspaces - ad_account_id (string, optional) — omit first call to get account list - campaign_name (string, optional) — max 200 chars; convention: {AdAccountName}_{Funnel}_{Country}_{AssetDesc}_{Date} - objective (string, optional) — OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC, OUTCOME_ENGAGEMENT, OUTCOME_VIDEO_VIEWS, OUTCOME_AWARENESS - budget_strategy (string, optional) — "CAMPAIGN" (CBO) or "ADSET" - budget (integer, optional) — daily budget in account currency; required if budget_strategy="CAMPAIGN" - bid_strategy (string, optional) — friendly names: "Highest volume or value", "Bid cap", "Cost per result goal", "ROAS goal" - buying_type (string, optional) — "AUCTION" (default) or "RESERVED" Returns: - meta_campaign_id (string) — newly created campaign ID - campaign_name (string) - status (string) — always "PAUSED" - credits_charged (integer) — always 1 --- ### Tool: create_meta_adset Tier: PAID — 1 credit flat per ad set created Description: Create a PAUSED Meta ad set with audience targeting, pixel, budget, and EU DSA compliance. Multi-step: get account → get campaigns → collect inputs → handle EU beneficiary if needed → get pixel → confirm → create. Key parameters: - workspace_id (string, REQUIRED) - ad_account_id (string, optional) — omit to get account list - campaign_id (string, optional) — omit after account to get campaign list - adset_name (string, optional) — convention: {CampaignName}_{Concept} - countries (array of strings, optional) — e.g. ["HK", "US"] - pixel_id (string, optional) — omit to get pixel list - performance_goal (string, optional) — default "Maximize conversions" - conversion_event (string, optional) — default "PURCHASE" - age_min / age_max (integer, optional) — default 18–65 - genders (string, optional) — "all" / "male" / "female"; default "all" - daily_budget (integer, optional) — required for non-CBO campaigns - beneficiary (string, optional) — EU/EEA DSA legal advertiser name; tool requests automatically --- ### Tool: upload_meta_ads Tier: PAID — 1 credit per file uploaded (10 files = 10 credits) Description: Upload images or videos and create PAUSED Meta ads — one ad per file. Supports Google Drive, direct HTTPS URLs, Dropbox, and base64 data URIs. Max 50 files. Multi-step: get campaign → get ad set → collect inputs → get page → preview names → confirm → upload. Key parameters: - workspace_id (string, REQUIRED) - ad_account_id (string, REQUIRED) - campaign_id / adset_id / page_id — omit each in sequence to get respective lists - media_items (array of strings) — URLs or base64. Google Drive: "https://drive.google.com/uc?export=download&id=FILE_ID" - primary_texts (array, optional) — 1–5 body copy variants - headlines (array, optional) — 1–5 headline variants - destination_url (string, optional) — landing page with https:// - call_to_action (string, optional) — default "SHOP_NOW" - custom_text (string, optional) — label in ad name: {custom_text}_{filename}_{date}_{landing_page} - confirmed (boolean, optional) — false = preview ad names; true = create and charge credits --- ### Tool: duplicate_meta_campaign_or_adset Tier: PAID — 1 credit on confirmed creation Description: Duplicate a Meta campaign shell (no ad sets) or ad set shell (no ads). Duplicate is always PAUSED. Supports rename, budget override, EU DSA beneficiary. Multi-step: get account → find entity by name → show details + collect new name → handle EU beneficiary if ad_set → confirm → create. Parameters: - workspace_id (string, REQUIRED) - entity_type (string, REQUIRED) — "campaign" or "ad_set" - ad_account_id (string, optional) — omit to get account list - campaign_search_name (string, optional) — partial name; case-insensitive search - campaign_id (string, optional) — carry forward from search; do not ask user - adset_search_name / adset_id (string, optional) — for entity_type="ad_set" - new_name (string, optional) — name for the duplicate; max 255 chars - new_daily_budget (integer, optional) — in cents; None = copy original - new_lifetime_budget (integer, optional) — in cents; must pair with new_end_date - new_end_date (string, optional) — YYYY-MM-DD; required with new_lifetime_budget - beneficiary (string, optional) — EU/EEA DSA name; tool requests automatically - confirmed (boolean, optional) — false = preview; true = create --- ### Tool: set_meta_campaign_status Tier: PAID — 1 credit on confirmed status change Description: Activate or pause a Meta campaign. Looks up campaign by name — never asks the user for a campaign ID. Always shows current status preview first. Parameters: - workspace_id (string, REQUIRED) - new_status (string, REQUIRED) — "ACTIVE" or "PAUSED" - ad_account_id (string, optional) — omit to get account list - campaign_search_name (string, optional) — partial name; omit to get first 50 campaigns - campaign_id (string, optional) — carry forward from search - confirmed (boolean, optional) — false = preview; true = apply Returns on success: - success (boolean) - campaign_id, name, new_status (string) - credits_charged (integer) — 1 --- ### Tool: update_meta_campaign_budget Tier: PAID — 1 credit on confirmed budget change Description: Update a Meta campaign's daily or lifetime budget (campaign-level CBO only). Shows current budget before changes. Warns on type switches. All amounts in cents. Parameters: - workspace_id (string, REQUIRED) - ad_account_id (string, optional) — omit to get account list - campaign_search_name (string, optional) — partial name; omit to get first 50 campaigns - campaign_id (string, optional) — carry forward from search - new_budget_type (string, optional) — "daily" or "lifetime"; collected after showing current - new_budget_amount (integer, optional) — in cents; $50/day → 5000; max $100,000 = 10000000 - new_end_date (string, optional) — YYYY-MM-DD; required when new_budget_type="lifetime" - confirmed (boolean, optional) — false = preview; true = apply Returns on success: - success, campaign_id, new_budget_type, new_budget_amount_cents (integer) - new_budget_display (string) — e.g. "$50.00/day" - credits_charged (integer) — 1 --- ## Notes - All monetary values are in the workspace's configured currency (check `currency` field) - Dates use YYYY-MM-DD format; timestamps are ISO 8601 - `ctr` is a decimal: 0.019 = 1.9% - Meta tools use `query_ad_report`; Google Ads tools use `query_google_ads_report` - `query_ad_report` with `group_by="creative"` and `include_breakdowns=true` returns platform and demographic breakdowns per creative - `get_workspace_dashboard` caches results; check `cache_info.source` to know if data is fresh or cached - For Google Ads `group_by="headline"` or `group_by="copy"`, only `metrics=["impressions"]` is valid — the Google Ads API does not expose spend/clicks at RSA asset level - Campaign management tools (create, duplicate, set status, update budget) all require a confirmed=True call after a preview step — never skip the preview - Budget amounts for campaign management tools are in cents: $50 = 5000