Back to use cases

    Use case / Marketers / Python 3 / Published

    Voice of Customer Analysis from Instagram and TikTok Comments

    Card for Voice of Customer Analysis from Instagram and TikTok Comments

    Comment Voice-of-Customer Report is a small Python script for brand, support and product teams. Give it a brand's public Instagram and TikTok handles and it sorts the comments on recent posts into questions, complaints, product requests, praise and other, so you can see what customers are saying in one report.

    The problem

    Comment sections hold a lot of customer feedback, but it is spread across dozens of posts and two apps. Reading them by hand takes hours, and the useful comments (real questions, complaints, feature requests) are mixed in with emojis and tags.

    What the app does

    • Takes a public Instagram username, a TikTok username, or both.
    • Pulls the newest posts per platform (pinned posts are skipped).
    • Pulls public comments on each post.
    • Sorts every comment into questions, complaints, requests, praise or other.
    • Writes a report with counts per group and the most-liked comments in each, with post links.
    • Lets you plug in your own classifier, or an LLM, and re-sort a saved run for free.

    How it works

    1. Posts. GET /desearch/instagram/profile/{username}/posts and GET /desearch/tiktok/profile/{username}/posts.
    2. Comments. GET /desearch/instagram/comments/{shortcode} or GET /desearch/tiktok/comments/{video_id} for each post.
    3. Sort. Ordered keyword rules, first match wins. Optional LLM mode sends comments in batches to an endpoint you configure.
    4. Write report.md, comments.csv and run.json with every call and its cost.

    The code

        def get(self, path: str, params: dict, label: str):
            url = API_BASE + path
            attempt = 0
            while True:
                t = time.perf_counter()
                r = requests.get(url, headers={"Authorization": self.key}, params=params, timeout=120)
                elapsed = round(time.perf_counter() - t, 2)
                try:
                    body = r.json()
                except ValueError:
                    body = {"_raw_text": r.text[:5000]}
                call = {
                    "when": dt.datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %z"),
                    "path": path, "params": params, "status": r.status_code, "latency_s": elapsed,
                    "items": len(body) if isinstance(body, list) else None,
                    "cost_usd": float(r.headers.get("X-Desearch-Cost-Usd") or 0),
                    "usage_count": int(r.headers.get("X-Desearch-Usage-Count") or 0),
                    "service": r.headers.get("X-Desearch-Service"),
                    "attempt": attempt + 1,
                }
                self.calls.append(call)
                if self.raw_dir:
                    os.makedirs(self.raw_dir, exist_ok=True)
                    fn = os.path.join(self.raw_dir, f"{len(self.calls):03d}-{label}.json")
                    rec = {"request": {"method": "GET", "url": url, "params": params,
                                       "headers": {"Authorization": "<redacted>"}},
                           "call": call, "response_headers": {k: v for k, v in r.headers.items() if k.lower().startswith("x-desearch")},
                           "response": body}
                    s = json.dumps(rec, indent=2, ensure_ascii=False)
                    assert self.key not in s
                    with open(fn, "w") as f:
                        f.write(s)
                # 503 "Service request failed" happened once on 2026-10-06 and was not billed; retry once.
                if r.status_code in (429, 500, 502, 503, 504) and attempt < self.retries:
                    attempt += 1
                    time.sleep(5)
                    continue
                return r.status_code, body
    

    The folder has one script, vocreport.py, offline checks in test_vocreport.py and a real report in sample-output.md.

    Endpoints

    • GET /desearch/instagram/profile/{username}/posts
    • GET /desearch/instagram/comments/{shortcode}
    • GET /desearch/tiktok/profile/{username}/posts
    • GET /desearch/tiktok/comments/{video_id}

    Example output

    From a run on 2026-10-06 for a language-learning app's brand accounts, 10 posts per platform: 23 calls and 322 items returned. The report shows comment counts per group (questions, complaints, requests, praise, other), the top 5 most-liked comments in each group with post links, and the posts covered.

    Run it yourself

    The public examples folder linked above includes the script and a README. Install its requirements, set DESEARCH_API_KEY from console.desearch.ai, and use the run command in that README.

    Useful flags: --posts (default 10), --comments (per post, default 30), --classifier (keyword, llm or your own class), --max-spend (default $1.50), --from-run DIR (re-sort with no API calls).

    What it costs

    Each item returned cost $0.00207 on 2026-10-06. Billing is per item returned, and empty results cost nothing. One brand on both platforms with the defaults was 23 calls, 322 items and $0.667. See pricing.

    Ideas to extend it

    • Run it weekly and track how the share of complaints changes.
    • Route questions to your support team and requests to product.
    • Compare your comment mix with two peers in your category.

    Use with AI agents

    Point an MCP client at the hosted Desearch server. Replace the placeholder with a key from the console. Do not commit the key.

    {
      "mcpServers": {
        "desearch": {
          "url": "https://mcp.desearch.ai/mcp",
          "headers": {
            "Authorization": "Bearer <DESEARCH_API_KEY>"
          }
        }
      }
    }

    Prompt you can paste for this example:

    Use Desearch to read public comments on the latest Instagram and TikTok posts for the brand I name. Sort them into questions, complaints, requests, and praise, and quote the comments you retrieve. Do not invent comments.

    Build your own example.

    Give your agents access to web and social search. Get an API key to start building, or talk to us about your integration.

    Read docs