{"openapi":"3.1.0","info":{"title":"HeyYumi API","version":"1.0.0","description":"Refined food & drink venue data (the 'oneset'): identity, location, standardized hours, menu, price band, rating, freshness, confidence. One curator's notebook, served as an API.\n\n## Field Mask & tiered billing\nUse the `fields` query param (comma-separated) to choose what you receive. Tokens can be tier names, `all`, or individual field names. Unknown tokens are ignored and reported via the `X-Map3-Ignored-Fields` response header. When `fields` is omitted, the default is `core`.\n\n## Authentication\nUse `Authorization: Bearer <API_KEY>` or the `X-API-Key` header. Do not put API keys in URLs. `?api_key=` is deprecated and scheduled for removal (it will be rejected with `401 query_auth_disabled`) because URLs are commonly stored in browser, proxy, server, and error logs.\n\nBilling is per request: each call is billed at the highest field tier you request (returned in the `X-Map3-Units` header). `page_size` does not change tokens.\n- `core` (= 1 token/request): id, name, category, categoryLabel, location, address, regionCode, confidence, sourceCount, lastSeenAt\n- `contact_hours` (= 2 tokens/request): phone, homepage, bookingUrl, snsLinks, businessHours, is24h\n- `quality` (= 2 tokens/request): rating, reviewCount, latestReviewDate, freshnessScore, dataQuality, price, menuSummary, openNow, photoCount, nearestStation\n- `edge` (= 4 tokens/request): accessHints, recommendedFor, atmosphere, cautions, menu, serviceAttributes, dietary, atmosphereScores, aiSummary, reputation\n- `media` (= 8 tokens/request): photos\n\nAbuse is controlled by limits, not price: per-key rate limit (requests/min) and a daily token cap by plan (429 with `Retry-After`), and a 5,000-result window for the live API. Larger or full-dataset extraction requires Bulk Export / data licensing, not paginated API calls (see Acceptable Use in the Terms).","contact":{"name":"heyyumi","url":"https://heyyumi.ai"}},"servers":[{"url":"https://api.heyyumi.ai"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Preferred: Authorization: Bearer <API_KEY>. Do not pass keys in URLs."},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Alternative header auth. Query-string api_key is deprecated."}}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"paths":{"/api/v1/places":{"get":{"operationId":"list-places","summary":"Search places","description":"Search refined places (the oneset) by keyword, region, category, and confidence. Sorted by review count and confidence, paginated. Use fields to shape the response.","parameters":[{"name":"keyword","in":"query","required":false,"description":"Partial match on name/address","schema":{"type":"string"},"example":"버거킹"},{"name":"region_code","in":"query","required":false,"description":"Region (admin-dong) code","schema":{"type":"string"}},{"name":"business_category","in":"query","required":false,"description":"Category (restaurant/cafe…)","schema":{"type":"string"},"example":"restaurant"},{"name":"min_confidence","in":"query","required":false,"description":"Minimum confidence (0-1)","schema":{"type":"number"},"example":"0.6"},{"name":"recommended_for","in":"query","required":false,"description":"Narrow by occasion (comma, all must match). Natural language resolves too. Values: solo_dining, date, group_dining, family, business_meeting, formal_gathering, late_night… Full list & aliases at /api/v1/meta.","schema":{"type":"string"},"example":"group_dining"},{"name":"atmosphere","in":"query","required":false,"description":"Atmosphere (comma). quiet, lively, view, cozy, trendy, spacious, traditional, clean, work_study, rainy_mood.","schema":{"type":"string"},"example":"quiet"},{"name":"parking","in":"query","required":false,"description":"Only places with confirmed parking. See parking_type for the kind.","schema":{"type":"boolean"},"example":"true"},{"name":"parking_type","in":"query","required":false,"description":"Parking type: onsite, valet, partner, nearby, none. Natural language (e.g. 발렛→valet) resolves.","schema":{"type":"string"},"example":"onsite"},{"name":"reservable","in":"query","required":false,"description":"Only reservable places (crawl-confirmed plus Yumi Partner venues).","schema":{"type":"boolean"},"example":"true"},{"name":"payment_methods","in":"query","required":false,"description":"Require payment methods (comma, all must match). cash, card, naver_pay, kakao_pay, toss_pay, alipay, wechat_pay…","schema":{"type":"string"},"example":"alipay"},{"name":"serves","in":"query","required":false,"description":"Serves (comma). coffee, alcohol, dessert, vegetarian, vegan.","schema":{"type":"string"},"example":"alcohol"},{"name":"dietary","in":"query","required":false,"description":"Dietary (comma). vegan_options, vegetarian_options, fully_vegan, mixed_group_suitable.","schema":{"type":"string"},"example":"vegan_options"},{"name":"pet_friendly","in":"query","required":false,"description":"Example boolean presence filter. Attach the param to require =true (only confirmed places). Full list (wifi, private_room, outdoor_seating, group_friendly, takeout, delivery, corkage_free, has_promotion…) at /api/v1/meta filters.boolean.","schema":{"type":"boolean"},"example":"true"},{"name":"fields","in":"query","required":false,"description":"Pick fields (Field Mask). Comma-separated tier names (core/contact_hours/quality/edge/media), 'all', or individual field names. Defaults to core. Call tokens = the highest field tier requested (per-request; page_size does not affect tokens). Owner-uploaded photos come via photos (media tier, highest cost 8 — venue & menu image URLs); in lists use photoCount (quality) for a cheap count. recommendedFor may include occasion tags such as solo_dining, late_night, and late_night_eatery.","schema":{"type":"string"},"example":"core,rating,accessHints"},{"name":"page","in":"query","required":false,"description":"Page (default 1)","schema":{"type":"integer"},"example":"1"},{"name":"page_size","in":"query","required":false,"description":"Items per page (max 100). Does not affect tokens (per-request billing). Live API keys can access up to a 5,000-result window; beyond that use Bulk Export.","schema":{"type":"integer"},"example":"20"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":[{"id":"11892345","name":"콩부자 홍제점","category":"restaurant","categoryLabel":"국밥","location":{"lat":37.5891,"lng":126.9436},"address":{"road":"서울 서대문구 통일로 450","jibun":"서울 서대문구 홍제동 330"},"regionCode":"1141011100","confidence":0.64,"sourceCount":2,"lastSeenAt":"2026-06-18T03:00:00.000Z"}],"meta":{"total":5,"page":1,"pageSize":20,"totalPages":1}}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/places/nearby":{"get":{"operationId":"nearby-places","summary":"Nearby search","description":"Find places around a coordinate (lat·lng) within a radius (m), nearest first. Each result includes distanceM (meters from center). fields/tokens behave like Search places.","parameters":[{"name":"lat","in":"query","required":true,"description":"Latitude","schema":{"type":"number"},"example":"37.5704"},{"name":"lng","in":"query","required":true,"description":"Longitude","schema":{"type":"number"},"example":"126.9921"},{"name":"radius","in":"query","required":false,"description":"Radius in meters (default 1000, max 5000)","schema":{"type":"integer"},"example":"500"},{"name":"business_category","in":"query","required":false,"description":"Category filter","schema":{"type":"string"},"example":"cafe"},{"name":"keyword","in":"query","required":false,"description":"Partial match on name/address","schema":{"type":"string"}},{"name":"recommended_for","in":"query","required":false,"description":"Narrow by occasion (comma, all must match). Natural language resolves too. Values: solo_dining, date, group_dining, family, business_meeting, formal_gathering, late_night… Full list & aliases at /api/v1/meta.","schema":{"type":"string"},"example":"group_dining"},{"name":"atmosphere","in":"query","required":false,"description":"Atmosphere (comma). quiet, lively, view, cozy, trendy, spacious, traditional, clean, work_study, rainy_mood.","schema":{"type":"string"},"example":"quiet"},{"name":"parking","in":"query","required":false,"description":"Only places with confirmed parking. See parking_type for the kind.","schema":{"type":"boolean"},"example":"true"},{"name":"parking_type","in":"query","required":false,"description":"Parking type: onsite, valet, partner, nearby, none. Natural language (e.g. 발렛→valet) resolves.","schema":{"type":"string"},"example":"onsite"},{"name":"reservable","in":"query","required":false,"description":"Only reservable places (crawl-confirmed plus Yumi Partner venues).","schema":{"type":"boolean"},"example":"true"},{"name":"payment_methods","in":"query","required":false,"description":"Require payment methods (comma, all must match). cash, card, naver_pay, kakao_pay, toss_pay, alipay, wechat_pay…","schema":{"type":"string"},"example":"alipay"},{"name":"serves","in":"query","required":false,"description":"Serves (comma). coffee, alcohol, dessert, vegetarian, vegan.","schema":{"type":"string"},"example":"alcohol"},{"name":"dietary","in":"query","required":false,"description":"Dietary (comma). vegan_options, vegetarian_options, fully_vegan, mixed_group_suitable.","schema":{"type":"string"},"example":"vegan_options"},{"name":"pet_friendly","in":"query","required":false,"description":"Example boolean presence filter. Attach the param to require =true (only confirmed places). Full list (wifi, private_room, outdoor_seating, group_friendly, takeout, delivery, corkage_free, has_promotion…) at /api/v1/meta filters.boolean.","schema":{"type":"boolean"},"example":"true"},{"name":"fields","in":"query","required":false,"description":"Pick fields (Field Mask). Comma-separated tier names (core/contact_hours/quality/edge/media), 'all', or individual field names. Defaults to core. Call tokens = the highest field tier requested (per-request; page_size does not affect tokens). Owner-uploaded photos come via photos (media tier, highest cost 8 — venue & menu image URLs); in lists use photoCount (quality) for a cheap count. recommendedFor may include occasion tags such as solo_dining, late_night, and late_night_eatery.","schema":{"type":"string"},"example":"core,rating,accessHints"},{"name":"page","in":"query","required":false,"description":"Page (default 1)","schema":{"type":"integer"},"example":"1"},{"name":"page_size","in":"query","required":false,"description":"Items per page (max 100). Does not affect tokens (per-request billing). Live API keys can access up to a 5,000-result window; beyond that use Bulk Export.","schema":{"type":"integer"},"example":"20"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":[{"id":"11892345","name":"콩부자 홍제점","category":"restaurant","categoryLabel":"국밥","location":{"lat":37.5891,"lng":126.9436},"address":{"road":"서울 서대문구 통일로 450","jibun":"서울 서대문구 홍제동 330"},"regionCode":"1141011100","confidence":0.64,"sourceCount":2,"lastSeenAt":"2026-06-18T03:00:00.000Z","distanceM":0}],"meta":{"total":12,"page":1,"pageSize":20,"totalPages":1,"center":{"lat":37.5704,"lng":126.9921},"radius":500}}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/places/{id}":{"get":{"operationId":"get-place","summary":"Place detail","description":"A single place. Use fields to fetch only the tiers you need (fields=all returns hours, menu, access hints, recommendation context, and more).","parameters":[{"name":"id","in":"path","required":true,"description":"Place id (canonical)","schema":{"type":"string"},"example":"11782345"},{"name":"fields","in":"query","required":false,"description":"Pick fields (Field Mask). Comma-separated tier names (core/contact_hours/quality/edge/media), 'all', or individual field names. Defaults to core. Call tokens = the highest field tier requested (per-request; page_size does not affect tokens). Owner-uploaded photos come via photos (media tier, highest cost 8 — venue & menu image URLs); in lists use photoCount (quality) for a cheap count. recommendedFor may include occasion tags such as solo_dining, late_night, and late_night_eatery.","schema":{"type":"string"},"example":"core,rating,accessHints"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":{"id":"11892345","name":"콩부자 홍제점","category":"restaurant","categoryLabel":"국밥","location":{"lat":37.5891,"lng":126.9436},"address":{"road":"서울 서대문구 통일로 450","jibun":"서울 서대문구 홍제동 330"},"regionCode":"1141011100","confidence":0.64,"sourceCount":2,"lastSeenAt":"2026-06-18T03:00:00.000Z","rating":null,"reviewCount":10731,"latestReviewDate":"2026-06-15","freshnessScore":0.82,"dataQuality":{"veracity":5,"completeness":1,"confidence":0.64,"recency":0.99,"last_verified_days_ago":4},"price":{"level":2,"avg":8000,"min":4500,"max":12000},"menu":[{"name":"콩나물국밥","price":8000,"recommend":true}],"openNow":{"open":true,"reason":"open","lastOrderPassed":false},"nearestStation":{"station":"홍제","walkMin":5},"photoCount":5,"photos":{"count":5,"main":"https://<supabase>/storage/v1/object/public/owner-photos/<uid>/11892345/1718000000000.jpg","gallery":[{"category":"interior","url":"https://<supabase>/storage/v1/object/public/owner-photos/<uid>/11892345/1718000000000.jpg","isMain":true},{"category":"exterior","url":"https://<supabase>/storage/v1/object/public/owner-photos/<uid>/11892345/1718000000001.jpg","isMain":false}],"menu":[{"menuItem":"콩나물국밥","url":"https://<supabase>/storage/v1/object/public/owner-photos/<uid>/11892345/1718000000002.jpg"}]},"phone":"02-123-4567","homepage":null,"bookingUrl":null,"snsLinks":null,"businessHours":[{"day":"mon","closed":false,"open":"00:00","close":"24:00","endsNextDay":false,"breaks":[],"lastOrder":null}],"is24h":true,"accessHints":{"subway":[{"station":"홍제","lines":["3호선"],"distanceM":360,"walkMin":5},{"station":"무악재","lines":["3호선"],"distanceM":920,"walkMin":13}]},"recommendedFor":["solo_dining","late_night","late_night_eatery"],"atmosphere":["캐주얼","빠른"],"cautions":["unkind_service"],"serviceAttributes":{"parking":true,"parking_type":"onsite","parking_fee":"paid","parking_note":"매장 주차 가능(유료)","dine_in":true,"reservable":true,"dietary":{"fully_vegan":false,"vegan_options":true,"vegetarian_options":true,"mixed_group_suitable":true,"vegan_menu_count":3,"non_vegan_menu_count":8,"confidence":0.62,"note":"비건 메뉴와 일반 메뉴가 함께 있어 비건과 비(非)비건이 같이 가기 좋아요. 조리 분리는 확인이 필요해요."}},"atmosphereScores":{"late_night":6,"late_night_eatery":8,"quiet":6.5,"lively":4},"aiSummary":"홍제역 근처 캐주얼 국밥집, 혼밥·심야식당 수요에 적합."}}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/places/{id}/history":{"get":{"operationId":"place-history","summary":"Place history","description":"Daily rating and activity-freshness (freshnessScore) trend (accumulated snapshots). A signal you can use to judge changes in a place's activity yourself.","parameters":[{"name":"id","in":"path","required":true,"description":"Place id (canonical)","schema":{"type":"string"},"example":"11782345"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":[{"date":"2026-06-18","reviewCount":10731,"rating":null,"latestReviewDate":"2026-06-15","freshnessScore":0.82}]}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/regions":{"get":{"operationId":"list-regions","summary":"Regions · resolve dong name","description":"Resolves a dong (neighborhood) name into codes & coordinates (location lookup when you have no GPS). Dong names are not unique (e.g. Hongje-dong = Seoul Seodaemun-gu + Gangwon Gangneung), so candidates are returned disambiguated by sido/sigungu, with place counts and a representative center. Feed a chosen center into /places/nearby to also cover adjacent dongs. Without dong, lists all regions that have places.","parameters":[{"name":"dong","in":"query","required":false,"description":"Dong name (e.g. 홍제동) — returns candidates","schema":{"type":"string"},"example":"홍제동"},{"name":"sigungu","in":"query","required":false,"description":"Narrow by sigungu (e.g. 서대문구)","schema":{"type":"string"}},{"name":"sido","in":"query","required":false,"description":"Narrow by sido (e.g. 서울특별시)","schema":{"type":"string"}},{"name":"region_code","in":"query","required":false,"description":"Look up a single region code","schema":{"type":"string"}},{"name":"include_empty","in":"query","required":false,"description":"Include regions with no places yet (default false)","schema":{"type":"boolean"}}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":[{"regionCode":"1141011100","sido":"서울특별시","sigungu":"서대문구","dong":"홍제동","fullName":"서울특별시 서대문구 홍제동","center":{"lat":37.577976,"lng":126.938483},"placeCount":280}]}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/categories":{"get":{"operationId":"list-categories","summary":"Categories","description":"Place counts per category in the oneset.","parameters":[],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":[{"category":"restaurant","count":82140}]}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/stats":{"get":{"operationId":"stats","summary":"Dataset stats","description":"Total places, regions, multi-source share, average confidence, category breakdown.","parameters":[],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"success":true,"data":{"totalPlaces":143027,"totalRegions":512,"multiSourcePlaces":70118,"avgConfidence":0.72,"byCategory":[{"category":"restaurant","count":82140},{"category":"cafe","count":51730},{"category":"bar","count":9157}]}}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}},"/api/v1/meta":{"get":{"operationId":"meta","summary":"Filter & field vocabulary","description":"Key-free (no billing, 1h cache). Returns the supported attribute filters, values, natural-language aliases, and field tiers. The single source of truth for filter vocabulary, which MCP and SDKs sync from automatically.","parameters":[],"security":[],"responses":{"200":{"description":"OK","headers":{"X-Map3-Units":{"description":"Billed tokens for this call = the highest field tier requested. page_size does not affect tokens (per-request billing).","schema":{"type":"integer"}},"X-Map3-Ignored-Fields":{"description":"Comma-separated unknown field tokens that were ignored (present only when some were dropped).","schema":{"type":"string"}}},"content":{"application/json":{"example":{"version":1,"filters":{"boolean":["wifi","parking","outdoor_seating","pet_friendly","group_friendly","kids_friendly","reservable","takeout","delivery","dine_in","catering","corkage_free","wheelchair_accessible","high_chair","no_kids_zone","smoking_area","restroom_gender_separated","power_outlets","stroller_storage","deposit_required","restroom_clean","waiting_expected","leftover_packing","repeat_customers","private_room","has_promotion"],"enum":{"parking_type":["onsite","valet","partner","nearby","none"]},"array":{"payment_methods":["cash","card","toss_pay","kakao_pay","naver_pay","zero_pay","local_gift","gov_support","alipay","wechat_pay"],"serves":["coffee","alcohol","dessert","vegetarian","vegan"],"dietary":["vegan_options","vegetarian_options","fully_vegan","mixed_group_suitable"],"recommended_for":["solo_dining","solo_drinking","date","group_dining","group_drinking","family","business_meeting","formal_gathering","late_night","late_night_eatery"],"atmosphere":["cozy","quiet","lively","spacious","view","trendy","traditional","clean","work_study","rainy_mood"]},"aliases":{"recommended_for":{"회식":"group_dining","혼밥":"solo_dining","상견례":"formal_gathering"},"atmosphere":{"조용한":"quiet","뷰맛집":"view"},"parking_type":{"발렛":"valet"}}},"fields":{"tiers":{"core":1,"contact_hours":2,"quality":2,"edge":4,"media":8},"byField":{"name":"core","rating":"quality","serviceAttributes":"edge","photos":"media"}}}}}},"400":{"description":"Invalid parameters / bulk_export_required (result window too large)"},"401":{"description":"API key required or invalid"},"429":{"description":"Rate limit, daily quota, or monthly quota exceeded (see Retry-After)"}}}}}}