Objective
- Reduce repeat overexposure of the same Thumbtack contractors in repair-list quote flows — especially when the same pro appears first on every search and receives disproportionate homeowner/agent outreach.
- Explore and ship a mitigation that fits Attik’s Thumbtack integration: rotation, suppression/exclusion, or another approach that balances contractor fairness with Thumbtack’s best-match ordering.
- Improve operator confidence that exclusion and fairness concerns are handled in product, not only via external spreadsheets.
Background
- June 2 implementation call: Catherine reported contractor complaints about repeatedly appearing first in Thumbtack handyman results, leading to repeated targeting and agent blowback.
- Chris: Initial ordering comes from Thumbtack’s perceived best match — changing order on the Attik side is not a simple yes/no; still worth exploring shuffle or other ways to avoid the same #1 every time.
- Team also referenced an exclusion sheet for contractors who should not appear — useful for hard blocks but does not solve fairness when a allowed contractor keeps winning the top slot.
- Today (code audit / product triage):
- Repair-list Thumbtack search: backend
POST /thumbtack/search/with-form-update → searchWithPrefill → searchBusinessesFiltered (Thumbtack API /api/v4/businesses/search-filtered, limit 10). Results are passed through in Thumbtack order — no Attik rotation, shuffle, or businessID filtering.
- Client UI (
MultiCategoryRequestClient.tsx): default sort default preserves API order; optional client re-sorts (top rated, fastest response, etc.) only after load.
- No in-app Thumbtack contractor exclusion/blocklist found in the search path; the transcript’s exclusion sheet appears to be external/manual, not wired into filtered search.
- Separate
repair-companies / QwikFix partner flows use a different submission model — out of scope unless product explicitly ties them in.
Scope
Backend (attik-backend) — if product chooses post-search filtering or rotation
routes/thumbtack.ts, searchWithPrefill.ts, thumbtackService.ts — hook point after searchBusinessesFiltered returns, before response to client (filter suppressed IDs, reorder, or inject rotation metadata).
- Possible new persistence: company- or org-level excluded Thumbtack
businessID list (replace external sheet) — schema/route TBD by product decision.
- Possible rotation state: track recent #1 placements or submissions per category/zip — TBD.
Frontend (attik-frontend) — display + settings
MultiCategoryRequestClient.tsx / RequestPageClient.tsx — today render businesses in API/default order; any rotation or suppression should stay consistent between server and client sort options.
- Optional: admin/settings UI to manage exclusion list (if not backend-only config).
- Copy/UX: clarify results are “from Thumbtack” if order is modified.
Out of scope (v1 unless product expands)
- Changing Thumbtack’s own ranking algorithm or partner API contract (may require Thumbtack engagement — see Decisions needed).
- QwikFix / specialty repair-companies assignment flows (ATT-1367).
- Reports Hub service exclusion filters (ATT-1806) — unrelated domain.
Done when
- Product-selected mitigation is implemented for repair-list Thumbtack results (rotation or in-app suppression or documented alternative approved by stakeholders).
- Repeat #1 overexposure scenario is measurably reduced per acceptance criteria product defines (e.g. same
businessID not default-first across N consecutive searches in a market).
- Hard-excluded contractors (if in scope) do not appear in Attik-rendered Thumbtack result lists.
Decisions needed
- Primary strategy — Rotation/shuffle (Attik reorders after search), suppression only (filter excluded IDs), or both? Any preference to escalate to Thumbtack instead of Attik-side reorder?
- Thumbtack partner constraints — Confirm with Thumbtack whether reordering or hiding pros from API results is allowed under partner terms.
- Exclusion list — Replace external sheet with in-app admin settings (per company / org / brand)? Who maintains it? Match by
businessID, name, or both?
- Rotation rules — If rotating: per repair list, per zip, per category, time window, or random shuffle of top N? Should recent quote submissions on the repair list influence who is shown first?
- Default UX — Keep Thumbtack best-match first with optional rotation, or change default sort/display for all users in affected categories (e.g. handyman only vs all categories)?
- Empty results — If suppression filters all returned businesses, fall back to unfiltered list, show message, or expand search?
- Success metric — What counts as “done” for fairness: fewer #1 repeat complaints, cap on impressions per contractor per week, or something else?
References
- Thumbtack search orchestration:
attik-backend/src/util/functions/thumbtack/searchWithPrefill.ts, thumbtackService.ts
- API routes:
attik-backend/src/routes/thumbtack.ts
- Client repair-list request UI:
attik-frontend/src/app/client/reports/[slug]/repair-list/[id]/request/components/MultiCategoryRequestClient.tsx
- Server actions:
attik-frontend/src/app/client/reports/[slug]/repair-list/[id]/request/actions.ts
- Thumbtack integration history: ATT-140, ATT-141
- Related repair journey: ATT-1367