API reference
Every endpoint with its parameters, an example and an excerpt of the real production response. The base URL is https://michiyomi.dev. No API key is needed. Observation text in responses is Japanese.
Basics
- Base URL
https://michiyomi.dev- Auth
- None. No sign-up and no API key.
- Methods
- Read-only. Besides
GET, onlyPOST /amenities/search(coordinates in the body) andPOST /mcp. Write methods on/v1return 405. - Format
- JSON (UTF-8). Observation text is Japanese (
data_language: "ja"). - Rate limits
- Per IP address: 300 REST requests and 120 MCP requests per 60 seconds. Over the limit you get
429withretry-after: 60. - CORS
- Open to all origins (
access-control-allow-origin: *). - IDs
- Keep Mapillary image IDs as strings. Converting them to numbers can lose digits.
- Zero results
- Zero results still return
200, usually with anote. Zero means not recorded, not absent in the real world. - Pagination
- None. Nearby searches return at most 50 records. Move the center or change the radius to cover more ground.
Common fields
Successful /v1 responses share these fields. The per-endpoint examples below omit them.
| Field | Type | Description |
|---|---|---|
| api_version | "v1" | |
| data_language | string | Language of the observation text. Always "ja" for now (not yet in the OpenAPI file) |
| snapshot | string | null | release_id of the latest published release, or latest staged release if none is published |
| request_id | string(uuid) | Generated by crypto.randomUUID(); included in every response and log entry |
| data_as_of | string | null | |
| quality_policy | object | |
| license | object | Conditions for each layer of the response. Values vary by product (scenes, streets and edges, town blocks, schools). See https://michiyomi.dev/docs/license/ |
| note | string | Honesty note covering experimental inclusion, zero results, sparse coverage, or data inconsistency. It never claims that zero records prove no real-world change occurred. |
| warnings | string[] | Accepted but ignored legacy parameters and similar warnings |
GET /v1/meta responseOpen raw ↗{
"api_version": "v1",
"data_language": "ja",
"snapshot": "2026-09-13-r1",
"request_id": "b44f51c0-382e-445b-9013-a3f9e7ed500e",
"data_as_of": "2026-09-13",
"quality_policy": { "requested": "released", "generation": null, "experimental_included": false },
"license": {
"schema_version": 2,
"id": "LicenseRef-michiyomi-layered",
"url": "https://michiyomi.dev/docs/license/",
"policy_version": "2026-10-03",
"summary": "観測データ(本文・構造化JSON・機械層の値・経年変化)は CC BY 4.0 で使えます…",
"summary_en": "Observation data (text, structured JSON, machine features, changes) is available under CC …",
"obligations": {
"use_in_results": ["none"],
"display_or_quote_records": ["none"],
"redistribute_as_data": ["attribution", "upstream_not_licensed_if_bulk", "source_notice_if_bulk"]
},
"notices": [
"mapillary_reference_not_licensed",
"photos_not_included",
… 4 more
],
"layers": {
"observation": "CC-BY-4.0",
"mapillary_reference": "NOASSERTION",
"public_sector": "CC-BY-4.0"
},
"linked_only": { "photo": "CC-BY-SA-4.0" },
"attribution": "出典: みちよみ(michiyomi.dev…",
"attribution_en": "Source: michiyomi (michiyomi.dev), from Mapillary street-level photos, CC BY 4.0 (https://…",
… 8 more fields
}
}Errors
4xx and 5xx responses use one JSON shape. Parameter errors name the parameter in field. Internal paths and SQL are never returned.
| code | HTTP | Meaning |
|---|---|---|
invalid_parameter | 400 | Invalid parameter (out of range, unknown value, non-numeric string and so on) |
not_found | 404 | No such record |
method_not_allowed | 405 | The API is read-only, so that method is not allowed |
payload_too_large | 413 | Body too large (64 KB for /mcp, 2048 bytes for /amenities/search) |
rate_limited | 429 | Rate limit exceeded. Wait retry-after seconds |
internal | 500 | Server-side problem. Contact us with the request_id |
lat=135 · HTTP 400{
"error": {
"code": "invalid_parameter",
"message": "lat must be between -90 and 90",
"request_id": "3c3760d3-c98e-4c66-bf6b-de444f8af988",
"field": "lat"
}
}Scenes (one photo each)
The AI reading of each photo (scene). Check coverage first, find nearby photos with scenes/nearby, then read the full record with scenes/{id}.
GET/v1/coverage
Disclose data coverage at a point
Reports how much evidence exists near a point. Zero results remain zero; missing dataset coverage must never be reinterpreted as evidence that a real-world feature or change is absent.
scenes_by_year, scenes_by_generation, and scenes_total are collapsed under the selected quality policy. released_count and experimental_count are actual verbalization counts within the radius, independent of the requested quality policy. n_changes counts only status='supported'. All exclude quarantine. year_from and year_to filter scene capture years only. n_changes includes all years; use the year parameters on /v1/changes/nearby to filter change periods.
openapi.en.yaml sets the lower bound of
year_from and year_to to 2000. Production accepts years from 1970.Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
radius_m | query | integer | default 300 · range 1–1000 |
quality | query | string | Verbalization-generation quality policy.
"released" · values released include_experimental experimental_only |
generation | query | string | Explicit generation ID; takes precedence over quality; an unknown ID returns 400max 64 chars |
year_from | query | integer | range 1970–2100 |
year_to | query | integer | Returns 400 unless year_from is less than or equal to year_torange 1970–2100 |
Legacy parameters accepted for compatibility (deprecated): radius (Legacy alias for radius_m; when both are present, radius_m takes precedence)
Example
// common fields (snapshot, license and so on) omitted { "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 300, "year_from": null, "year_to": null }, "scenes_total": 2312, "scenes_by_year": { "2010": 2, "2013": 4, "2015": 25, "2016": 324, "2017": 321, "2018": 581, "2019": 324, "2020": 51, "2022": 125, "2023": 206, "2024": 89, "2025": 67, "2026": 193 }, "scenes_by_generation": { "gen2-qwen-local": 1429, "gen1-codex": 883 }, "released_count": 2312, "experimental_count": 0, "latest_year": 2026, "n_changes": 5, "candidate_truncated": false, "counting_notes": { "released_count": "この半径に released世代の言語化を持つシーン数(品質ポリシーに関わらず実数)", "experimental_count": "この半径に experimental世代の言語化を持つシーン数(同上)", "n_changes": "status='supported' の経年変化を全年で数えた件数(year_from/year_toはシーンの撮影年に…", "quarantine": "この地点クエリは capture_time_quality異常(quarantined=1)のシーンを全ての集計から除外…" } }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| scenes_total | integer | |
| scenes_by_year | object<integer> | Keys are capture years, or "unknown" when the capture year is unavailable |
| scenes_by_generation | object<integer> | |
| released_count | integer | |
| experimental_count | integer | |
| latest_year | integer | null | |
| n_changes | integer | |
| candidate_truncated | boolean | |
| counting_notes | object<string> |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
GET/v1/scenes/nearby
Search nearby scenes
Retrieves grid-cell y-bands one at a time in order of proximity to the query latitude, then applies an exact circular Haversine filter. Results are ordered by unrounded Haversine distance ASC, capture_year DESC for equal distances, then id ASC. distance_m is rounded only for display.
When the candidate limit is reached (8,000 within a band or cumulatively), candidate_truncated=true. Truncation always removes bands farther from the query center, so the true nearest records are retained even in dense areas. Scenes with quarantined=1 are excluded.
openapi.en.yaml sets the lower bound of
year_from and year_to to 2000. Production accepts years from 1970.Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
radius_m | query | integer | Search radius in meters; integer onlydefault 150 · range 1–1000 |
limit | query | integer | Number of records to return; default 10 for scenes and 20 for changesrange 1–50 |
quality | query | string | Verbalization-generation quality policy.
"released" · values released include_experimental experimental_only |
generation | query | string | Explicit generation ID; takes precedence over quality; an unknown ID returns 400max 64 chars |
year_from | query | integer | range 1970–2100 |
year_to | query | integer | Returns 400 unless year_from is less than or equal to year_torange 1970–2100 |
Legacy parameters accepted for compatibility (deprecated): radius (Legacy alias for radius_m; when both are present, radius_m takes precedence); gen (Legacy alias for generation); era (Legacy parameter. It is accepted but does not affect results. The warnings array reports); min_score (Legacy parameter. Like era, it is accepted but does not affect results)
Example
// common fields (snapshot, license and so on) omitted { "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 150, "limit": 2, "year_from": null, "year_to": null }, "count": 2, "results": [ { "id": "964535250779795", "distance_m": 3, "capture_year": 2019, "ward": "中央区", "view_class": "全方位(パノラマ)", "generation": { "id": "gen1-codex", "status": "released", "version": 1 }, "model": "gpt-5.6-sol", "summary": "施設: 一般道路 / 歩道: 左=あり(分離歩道,5m), 右=あり(分離歩道,4m), 有効幅約4m, 点字ブロックあ…", "image_page": "https://www.mapillary.com/app/?pKey=964535250779795", … 8 more fields }, { "id": "328331618839370", "distance_m": 4, "capture_year": 2018, "ward": "中央区", "view_class": "前方視", "generation": { "id": "gen1-codex", "status": "released", "version": 1 }, "model": "gpt-5.6-terra", "summary": "施設: 一般道路 / 歩道: 左=あり(分離歩道,3m), 右=あり(分離歩道,4m), 有効幅約2.5m, 車道幅約1…", "image_page": "https://www.mapillary.com/app/?pKey=328331618839370", … 8 more fields } ], "candidate_truncated": false }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| query.lat | number | |
| query.lon | number | |
| query.radius_m | integer | |
| query.limit | integer | |
| query.year_from | integer | null | |
| query.year_to | integer | null | |
| count | integer | |
| results | object[] | |
| results[].id | string | Mapillary image ID. Do not convert it to a number. |
| results[].distance_m | integer | |
| results[].lat | number | |
| results[].lon | number | |
| results[].position_source | string | Source of the representative coordinate; computed is Mapillary-corrected, raw is GPSvalues mapillary_computed mapillary_raw |
| results[].capture_year | integer | null | |
| results[].year | integer | null | Alias of capture_year for MCP and legacy-client compatibility |
| results[].ward | string | null | |
| results[].view_class | string | null | |
| results[].travel_bearing | number | null | |
| results[].is_pano | boolean | null | |
| results[].generation | object | |
| results[].model | string | null | |
| results[].prompt_version | string | null | |
| results[].summary | string | Precomputed Japanese streetscape summary |
| results[].analysis_status | string | values ok invalid |
| results[].image_page | string(uri) | |
| candidate_truncated | boolean |
Status codes
- 200 OK (200 is returned even for zero results)
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/scenes/{id}
Scene detail
When include is omitted, only analysis is requested (compatible with legacy /v1/node/{id}).
- If no verbalization matches the selected quality policy, the endpoint still returns 200 with
verbalization: null, anote, andavailable_generations; it never falls back automatically. - Invalid stored analysis returns
analysis: nullandanalysis_status: "invalid", not a 500 response. - A quarantined scene is returned with 200 when looked up directly by ID, together with
capture_time_qualityand a note.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string | Mapillary image ID(string) |
include | query | string | Comma-separated layers to retrieve. Unknown values or an empty string return 400.default "analysis" · example analysis metadata,machine,analysis |
quality | query | string | Verbalization-generation quality policy.
"released" · values released include_experimental experimental_only |
generation | query | string | Explicit generation ID; takes precedence over quality; an unknown ID returns 400max 64 chars |
Legacy parameters accepted for compatibility (deprecated): gen (Legacy alias for generation)
Example
// common fields (snapshot, license and so on) omitted { "scene": { "id": "1499911054492109", "lat": 35.688942434653, "lon": 139.72195407201, "position_source": "mapillary_computed", "capture_year": 2025, "capture_time_quality": "ok", "ward": "新宿区", "quarantined": false }, "image_page": "https://www.mapillary.com/app/?pKey=1499911054492109", "available_generations": [ { "id": "gen2-qwen-local", "status": "released", "version": 2 } ], "include": ["analysis", "machine", "metadata"], "verbalization": { "generation": { "id": "gen2-qwen-local", "status": "released", "version": 2 }, "model": "sakamakismile/Qwen3.8-27B-MTP-NVFP4", "prompt_version": "v3.5a-tf-nothink", "generated_at": "2026-08-15T19:53:11Z", "summary": "施設: 一般道路 / 歩道: 左=あり(路側帯,1.5m), 右=画角外不明, 有効幅約1.5m, 車道幅約4m / 舗…", "analysis_status": "ok", "content_sha256": "d4b3fc750fc0542d5df071c7cfa54a65e9aa9801af02dfacd11846e06c6d…", "analysis": { "image_file": "image.png", "capture_meta": {…}, "road_context": "両側に木造の店舗・住居が立ち並ぶ狭い市街地の路地…", "road_structure": { "type": "平面", "facility_type": "一般道路", "grade_separated_crossing": "なし" }, "geometry": {…}, "pavement": {…}, "markings_wear": […], "infrastructure": {…}, "mobility": {…}, "accessibility": {…}, … 9 more fields } }, "metadata": { "raw_lat": 35.6889384, "raw_lon": 139.7219968, "computed_lat": 35.688942434653, "computed_lon": 139.72195407201, "position_source": "mapillary_computed", "position_offset_m": 3.9, "raw_compass": 264.84407438728863, "computed_compass": 262.94484333912, "travel_bearing": 224.9, "view_class": "前方視", … 11 more fields }, "machine": { "node_id": "1499911054492109", "feature_version": "ml-2026-09-13", "month": 10, "weekday": "火", "hour": 15, "season": "秋", "time_bucket": "昼", "heading": 262.94484333912, "heading8": "西", "left_side8": "南東", … 7 more fields }, "machine_note": "機械層(画像処理由来の客観指標)…" }
Response fields
| Field | Type | Description |
|---|---|---|
| scene | object | |
| scene.id | string | |
| scene.lat | number | |
| scene.lon | number | |
| scene.position_source | string | values mapillary_computed mapillary_raw |
| scene.capture_year | integer | null | |
| scene.capture_time_quality | string | values ok epoch_anomaly unknown |
| scene.ward | string | null | |
| scene.quarantined | boolean | |
| image_page | string(uri) | |
| available_generations | object[] | |
| available_generations[].id | string | |
| available_generations[].status | string | values experimental released deprecated |
| available_generations[].version | integer | |
| include | string[] | values metadata machine analysis |
| verbalization | null | object | |
| verbalization.generation | object | |
| verbalization.model | string | null | |
| verbalization.prompt_version | string | null | |
| verbalization.generated_at | string | null | |
| verbalization.summary | string | |
| verbalization.analysis_status | string | values ok invalid |
| verbalization.content_sha256 | string | |
| verbalization.analysis | object | null | Full Japanese verbalization as structured JSON. Present only when include contains analysis. It is null, rather than causing a 500 response, when analysis_status = "invalid". |
| metadata | object | Present only when include=metadata |
| metadata.raw_lat | number | null | |
| metadata.raw_lon | number | null | |
| metadata.computed_lat | number | null | |
| metadata.computed_lon | number | null | |
| metadata.position_source | string | |
| metadata.position_offset_m | number | null | Distance in meters between raw and computed coordinates; null if either is missing |
| metadata.raw_compass | number | null | |
| metadata.computed_compass | number | null | |
| metadata.travel_bearing | number | null | |
| metadata.view_class | string | null | |
| metadata.sequence_id | string | null | |
| metadata.is_pano | boolean | null | |
| metadata.quality_score | number | null | |
| metadata.camera_type | string | null | |
| metadata.width | integer | null | |
| metadata.height | integer | null | |
| metadata.captured_at_ms | integer | null | |
| metadata.captured_at_jst | string | null | |
| metadata.capture_time_quality | string | |
| metadata.cell_250m | integer | |
| metadata.position_note | string | |
| machine | null | object | Present only when include=machine. Contains objective indicators derived from image processing and is null when no machine row exists. This is a separate namespace from VLM verbalization and should not be blended with it during interpretation. |
| machine.node_id | string | |
| machine.feature_version | string | |
| machine.month | integer | null | |
| machine.weekday | string | null | |
| machine.hour | integer | null | |
| machine.season | string | null | |
| machine.time_bucket | string | null | |
| machine.heading | number | null | |
| machine.heading8 | string | null | |
| machine.left_side8 | string | null | |
| machine.right_side8 | string | null | |
| machine.abs_objects | | |
| machine.colorfulness | number | null | |
| machine.green_ratio | number | null | |
| machine.warm_ratio | number | null | |
| machine.dominant_colors | | |
| machine.color_status | string | null | |
| machine_note | string |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 404 The requested resource does not exist
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
Streets (lines)
Street kartes for named streets, and numbers for unnamed road segments. Karte text is Japanese. See Reading the data.
GET/v1/streets/nearby
Nearest named streets (lines) and unnamed edges
Finds road edges (OSM ways cut at intersections, >=15 scenes) within radius_m and groups them by named street (same-name edges within a ward), nearest first. Unnamed roads are returned as unnamed_edges. Karte text is at /v1/streets/{street_id}.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
radius_m | query | integer | default 60 · range 1–500 |
limit | query | integer | default 5 · range 1–20 |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "la_counts": { "streets": 6248, "areas": 5256, "edges": 30362, "karte_streets": 3563, "karte_areas": 4734 }, "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 60, "limit": 5 }, "streets": [ { "street_id": 799, "name": "晴海通り", "ward": "中央区", "highway_class": "幹線", "length_m": 4480, "coverage_grade": "A", "n_scenes": 1739, "n_sequences": 121, "year_span": [2013, 2026], "bbox": [35.6575946, 139.7622352, 35.6730203, 139.7794593], "has_karte": true, "nearest_edge": { "edge_id": "884274229_3", "dist_m": 29 } }, { "street_id": 720, "name": "中央通り", "ward": "中央区", "highway_class": "幹線", "length_m": 5337, "coverage_grade": "A", "n_scenes": 2244, "n_sequences": 222, "year_span": [2010, 2026], "bbox": [35.6674922, 139.7611031, 35.6899098, 139.7746484], "has_karte": true, "nearest_edge": { "edge_id": "1026056857_1", "dist_m": 54.1 } } ], "unnamed_edges": [ { "edge_id": "522859644_1", "highway_class": "歩道・歩行者路", "length_m": 71, "n_scenes": 16, "dist_m": 50.5, "town_key": "13102003004", "ward": "中央区" } ], "n_edges_considered": 3, "notes": { "grade": "coverage_grade は被覆等級…", "rates": "率(sidewalk.rate など)は判定できた件数(judged)が分母…", "years": "統計は複数年の集計…", "sides": "通りの sides は軸に対する絶対方位の側(例: 北東側)…", "versions": "karte は主版(karte_provenance.model)…", "license": "通り・町丁目の骨格は © OpenStreetMap contributors(ODbL 1.0)…" } }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| streets | object[] | |
| streets[].street_id | integer | |
| streets[].name | string | |
| streets[].ward | string | null | |
| streets[].highway_class | string | null | 幹線 (arterial) |
| streets[].length_m | integer | null | |
| streets[].coverage_grade | string | values A B C D |
| streets[].n_scenes | integer | |
| streets[].n_sequences | integer | null | |
| streets[].year_span | integer | null[] | |
| streets[].bbox | number | null[] | min_lat, min_lon, max_lat, max_lon の順 |
| streets[].has_karte | boolean | |
| streets[].nearest_edge | object | |
| unnamed_edges | object[] | |
| n_edges_considered | integer | |
| notes | object |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 404 The requested resource does not exist
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/streets/search
Street name search (partial match)
Partial match on OSM street names (NFKC-normalized). ward narrows by ward/city name.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
qrequired | query | string | range 1–60 chars |
ward | query | string | max 20 chars |
limit | query | integer | default 10 · range 1–50 |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "la_counts": {…}, "query": { "q": "晴海通り", "ward": null, "limit": 2 }, "count": 2, "results": [ { "street_id": 5755, "name": "晴海通り", "ward": "江東区", "highway_class": "幹線", "length_m": 5203, "coverage_grade": "A", "n_scenes": 1939, "n_sequences": 144, "year_span": [2016, 2026], "bbox": [35.6405864, 139.7903256, 35.659162, 139.8026981], "has_karte": true }, { "street_id": 799, "name": "晴海通り", "ward": "中央区", "highway_class": "幹線", "length_m": 4480, "coverage_grade": "A", "n_scenes": 1739, "n_sequences": 121, "year_span": [2013, 2026], "bbox": [35.6575946, 139.7622352, 35.6730203, 139.7794593], "has_karte": true } ], "notes": {…} }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| count | integer | |
| results | object[] | |
| results[].street_id | integer | |
| results[].name | string | |
| results[].ward | string | null | |
| results[].highway_class | string | null | 幹線 (arterial) |
| results[].length_m | integer | null | |
| results[].coverage_grade | string | values A B C D |
| results[].n_scenes | integer | |
| results[].n_sequences | integer | null | |
| results[].year_span | integer | null[] | |
| results[].bbox | number | null[] | min_lat, min_lon, max_lat, max_lon の順 |
| results[].has_karte | boolean |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/streets/{street_id}
Street karte and aggregated profile
Street-level verbalization. karte is Japanese text synthesized by a local LLM only from profile (aggregated scene observations; rates use judged counts as denominators, with year spans) and machine-checked so that numbers, years and proper nouns exist in the profile. coverage_grade D has no karte. include=profile,axis,edges adds the profile, the axis polyline and the edge list.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
street_idrequired | path | integer | min 1 |
include | query | string | comma-separated list of profile, axis, edges, versions (versions = karte text of other model versions) |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "street_id": 799, "name": "晴海通り", "ward": "中央区", "highway_class": "幹線", "length_m": 4480, "coverage_grade": "A", "n_scenes": 1739, "year_span": [2013, 2026], "has_karte": true, "karte": { "street_id": "799", "name": "晴海通り(中央区)", "character": "区全体より幅の広い複数車線の車道が北西へ延び…", "tsuranari": "2013…", "sides": "南西側・北東側とも歩道がほぼ途切れずに続き…", "streetscape": "高層ビルの多くは築年の新しい外観で…", "walking": "判定できた1,906側のうち約98%に車道と分離された歩道があり…", "notable": "観測文には…", "changes_summary": "裁定済みの変化は記録にない…", "coverage_note": "被覆はA(2013…", "evidence_ids": [ "1516117756754071", … 4 more ] }, "karte_provenance": { "model": "opus55-v12-xhigh", "prompt": "prompt_street_v1_2.md", "generated_at": "2026-09-24 20:04:34", "note": "素材束(profile)だけから生成し…" }, "karte_versions": [ { "tag": "fable-low", "model": "fable-low", "prompt": "prompt_street_v1_1.md", "generated_at": "2026-09-22 13:35:28" }, … 2 more ], … 4 more fields }
Response fields
| Field | Type | Description |
|---|---|---|
| street_id | integer | |
| name | string | |
| ward | string | null | |
| highway_class | string | null | 幹線 (arterial) |
| length_m | integer | null | |
| coverage_grade | string | values A B C D |
| n_scenes | integer | |
| n_sequences | integer | null | |
| year_span | integer | null[] | |
| bbox | number | null[] | min_lat, min_lon, max_lat, max_lon の順 |
| has_karte | boolean | |
| karte | object | null | Street karte (Japanese; keys name/character/tsuranari/sides/streetscape/walking/notable/changes_summary/coverage_note/evidence_ids). null for grade D. |
| karte_provenance | object | null | |
| karte_versions | object[] | Karte versions (tag/model/prompt/generated_at; include=versions adds each karte text) |
| profile | object | Aggregated profile (include=profile). Rates use judged as denominator; judged_rate is the share of scenes that could be judged. |
| axis | number[][] | Axis polyline; each element is lat, lon (include=axis) |
| edges | object[] |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 404 The requested resource does not exist
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/edges/{edge_id}
Numbers for an unnamed road edge
Aggregated numbers for one road edge (OSM way cut at intersections, >=15 scenes). Karte text is provided at street and area level only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
edge_idrequired | path | string | ^[0-9]+_[0-9]+$ |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "la_counts": {…}, "edge_id": "522859644_1", "street_id": null, "town_key": "13102003004", "name": null, "ward": "中央区", "highway_class": "歩道・歩行者路", "length_m": 71, "n_scenes": 16, "geom": [ [35.6720502, 139.7657558], [35.6715701, 139.7652352] ], "profile": { "edge_id": "522859644_1", "street_id": null, "name": null, "ward": "中央区", "town_key": "13102003004", "highway": "footway", "highway_class": "歩道・歩行者路", "length_m": 71, "stats": {…}, "evidence": […] }, … 1 more fields }
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 404 The requested resource does not exist
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
Town blocks (areas)
Area kartes for 2020 census small areas (town blocks). Karte text is Japanese.
GET/v1/areas/at
Town block (2020 census small area) containing a point
Returns the 2020 census small area (town block) that contains the point. Area karte is at /v1/areas/{town_key}.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "la_counts": {…}, "query": { "lat": 35.6717, "lon": 139.7647 }, "area": { "town_key": "13102003004", "name": "銀座四丁目", "ward": "中央区", "coverage_grade": "A", "n_scenes": 1001, "n_sequences": 115, "year_span": [2010, 2026], "center": { "lat": 35.671029, "lon": 139.766331 }, "bbox": [35.66845943310958, 139.7626621643848, 35.67364263757046, 139.7695740383911], "has_karte": true }, "notes": {…} }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| area | object | null | |
| area.town_key | string | 2020 census small-area key |
| area.name | string | |
| area.ward | string | |
| area.coverage_grade | string | values A B C D |
| area.n_scenes | integer | |
| area.n_sequences | integer | null | |
| area.year_span | integer | null[] | |
| area.center | object | |
| area.bbox | number | null[] | |
| area.has_karte | boolean |
Status codes
- 200 OK (area is null when no town block contains the point)
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/areas/nearby
Town blocks whose centers are near a point
Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
radius_m | query | integer | default 800 · range 1–3000 |
limit | query | integer | default 5 · range 1–20 |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "la_counts": {…}, "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 800, "limit": 2 }, "count": 2, "results": [ { "town_key": "13102003004", "name": "銀座四丁目", "ward": "中央区", "coverage_grade": "A", "n_scenes": 1001, "n_sequences": 115, "year_span": [2010, 2026], "center": { "lat": 35.671029, "lon": 139.766331 }, "bbox": [35.66845943310958, 139.7626621643848, 35.67364263757046, 139.7695740383911], "has_karte": true, "center_dist_m": 165 }, { "town_key": "13102003005", "name": "銀座五丁目", "ward": "中央区", "coverage_grade": "A", "n_scenes": 991, "n_sequences": 131, "year_span": [2010, 2026], "center": { "lat": 35.670158, "lon": 139.765335 }, "bbox": [35.667463339979385, 139.76039842376687, 35.67296422354896, 139.7683763995818], "has_karte": true, "center_dist_m": 181 } ], "notes": {…} }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| count | integer | |
| results | object[] | |
| results[].town_key | string | 2020 census small-area key |
| results[].name | string | |
| results[].ward | string | |
| results[].coverage_grade | string | values A B C D |
| results[].n_scenes | integer | |
| results[].n_sequences | integer | null | |
| results[].year_span | integer | null[] | |
| results[].center | object | |
| results[].bbox | number | null[] | |
| results[].has_karte | boolean |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/areas/search
Town block name search (partial match)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
qrequired | query | string | range 1–60 chars |
ward | query | string | max 20 chars |
limit | query | integer | default 10 · range 1–50 |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "la_counts": {…}, "query": { "q": "銀座", "ward": null, "limit": 2 }, "count": 2, "results": [ { "town_key": "13102003008", "name": "銀座八丁目", "ward": "中央区", "coverage_grade": "A", "n_scenes": 1617, "n_sequences": 173, "year_span": [2013, 2026], "center": { "lat": 35.666841, "lon": 139.76345 }, "bbox": [35.663246854310266, 139.75849564746505, 35.67042470785432, 139.76595510852744], "has_karte": true }, { "town_key": "13102003001", "name": "銀座一丁目", "ward": "中央区", "coverage_grade": "A", "n_scenes": 1003, "n_sequences": 99, "year_span": [2015, 2026], "center": { "lat": 35.673638, "lon": 139.770276 }, "bbox": [35.671345054813635, 139.7652718203785, 35.6759623472913, 139.7725043952394], "has_karte": true } ], "notes": {…} }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| count | integer | |
| results | object[] | |
| results[].town_key | string | 2020 census small-area key |
| results[].name | string | |
| results[].ward | string | |
| results[].coverage_grade | string | values A B C D |
| results[].n_scenes | integer | |
| results[].n_sequences | integer | null | |
| results[].year_span | integer | null[] | |
| results[].center | object | |
| results[].bbox | number | null[] | |
| results[].has_karte | boolean |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
GET/v1/areas/{town_key}
Area karte and aggregated profile
Area-level verbalization; karte generation and grade handling are the same as /v1/streets/{street_id}. include=profile,geometry adds the profile and the simplified GeoJSON geometry.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
town_keyrequired | path | string | ^[0-9]{9,12}$ |
include | query | string |
Example
// common fields (snapshot, license and so on) omitted { "la_release": "2026-10-03-la2", "town_key": "13102003004", "name": "銀座四丁目", "ward": "中央区", "coverage_grade": "A", "n_scenes": 1001, "year_span": [2010, 2026], "has_karte": true, "karte": { "town_key": "13102003004", "name": "銀座四丁目(中央区)", "character": "ガラス張りの高層オフィスビルと商業ビルが広い幹線沿いに連なり…", "skeleton": "晴海通り・中央通り・昭和通りの幹線が骨格をなし…", "streetscape": "2010…", "walking": "判定できた1,224側のうち約99%に歩道があり…", "notable": "観測文には…", "changes_summary": "裁定済みの変化は記録にない…", "compared_to": "車道幅の中央値は約12.0mで中央区・都全体のいずれより広く…", "coverage_note": "等級A…", "evidence_ids": [ "1244325431140140", … 4 more ] }, "karte_provenance": { "model": "opus55-v12-xhigh", "prompt": "prompt_area_v1_2.md", "generated_at": "2026-09-25 10:43:56", "note": "素材束(profile)だけから生成し…" }, "karte_versions": [ { "tag": "fable-low", "model": "fable-low", "prompt": "prompt_area_v1_1.md", "generated_at": "2026-09-22 19:32:08" }, … 2 more ], … 5 more fields }
Response fields
| Field | Type | Description |
|---|---|---|
| town_key | string | 2020 census small-area key |
| name | string | |
| ward | string | |
| coverage_grade | string | values A B C D |
| n_scenes | integer | |
| n_sequences | integer | null | |
| year_span | integer | null[] | |
| center | object | |
| center.lat | number | |
| center.lon | number | |
| bbox | number | null[] | |
| has_karte | boolean | |
| karte | object | null | Area karte (Japanese; keys name/character/skeleton/streetscape/walking/notable/changes_summary/compared_to/coverage_note/evidence_ids). null for grade D. |
| karte_provenance | object | null | |
| profile | object | |
| geometry | object | Simplified GeoJSON geometry (include=geometry) |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 404 The requested resource does not exist
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
Changes over time
Changes found by comparing photos of the same place from different years, returned only if they survived an attempt to refute them.
GET/v1/changes/nearby
Search nearby adjudicated longitudinal changes
The default is status=supported, meaning the claim survived falsification-oriented re-evaluation. evidence is truncated to 200 Japanese characters and sets evidence_truncated; use the detail endpoint for the full text. Coordinates are the center of the road group (group_id), not the exact changed object. Ordering is distance_m ASC, then year_b DESC, then change_id ASC.
quality and generation are validated as strictly as on other endpoints (unknown values return 400), but longitudinal changes are a separate layer from verbalization generations, so these parameters do not filter results; they are reflected only in quality_policy and field_notes.quality.
openapi.en.yaml sets the lower bound of
year_from and year_to to 2000. Production accepts years from 1970.Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
radius_m | query | integer | default 500 · range 1–3000 |
limit | query | integer | Number of records to return; default 10 for scenes and 20 for changesrange 1–50 |
category | query | string | Japanese change category. Values mean equipment, building, road marking, pavement, roadside use, vegetation, and other.values 設備 建物 区画線・標示 舗装 沿道用途 植栽 その他 |
status | query | string | default "supported" · values supported refuted unverifiable withdrawn |
year_from | query | integer | range 1970–2100 |
year_to | query | integer | Returns 400 unless year_from is less than or equal to year_torange 1970–2100 |
quality | query | string | Verbalization-generation quality policy.
"released" · values released include_experimental experimental_only |
generation | query | string | Explicit generation ID; takes precedence over quality; an unknown ID returns 400max 64 chars |
Legacy parameters accepted for compatibility (deprecated): radius (Legacy alias for radius_m; when both are present, radius_m takes precedence)
Example
// common fields (snapshot, license and so on) omitted { "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 500, "limit": 2, "category": null, "status": "supported", "year_from": null, "year_to": null }, "count": 2, "results": [ { "change_id": "chg_4424424a5b4f", "group_id": 1670, "distance_m": 233, "lat": 35.669806875, "lon": 139.763595175, "year_a": 2017, "year_b": 2026, "category": "設備", "subject": "GINZA SIX前のタクシー関連標識", "evidence": "右側のGINZA SIX緑色外壁前にあり…", "evidence_truncated": false, "segment_priority_score": 10, "status": "supported" }, { "change_id": "chg_e9d920b5c524", "group_id": 1670, "distance_m": 233, "lat": 35.669806875, "lon": 139.763595175, "year_a": 2017, "year_b": 2026, "category": "植栽", "subject": "GINZA SIX前を含む両側歩道の街路樹", "evidence": "2017年のフレーム1…", "evidence_truncated": false, "segment_priority_score": 10, "status": "supported" } ], "candidate_truncated": false, "field_notes": { "segment_priority_score": "道路区間の点検優先度ヒューリスティック(変化自体の危険度ではない)…", "change_position": "lat/lon は変化地点そのものではなく…", "verification": "同一モデル系列の文脈分離した別セッションによる反証優先の再検証を通過した(verdict=supported)所見のみを…", "quality": "経年変化は言語化世代(generation)とは別レイヤ…" } }
Response fields
| Field | Type | Description |
|---|---|---|
| query | object | |
| count | integer | |
| results | object[] | |
| results[].change_id | string | |
| results[].group_id | integer | Road-group ID, formerly gid |
| results[].distance_m | integer | |
| results[].lat | number | Road-group center coordinate, not the exact changed-object location |
| results[].lon | number | |
| results[].year_a | integer | |
| results[].year_b | integer | |
| results[].category | string | Japanese enum value for equipment, building, road marking, pavement, roadside use, vegetation, or othervalues 設備 建物 区画線・標示 舗装 沿道用途 植栽 その他 |
| results[].subject | string | Japanese change subject, formerly what |
| results[].evidence | string | null | Japanese evidence truncated to 200 characters |
| results[].evidence_truncated | boolean | |
| results[].segment_priority_score | integer | null | Road-segment inspection-priority heuristic, formerly max_risk. This is not the danger or severity of the change itself. It is null for many rows. |
| results[].status | string | values supported refuted unverifiable withdrawn |
| candidate_truncated | boolean | |
| field_notes | object<string> |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
GET/v1/changes/{change_id}
Longitudinal-change detail
Returns full Japanese evidence and verification metadata from falsification-oriented re-evaluation. scene_ids_a and scene_ids_b are null for every row in this release because the source data does not contain them. The service does not fabricate IDs and discloses this in note.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
change_idrequired | path | string | ^chg_[0-9a-f]{12}$ |
Example
// common fields (snapshot, license and so on) omitted { "change": { "change_id": "chg_4424424a5b4f", "group_id": 1670, "lat": 35.669806875, "lon": 139.763595175, "cell_1km": 174101796, "year_a": 2017, "year_b": 2026, "category": "設備", "subject": "GINZA SIX前のタクシー関連標識", "evidence": "右側のGINZA SIX緑色外壁前にあり…", "scene_ids_a": null, "scene_ids_b": null, "segment_priority_score": 10, "status": "supported", "verification": { "method": "same-model independent-context adversarial review", "method_ja": "同一モデル系列の文脈分離した別セッションによる反証優先の再検証", "detector_model": "gpt-5.6-sol", "reviewer_model": "gpt-5.6-sol", "same_model_family": true, "verdict": "supported", "limitations": ["shared systematic errors may remain", "supported率は反証パスの生存率であり精度の下限保証ではない"] } }, "field_notes": { "segment_priority_score": "道路区間の点検優先度ヒューリスティック(変化自体の危険度ではない)…", "change_position": "lat/lon は変化地点そのものではなく…", "verification": "同一モデル系列の文脈分離した別セッションによる反証優先の再検証を通過した(verdict=supported)所見のみを…" } }
Response fields
| Field | Type | Description |
|---|---|---|
| change | object | |
| change.change_id | string | |
| change.group_id | integer | Road-group ID, formerly gid |
| change.distance_m | integer | |
| change.lat | number | Road-group center coordinate, not the exact changed-object location |
| change.lon | number | |
| change.year_a | integer | |
| change.year_b | integer | |
| change.category | string | Japanese enum value for equipment, building, road marking, pavement, roadside use, vegetation, or othervalues 設備 建物 区画線・標示 舗装 沿道用途 植栽 その他 |
| change.subject | string | Japanese change subject, formerly what |
| change.evidence | string | null | Full Japanese evidence text |
| change.evidence_truncated | boolean | |
| change.segment_priority_score | integer | null | Road-segment inspection-priority heuristic, formerly max_risk. This is not the danger or severity of the change itself. It is null for many rows. |
| change.status | string | values supported refuted unverifiable withdrawn |
| change.cell_1km | integer | |
| change.scene_ids_a | string[] | null | Always null in this release because the source data does not contain these IDs |
| change.scene_ids_b | string[] | null | |
| change.verification | object | null | Adjudication metadata. method_ja contains the Japanese method label meaning a falsification-oriented re-evaluation by a separate, context-isolated session from the same model family. |
| field_notes | object<string> |
Status codes
- 200 OK
- 404 The requested resource does not exist
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists.
Amenities
Capture points of photos in which a vending machine, toilet or bench was seen.
GET/v1/amenities/nearby
Nearby amenity observations (vending machines, toilets, benches)
Returns capture points of photos in which the amenity (kind) was seen, nearest first by straight-line distance. Coordinates and distances refer to where the photo was taken. The amenity position, whether it is still there and whether it is usable are not verified. Omitting year_from includes all years. To keep a visitor location out of URLs, use POST /amenities/search.
openapi.en.yaml lists only
vending_machine for kind. Production also accepts toilet and bench.Parameters
| Name | In | Type | Description |
|---|---|---|---|
latrequired | query | number | Latitude (WGS84), parsed strictly with /^-?\d+(\.\d+)?$/range -90–90 |
lonrequired | query | number | Longitude (WGS84)range -180–180 |
kind | query | string | Amenity kind: vending_machine, toilet or benchdefault "vending_machine" · values vending_machine toilet bench |
radius_m | query | integer | default 1000 · range 100–3000 |
limit | query | integer | default 3 · range 1–10 |
year_from | query | integer | range 2000–2100 |
Example
// common fields (snapshot, license and so on) omitted { "count": 2, "results": [ { "id": "bn_1470fb07087f1e7c", "lat": 35.67205272116, "lon": 139.76419890994, "position_basis": "capture_location", "scene_id": "529346588414766", "capture_year": 2019, "evidence": "ベンチ:良好", "object_position": "右", "object_distance_m_est": 10, "confidence": "high", "image_page": "https://www.mapillary.com/app/?pKey=529346588414766", "generation_id": "gen2-qwen-local", "ward": "中央区", "evidence_count": 1, "distance_m": 60 }, { "id": "bn_235844e9fd8e40d2", "lat": 35.672235417637, "lon": 139.76394183294, "position_basis": "capture_location", "scene_id": "2910127179305154", "capture_year": 2019, "evidence": "ベンチ:良好", "object_position": "中央", "object_distance_m_est": 5, "confidence": "high", "image_page": "https://www.mapillary.com/app/?pKey=2910127179305154", "generation_id": "gen2-qwen-local", "ward": "中央区", "evidence_count": 1, "distance_m": 91 } ], "dataset": { "kind": "bench", "source_snapshot": "2026-09-13-r1", "built_at": "2026-09-17T17:43:39.549691Z", "total_candidates": 16849, "min_year": 2006, "max_year": 2026 }, "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 1000, "limit": 2, "year_from": null, "kind": "bench" } }
Response fields
| Field | Type | Description |
|---|---|---|
| count | integer | |
| query | object | |
| dataset | object | |
| dataset.source_snapshot | string | |
| dataset.built_at | string | |
| dataset.total_candidates | integer | |
| dataset.min_year | integer | null | |
| dataset.max_year | integer | null | |
| results | object[] | |
| results[].id | string | |
| results[].scene_id | string | |
| results[].lat | number | |
| results[].lon | number | |
| results[].position_basis | "capture_location" | |
| results[].distance_m | integer | |
| results[].capture_year | integer | |
| results[].evidence | string | |
| results[].object_position | string | null | |
| results[].object_distance_m_est | number | null | |
| results[].confidence | string | values high medium |
| results[].image_page | string(uri) | |
| results[].generation_id | string | |
| results[].ward | string | null | |
| results[].evidence_count | integer |
Status codes
- 200 OK (Cache-Control is no-store)
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
POST/amenities/search
Amenity search with coordinates in the body
Returns the same result as GET /v1/amenities/nearby. Coordinates travel in the JSON body (2048 bytes at most), so they stay out of URLs. Nothing is written.
openapi.en.yaml lists this endpoint under its alias
/vending/search. Both return the same result, and kind also accepts toilet and bench.Body (JSON)
| Name | In | Type | Description |
|---|---|---|---|
latrequired | body | number | range -90–90 |
lonrequired | body | number | range -180–180 |
radius_m | body | integer | default 1000 · range 100–3000 |
limit | body | integer | default 3 · range 1–10 |
kind | body | string | default "vending_machine" · values vending_machine toilet bench |
year_from | body | integer | null | range 2000–2100 |
Example
// common fields (snapshot, license and so on) omitted { "count": 2, "results": [ { "id": "bn_1470fb07087f1e7c", "lat": 35.67205272116, "lon": 139.76419890994, "position_basis": "capture_location", "scene_id": "529346588414766", "capture_year": 2019, "evidence": "ベンチ:良好", "object_position": "右", "object_distance_m_est": 10, "confidence": "high", "image_page": "https://www.mapillary.com/app/?pKey=529346588414766", "generation_id": "gen2-qwen-local", "ward": "中央区", "evidence_count": 1, "distance_m": 60 }, … 1 more ], "dataset": { "kind": "bench", "source_snapshot": "2026-09-13-r1", "built_at": "2026-09-17T17:43:39.549691Z", "total_candidates": 16849, "min_year": 2006, "max_year": 2026 }, "query": { "lat": 35.6717, "lon": 139.7647, "radius_m": 1000, "limit": 2, "year_from": null, "kind": "bench" } }
Response fields
| Field | Type | Description |
|---|---|---|
| count | integer | |
| query | object | |
| dataset | object | |
| dataset.source_snapshot | string | |
| dataset.built_at | string | |
| dataset.total_candidates | integer | |
| dataset.min_year | integer | null | |
| dataset.max_year | integer | null | |
| results | object[] | |
| results[].id | string | |
| results[].scene_id | string | |
| results[].lat | number | |
| results[].lon | number | |
| results[].position_basis | "capture_location" | |
| results[].distance_m | integer | |
| results[].capture_year | integer | |
| results[].evidence | string | |
| results[].object_position | string | null | |
| results[].object_distance_m_est | number | null | |
| results[].confidence | string | values high medium |
| results[].image_page | string(uri) | |
| results[].generation_id | string | |
| results[].ward | string | null | |
| results[].evidence_count | integer |
Status codes
- 200 OK (Cache-Control is no-store)
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 413 Request body exceeds 2048 bytes
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
- 500 Internal error. Responses never expose stack traces, SQL, or internal paths. Details are recorded only in server logs with the
request_id.
Schools
Tokyo elementary-school locations (National Land Numerical Information P29), useful for turning a school name into coordinates.
GET/v1/schools/search
Search elementary schools by partial Japanese name
Normalizes q with NFKC, lowercase conversion, and removal of half-width and full-width spaces; escapes %, _, and \; then matches with LIKE '%q%' ESCAPE '\'. Results use ORDER BY name_norm ASC, school_id ASC LIMIT 10. Zero matches return 200 and an empty array.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
qrequired | query | string | Part of a Japanese school name (1–100 characters)range 1–100 chars |
Example
// common fields (snapshot, license and so on) omitted { "query": "明石", "normalized_query": "明石", "count": 1, "results": [ { "school_id": "sch_c75f0606e47b", "name": "中央区立明石小学校", "lat": 35.66885987315959, "lon": 139.77649718335653 } ], "source": "国土交通省 国土数値情報(P29 学校)を加工" }
Response fields
| Field | Type | Description |
|---|---|---|
| query | string | |
| normalized_query | string | |
| count | integer | |
| results | object[] | |
| results[].school_id | string | |
| results[].name | string | Japanese school name |
| results[].lat | number | |
| results[].lon | number | |
| source | string |
Status codes
- 200 OK
- 400 Invalid parameter (negative value, NaN, Infinity, empty string, nonnumeric text, unknown enum, or out of range)
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists.
Catalog
Release, counts, generations and provenance: information about the data itself.
GET/v1/meta
Release counts and generation catalog
Returns the published release, counts and the generation catalog. Counts come from release_stats, fixed at release time, so nothing is recounted per request. processed_total and machine_feature_rows include quarantined scenes. The other counts and year_min and year_max exclude them (see counting_notes).
Unlike the description in openapi.en.yaml,
processed_total and machine_feature_rows include quarantined scenes (see counting_notes in the response).Example
{
"api_version": "v1",
"data_language": "ja",
"snapshot": "2026-09-13-r1",
"request_id": "b44f51c0-382e-445b-9013-a3f9e7ed500e",
"data_as_of": "2026-09-13",
"quality_policy": { "requested": "released", "generation": null, "experimental_included": false },
"license": {
"schema_version": 2,
"id": "LicenseRef-michiyomi-layered",
"url": "https://michiyomi.dev/docs/license/",
"policy_version": "2026-10-03",
"summary": "観測データ(本文・構造化JSON・機械層の値・経年変化)は CC BY 4.0 で使えます…",
"summary_en": "Observation data (text, structured JSON, machine features, c…",
"obligations": {
"use_in_results": ["none"],
"display_or_quote_records": ["none"],
"redistribute_as_data": ["attribution", "upstream_not_licensed_if_bulk", "source_notice_if_bulk"]
},
"notices": [
"mapillary_reference_not_licensed",
… 5 more
],
"layers": {
"observation": "CC-BY-4.0",
"mapillary_reference": "NOASSERTION",
"public_sector": "CC-BY-4.0"
},
"linked_only": { "photo": "CC-BY-SA-4.0" },
"attribution": "出典: みちよみ(michiyomi.dev…",
"attribution_en": "Source: michiyomi (michiyomi.dev), from Mapillary street-lev…",
"public_sector_sources": ["…"],
"mapillary": "https://www.mapillary.com",
"ui_requirements": "テキストや数値を表示するだけなら…",
"ui_requirements_en": "No logo or credit is needed to display text or values. Only …",
… 4 more fields
},
"release": {
"release_id": "2026-09-13-r1",
"status": "published",
"created_at": "2026-09-12T20:42:08.414276Z",
"published_at": "2026-09-12T22:00:00Z",
"data_as_of": "2026-09-13"
},
"counts": {
"processed_total": 1914490,
"served_total": 1914451,
"released_total": 1914451,
"experimental_total": 0,
"changes_total": 2522,
"schools_total": 1323,
"quarantined_total": 39,
"machine_feature_rows": 1914490,
"position_source": { "mapillary_computed": 1899940, "mapillary_raw": 14511 }
},
"machine_feature_coverage": {
"rows": { "count": 1914490, "denominator": 1914490, "ratio": 1 },
"served_columns": {
"travel_bearing": { "count": 1907664, "denominator": 1914451, "ratio": 0.996455 },
"abs_objects": { "count": 1650371, "denominator": 1914451, "ratio": 0.86206 },
"color_status_ok": { "count": 1914412, "denominator": 1914451, "ratio": 0.99998 },
"green_ratio": { "count": 1914412, "denominator": 1914451, "ratio": 0.99998 }
}
},
"years": { "min": 1986, "max": 2026 },
"sharding": {
"active": true,
"shard_count": 4,
"shards": ["s002", "s003", "s004", "s005"],
"routing": "longitude bands on cell_250m edges"
},
"generations": [
{
"id": "gen2-qwen-local",
"status": "released",
"version": 2,
"gen_id": "gen2-qwen-local",
"model_family": "qwen-local",
"model": "sakamakismile/Qwen3.8-27B-MTP-NVFP4 / nvidia/Qwen3.6-27B-NVF…",
"prompt_version": null,
"output_contract": "v2: 純粋視覚・カメラ基準左右・image_file付きJSON",
"released_at": "2026-08-22",
"notes": "ローカルVLMによる言語化…",
"evidence": null,
"stats": {…}
},
… 1 more
],
"metrics": {
"processed_total": 1914490,
"served_total": 1914451,
"released_total": 1914451,
"experimental_total": 0,
"changes_total": 2522,
"schools_total": 1323,
"position_source_computed": 1899940,
"position_source_raw": 14511,
"computed_discarded_outside_service": 183,
"machine_feature_rows": 1914490,
"machine_travel_bearing_nonnull": 1907664,
"machine_abs_objects_nonnull": 1650371,
"machine_color_status_ok": 1914412,
"machine_green_ratio_nonnull": 1914412,
"year_min": 1986,
"year_max": 2026,
… 3 more fields
},
"counting_notes": {
"source": "件数は release_stats(リリース時に確定した正本)から返す…",
"quarantine": "processed_total / machine_feature_rows は隔離を含む処理済み総数…",
"search_vs_release": "近傍検索・coverage は隔離シーンを常に除外するため…"
}
}Response fields
| Field | Type | Description |
|---|---|---|
| release | object | null | |
| release.release_id | string | |
| release.status | string | values building staged published withdrawn |
| release.created_at | string | |
| release.published_at | string | null | |
| release.data_as_of | string | |
| counts | object | |
| counts.processed_total | integer | null | |
| counts.served_total | integer | null | |
| counts.released_total | integer | null | |
| counts.experimental_total | integer | null | |
| counts.changes_total | integer | null | |
| counts.schools_total | integer | null | |
| counts.quarantined_total | integer | null | |
| counts.machine_feature_rows | integer | null | |
| counts.position_source | object | |
| machine_feature_coverage | object | Row coverage and populated-field rates for major machine features in served records |
| years | object | |
| years.min | integer | null | |
| years.max | integer | null | |
| generations | object[] | |
| generations[].id | string | |
| generations[].status | string | values experimental released deprecated |
| generations[].version | integer | |
| generations[].gen_id | string | |
| generations[].model_family | string | null | |
| generations[].model | string | null | |
| generations[].prompt_version | string | null | |
| generations[].output_contract | string | |
| generations[].released_at | string | null | |
| generations[].notes | string | null | |
| generations[].evidence | object | null | |
| generations[].stats | object | |
| metrics | object<integer> | Raw metric-to-value map from release_stats |
| counting_notes | object<string> |
Status codes
- 200 OK
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists.
GET/v1/generations
Verbalization-generation catalog and governance
Example
// common fields (snapshot, license and so on) omitted { "default_generation": "gen2-qwen-local", "governance": "3層管理: ①行来歴(model/prompt_version/generated_at=不変の事実) ②世代(出力契約…", "generations": [ { "id": "gen2-qwen-local", "status": "released", "version": 2, "gen_id": "gen2-qwen-local", "model_family": "qwen-local", "model": "sakamakismile/Qwen3.8-27B-MTP-NVFP4 / nvidia/Qwen3.6-27B-NVF…", "prompt_version": null, "output_contract": "v2: 純粋視覚・カメラ基準左右・image_file付きJSON", "released_at": "2026-08-22", "notes": "ローカルVLMによる言語化…", "evidence": null, "stats": {…} }, … 1 more ] }
Response fields
| Field | Type | Description |
|---|---|---|
| default_generation | string | null | |
| governance | string | |
| generations | object[] | |
| generations[].id | string | |
| generations[].status | string | values experimental released deprecated |
| generations[].version | integer | |
| generations[].gen_id | string | |
| generations[].model_family | string | null | |
| generations[].model | string | null | |
| generations[].prompt_version | string | null | |
| generations[].output_contract | string | |
| generations[].released_at | string | null | |
| generations[].notes | string | null | |
| generations[].evidence | object | null | |
| generations[].stats | object |
Status codes
- 200 OK
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists.
GET/v1/provenance
Release manifest and provenance
provenance is the Rootline node chain. It records only the released gen1-codex generation and does not apply to gen2-qwen-local, as disclosed by provenance_scope.
Example
// common fields (snapshot, license and so on) omitted { "release": { "release_id": "2026-09-13-r1", "status": "published", "data_as_of": "2026-09-13", "published_at": "2026-09-12T22:00:00Z", "manifest": {…} }, "provenance": { "dataset_node": "dc263171b410", "repository": "rootline (追記型来歴リポジトリ…", "nodes": […] }, "provenance_scope": "src/prov.json の来歴連鎖(Rootlineノード)は released世代 gen1-codex に限った…", "verification_method": "経年変化(changes)の裁定は…" }
Response fields
| Field | Type | Description |
|---|---|---|
| release | object | null | |
| provenance | object | |
| provenance_scope | string | |
| verification_method | string |
Status codes
- 200 OK
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists.
GET/v1
API self-description JSON
Returns the endpoint catalog, aliases, serving policies, and license as machine-readable JSON.
Example
{
"api_version": "v1",
"name": "michiyomi API",
"description": "Read-only API for structured VLM descriptions of Mapillary s…",
"description_ja": "Mapillary街路画像をVLMで構造化テキスト化した…",
"data_language": "ja",
"endpoints": {
"GET /v1/meta": "Authoritative release counts and verbalization-generation ca…",
"GET /v1/scenes/nearby": "Nearby scenes. Requires lat/lon; supports radius_m, limit, q…",
"GET /v1/amenities/nearby": "Nearby amenity observations (kind=vending_machine|toilet|ben…",
"POST /amenities/search": "Same amenity search with coordinates in a JSON body (keeps v…",
"GET /v1/scenes/{id}": "Scene detail. Select metadata, deterministic machine feature…",
"GET /v1/coverage": "Honest coverage report around a coordinate; zero means no re…",
"GET /v1/changes/nearby": "Nearby adjudicated longitudinal change observations with cat…",
"GET /v1/changes/{change_id}": "Full change evidence and verification metadata",
"GET /v1/schools/search": "Partial-name search for elementary schools (NFKC normalized;…",
"GET /v1/generations": "Verbalization-generation catalog and governance metadata",
"GET /v1/provenance": "Release manifest and gen1 provenance chain",
"POST /mcp": "Stateless MCP Streamable HTTP endpoint (2025-06-18 compatibl…"
},
"aliases": {
"GET /v1/nearby": "GET /v1/scenes/nearby",
"GET /v1/node/{id}": "GET /v1/scenes/{id}",
"GET /v1/prov": "GET /v1/provenance"
},
"policies": [
"The default is quality=released. Experimental generations ar…",
"Scenes with anomalous capture timestamps (quarantined=1) are…",
… 2 more
],
"policies_ja": [
"既定は quality=released…",
"撮影時刻が異常なシーン(quarantined=1)は近傍検索・統計から除外され…",
… 2 more
],
"request_id": "71eea11c-97ba-4f03-bc98-0dc10136ac00",
"license": {
"schema_version": 2,
"id": "LicenseRef-michiyomi-layered",
"url": "https://michiyomi.dev/docs/license/",
"policy_version": "2026-10-03",
"summary": "観測データ(本文・構造化JSON・機械層の値・経年変化)は CC BY 4.0 で使えます…",
"summary_en": "Observation data (text, structured JSON, machine features, c…",
"obligations": {
"use_in_results": ["none"],
"display_or_quote_records": ["none"],
"redistribute_as_data": ["attribution", "upstream_not_licensed_if_bulk", "source_notice_if_bulk"]
},
"notices": [
"mapillary_reference_not_licensed",
"photos_not_included",
… 4 more
],
"layers": {
"observation": "CC-BY-4.0",
"mapillary_reference": "NOASSERTION",
"public_sector": "CC-BY-4.0"
},
"linked_only": { "photo": "CC-BY-SA-4.0" },
"attribution": "出典: みちよみ(michiyomi.dev…",
"attribution_en": "Source: michiyomi (michiyomi.dev), from Mapillary street-lev…",
"public_sector_sources": ["…"],
"mapillary": "https://www.mapillary.com",
… 6 more fields
}
}Response fields
| Field | Type | Description |
|---|---|---|
| name | string | |
| description | string | |
| endpoints | object<string> | |
| aliases | object<string> | |
| policies | string[] |
Status codes
- 200 OK
MCP
The MCP server for AI agents that looks up places. See Use from AI for setup and tool usage. Scenery search by impression is a separate MCP server (/explore/mcp) and is not part of this definition.
POST/mcp
MCP (Model Context Protocol) Streamable HTTP
Stateless Streamable HTTP. The endpoint returns one JSON response and uses neither SSE nor session IDs. It is compatible with protocol version 2025-06-18.
Tools (11): get_metadata, find_school, coverage, describe_location, get_scene, changes_near, find_amenities, describe_street, describe_area, find_street, find_area. See Use from AI.
initialize echoes a requested version only when it is one the server actually supports: 2025-06-18, 2025-03-26, or 2024-11-05. Otherwise it returns 2025-06-18 and does not claim support for unverified future specifications.
Limits:
| Condition | Response |
|---|---|
| body > 64KB | HTTP 413 payload_too_large |
| malformed JSON | HTTP 400 / JSON-RPC -32700 |
| empty batch | HTTP 400 / JSON-RPC -32600 |
| batch > 20 | HTTP 400 / JSON-RPC -32600 |
N tools/call entries in a batch | counts N times against the MCP rate limit; HTTP 429 if any call exceeds the limit |
no id member (notification) | HTTP 202 with no body; the tool is not executed |
| unknown method | JSON-RPC -32601 |
| unknown tool | result.isError = true; the database is not queried |
Errors never expose stack traces, SQL, or internal paths.
The description in openapi.en.yaml lists only five tools. Production has 11 (the list above comes from the live
tools/list).Body (JSON)
| Name | In | Type | Description |
|---|---|---|---|
jsonrpcrequired | body | "2.0" | |
id | body | string | integer | null | A message without an id member is a notification under JSON-RPC 2.0 §4.1. The server returns no JSON-RPC response and does not execute the tool, even for tools/call (HTTP 202, empty body). "id": null still has an id member and is therefore a request; null is echoed in the response. |
methodrequired | body | string | example initialize ping tools/list tools/call notifications/initialized |
params | body | object |
Example
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_metadata",
"description": "Read the current published snapshot, authoritative counts, r…",
"inputSchema": {…},
"annotations": { "readOnlyHint": true, "destructiveHint": false, "openWorldHint": true },
"outputSchema": {…}
},
{
"name": "find_school",
"description": "Search the recorded Tokyo elementary-school name catalog, in…",
"inputSchema": {…},
"annotations": { "readOnlyHint": true, "destructiveHint": false, "openWorldHint": true },
"outputSchema": {…}
},
… 9 more
]
}
}Status codes
- 200 JSON-RPC response (single request or batch)
- 202 No response body because the request contained notifications only
- 400 Parse error or invalid request in JSON-RPC error form
- 405 Read-only API. POST, PUT, DELETE, and PATCH to
/v1, andGET /mcp, always return 405. No administrative or write endpoint exists. - 413 Request body exceeds 64 KB
- 429 Rate limit exceeded. REST allows 300 requests per 60 seconds per IP; MCP allows 120.
Aliases
These older names still work for existing clients. Use the name on the right in new code.
| Alias | Same as |
|---|---|
GET /v1/nearby | GET /v1/scenes/nearby |
GET /v1/node/{id} | GET /v1/scenes/{id} |
GET /v1/prov | GET /v1/provenance |
This page was generated by tools/gen_api_reference.py from api/openapi.en.yaml and live production responses.