Tutorial2026-07-226 min read

How to check if Copilot recommends your product

Microsoft Copilot recommends products all the time, it just never uses the word. Ask it "best help desk software for a 30-person support team" and it names three or four tools, each with a line of reasoning attached. To find out whether yours is one of them, run the questions your customers type at the moment of choosing and read what comes back. The part worth doing properly: being named is not being recommended, so don't stop at a yes or no — pull the sentence your brand sits in. And because Copilot ran a Bing search before it answered, that sentence has an address. Most claims it makes about you trace back to something in sources[], which means an unflattering description is a page you can open rather than a mood you have to argue with.

Tutorial

To check whether Microsoft Copilot recommends your product, ask the questions a buyer asks while deciding — "best X for Y", "X alternatives", "X vs Y" — and look for your name in the answer. Then do the part that decides the outcome: read the sentence around the mention, and read the Bing sources underneath it. Being listed is not being recommended, and on a search-grounded assistant the difference is usually traceable to one cited page.

The manual way (and why it stops working)

Open Copilot at copilot.microsoft.com and ask like a buyer, not like a marketer. "Best help desk software for a 30-person support team." "Acme alternatives." "Is Acme worth it for a small support team?" Find your name, read the sentence it sits in — that sentence is the actual result — then glance at the numbered citations, because one of them is the Bing page the sentence came from. Five or six phrasings, ten minutes, no cost, and you'll know roughly where you stand today.

Then the second pass arrives, and the cracks show fast.

  • Buying intent fans out. "Best", "cheapest", "alternatives to", "X vs Y", and one variant per segment and team size — each is a separate answer with its own shortlist and its own framing of you. Covering that honestly is a morning, and it's a morning you owe again next month.
  • Copilot re-searches Bing on every ask. It retrieves fresh each time, so Tuesday's flattering sentence and Thursday's lukewarm one can both be real. One reading can't separate a genuine slip from ordinary churn.
  • You will read yourself into a conclusion. Skimming prose for your own name, "also worth a look" files itself under win with remarkable ease. Extracting the sentence and judging it deliberately is a different exercise from scanning for a highlight.
  • The Bing source behind the sentence gets lost. The citation that produced an unflattering claim is sitting right there in the numbered list, and it is the single most useful thing on the page — but only if you note which one it was before you close the tab.
  • Nothing is stored and nothing is scheduled. In two months you'll want to know whether the framing improved after you rewrote the pricing page. Chat history is not a dataset, and it can't page you the week a competitor takes your slot.

Do it with one API call

One POST to AgentGEO returns the raw record for a query: the full answer text and every Bing source cited, structured. No headless browser, no selectors to keep alive — the managed-scraper engine is maintained for you, across all six engines.

curl -X POST https://api.agentgeo.org/v1/fetches \
  -H "Authorization: Bearer ag_live_..." \
  -H "Content-Type: application/json" \
  -d '{"query": "Acme alternatives for help desk software", "surfaces": ["copilot"], "country": "US"}'

What comes back is the whole record: the answer in full, plus every Bing page Copilot cited, in rank order. The signal you want lives in two fields — the sentence in answerText that names you, and the sources[] entry it was most likely written from:

{
  "id": "run_8f3ac21b",
  "query": "best help desk software for a 30-person support team",
  "surfaces": ["copilot"],
  "status": "completed",
  "recordsDelivered": 1,
  "creditsCharged": 1,
  "answers": [
    {
      "surfaceKey": "copilot",
      "status": "delivered",
      "answerText": "For a 30-person support team, a few tools come up repeatedly. Globex is the usual first pick for its shared inbox and reporting depth. Acme is a lighter option that teams choose for fast setup, though its analytics are thinner than Globex's. Initech rounds out the list for companies already inside the Microsoft stack.",
      "sources": [
        { "title": "Globex Help Desk - Features", "url": "https://globex.example.com/help-desk", "position": 1 },
        { "title": "Best help desk software in 2026", "url": "https://example.com/roundups/help-desk", "position": 2 },
        { "title": "Acme vs Globex, compared", "url": "https://example.com/compare/acme-globex", "position": 3 }
      ],
      "fetchedAt": "2026-07-22T09:14:22Z",
      "latencyMs": 8231
    }
  ]
}

