{"openapi":"3.1.0","info":{"title":"Synoptic Data (BYOK) API","version":"0.1.0","description":"Synoptic Data (BYOK) lets an AI assistant read your own Synoptic Data data through the Synoptic Data API with a key you supply (Synoptic public API token). Read-only: 9 tools (get_latest_observations, get_station_timeseries, get_nearest_time_observations, get_station_statistics, get_precipitation, get_station_metadata, list_networks, list_variables, list_quality_control_types). The BYOK key...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-synoptic.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-synoptic/docs"},"termsOfService":"https://connectorbay.com/byok-synoptic/terms"},"servers":[{"url":"https://byok-synoptic.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-synoptic/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/get_latest_observations":{"post":{"operationId":"get_latest_observations","summary":"Get the most recent observation of weather stations picked by station ID, state, country, network, radius or bounding bo","description":"Get the most recent observation of weather stations picked by station ID, state, country, network, radius or bounding box. Needs at least one selector. Use for \"What is the latest temperature and wind at weather station KSLC\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"stid":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated Synoptic station IDs, for example 'KSLC,WBB'. Prefix a value with ! to exclude it.","title":"Stid"},"state":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated 2-letter state or province codes; the country defaults to US when country is not given.","title":"State"},"country":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated 2 or 3 letter country codes, for example 'us,ca'.","title":"Country"},"network":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network IDs or short names (see list_networks).","title":"Network"},"radius":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Stations within a radius: 'latitude,longitude,miles' or 'station_id,miles', for example '40.76,-111.89,20'. Combine with limit to get the nearest.","title":"Radius"},"bbox":{"anyOf":[{"maxLength":80,"type":"string"},{"type":"null"}],"default":null,"description":"Bounding box as 'lonmin,latmin,lonmax,latmax' in decimal degrees, for example '-112,40,-111,41'.","title":"Bbox"},"vars":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated sensor variables, for example 'air_temp,wind_speed,relative_humidity' (see list_variables).","title":"Vars"},"units":{"anyOf":[{"enum":["metric","english"],"type":"string"},{"type":"null"}],"default":"metric","description":"Unit system: metric (default) or english.","title":"Units"},"limit":{"anyOf":[{"maximum":200,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Return at most this many stations (1 to 200); with radius they are ordered by distance.","title":"Limit"},"within":{"anyOf":[{"maximum":1440,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Only observations from the last N minutes (1 to 1440).","title":"Within"},"status":{"anyOf":[{"enum":["active","inactive"],"type":"string"},{"type":"null"}],"default":null,"description":"Only stations with this status: active or inactive.","title":"Status"}},"title":"get_latest_observationsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_station_timeseries":{"post":{"operationId":"get_station_timeseries","summary":"Get a station's observations over a time span, either the last N minutes or between two UTC times. Keep the span short: ","description":"Get a station's observations over a time span, either the last N minutes or between two UTC times. Keep the span short: requests are limited to 100,000 station-hours. Use for \"Show the temperature at station WBB for the last 3 hours\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"stid":{"description":"Comma-separated Synoptic station IDs, for example 'KSLC,WBB' (up to a few stations; large requests hit station-hour limits).","maxLength":300,"title":"Stid","type":"string"},"vars":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated sensor variables, for example 'air_temp,wind_speed,relative_humidity' (see list_variables).","title":"Vars"},"units":{"anyOf":[{"enum":["metric","english"],"type":"string"},{"type":"null"}],"default":"metric","description":"Unit system: metric (default) or english.","title":"Units"},"recent":{"anyOf":[{"maximum":10080,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Return the last N minutes of observations (1 to 10080). Use this or start with end.","title":"Recent"},"start":{"anyOf":[{"maxLength":12,"type":"string"},{"type":"null"}],"default":null,"description":"Start time in UTC as YYYYmmddHHMM, for example 202610200000; needs end.","title":"Start"},"end":{"anyOf":[{"maxLength":12,"type":"string"},{"type":"null"}],"default":null,"description":"End time in UTC as YYYYmmddHHMM; needs start.","title":"End"}},"required":["stid"],"title":"get_station_timeseriesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_nearest_time_observations":{"post":{"operationId":"get_nearest_time_observations","summary":"Get each station's observation closest to a given UTC time, within a window in minutes before it. Use for \"What did stat","description":"Get each station's observation closest to a given UTC time, within a window in minutes before it. Use for \"What did station KSLC report around 18:00 UTC on 1 June 2026\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"stid":{"description":"Comma-separated Synoptic station IDs, for example 'KSLC,WBB' (up to a few stations; large requests hit station-hour limits).","maxLength":300,"title":"Stid","type":"string"},"attime":{"description":"Target time in UTC as YYYYmmddHHMM, for example 202606011800.","maxLength":12,"title":"Attime","type":"string"},"within":{"description":"Accept observations up to this many minutes before attime (1 to 1440).","maximum":1440,"minimum":1,"title":"Within","type":"integer"},"vars":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated sensor variables, for example 'air_temp,wind_speed,relative_humidity' (see list_variables).","title":"Vars"},"units":{"anyOf":[{"enum":["metric","english"],"type":"string"},{"type":"null"}],"default":"metric","description":"Unit system: metric (default) or english.","title":"Units"}},"required":["stid","attime","within"],"title":"get_nearest_time_observationsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_station_statistics":{"post":{"operationId":"get_station_statistics","summary":"Get daily or monthly minimum, maximum, mean and count of chosen variables for stations over a date range. Use for \"What ","description":"Get daily or monthly minimum, maximum, mean and count of chosen variables for stations over a date range. Use for \"What were the daily high and low temperatures at station WBB last week\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"stid":{"description":"Comma-separated Synoptic station IDs, for example 'KSLC,WBB' (up to a few stations; large requests hit station-hour limits).","maxLength":300,"title":"Stid","type":"string"},"vars":{"description":"Comma-separated variables to summarise, for example 'air_temp,precip_accum'. At least one is required.","maxLength":200,"title":"Vars","type":"string"},"units":{"anyOf":[{"enum":["metric","english"],"type":"string"},{"type":"null"}],"default":"metric","description":"Unit system: metric (default) or english.","title":"Units"},"period":{"anyOf":[{"enum":["day","month"],"type":"string"},{"type":"null"}],"default":"day","description":"Statistics period: day (default) or month.","title":"Period"},"recent":{"anyOf":[{"maximum":366,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Last N days or months, depending on period (1 to 366). Use this or start with end.","title":"Recent"},"start":{"anyOf":[{"maxLength":12,"type":"string"},{"type":"null"}],"default":null,"description":"Start date in UTC as YYYYmmdd or YYYYmmddHHMM; needs end.","title":"Start"},"end":{"anyOf":[{"maxLength":12,"type":"string"},{"type":"null"}],"default":null,"description":"End date in UTC as YYYYmmdd or YYYYmmddHHMM; needs start.","title":"End"}},"required":["stid","vars"],"title":"get_station_statisticsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_precipitation":{"post":{"operationId":"get_precipitation","summary":"Get derived precipitation totals, interval accumulations or recent accumulations for stations. Use for \"How much rain fe","description":"Get derived precipitation totals, interval accumulations or recent accumulations for stations. Use for \"How much rain fell at station WBB in the last 24 hours\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"stid":{"description":"Comma-separated Synoptic station IDs, for example 'KSLC,WBB' (up to a few stations; large requests hit station-hour limits).","maxLength":300,"title":"Stid","type":"string"},"units":{"anyOf":[{"enum":["metric","english"],"type":"string"},{"type":"null"}],"default":"metric","description":"Unit system: metric (default) or english.","title":"Units"},"pmode":{"anyOf":[{"enum":["totals","intervals","last"],"type":"string"},{"type":"null"}],"default":"last","description":"totals (over start..end), intervals (needs interval) or last (accumulation back from end).","title":"Pmode"},"accum_hours":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"With pmode=last: comma-separated hours to accumulate back from end, for example '1,6,24'.","title":"Accum Hours"},"interval":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":null,"description":"With pmode=intervals: hour, day, week, month, year or a number of hours that divides 24.","title":"Interval"},"recent":{"anyOf":[{"maximum":43200,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Look back N minutes from now (1 to 43200). Use this or start with end.","title":"Recent"},"start":{"anyOf":[{"maxLength":12,"type":"string"},{"type":"null"}],"default":null,"description":"Start time in UTC as YYYYmmddHHMM; needs end.","title":"Start"},"end":{"anyOf":[{"maxLength":12,"type":"string"},{"type":"null"}],"default":null,"description":"End time in UTC as YYYYmmddHHMM; needs start.","title":"End"}},"required":["stid"],"title":"get_precipitationArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_station_metadata":{"post":{"operationId":"get_station_metadata","summary":"List stations with their ID, name, network, coordinates, elevation, timezone and status; filter by station, state, count","description":"List stations with their ID, name, network, coordinates, elevation, timezone and status; filter by station, state, country, network, radius or bounding box. Use for \"Which weather stations are within 20 miles of Salt Lake City airport\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"stid":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated Synoptic station IDs, for example 'KSLC,WBB'. Prefix a value with ! to exclude it.","title":"Stid"},"state":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated 2-letter state or province codes; the country defaults to US when country is not given.","title":"State"},"country":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated 2 or 3 letter country codes, for example 'us,ca'.","title":"Country"},"network":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network IDs or short names (see list_networks).","title":"Network"},"radius":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Stations within a radius: 'latitude,longitude,miles' or 'station_id,miles', for example '40.76,-111.89,20'. Combine with limit to get the nearest.","title":"Radius"},"bbox":{"anyOf":[{"maxLength":80,"type":"string"},{"type":"null"}],"default":null,"description":"Bounding box as 'lonmin,latmin,lonmax,latmax' in decimal degrees, for example '-112,40,-111,41'.","title":"Bbox"},"vars":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated sensor variables, for example 'air_temp,wind_speed,relative_humidity' (see list_variables).","title":"Vars"},"limit":{"anyOf":[{"maximum":200,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Return at most this many stations (1 to 200); with radius they are ordered by distance.","title":"Limit"},"status":{"anyOf":[{"enum":["active","inactive"],"type":"string"},{"type":"null"}],"default":null,"description":"Only stations with this status: active or inactive.","title":"Status"},"complete":{"anyOf":[{"maximum":1,"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"Set 1 to include extended attributes such as county and NWS zones.","title":"Complete"}},"title":"get_station_metadataArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_networks":{"post":{"operationId":"list_networks","summary":"List the station networks in the Synoptic dataset with station counts, reporting percentage, last observation time and p","description":"List the station networks in the Synoptic dataset with station counts, reporting percentage, last observation time and provider URL. Use for \"Which weather station networks does Synoptic cover\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"id":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network IDs to look up, for example '1,153'.","title":"Id"},"shortname":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated network short names, for example 'uunet,raws'.","title":"Shortname"}},"title":"list_networksArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_variables":{"post":{"operationId":"list_variables","summary":"List the sensor variable names accepted in the vars parameter, with long name, default unit and variable ID. Use for \"Wh","description":"List the sensor variable names accepted in the vars parameter, with long name, default unit and variable ID. Use for \"What weather variables can I request from Synoptic\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_variablesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_quality_control_types":{"post":{"operationId":"list_quality_control_types","summary":"List the data quality checks Synoptic and its providers apply, with ID, short name and source. Use for \"What quality con","description":"List the data quality checks Synoptic and its providers apply, with ID, short name and source. Use for \"What quality control checks does Synoptic apply to observations\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"shortname":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"A check's short name, for example 'sl_range_check'.","title":"Shortname"},"id":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated check IDs, for example '1,2,3'.","title":"Id"}},"title":"list_quality_control_typesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}