Operator Business Brain Profile
Purpose
Resolve a free-text business reference (name, website domain, city, or trade) into a single structured "Brain profile" from Operator's public substrate of 35.2M US local businesses. Returns: brain score (0–100) with six weighted components, market position (rank within city + trade), recent review sentiment aggregated from Google/Yelp/Meta, services + contact info (phone/address public; email privacy-protected), top 3 same-market competitors with brain scores only, the AI-generated why narrative, the operator_estimate_low/mid/high valuation band (USD, vertical-aware multiple drawn from Operator's own broker comparables — they cite Empire Flippers / Flippa / BizBuySell on the marketing page), the canonical /biz/{slug}/ URL, and the per-business MCP descriptor URL at /mcp/biz/{slug}/. Read-only — no booking, claiming, or activation calls.
When to Use
- A user pastes a business name, website URL, or
"plumber in austin"-style phrase and wants the full Operator dossier. - An agent needs a single JSON view of a local-services business before deciding to recommend, contact, or compare it.
- A downstream MCP-aware client needs the per-business tool/resource manifest at
/mcp/biz/{slug}/to delegate further calls. - Lightweight competitive benchmarking: top-3 same-trade-same-city peers with brain scores and valuation bands.
- ARR / valuation estimation for SMB acquisition research (the
operator_estimate_*fields are the vertical-multiple band).
Workflow
Operator exposes a stable, unauthenticated REST API at https://operator.fyi/api/v1/ with a 100 req/day free-tier ceiling, no key required (see https://operator.fyi/developers/ and OpenAPI 3.0.3 spec at https://operator.fyi/api/v1/openapi.json). The full brain profile is assembled from five GET calls in parallel after slug resolution. Do not drive a browser for this task — the same data backs the rendered /biz/{slug}/ and /{niche}/{city_slug}/{slug}/ pages and there is no anti-bot wall in front of the API.
- Resolve free-text input to a slug. Hit
GET https://operator.fyi/api/v1/recommend/?query={url-encoded-text}. The response auto-detectsniche+city+stateand returns up to 3recommendationswithname,rating,reviews,phone,address,url(the vertical listing URL — derive the slug from the trailing path segment),trust_score, and a one-sentencewhy(this is the AI narrative the task asks for). If the caller supplied a slug already, skip this step. - Fetch the canonical profile.
GET /api/v1/business/?slug={slug}→datacontainsid(UUID),name,slug,niche,city,city_slug,state,address,phone,website,rating,review_count,description(the long-form AI narrative blurb),services[],photos[],business_hours,claimed,listing_url,google_maps_url,same_as[]. Notedata.reviewsis an empty array in the free tier — review text is gated; aggregate sentiment is not. - Fetch brain score.
GET /api/v1/health-score/?slug={slug}→data.overall_score(0–100),data.grade(A-F), anddata.componentswith six weighted sub-scores:trust_layer(0.20),review_signal(0.25),market_position(0.20),digital_presence(0.20),demand_signal(0.15). This is the MCP-canonical brain score — theget_brain_scoreMCP tool resolves to exactly this endpoint. - Fetch market position.
GET /api/v1/market-position/?slug={slug}→data.rank,data.total_in_market,data.percentile,data.composite_score, plus market-average rating / review-count / years-in-business andgap_to_next_rank.advice(a short coaching string). Use this for the "market position rank within (city, trade)" field. - Fetch review intelligence.
GET /api/v1/review-intelligence/?slug={slug}→data.overall_sentiment(very_positive|positive|mixed|negative|very_negative),data.rating_distribution(1–5 star counts),data.themes[](theme extraction; often empty on unclaimed listings — see Gotchas),data.market_comparison(your-vs-market rating + review-count + verdict strings like"above"/"below"). - Fetch peer set + valuation band.
GET /api/v1/markets/{city_slug}/{niche}/returnsbusinesses[](up to ~50, sorted by Operator's own ranking). For each business you getid,name,slug,rating,review_count,market_rank(oftennullwhile indexing — see Gotchas),operator_verified_score(this is the publicly-exposed brain score per peer), and three valuation fields:operator_estimate_low,operator_estimate_mid,operator_estimate_high(USD, vertical-multiple). To build "top 3 competitors": find the queried business by slug, drop it from the array, take the next 3 highest-operator_verified_score(fall back to highest rating × log(reviews) if scores are null), and emit only{ name, slug, brain_score, canonical_url }— no detailed intel, per the task contract. The queried business's own row carries its valuation band — store{ low, mid, high }. - Construct canonical URL + MCP endpoint. Canonical:
https://operator.fyi/biz/{slug}/(always — verify withHEADif paranoid). Per-business MCP descriptor:https://operator.fyi/mcp/biz/{slug}/returns JSON withmcp.server.url(https://operator.fyi/api/mcp-v2),mcp.tools[](4 tools incl.scan_business,get_brain_score,claim_business,get_review_intelligence),mcp.resources[](links back to business_profile, market_rankings, public_profile_html), andmcp.prompts[](3 pre-built prompts). Pass that URL through to the caller so downstream MCP clients can mount it directly. - Emit one JSON object matching the Expected Output schema. ARR-with-confidence-band is not an explicit field anywhere in the Operator API — derive it (or omit it) from
operator_estimate_middivided by a vertical-typical revenue multiple (1.5–3× ARR for service trades on BizBuySell / Empire Flippers comparables); flag confidence aslowwhenoperator_estimate_midis null or whenhealth-score.components.demand_signalis 0. Be explicit in the output that ARR is derived, not directly returned by Operator.
Browser fallback
If the API is degraded (the /api/v1/search/ index falls back to supabase_timeout_then_fallback_http_500 intermittently — see Gotchas), open one of the two public profile pages and screenshot/extract:
https://operator.fyi/biz/{slug}/— modern "Brain dashboard" with 6-segment radial, profile completeness 0–100, brain level L0–L6,operator://...activity ledger.https://operator.fyi/{niche}/{city_slug}/{slug}/— long-form vertical listing with full health-score component breakdown, top-5 competitor leaderboard already rendered, services / specialties / certifications / service areas. Thelisting_urlreturned by/api/v1/businesspoints here.
Both render server-side, no anti-bot wall, no JS execution needed for content. Use Browserbase only if you need pixel screenshots; otherwise browse cloud fetch is sufficient.
Site-Specific Gotchas
- Every
/api/v1/*path requires a trailing slash. Hittinghttps://operator.fyi/api/v1/business?slug=Xreturns a 308 redirect to/api/v1/business/?slug=Xand (worse) the redirect Location URL-encodes the query string a second time, so a naive client follow can produce a 400. Always include the trailing slash explicitly. /api/v1/businesses/(the plural list endpoint) returns500 Internal server erroras of 2026-05-19, regardless of filters. Use/api/v1/recommend/or/api/v1/markets/{city_slug}/{niche}/for list-style needs./api/v1/search/?q=...is flaky — falls back tosearch_index_fallbackwithfallback_reason: "supabase_timeout_then_fallback_http_500"andresults: []for queries that have working/recommendmatches. Prefer/recommend?query=...as the slug-resolver; only use/searchfor known-exact name matches and treat empty results as transient./api/v1/competitors/?slug=Xreturns{"ok": true, "gated": true, "unlocked": true, "content": null}on the free tier — confirmed null even with a valid slug. Don't waste calls on it; derive competitors from/api/v1/markets/{city_slug}/{niche}/instead.- Three different "brain"/"health" scores can appear for the same business.
/api/v1/health-scoreis the MCP-canonical one (52 for Roto-Rooter on 2026-05-19). The/biz/{slug}/HTML dashboard shows a separate "BRAIN" number derived from profile completeness + ledger activity (75 for the same business). The/{niche}/{city_slug}/{slug}/listing page shows a third "Health score" snapshot with its own component breakdown (98 in the same window). For programmatic use, trust/api/v1/health-score; cite the date stamp on the listing page if you need a human-friendly grade. market_rankin/api/v1/markets/...is frequentlynull("Unranked" on the HTML, "Market rank refreshing") even for #1-by-composite_scorebusinesses. Use/api/v1/market-position?slug=X'srank+total_in_market+percentilefor the rank field instead; that endpoint always computes a synthetic rank from the composite score.data.reviews: []is by-design on the free tier — Operator gates the full review text behind an enrichment key./api/v1/review-intelligence/still returns aggregate sentiment + rating distribution + market comparison, which is what the task actually asks for. Don't interpret the empty array as "no reviews exist".- Contact email is intentionally privacy-protected.
data.emailis never returned by/api/v1/business/; the HTML profile shows "Contact this business" instead of an address. Phone + street address are public. The skill output should mirror this: emitphone+addressbut leaveemailasnullor omit it. - Two public profile URLs both work and both look canonical.
/biz/{slug}/(brain dashboard) and/{niche}/{city_slug}/{slug}/(vertical listing). The task spec says canonical is/biz/{slug}/; the API'slisting_urlfield returns the vertical-listing form. Emit/biz/{slug}/ascanonical_urland the vertical form aslisting_urlto satisfy both. - The
/mcp/biz/{slug}endpoint also needs a trailing slash (308 redirect otherwise). The returned manifest referenceshttps://operator.fyi/api/mcp-v2(a different server URL than/api/mcpused on the marketing page) — pass through whatever the per-business endpoint returns rather than hard-coding. - No authentication, no key, no signup — the 100 req/day free-tier ceiling is per-IP. The full brain-profile assemble for one business is 5–6 GETs; budget accordingly when batch-processing.
operator_estimate_*is a USD valuation band, not ARR, despite the field naming. Roto-Rooter's mid was $9.78M with low $6.5M / high $13M on 2026-05-19 — that's a sale-price comparable, not an annual-revenue figure. The task asks for both ARR and valuation; only valuation is directly served. If you must emit ARR, derive it (operator_estimate_mid / 2.0is a reasonable vertical-blind midpoint for service trades) and tag the confidence band asderived/low.operator_estimate_*isnullfor many listings (~25% of the Honolulu plumbing peer set on 2026-05-19, includingWaialae Plumbing & Construction). When null, emitvaluation_range: nullrather than fabricating a band.
Expected Output
One JSON object per business lookup. Fields with no corresponding Operator data are explicitly null (do not omit them). Example for the canonical test case roto-rooter-plumbing-water-cleanup-4b2ca5ed:
{
"slug": "roto-rooter-plumbing-water-cleanup-4b2ca5ed",
"id": "4b2ca5ed-e54d-41bc-a3b0-dd10a55c1ed1",
"name": "Roto-Rooter Plumbing & Water Cleanup",
"niche": "plumbing",
"city": "Honolulu",
"city_slug": "honolulu",
"state": "HI",
"canonical_url": "https://operator.fyi/biz/roto-rooter-plumbing-water-cleanup-4b2ca5ed/",
"listing_url": "https://operator.fyi/plumbing/honolulu/roto-rooter-plumbing-water-cleanup-4b2ca5ed/",
"mcp_endpoint": "https://operator.fyi/mcp/biz/roto-rooter-plumbing-water-cleanup-4b2ca5ed/",
"brain_score": {
"overall": 52,
"grade": "D",
"components": {
"trust_layer": { "score": 0, "weight": 0.20 },
"review_signal": { "score": 80, "weight": 0.25 },
"market_position": { "score": 100, "weight": 0.20 },
"digital_presence": { "score": 60, "weight": 0.20 },
"demand_signal": { "score": 0, "weight": 0.15 }
},
"source": "https://operator.fyi/api/v1/health-score?slug=roto-rooter-plumbing-water-cleanup-4b2ca5ed"
},
"market_position": {
"rank": 1,
"total_in_market": 114,
"percentile": 100,
"composite_score": 36.85,
"market_avg_rating": 4.54,
"market_avg_review_count": 41.81,
"gap_to_next_rank": "You are #1 in your market"
},
"review_intelligence": {
"overall_sentiment": "very_positive",
"rating": 4.8,
"review_count": 2159,
"rating_distribution": { "1": 70, "2": 139, "3": 279, "4": 557, "5": 1114 },
"themes": [],
"market_comparison": {
"rating_vs_market": "above",
"reviews_vs_market": "above",
"market_avg_rating": 4.53,
"market_avg_review_count": 153
}
},
"services": [
"Emergency plumbing services", "Plumbing and drain cleaning",
"Water cleanup", "Backflow services", "Commercial plumbing",
"Excavation", "Pipe restoration", "Garbage disposal service",
"Grease trap service", "Leak detection",
"Water heater plumbing support", "Sewer line service"
],
"contact": {
"phone": "(808) 842-5680",
"address": "3049 Ualena St Ste 713, Honolulu, HI 96819, USA",
"website": "https://www.rotorooter.com/honolulu/",
"email": null,
"google_maps_url": "https://www.google.com/maps/search/3049%20Ualena%20St%20Ste%20713%2C%20Honolulu%2C%20HI%2096819%2C%20USA%2C%20Honolulu%2C%20HI"
},
"competitors_top_3": [
{ "name": "Allens Plumbing", "slug": "allens-plumbing-757b1a0a", "brain_score": null, "canonical_url": "https://operator.fyi/biz/allens-plumbing-757b1a0a/" },
{ "name": "535 Plumbing LLC", "slug": "535-plumbing-llc-c46dec93", "brain_score": null, "canonical_url": "https://operator.fyi/biz/535-plumbing-llc-c46dec93/" },
{ "name": "Pipe Masters LLC", "slug": "pipe-masters-llc-b92f724d", "brain_score": null, "canonical_url": "https://operator.fyi/biz/pipe-masters-llc-b92f724d/" }
],
"ai_narrative": "Roto-Rooter Plumbing & Water Cleanup is Honolulu's trusted plumbing expert, delivering comprehensive solutions for residential and commercial properties...",
"valuation_range": {
"low": 6525000,
"mid": 9787500,
"high": 13050000,
"currency": "USD",
"source": "operator_estimate (vertical-multiple comparables: Empire Flippers, Flippa, BizBuySell)"
},
"arr_estimate": {
"low": 3262500,
"mid": 4893750,
"high": 6525000,
"confidence": "derived",
"note": "Not directly returned by Operator. Computed as operator_estimate / 2.0 (mid-band service-trade revenue multiple). Confidence is `low` when demand_signal=0 or operator_estimate is null."
},
"_meta": {
"claimed": false,
"data_freshness": "2026-05-19",
"free_tier_calls_used": 5
}
}
Outcome shape variants
not_found—/api/v1/recommend/returnsrecommendations: []AND/api/v1/search/returnsresults: [](not a transientsupabase_timeoutfallback — verify by retrying once). Emit{ "status": "not_found", "query": "<original input>" }and nothing else.ambiguous_match—/api/v1/recommend/returns 2+ recommendations with similarwhystrings. Return all candidates as{ "status": "ambiguous", "candidates": [ {name, slug, city, niche, rating}, ... ] }and let the caller disambiguate.valuation_unavailable— business exists butoperator_estimate_low/mid/highare allnullin the markets payload. Emit the full profile but setvaluation_range: nullandarr_estimate: null. Do not fabricate.gated_intel—/api/v1/competitors/and/api/v1/business-side enrichment fields returngated: true, content: null. This is the free-tier default and not an error. Surface competitor data from/api/v1/markets/{city_slug}/{niche}/instead and proceed.