LSD

AI Entity Match

Decides whether a business an AI named is the business you are tracking. Takes an answer's businesses plus a target and returns matched, confidence, and which signal decided it.

When to use this

The hardest part of AI visibility work is deciding whether "Cellino Plumbing, Heating, Cooling & Electric" is your client. Matching on the domain misses about a third of appearances — that is how often ChatGPT names a business with no website. Matching on the name fails on Google AI Mode, which labels cards editorially. This resolves your business against the local graph first, then matches on CID, domain, phone, name-with-address or name, and tells you which.

POST/v1/ai/match
Cost: 5 credits when the target is resolved against the business graph, 1 credit when you supply a cid, domain, website or phone yourself.
Rate Limit: Varies by plan
Response: ~5-15 seconds with the target lookup; immediate without it

Parameters

ParameterTypeRequiredDescription
target.business_namestringYesThe business being tracked
target.locationstringNoCity and state (e.g. "Buffalo, NY"). With this, the business is looked up and matched on its real identifiers rather than on its name.
target.cidstringNoGoogle CID in decimal, if you hold one. Strongest possible signal, and skips the lookup.
target.place_idstringNoGoogle place_id, used to resolve the business exactly rather than by name.
target.domainstringNoThe business's domain. Skips the lookup.
target.websitestringNoThe business's website URL. Skips the lookup.
target.phonestringNoThe business's phone number, in any format. Skips the lookup.
target.addressstringNoStreet address. Strengthens a name match when nothing else is available.
businessesarrayNoOne answer's businesses, exactly as /v1/ai/scraper, /v1/serp/ai-mode or a single /v1/ai/sample run returns them. Extra fields are ignored. Max 100.
runsarrayNoThe runs array from a /v1/ai/sample result, to get a rate across the whole sample instead of one verdict. Max 25. Pass this or businesses, never both.
resolvebooleanNoForce the profile lookup on or off. Default: on when there is a location and no identifier was supplied.

Example Request

curl -X POST https://api.localseodata.com/v1/ai/match \
  -H "Authorization: Bearer sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "target": { "business_name": "Cellino Plumbing", "location": "Buffalo, NY" },
    "businesses": [
      { "rank": 1, "name": "Roto-Rooter", "domain": "rotorooter.com" },
      { "rank": 2, "name": "The Classic Staple", "phone": "716-631-8080" }
    ]
  }'

Example Response

JSON
{
  "status": "success",
  "credits_used": 5,
  "data": {
    "target": {
      "business_name": "Cellino Plumbing",
      "resolved_from": "business_profile",
      "cid": "12345678901234567",
      "domain": "",
      "website": "https://www.cellino.com",
      "phone": "+1 716-631-8080",
      "address": "3 Coventry Green, Buffalo, NY 14221"
    },
    "matched": true,
    "confidence": 0.9,
    "matched_on": "phone",
    "rank": 2,
    "match": {
      "rank": 2,
      "name": "The Classic Staple",
      "phone": "716-631-8080"
    },
    "candidates": [
      { "name": "The Classic Staple", "score": 0.9, "matched_on": "phone", "rank": 2 }
    ]
  }
}

Response Fields

FieldTypeDescription
target.resolved_fromstring"business_profile" means the identifiers below came from a profile lookup, "not_found" that the lookup ran and found nothing, "request" that none was made
matchedbooleanWhether the target was found in the answer
confidencefloat0-1. The signal's strength, reduced when two candidates tied on a name-only match. matched is true exactly when this is 0.5 or above
matched_onstring"cid", "domain", "phone", "name_address", "name" or "none" — which signal decided it
rankintegerPosition in the answer, when the matched business carried one
matchobjectThe business that matched, exactly as it arrived
candidatesarrayEverything that scored above zero, best first — the near misses, not just the verdict

Notes

  • Matching on the domain alone misses roughly a third of appearances: that is how often ChatGPT names a business with an empty website and domain. Matching on the name alone fails on AI Mode, where Google labels cards editorially — the same business came back as "The Classic Staple" in one answer and under its trading name in the next.
  • Filter on matched_on rather than on confidence when you need identifier-grade certainty. A name match at 0.65 and a domain match at 0.9 are different kinds of answer, not the same answer at different strengths.
  • A website on a host many businesses share — Facebook, Instagram, Linktree, business.site, the big directories — is not a domain match. A Facebook page is a very common website for a small local business, and matching on the host alone would pair a client with the first rival in the answer who also has one.
  • A name matches only when the shorter of the two is wholly contained in the longer, and a one-word name never matches on its own. "Bolt Plumbing LLC" matches "Bolt Plumbing"; "Smith & Sons Plumbing" does not match "Smith & Sons Roofing"; "Buffalo" is left to an identifier.
  • target.place_id requires target.location alongside it — the lookup resolves the location before it uses the place_id.
  • Pass runs from a /v1/ai/sample result instead of businesses to get appearance_rate, best_rank, worst_rank and mean_rank for your business across the whole sample.
  • Supplying a cid, domain, website or phone yourself skips the lookup and drops the price to 1 credit.