Now write the check that matters. Here Acme is named as "a lighter option" with a caveat about analytics — a mention, not a clean win — and the comparison page at position 3 is the likeliest source of that framing. Instead of testing whether the brand is merely present, split the answer into sentences, keep the ones your brand appears in, and print the sources alongside them so the framing and the Bing page behind it stay attached:

import re
import requests
from urllib.parse import urlparse

KEY = "ag_live_your_key_here"
BRAND = "Acme"

# Buying intent - the questions asked immediately before a decision.
QUERIES = [
    "best help desk software for a 30-person support team",
    "Acme alternatives for help desk software",
    "Acme vs Globex for customer support",
    "cheapest help desk tool with a shared inbox",
]

MENTION = re.compile(rf"\b{re.escape(BRAND)}\b", re.I)


def sentences(text):
    # Split prose and bullet lines alike into quotable units.
    parts = re.split(r"(?<=[.!?])\s+|\n+", text)
    return [p.strip(" -*\t") for p in parts if p.strip()]


def host(url):
    h = urlparse(url).netloc.lower()
    return h[4:] if h.startswith("www.") else h


for query in QUERIES:
    resp = requests.post(
        "https://api.agentgeo.org/v1/fetches",
        # Copilot honours country; it does not take language or web_search.
        json={"query": query, "surfaces": ["copilot"], "country": "US"},
        headers={"Authorization": f"Bearer {KEY}"},
        timeout=200,  # the API waits up to 180s for live surfaces
    )
    resp.raise_for_status()

    for answer in resp.json()["answers"]:
        if answer.get("status") == "failed":
            # A slow scrape fails at zero credits - see the gotchas to redeem it.
            print(f"{query!r}: no record this run")
            continue

        text = answer.get("answerText") or ""
        hits = [s for s in sentences(text) if MENTION.search(s)]

        print(f"\n{query!r}")
        for line in hits:
            print(f"  says: {line}")
        if not hits:
            print("  not named at all")

        # Copilot searched Bing before it wrote. These are the pages it read.
        sources = sorted(answer.get("sources") or [], key=lambda s: s["position"])
        print(f"  written from ({len(sources)} source(s)):")
        for src in sources:
            print(f"    {src['position']:>2}. {host(src['url'])} - {src['url']}")

The output isn't a score, it's evidence: for each buying query, the exact sentences Copilot wrote about you and the ranked list of Bing pages it wrote them from. Four queries against one surface is four delivered records — four credits, with failed records costing nothing. An ag_test_ key returns labelled demo records at zero credits while you shape the parser.

Read the two columns together and the fix usually names itself:

What the sentence doesWhat the Bing citations usually showThe fix
Names you first, with a reasonOne of your own pages ranking near position 1Protect it. Keep that page current — it is carrying the recommendation.
Lists you with no differentiatorA third-party roundup nobody ownsPublish the page that states the difference in one liftable sentence.
Names you only as an alternative to GlobexGlobex's own comparison page, cited highWrite your side of that comparison and get it into Bing's index.
Adds a caveat — "thin reporting", "pricey"The claim usually sits verbatim in one cited pageCorrect it at the source if it's stale; out-publish it if it's opinion.
Doesn't name you at allRead whoever was cited insteadCoverage first — answer this exact question on a page Bing can find.

The framing has an address, and on Copilot that address is a Bing result you can open. When Copilot says something about your product you don't recognise, walk sources[] in position order and you'll usually find the claim sitting there almost word for word — a stale review, a competitor's comparison page, an old forum thread. What you do next is a judgment: whether "a lighter option" is a win depends on your positioning, and AgentGEO deliberately doesn't decide. It returns answerText and computes no sentiment, no score and no ranking. Pass the extracted sentences to your own model with your own rubric, and the definition of recommended stays yours.

Let your agent do it

This job suits an agent better than a script, because the interesting step is the second one: fetch the answer, then go read the Bing page that produced it. One command connects the server:

claude mcp add agentgeo -- npx -y agentgeo-mcp --key ag_live_...

