Agents guide: how an AI agent should use Agent Salon SF
San Francisco haircuts, structured for AI agents. 908 San Francisco salons. No key, no account, no rate-limit sign-up. Independent; not affiliated with any salon listed; booking happens on the salon's own system.
Machine surfaces
- REST API: https://agentsalonsf.com/api/v1 (index) · OpenAPI 3.1: https://agentsalonsf.com/openapi.json (alias of https://agentsalonsf.com/api/v1/openapi.json)
- MCP server: https://agentsalonsf.com/mcp (streamable HTTP, stateless, no auth). Tools: compare_options, search_merchants, check_availability, get_merchant, search_haircuts, get_salon, get_stylist, get_availability, get_booking_link, list_salons.
- llms.txt: https://agentsalonsf.com/llms.txt (index) · llms-full.txt: https://agentsalonsf.com/llms-full.txt (everything in one file)
- Markdown twins: append .md to any page, e.g. https://agentsalonsf.com/salons/hairshaper.md, https://agentsalonsf.com/in/mission.md, https://agentsalonsf.com/neighborhoods.md. HTML pages link them with rel="alternate" type="text/markdown".
- Status: https://agentsalonsf.com/api/v1/status (availability freshness, provider permission record, dataset revision b-merchants@2026-10-23T11:05:07Z#4f15ef234749).
Decide, then complete booking with the merchant
**Start with compare_options for a supported service with a budget, selected extras or a date.** It evaluates the requested service together; search_merchants and search_haircuts are discovery tools and their base prices do not establish the cost with extras.
REST example: https://agentsalonsf.com/api/v1/options?service_intent=balayage%20color&neighborhood=soma&geography=nearby&budget=260&selected_addons=blow_dry. MCP: compare_options with service_intent="balayage color", neighborhood="soma", geography="nearby", budget=260, selected_addons=["blow_dry"]. Add date="YYYY-MM-DD" using the user's intended date in America/Los_Angeles.
Use geography=strict unless the user allows nearby salons. selected_addons contains only requested extras; mandatory extras are included automatically. Use salon=<slug or ref> to compare one discovered salon. Unknown intents and fields are rejected, never silently ignored.
Read all three groups: options meet known constraints; uncertain need specific checks; excluded have a documented disqualifier. Read known_subtotal_min/max, unresolved charges, conditions and per-fact evidence dates before making a recommendation. Continue with next_offset until null when assessing all results; an empty page or empty options group is not proof there are no conditional alternatives.
A known subtotal is not a guaranteed final quote. A starting price or an unknown extra cannot prove the complete task fits a budget. Consultation-required treatments return final quote unavailable. Deposit is advance payment, not an extra charge. Ordering is geographic then alphabetical, not a quality ranking.
No provider-confirmed availability exists. A requested date keeps otherwise possible choices uncertain. Time of day, stylist and hair length are not compare_options filters: retain those requirements explicitly and confirm them with the merchant. Never convert opening hours or candidate start times into bookable appointments.
Follow next_action.url and remaining_steps: confirm the exact service, full price, unresolved conditions and actual time at the merchant. The link does not preselect a service, hold a slot or complete a booking.
### Discovery and source detail when needed
- Find a salon by name/address or explore coverage: https://agentsalonsf.com/api/v1/search?mode=merchants&q=cinta (MCP search_merchants). Summaries provide refs, depth, booking_cta, published hours and matched offerings. Use the returned slug/ref as salon in compare_options to evaluate a specific service there.
- Inspect one salon's published hours and offerings: https://agentsalonsf.com/api/v1/availability?ref=<ref>&date=YYYY-MM-DD&service=balayage (MCP check_availability). This is not live availability or a complete price with extras.
- Full evidence for a known salon: MCP get_merchant or https://agentsalonsf.com/api/v1/merchants/<ref>. No need to fetch the full catalog to compare a few options.
- For base haircut-offering filters (type, length, stylist): https://agentsalonsf.com/api/v1/search?haircut_type=cut&max_price=50 (MCP search_haircuts). This preserves the existing contract; extras-inclusive decisions use compare_options. Without mode=merchants (or a merchant-only parameter such as service, has_booking, open_on_date, time_after), /api/v1/search keeps its v1 haircut-offerings contract.
- Ready-made task answers: https://agentsalonsf.com/tasks.md. These use the same decision engine; pass the user's actual date and constraints to /api/v1/options for a personalized answer.
### Task answer examples
- Can balayage + color + blow-dry fit a $260 budget in or near SoMa?
- What needs confirming for creative color under $300 in SoMa?
- Which Financial District haircut services can be evaluated against an $80 budget?
- What can published Castro hair-color menus establish for a $250 budget?
- Do published Pacific Heights highlight prices establish a complete service under $250?
- Which Financial District blowout services need confirmation for a $70 budget?
Availability: what it rests on
- availability_basis "schedule_candidates": UNCONFIRMED — candidate start times from the salon's published staff schedule; existing bookings are not subtracted, so some may already be taken — confirm on the booking page.
- availability_basis "published_hours": published opening hours only — the salon is open then, which does not mean an appointment is free.
- availability_basis "provider_confirmed": open times confirmed by the salon’s booking provider (existing bookings subtracted), captured within the freshness window. None today.
- require_availability=true is satisfied only by provider-confirmed availability (the booking provider’s own open times, existing bookings subtracted). No salon on this site has provider-confirmed availability today: profiled salons have candidate start times from the published staff schedule (existing bookings not subtracted, so they may already be taken) and listed salons have published opening hours only. Offerings with matching candidate start times are listed under
unconfirmed; confirm on the booking page.
Listed vs profiled
- PROFILED: researched in depth from the salon’s own website and online booking system — normalized haircut offerings, online-booking prices, stylists (booking-system names), booking rules and candidate start times.
- DETAILED: imported, and the business itself publishes a priced menu, an online booking link and its opening hours or service durations — every published service, price and duration is shown; not profiled in depth. Detailed = the business’s own website publishes a menu with prices, it has an online booking link, and the business itself publishes its opening hours (on its website or booking page, or confirmed by a manual check — map data does not count) or its service durations.
- LISTED: imported from public records (CA licence data, SF business registry, OpenStreetMap) and the business’s own website; not profiled in depth.
- Every salon in the API and MCP carries
depth; detail endpoints adddepth_infowith what you can and cannot rely on.
Data quality legend
- VERIFIED: supported by a named source and a check date.
- REPORTED: stated by a source, not independently confirmed.
- INFERRED: our interpretation, with reasons.
- UNKNOWN: we looked and could not establish it.
- STALE: previously observed, too old to rely on.
Rules we hold ourselves to
- Hard constraints are never relaxed silently; a no-match says which constraint blocked and the smallest change that would match.
- A budget match needs a bounded subtotal covering selected and mandatory extras, with no unresolved price conditions. It is still not a provider-confirmed final quote; starting prices that may exceed the cap remain
uncertain. - No Google or Yelp content is published. No ratings, no paid placement.
- Booking links go through https://agentsalonsf.com/out (a logged redirect to the business's own booking page or website).