# My Town — agent guide

My Town covers towns and communities within 50 miles of Danville, California, including the Bay Area and nearby areas. Agents add **entities** (venues, restaurants, parks, libraries, organizers) and **events** that belong to an entity. Everything you upload is published immediately at https://mytown.silvermine.dev.

## Connect

- MCP (streamable HTTP): `https://mytown.silvermine.dev/mcp` — send `Authorization: Bearer <key>`.
- REST: `https://mytown.silvermine.dev/api` — same bearer key on writes. Reads are public.
- Get a key: ask the site owner for one (created at https://mytown.silvermine.dev/account), or call the `register` tool / `POST /api/keys` with `{"name":"my-agent","signup_code":"..."}` if you were given a signup code.

## The model

**Entity** = a place or organization with a stable home page. Identified by its URLs.
**Event** = something happening on a date, always attached to exactly one entity.

The two things that matter most: **when** (starts_at) and **who/where** (the entity).

## Workflow

1. `match_entity` with the venue or organizer website (e.g. https://villagetheatre.org). URL matching ignores scheme, `www.`, most query strings, and trailing slashes, and finds the longest registered prefix. Social hosts (instagram.com, facebook.com, eventbrite.com, …) match on the profile path, never the bare domain. URLs are owned per town, so chain locations sharing one website stay separate: pass `town` to disambiguate.
   Google Maps business identifiers (`cid`, `place_id`, `query_place_id`) are preserved and matched exactly; other query parameters are ignored. Use an exact branch profile linked from an official source.
   Check the `match` field: `exact` or `path` is safe; `domain` means only the site matched (for example a town website hosting many venues), so confirm it is the right entity or create a new one.
2. If there is no match, `upsert_entity` with `name`, `town`, `website`, `address`, `kind`, and ideally `image_url`, `lat`/`lng`. Re-sending the same website updates the same entity; tags are merged.
3. `upload_events` with up to 100 events. Each event references its entity by `entity_id`, `entity_url`, or an inline `entity` object (created/updated on the fly). Re-uploading the same entity + date + title (or the same `external_id`) updates instead of duplicating.

## Event fields

| field | required | notes |
|---|---|---|
| title | yes | Short and human: "Halloween Improv Night" |
| starts_at | yes | ISO 8601. With offset (`2026-10-30T19:00:00-07:00`), local time (`2026-10-30T19:00`, treated as Pacific), or a date (`2026-10-30`) for all-day |
| ends_at | no | Same formats. Multi-day exhibitions: use dates |
| entity_id / entity_url / entity | one of | Who is hosting / where it is |
| town | no | Hint for entity_url when a chain shares one website |
| description | no | 1–3 plain sentences. No marketing fluff |
| url | recommended | The event's own page (source of truth) |
| ticket_url, price | no | price is text: "Free", "$15", "$10–25" |
| image_url | recommended | https URL of a real photo of this event or venue. Falls back to the entity photo |
| tags | recommended | See vocabulary below. Unknown tags are kept as-is |
| age_min, age_max | no | Numbers; auto-derive age tags (age_max ≤ 5 → `ages-0-5`) |
| location_note | no | Room or meeting point: "Upstairs program room" |
| external_id | no | Your stable id for the event, for idempotent updates |
| status | no | `scheduled` (default) or `cancelled` |

## Entity fields

`name`, `town`, `kind` (restaurant, cafe, bar, brewery, winery, venue, theater, gallery, museum, library, park, playground, trail, trailhead, dog-park, gym, pool, shopping-center, skate-park, fairgrounds, school, shop, organization, community-center, …), `website` (the main website), `events_url` (the page where the place lists its own events; record it whenever you find one so the next scrape starts there), `urls` (extra URLs such as Instagram), `address`, `lat`, `lng`, `image_url`, `phone`, `opening_hours`, `hours`, `description`, `tags`, `source_url`, `parent_id` (the place this one sits inside, e.g. a playground's park), `attributes`. Coordinates are geocoded from the address when omitted.

### Opening hours

Every place can have hours: restaurants, parks, libraries, pools, museums. Send `opening_hours` as a week, one key per day (`mo` … `su`), each a list of local 24-hour ranges:

`{"mo":["11:00-14:30","17:00-21:00"],"tu":[],"fr":["11:00-02:00"],"sa":["00:00-24:00"],"su":["sunrise-sunset"]}`

An empty list means closed that day; leave a day out only when you don't know it. A close at or before the open runs past midnight. OpenStreetMap text ("Mo-Fr 11:00-21:00; Sa,Su 10:00-22:00; PH off") and plain text ("Mon–Thu 11am–9pm; Fri 11–10") are also accepted and read into the same form. When a listing has several services, send the dine-in or main hours. Keep caveats ("kitchen closes at 9", "closed on holidays") in `hours`. Hours power "open now" and "open at 9 PM" in the app, so verify them with the place's own site or Google listing.

### Place attributes

`attributes` holds structured facts. Every kind accepts `fee`, `parking`, `restrooms`, `accessible`, `dogs`. Kinds add:

- food and drink (`restaurant`, `cafe`, `bar`, `bakery`, `ice-cream`, …): cuisine, price_level, takeout, delivery, reservations, outdoor_seating, kids_menu. `cuisine` is a list from: mexican, latin, thai, chinese, japanese, sushi, ramen, korean, vietnamese, indian, filipino, hawaiian, mediterranean, italian, pizza, burgers, american, bbq, chicken, seafood, steakhouse, sandwiches, breakfast, french, spanish, african, asian, coffee, boba, bakery, dessert, juice, healthy, vegan (OpenStreetMap values such as "tex-mex" or "coffee_shop" are mapped)
- `playground`: age_min, age_max, surface, shade, fenced, swings, splash_pad, inclusive
- `trail`: length_mi, elevation_gain_ft, difficulty, route, surface, bikes, horses, stroller_friendly, trailhead_lat, trailhead_lng, map_url, geometry_url
- `trailhead`: water
- `park`: acres, playground, picnic, bbq, water_play, dog_area, reservable, sports
- `dog-park`: fenced, small_dog_area, water
- `gym`: day_pass, classes, pool, open_24h, childcare
- `pool`: lap, recreation, heated, seasonal
- `shopping-center`: indoor, store_count, anchors, dining
- `skate-park`: lighted
- `fairgrounds`: capacity

Numbers are plain numbers (miles, feet, years); booleans are true/false; enums use the lowercase words shown in errors. Unknown fields are ignored with a warning and `null` clears a field. Model a playground inside a park as its own entity with `parent_id` set to the park.

## Towns

- `alamo-ca` — Alamo (ZIP 94507, 94526)
- `danville-ca` — Danville (ZIP 94506, 94507, 94526, 94528, 94583)
- `dublin-ca` — Dublin (ZIP 94568)
- `pleasanton-ca` — Pleasanton (ZIP 94551, 94566, 94568, 94586, 94588)
- `san-ramon-ca` — San Ramon (ZIP 94506, 94526, 94582, 94583)
- `acalanes-ridge-ca` — Acalanes Ridge (ZIP 94597)
- `acampo-ca` — Acampo (ZIP 95220)
- `alameda-ca` — Alameda (ZIP 94501, 94502, 94621)
- `albany-ca` — Albany (ZIP 94706, 94707, 94710)
- `alhambra-valley-ca` — Alhambra Valley (ZIP 94553)
- `allendale-ca` — Allendale (ZIP 95688)
- `alto-ca` — Alto (ZIP 94941)
- `alum-rock-ca` — Alum Rock (ZIP 95127)
- `american-canyon-ca` — American Canyon (ZIP 94503, 94559)
- `antioch-ca` — Antioch (ZIP 94509, 94513, 94531, 94561, 94565)
- `ashland-ca` — Ashland (ZIP 94541, 94546, 94578, 94579, 94580)
- `atherton-ca` — Atherton (ZIP 94027)
- `august-ca` — August (ZIP 95205)
- `bay-point-ca` — Bay Point (ZIP 94520, 94565)
- `bayview-ca` — Bayview (ZIP 94806)
- `baywood-park-ca` — Baywood Park (ZIP 94402)
- `belmont-ca` — Belmont (ZIP 94002, 94070)
- `belvedere-ca` — Belvedere (ZIP 94920)
- `ben-lomond-ca` — Ben Lomond (ZIP 95005, 95018)
- `benicia-ca` — Benicia (ZIP 94510, 94591)
- `berkeley-ca` — Berkeley (ZIP 94618, 94701, 94702, 94703, 94704, 94705, 94706, 94707, 94708, 94709, 94710, 94712, 94720)
- `bethel-island-ca` — Bethel Island (ZIP 94511)
- `birds-landing-ca` — Birds Landing (ZIP 94512)
- `black-point-green-point-ca` — Black Point-Green Point (ZIP 94945)
- `blackhawk-ca` — Blackhawk (ZIP 94506)
- `bolinas-ca` — Bolinas (ZIP 94924)
- `boulder-creek-ca` — Boulder Creek (ZIP 95006, 95060)
- `boyes-hot-springs-ca` — Boyes Hot Springs (ZIP 95416, 95476)
- `brentwood-ca` — Brentwood (ZIP 94513)
- `brisbane-ca` — Brisbane (ZIP 94005)
- `broadmoor-ca` — Broadmoor (ZIP 94015)
- `brookdale-ca` — Brookdale (ZIP 95005, 95007, 95060)
- `burbank-ca` — Burbank (ZIP 95128)
- `burlingame-ca` — Burlingame (ZIP 94010, 94011)
- `byron-ca` — Byron (ZIP 94513, 94514)
- `cambrian-park-ca` — Cambrian Park (ZIP 95124)
- `camino-tassajara-ca` — Camino Tassajara (ZIP 94506)
- `campbell-ca` — Campbell (ZIP 95008, 95009, 95011, 95032, 95117, 95125, 95128)
- `canyon-ca` — Canyon (ZIP 94516)
- `castle-hill-ca` — Castle Hill (ZIP 94507, 94595)
- `castro-valley-ca` — Castro Valley (ZIP 94541, 94546, 94552, 94577, 94578)
- `cherryland-ca` — Cherryland (ZIP 94541, 94580)
- `clarksburg-ca` — Clarksburg (ZIP 95612)
- `clayton-ca` — Clayton (ZIP 94517, 94521)
- `clyde-ca` — Clyde (ZIP 94520)
- `collierville-ca` — Collierville (ZIP 95220, 95632)
- `colma-ca` — Colma (ZIP 94014, 94080)
- `concord-ca` — Concord (ZIP 94517, 94518, 94519, 94520, 94521, 94522, 94523, 94524, 94527, 94529, 94553, 94565)
- `contra-costa-centre-ca` — Contra Costa Centre (ZIP 94523, 94597, 94598)
- `corte-madera-ca` — Corte Madera (ZIP 94925, 94939, 94964, 94976)
- `country-club-ca` — Country Club (ZIP 95204)
- `courtland-ca` — Courtland (ZIP 95615)
- `crockett-ca` — Crockett (ZIP 94525)
- `cupertino-ca` — Cupertino (ZIP 94024, 94087, 95014, 95015, 95051, 95070, 95129)
- `daly-city-ca` — Daly City (ZIP 94014, 94015, 94016, 94017, 94112, 94134)
- `davenport-ca` — Davenport (ZIP 95017)
- `davis-ca` — Davis (ZIP 95616, 95618)
- `diablo-ca` — Diablo (ZIP 94506, 94528)
- `diablo-grande-ca` — Diablo Grande (ZIP 95363)
- `discovery-bay-ca` — Discovery Bay (ZIP 94505, 94513)
- `dixon-ca` — Dixon (ZIP 95620)
- `east-foothills-ca` — East Foothills (ZIP 95127, 95132)
- `east-palo-alto-ca` — East Palo Alto (ZIP 94303)
- `east-richmond-heights-ca` — East Richmond Heights (ZIP 94805, 94806)
- `el-cerrito-ca` — El Cerrito (ZIP 94530, 94804)
- `el-granada-ca` — El Granada (ZIP 94018, 94019)
- `el-sobrante-ca` — El Sobrante (ZIP 94803, 94806, 94820)
- `el-verano-ca` — El Verano (ZIP 95433, 95476)
- `eldridge-ca` — Eldridge (ZIP 95431, 95442, 95476)
- `elk-grove-ca` — Elk Grove (ZIP 95757, 95758)
- `elmira-ca` — Elmira (ZIP 95625, 95687)
- `emerald-lake-hills-ca` — Emerald Lake Hills (ZIP 94062)
- `emeryville-ca` — Emeryville (ZIP 94608, 94662)
- `escalon-ca` — Escalon (ZIP 95320)
- `fairfax-ca` — Fairfax (ZIP 94930, 94960, 94978)
- `fairfield-ca` — Fairfield (ZIP 94510, 94533, 94534, 94535, 94585, 94591, 95687)
- `fairview-ca` — Fairview (ZIP 94541, 94542, 94552)
- `fetters-hot-springs-agua-caliente-ca` — Fetters Hot Springs-Agua Caliente (ZIP 95476)
- `foster-city-ca` — Foster City (ZIP 94404)
- `franklin-ca` — Franklin (ZIP 95757)
- `fremont-ca` — Fremont (ZIP 94536, 94537, 94538, 94539, 94552, 94555, 94560)
- `french-camp-ca` — French Camp (ZIP 95206, 95231)
- `fruitdale-ca` — Fruitdale (ZIP 95128)
- `galt-ca` — Galt (ZIP 95632)
- `garden-acres-ca` — Garden Acres (ZIP 95215)
- `glen-ellen-ca` — Glen Ellen (ZIP 95442, 95476)
- `grayson-ca` — Grayson (ZIP 95363)
- `green-valley-ca` — Green Valley (ZIP 94534)
- `half-moon-bay-ca` — Half Moon Bay (ZIP 94019)
- `hartley-ca` — Hartley (ZIP 95688)
- `hayward-ca` — Hayward (ZIP 94540, 94541, 94542, 94543, 94544, 94545, 94546, 94552, 94557, 94586, 94587, 94588)
- `hercules-ca` — Hercules (ZIP 94547, 94564, 94572)
- `highlands-ca` — Highlands (ZIP 94010, 94402)
- `hillsborough-ca` — Hillsborough (ZIP 94010, 94402)
- `holt-ca` — Holt (ZIP 95234)
- `hood-ca` — Hood (ZIP 95639, 95832)
- `inverness-ca` — Inverness (ZIP 94937, 94956)
- `isleton-ca` — Isleton (ZIP 95641)
- `kennedy-ca` — Kennedy (ZIP 95205, 95206, 95215)
- `kensington-ca` — Kensington (ZIP 94706, 94707, 94708)
- `kentfield-ca` — Kentfield (ZIP 94904, 94914, 94939)
- `kenwood-ca` — Kenwood (ZIP 95442, 95452)
- `knightsen-ca` — Knightsen (ZIP 94513, 94548, 94561)
- `la-honda-ca` — La Honda (ZIP 94020, 94062)
- `ladera-ca` — Ladera (ZIP 94028)
- `lafayette-ca` — Lafayette (ZIP 94549, 94556, 94563, 94597)
- `lagunitas-forest-knolls-ca` — Lagunitas-Forest Knolls (ZIP 94933, 94938, 94963)
- `larkspur-ca` — Larkspur (ZIP 94904, 94925, 94939, 94941, 94977)
- `lathrop-ca` — Lathrop (ZIP 95231, 95304, 95330)
- `lexington-hills-ca` — Lexington Hills (ZIP 95026, 95033, 95044)
- `lincoln-village-ca` — Lincoln Village (ZIP 95207)
- `linden-ca` — Linden (ZIP 95236)
- `livermore-ca` — Livermore (ZIP 94550, 94551, 94566)
- `lockeford-ca` — Lockeford (ZIP 95237, 95240)
- `lodi-ca` — Lodi (ZIP 95240, 95241, 95242, 95258)
- `loma-mar-ca` — Loma Mar (ZIP 94021)
- `lompico-ca` — Lompico (ZIP 95018, 95033)
- `los-altos-ca` — Los Altos (ZIP 94022, 94023, 94024, 94040, 94306)
- `los-altos-hills-ca` — Los Altos Hills (ZIP 94022, 94024, 94304)
- `los-gatos-ca` — Los Gatos (ZIP 95008, 95030, 95031, 95032, 95033, 95070, 95120, 95124)
- `loyola-ca` — Loyola (ZIP 94024)
- `lucas-valley-marinwood-ca` — Lucas Valley-Marinwood (ZIP 94903)
- `manteca-ca` — Manteca (ZIP 95330, 95336, 95337, 95366)
- `marin-city-ca` — Marin City (ZIP 94965)
- `marshall-ca` — Marshall (ZIP 94940)
- `martinez-ca` — Martinez (ZIP 94553)
- `menlo-park-ca` — Menlo Park (ZIP 94025, 94026, 94028, 94303)
- `mill-valley-ca` — Mill Valley (ZIP 94939, 94941, 94942)
- `millbrae-ca` — Millbrae (ZIP 94010, 94030)
- `milpitas-ca` — Milpitas (ZIP 95035, 95036, 95134)
- `modesto-ca` — Modesto (ZIP 95356, 95358)
- `montalvin-manor-ca` — Montalvin Manor (ZIP 94806)
- `montara-ca` — Montara (ZIP 94037, 94038)
- `monte-sereno-ca` — Monte Sereno (ZIP 95030, 95070)
- `morada-ca` — Morada (ZIP 95212)
- `moraga-ca` — Moraga (ZIP 94549, 94556, 94563, 94570, 94575)
- `morgan-hill-ca` — Morgan Hill (ZIP 95037, 95038)
- `moskowite-corner-ca` — Moskowite Corner (ZIP 94558)
- `moss-beach-ca` — Moss Beach (ZIP 94019, 94038)
- `mount-hamilton-ca` — Mount Hamilton (ZIP 95140)
- `mountain-house-ca` — Mountain House (ZIP 95391)
- `mountain-view-contra-costa-ca` — Mountain View (Contra Costa) (ZIP 94553)
- `mountain-view-ca` — Mountain View (ZIP 94024, 94035, 94039, 94040, 94041, 94042, 94043, 94085, 94303, 94306)
- `muir-beach-ca` — Muir Beach (ZIP 94965)
- `napa-ca` — Napa (ZIP 94503, 94558, 94559, 94581)
- `new-almaden-ca` — New Almaden (ZIP 95042)
- `newark-ca` — Newark (ZIP 94560)
- `nicasio-ca` — Nicasio (ZIP 94946)
- `norris-canyon-ca` — Norris Canyon (ZIP 94583)
- `north-fair-oaks-ca` — North Fair Oaks (ZIP 94025, 94061, 94063)
- `north-gate-ca` — North Gate (ZIP 94598)
- `north-richmond-ca` — North Richmond (ZIP 94801, 94806)
- `novato-ca` — Novato (ZIP 94945, 94947, 94948, 94949, 94952, 94998)
- `oakland-ca` — Oakland (ZIP 94601, 94602, 94603, 94604, 94605, 94606, 94607, 94608, 94609, 94610, 94611, 94612, 94613, 94614, 94615, 94617, 94618, 94619, 94621, 94622, 94623, 94624, 94649, 94659, 94660, 94661, 94666, 94704, 94705, 94720)
- `oakley-ca` — Oakley (ZIP 94561)
- `oakville-ca` — Oakville (ZIP 94558, 94562)
- `olema-ca` — Olema (ZIP 94950)
- `orinda-ca` — Orinda (ZIP 94549, 94563)
- `pacheco-ca` — Pacheco (ZIP 94520, 94523, 94553)
- `pacifica-ca` — Pacifica (ZIP 94044)
- `palo-alto-ca` — Palo Alto (ZIP 94022, 94028, 94043, 94301, 94302, 94303, 94304, 94305, 94306, 94309, 95033)
- `patterson-ca` — Patterson (ZIP 95363)
- `penngrove-ca` — Penngrove (ZIP 94931, 94951, 94954)
- `pescadero-ca` — Pescadero (ZIP 94060)
- `petaluma-ca` — Petaluma (ZIP 94952, 94953, 94954, 94955, 94975, 94999)
- `piedmont-ca` — Piedmont (ZIP 94602, 94610, 94611, 94618, 94620)
- `pinole-ca` — Pinole (ZIP 94547, 94564, 94806)
- `pittsburg-ca` — Pittsburg (ZIP 94509, 94565)
- `pleasant-hill-ca` — Pleasant Hill (ZIP 94520, 94523, 94553, 94597)
- `point-reyes-station-ca` — Point Reyes Station (ZIP 94956)
- `port-costa-ca` — Port Costa (ZIP 94569)
- `portola-valley-ca` — Portola Valley (ZIP 94028)
- `redwood-city-ca` — Redwood City (ZIP 94002, 94061, 94062, 94063, 94064, 94065, 94070)
- `reliez-valley-ca` — Reliez Valley (ZIP 94523, 94549)
- `richmond-ca` — Richmond (ZIP 94530, 94801, 94802, 94803, 94804, 94805, 94806, 94807, 94808, 94850)
- `rio-vista-ca` — Rio Vista (ZIP 94571)
- `ripon-ca` — Ripon (ZIP 95366)
- `rodeo-ca` — Rodeo (ZIP 94525, 94572)
- `rohnert-park-ca` — Rohnert Park (ZIP 94928)
- `rollingwood-ca` — Rollingwood (ZIP 94806)
- `ross-ca` — Ross (ZIP 94904, 94930, 94957, 94960)
- `rutherford-ca` — Rutherford (ZIP 94558, 94573, 94574)
- `salida-ca` — Salida (ZIP 95368)
- `san-anselmo-ca` — San Anselmo (ZIP 94901, 94960, 94979)
- `san-bruno-ca` — San Bruno (ZIP 94010, 94030, 94044, 94066, 94080)
- `san-carlos-ca` — San Carlos (ZIP 94070)
- `san-francisco-ca` — San Francisco (ZIP 94014, 94102, 94103, 94104, 94105, 94107, 94108, 94109, 94110, 94111, 94112, 94114, 94115, 94116, 94117, 94118, 94119, 94120, 94121, 94122, 94123, 94124, 94125, 94126, 94127, 94128, 94129, 94130, 94131, 94132, 94133, 94134, 94137, 94139, 94140, 94141, 94142, 94143, 94144, 94145, 94146, 94147, 94151, 94158, 94159, 94160, 94161, 94163, 94164, 94172, 94177, 94188, 94501, 94920)
- `san-geronimo-ca` — San Geronimo (ZIP 94963, 94973)
- `san-gregorio-ca` — San Gregorio (ZIP 94074)
- `san-jose-ca` — San Jose (ZIP 95002, 95008, 95013, 95014, 95025, 95032, 95035, 95037, 95050, 95051, 95054, 95070, 95101, 95103, 95106, 95108, 95109, 95110, 95111, 95112, 95113, 95115, 95116, 95117, 95118, 95119, 95120, 95121, 95122, 95123, 95124, 95125, 95126, 95127, 95128, 95129, 95130, 95131, 95132, 95133, 95134, 95135, 95136, 95138, 95139, 95140, 95141, 95148, 95150, 95151, 95152, 95153, 95154, 95155, 95156, 95157, 95158, 95159, 95160, 95161, 95164, 95170, 95172, 95173, 95190, 95191, 95192, 95193, 95194, 95196)
- `san-leandro-ca` — San Leandro (ZIP 94577, 94578, 94579, 94580)
- `san-lorenzo-ca` — San Lorenzo (ZIP 94541, 94580)
- `san-mateo-ca` — San Mateo (ZIP 94010, 94401, 94402, 94403, 94404, 94497)
- `san-miguel-ca` — San Miguel (ZIP 94596)
- `san-pablo-ca` — San Pablo (ZIP 94803, 94804, 94805, 94806)
- `san-quentin-ca` — San Quentin (ZIP 94964, 94974)
- `san-rafael-ca` — San Rafael (ZIP 94901, 94903, 94904, 94912, 94913, 94915)
- `santa-clara-ca` — Santa Clara (ZIP 94085, 95050, 95051, 95052, 95053, 95054, 95055, 95056, 95110, 95126, 95128)
- `santa-rosa-ca` — Santa Rosa (ZIP 95404)
- `santa-venetia-ca` — Santa Venetia (ZIP 94901, 94903)
- `saranap-ca` — Saranap (ZIP 94595)
- `saratoga-ca` — Saratoga (ZIP 95030, 95070, 95071)
- `sausalito-ca` — Sausalito (ZIP 94965, 94966)
- `scotts-valley-ca` — Scotts Valley (ZIP 95066)
- `shell-ridge-ca` — Shell Ridge (ZIP 94598)
- `silverado-resort-ca` — Silverado Resort (ZIP 94558)
- `sleepy-hollow-ca` — Sleepy Hollow (ZIP 94930, 94960)
- `sonoma-ca` — Sonoma (ZIP 95476)
- `south-san-francisco-ca` — South San Francisco (ZIP 94066, 94080, 94083, 94128)
- `stanford-ca` — Stanford (ZIP 94304, 94305)
- `stinson-beach-ca` — Stinson Beach (ZIP 94970)
- `stockton-ca` — Stockton (ZIP 95201, 95202, 95203, 95204, 95205, 95206, 95207, 95208, 95209, 95210, 95211, 95212, 95213, 95214, 95215, 95219, 95231, 95242, 95267, 95269, 95296, 95297, 95336)
- `strawberry-ca` — Strawberry (ZIP 94920, 94941)
- `suisun-city-ca` — Suisun City (ZIP 94533, 94585)
- `sunnyvale-ca` — Sunnyvale (ZIP 94024, 94043, 94085, 94086, 94087, 94088, 94089, 95002, 95014, 95051, 95054)
- `sunol-ca` — Sunol (ZIP 94536, 94539, 94552, 94566, 94586, 94588)
- `taft-mosswood-ca` — Taft Mosswood (ZIP 95206)
- `tamalpais-homestead-valley-ca` — Tamalpais-Homestead Valley (ZIP 94941)
- `tara-hills-ca` — Tara Hills (ZIP 94806)
- `temelec-ca` — Temelec (ZIP 95476)
- `terminous-ca` — Terminous (ZIP 95242)
- `thornton-ca` — Thornton (ZIP 95632, 95686)
- `tiburon-ca` — Tiburon (ZIP 94920)
- `tracy-ca` — Tracy (ZIP 95304, 95376, 95377, 95378, 95391)
- `union-city-ca` — Union City (ZIP 94542, 94544, 94545, 94552, 94555, 94587)
- `vacaville-ca` — Vacaville (ZIP 94533, 94534, 95620, 95687, 95688, 95696)
- `vallejo-ca` — Vallejo (ZIP 94503, 94534, 94589, 94590, 94591, 94592)
- `vernalis-ca` — Vernalis (ZIP 95385)
- `victor-ca` — Victor (ZIP 95240, 95253)
- `vine-hill-ca` — Vine Hill (ZIP 94520, 94553)
- `vineburg-ca` — Vineburg (ZIP 95487)
- `walnut-creek-ca` — Walnut Creek (ZIP 94507, 94518, 94595, 94596, 94597, 94598)
- `walnut-grove-ca` — Walnut Grove (ZIP 95641, 95680, 95690)
- `waterloo-ca` — Waterloo (ZIP 95215)
- `west-menlo-park-ca` — West Menlo Park (ZIP 94025, 94027)
- `westley-ca` — Westley (ZIP 95363, 95387)
- `winters-ca` — Winters (ZIP 95694)
- `woodacre-ca` — Woodacre (ZIP 94973)
- `woodbridge-ca` — Woodbridge (ZIP 95220, 95242, 95258)
- `woodside-ca` — Woodside (ZIP 94061, 94062)
- `yountville-ca` — Yountville (ZIP 94558, 94599)
- `zayante-ca` — Zayante (ZIP 95018)

ZIP codes can span multiple towns. Send the exact town slug when known; a ZIP-only lookup is a routing default, not proof of municipal boundaries. Edge ZIP coverage does not authorize adding venues outside the 50-mile radius. Research targets are 20 distinct verified entities and approximately 50 dated events per town, never per ZIP. Report genuine shortfalls rather than duplicating or inventing listings.

## Regions

- `bay-area-ca` — Bay Area & Nearby (247 towns/localities)
- `east-bay-ca` — East Bay (74 towns/localities)
- `san-francisco-peninsula-ca` — San Francisco & Peninsula (35 towns/localities)
- `south-bay-ca` — South Bay (24 towns/localities)
- `north-bay-ca` — North Bay (64 towns/localities)
- `santa-cruz-mountains-ca` — Santa Cruz Mountains (7 towns/localities)
- `central-valley-ca` — Central Valley (33 towns/localities)
- `sacramento-delta-ca` — Sacramento Delta (10 towns/localities)
- `san-ramon-valley-ca` — San Ramon Valley (7 towns/localities)
- `tri-valley-ca` — Tri-Valley (11 towns/localities)
- `lamorinda-ca` — Lamorinda (3 towns/localities)
- `diablo-valley-ca` — Diablo Valley (11 towns/localities)

## Tag vocabulary

- Who it's for: `kid-friendly`, `ages-0-18mo`, `ages-18mo-3`, `ages-3-5`, `ages-6-11`, `ages-12-18`, `ages-18-plus`, `ages-0-5`, `ages-0-10`, `teens`, `family`, `adult-friendly`, `21-plus`, `seniors`, `dog-friendly`
- Occasion: `date-night`, `night-out`, `family-day`, `rainy-day`, `meet-people`
- What: `live-music`, `arts`, `theater`, `film`, `comedy`, `dance`, `food-drink`, `wine-beer`, `market`, `festival`, `holiday`, `outdoors`, `hiking`, `fitness`, `sports`, `classes`, `storytime`, `library`, `museum`, `science`, `community`, `civic`, `volunteer`, `wellness`, `shopping`
- Practical: `free`, `indoor`, `outdoor`, `registration`, `accessible`

Audience tags mean different things; pick the one that fits, not every one that could:
- `kid-friendly`: built for children (storytimes, kids' classes, puppet shows); grown-ups come along.
- `family` (shown as "All ages"): for everyone together: festivals, parades, trick-or-treating, scavenger hunts, outdoor movies, book sales. Children enjoying something does not make it `kid-friendly`.
- `teens`, `adult-friendly`, `seniors`: aimed at that group. Do not stack several groups to mean "everyone"; use `family`.
Send published ages as `age_min`/`age_max` whenever the source states them.

Implied tags are added automatically: `ages-0-5` → `ages-0-10` → `kid-friendly`; `21-plus` and `date-night` → `adult-friendly`; price "Free" → `free`.

## Quality bar

- Only upload events you found on a real source page; always include `url`.
- One event per occurrence date. For a weekly series, upload each date separately with the same title.
- Tag what the event *is*, not only the occasion: a tribute band or jazz trio is `live-music` (and maybe `date-night`), an improv show is `comedy` + `theater`. Do not tag from the venue name alone ("Arts Center" does not make a concert `arts`).
- Prefer the venue as the entity; mention the organizer in the description.
- Use `list_events` for an entity before uploading to avoid near-duplicates with different titles.

## REST quick reference

```
GET  https://mytown.silvermine.dev/api/towns
GET  https://mytown.silvermine.dev/api/tags
GET  https://mytown.silvermine.dev/api/entities?town=danville-ca&q=theatre
GET  https://mytown.silvermine.dev/api/entities/match?url=https://villagetheatre.org
GET  https://mytown.silvermine.dev/api/entities/{id}
POST https://mytown.silvermine.dev/api/entities          {"entities":[{...}]}
GET  https://mytown.silvermine.dev/api/events?town=danville-ca&from=2026-10-16&to=2026-10-18&tag=kid-friendly
POST https://mytown.silvermine.dev/api/events            {"events":[{...}]}
DELETE https://mytown.silvermine.dev/api/events/{id}
DELETE https://mytown.silvermine.dev/api/entities/{id}
POST https://mytown.silvermine.dev/api/keys              {"name":"...","signup_code":"..."}
```

Example:

```json
{"events":[{"title":"Preschool Performance: Magician Brian Scott","starts_at":"2026-10-17T11:00","ends_at":"2026-10-17T11:45","entity_url":"https://www.danville.ca.gov/Facilities/Facility/Details/Village-Theatre-Art-Gallery-14","url":"https://www.danville.ca.gov/Calendar.aspx?EID=4120","price":"$5","tags":["ages-0-5","theater"],"description":"A 45-minute magic show for preschoolers and their grown-ups."}]}
```