That's the install: agentgeo-mcp over stdio, zero npm dependencies, Node.js 18+, and a single tool called fetch_raw_answers. From there you describe the task rather than implement it:

Fetch Microsoft Copilot's answer for "best help desk software for a 30-person support team". Quote the sentence that mentions Acme, then open the Bing source it most likely came from and tell me whether that page actually says it.

Notice where the judgment sits. AgentGEO hands back the record and stops; your agent — which knows your positioning, your pricing and what you'd call a fair description — decides what counts as a recommendation and whether the cited page needs correcting or out-writing. That split is the whole argument for a data layer rather than a dashboard, and you can drive it from Python or curl just as easily.

Common problems

Five things that will make this check lie to you, in rough order of how often they do:

  • Substring matching over-reports. A bare "acme" in text also fires on "AcmeBank", "Acme Freight" and the phrase "the acme of support". Use a word-boundary regex and keep an explicit ignore list for the namesakes you already know live in your category.
  • Make sure you're reading the right Copilot. This is consumer Microsoft Copilot at copilot.microsoft.com — the one grounded in a live Bing search — not GitHub Copilot and not the M365 Copilot inside Word and Teams. The copilot surface targets the consumer assistant; the enterprise ones answer over private tenant data and won't match what a buyer sees.
  • One run is not a verdict. Copilot re-searches Bing on every ask, so a mention that disappears once has probably not disappeared. Re-fetch two or three times before you tell anyone the framing got worse.
  • The Bing citation is a lead, not proof. The model paraphrases and merges several results, so the sentence about you may be assembled from two of them rather than lifted from one. Treat the source list as where to start reading, not as a citation in the academic sense.
  • Slow scrapes come back failed. Requests wait up to 180 seconds; a scrape that runs longer returns status: "failed" at zero credits with a providerFields.snapshot_id. Retry with that id and the same single copilot surface to redeem the finished answer instead of paying to re-scrape it.

Summary

For a one-off answer to "does Copilot recommend us?", ask it yourself and read the sentence. When the question has to be asked every month, across the queries that actually drive revenue, and answered with quotes instead of impressions — fetch the records, keep the sentences, and keep the Bing sources next to them. The sentence tells you how you're described; the citation tells you which page to go and fix.

Find out how Microsoft Copilot actually describes your product — and which Bing page it read to get there. Start free — no credit card.

Start for free

Frequently asked questions

Does Microsoft Copilot recommend products?
In practice, yes. For buying-intent prompts like "best help desk software" or "Acme alternatives", Copilot names specific products with a short reason for each and attaches the Bing sources it drew on. It doesn't frame that as an endorsement, but for the person reading it a named shortlist with reasoning works exactly like a recommendation.
How do I know if Copilot recommends my product?
Run your buying-intent queries and check two things: whether your brand appears, and how the sentence around it reads. The repeatable version is one API call — POST the query to https://api.agentgeo.org/v1/fetches with "surfaces": ["copilot"], split answerText into sentences, keep the ones matching your brand, and print sources[] beside them.
Why does Copilot mention my product but not recommend it?
Because a mention and a recommendation are different outcomes. You can be listed among four options with no differentiator, named only as an alternative to whoever owns the query, or named with a caveat like "thin reporting" or "pricey". Reading the surrounding sentence separates those cases, which is why a useful check extracts context rather than a boolean.
Can I see which page made Copilot describe my product that way?
Usually. Copilot runs a live Bing search before it writes, so it draws from pages it just retrieved, and those arrive in sources[] with title, url and position. Open them in position order and the claim is often sitting there nearly verbatim. Treat it as a lead rather than proof — answers do get assembled from more than one source.
Does the copilot surface cover GitHub Copilot or M365 Copilot?
No. The copilot surface targets consumer Microsoft Copilot at copilot.microsoft.com, grounded in Bing — the assistant a buyer would actually ask, not GitHub Copilot or the M365 Copilot in Word and Teams. To pull a record, POST to https://api.agentgeo.org/v1/fetches with "surfaces": ["copilot"] and an optional "country"; note that language and web_search are rejected on this surface.

Keep reading