# Weatherstack-Compatible API Specification > **Complete Drop-In Replacement for Weatherstack API** > This specification enables developers to build a fully Weatherstack-compatible weather service. --- ## Table of Contents 1. [Overview](#overview) 2. [Authentication](#authentication) 3. [Endpoints](#endpoints) - [Current Weather](#endpoint-current-weather) - [Historical Weather](#endpoint-historical-weather) - [Weather Forecast](#endpoint-weather-forecast) - [Location Autocomplete](#endpoint-location-autocomplete) 4. [Response Objects](#response-objects) 5. [Weather Codes](#weather-codes) 6. [Error Handling](#error-handling) 7. [Implementation Guide](#implementation-guide) --- ## Overview ### Base URL ``` https://api.yourweatherservice.com ``` ### Protocol - HTTP and HTTPS supported - HTTPS recommended for production ### Response Format All responses are JSON with `Content-Type: application/json` --- ## Authentication Every request requires an `access_key` parameter containing the user's API key. ``` GET /current?access_key=YOUR_API_KEY&query=New York ``` ### Security Best Practices - Validate API keys on every request - Implement rate limiting per key - Log all API access for monitoring --- ## Endpoints --- ### Endpoint: Current Weather Returns real-time weather conditions for one or more locations. **URL:** `GET /current` #### Request Parameters | Parameter | Required | Type | Default | Description | |-----------|----------|------|---------|-------------| | `access_key` | Yes | string | - | API authentication key | | `query` | Yes | string | - | Location identifier (see Location Formats) | | `units` | No | string | `m` | Unit system: `m` (metric), `f` (fahrenheit), `s` (scientific) | | `language` | No | string | `en` | Response language code | | `callback` | No | string | - | JSONP callback function name | #### Location Formats Supported | Format | Example | Description | |--------|---------|-------------| | City Name | `New York` | City name, optionally with country | | Coordinates | `40.7128,-74.0060` | Latitude,Longitude | | US Zip Code | `10001` | 5-digit US zip code | | UK Postcode | `SW1A 1AA` | UK postal code | | IP Address | `153.65.8.20` | IPv4 or IPv6 address | | Auto IP | `fetch:ip` | Auto-detect from request IP | | Bulk Query | `New York;London;Tokyo` | Multiple locations (semicolon-separated) | #### Example Request ``` GET /current?access_key=abc123&query=40.7128,-74.0060&units=f ``` #### Example Response ```json { "request": { "type": "LatLon", "query": "Lat 40.71 and Lon -74.01", "language": "en", "unit": "f" }, "location": { "name": "New York", "country": "United States of America", "region": "New York", "lat": "40.714", "lon": "-74.006", "timezone_id": "America/New_York", "localtime": "2026-01-30 12:45", "localtime_epoch": 1738255500, "utc_offset": "-5.0" }, "current": { "observation_time": "05:45 PM", "temperature": 42, "weather_code": 116, "weather_icons": [ "https://api.yourweatherservice.com/images/wsymbol_0002_sunny_intervals.png" ], "weather_descriptions": ["Partly Cloudy"], "wind_speed": 12, "wind_degree": 225, "wind_dir": "SW", "pressure": 1018, "precip": 0, "humidity": 55, "cloudcover": 25, "feelslike": 38, "uv_index": 3, "visibility": 10, "is_day": "yes", "astro": { "sunrise": "07:08 AM", "sunset": "05:15 PM", "moonrise": "10:32 AM", "moonset": "11:45 PM", "moon_phase": "Waxing Crescent", "moon_illumination": 25 }, "air_quality": { "co": "234.5", "no2": "15.2", "o3": "48.0", "so2": "5.1", "pm2_5": "8.5", "pm10": "12.3", "us-epa-index": "1", "gb-defra-index": "1" } } } ``` --- ### Endpoint: Historical Weather Returns historical weather data for a specific date or date range. **URL:** `GET /historical` #### Request Parameters | Parameter | Required | Type | Default | Description | |-----------|----------|------|---------|-------------| | `access_key` | Yes | string | - | API authentication key | | `query` | Yes | string | - | Location identifier | | `historical_date` | Yes* | string | - | Date in `YYYY-MM-DD` format | | `historical_date_start` | Yes* | string | - | Start date for time-series | | `historical_date_end` | Yes* | string | - | End date for time-series | | `hourly` | No | string | `0` | Include hourly data: `1` or `0` | | `interval` | No | integer | `3` | Hourly interval: `1`, `3`, `6`, `12`, `24` | | `units` | No | string | `m` | Unit system | | `language` | No | string | `en` | Response language | *Either `historical_date` OR both `historical_date_start` and `historical_date_end` required. #### Example Request ``` GET /historical?access_key=abc123&query=40.7128,-74.0060&historical_date=2026-01-30&units=f ``` #### Example Response ```json { "request": { "type": "LatLon", "query": "Lat 40.71 and Lon -74.01", "language": "en", "unit": "f" }, "location": { "name": "New York", "country": "United States of America", "region": "New York", "lat": "40.714", "lon": "-74.006", "timezone_id": "America/New_York", "localtime": "2026-01-30 12:45", "localtime_epoch": 1738255500, "utc_offset": "-5.0" }, "current": { "observation_time": "05:45 PM", "temperature": 42, "weather_code": 116, "weather_icons": ["https://api.yourweatherservice.com/images/partly_cloudy.png"], "weather_descriptions": ["Partly Cloudy"], "wind_speed": 12, "wind_degree": 225, "wind_dir": "SW", "pressure": 1018, "precip": 0, "humidity": 55, "cloudcover": 25, "feelslike": 38, "uv_index": 3, "visibility": 10 }, "historical": { "2026-01-30": { "date": "2026-01-30", "date_epoch": 1738209600, "astro": { "sunrise": "07:08 AM", "sunset": "05:15 PM", "moonrise": "10:32 AM", "moonset": "11:45 PM", "moon_phase": "Waxing Crescent", "moon_illumination": 25 }, "mintemp": 28, "maxtemp": 42, "avgtemp": 35, "totalsnow": 0, "sunhour": 9.5, "uv_index": 3, "hourly": [ { "time": "0", "temperature": 30, "wind_speed": 8, "wind_degree": 180, "wind_dir": "S", "weather_code": 113, "weather_icons": ["https://api.yourweatherservice.com/images/night_clear.png"], "weather_descriptions": ["Clear"], "precip": 0, "humidity": 65, "visibility": 10, "pressure": 1020, "cloudcover": 0, "heatindex": 30, "dewpoint": 18, "windchill": 25, "windgust": 12, "feelslike": 25, "chanceofrain": 0, "chanceofremdry": 95, "chanceofwindy": 10, "chanceofovercast": 5, "chanceofsunshine": 90, "chanceoffrost": 20, "chanceofhightemp": 0, "chanceoffog": 5, "chanceofsnow": 0, "chanceofthunder": 0, "uv_index": 0 } ] } } } ``` --- ### Endpoint: Weather Forecast Returns weather forecast for up to 14 days. **URL:** `GET /forecast` #### Request Parameters | Parameter | Required | Type | Default | Description | |-----------|----------|------|---------|-------------| | `access_key` | Yes | string | - | API authentication key | | `query` | Yes | string | - | Location identifier | | `forecast_days` | Yes | integer | - | Number of forecast days (1-14) | | `hourly` | No | string | `0` | Include hourly data: `1` or `0` | | `interval` | No | integer | `3` | Hourly interval: `1`, `3`, `6`, `12`, `24` | | `units` | No | string | `m` | Unit system | | `language` | No | string | `en` | Response language | #### Example Response The forecast endpoint returns data in the same format as historical, but under the `forecast` key instead of `historical`. --- ### Endpoint: Location Autocomplete Returns location suggestions for search/autocomplete functionality. **URL:** `GET /autocomplete` #### Request Parameters | Parameter | Required | Type | Description | |-----------|----------|------|-------------| | `access_key` | Yes | string | API authentication key | | `query` | Yes | string | Partial location name to search | #### Example Response ```json { "request": { "query": "New Yo", "type": "City" }, "locations": [ { "id": 2459115, "name": "New York", "country": "United States of America", "region": "New York", "lat": "40.714", "lon": "-74.006", "timezone_id": "America/New_York", "utc_offset": "-5.0" }, { "id": 2459116, "name": "New York Mills", "country": "United States of America", "region": "Minnesota", "lat": "46.518", "lon": "-95.376", "timezone_id": "America/Chicago", "utc_offset": "-6.0" } ] } ``` --- ## Response Objects ### Request Object | Field | Type | Description | |-------|------|-------------| | `type` | string | Query type: `City`, `LatLon`, `IP`, `Zipcode` | | `query` | string | Processed query string | | `language` | string | Language code used | | `unit` | string | Unit system: `m`, `f`, or `s` | ### Location Object | Field | Type | Description | |-------|------|-------------| | `name` | string | Location name | | `country` | string | Country name | | `region` | string | State/region/province | | `lat` | string | Latitude | | `lon` | string | Longitude | | `timezone_id` | string | IANA timezone identifier | | `localtime` | string | Local time: `YYYY-MM-DD HH:MM` | | `localtime_epoch` | integer | Unix timestamp | | `utc_offset` | string | UTC offset in hours | ### Current Object | Field | Type | Unit (f) | Description | |-------|------|----------|-------------| | `observation_time` | string | - | Time of observation: `HH:MM AM/PM` | | `temperature` | integer | °F | Current temperature | | `weather_code` | integer | - | Weather condition code | | `weather_icons` | array | - | Weather icon URLs | | `weather_descriptions` | array | - | Weather descriptions | | `wind_speed` | integer | mph | Wind speed | | `wind_degree` | integer | ° | Wind direction in degrees | | `wind_dir` | string | - | Compass direction: `N`, `NE`, `E`, etc. | | `pressure` | integer | mb | Atmospheric pressure | | `precip` | number | in | Precipitation amount | | `humidity` | integer | % | Humidity percentage | | `cloudcover` | integer | % | Cloud cover percentage | | `feelslike` | integer | °F | Feels-like temperature | | `uv_index` | integer | - | UV index (0-11+) | | `visibility` | integer | mi | Visibility | | `is_day` | string | - | Daytime: `yes` or `no` | ### Astro Object | Field | Type | Description | |-------|------|-------------| | `sunrise` | string | Sunrise time: `HH:MM AM` | | `sunset` | string | Sunset time: `HH:MM PM` | | `moonrise` | string | Moonrise time: `HH:MM AM/PM` | | `moonset` | string | Moonset time: `HH:MM AM/PM` | | `moon_phase` | string | Moon phase name | | `moon_illumination` | integer | Illumination percentage (0-100) | **Moon Phases:** - New Moon - Waxing Crescent - First Quarter - Waxing Gibbous - Full Moon - Waning Gibbous - Last Quarter - Waning Crescent ### Air Quality Object | Field | Type | Description | |-------|------|-------------| | `co` | string | Carbon Monoxide (μg/m³) | | `no2` | string | Nitrogen Dioxide (μg/m³) | | `o3` | string | Ozone (μg/m³) | | `so2` | string | Sulphur Dioxide (μg/m³) | | `pm2_5` | string | PM2.5 (μg/m³) | | `pm10` | string | PM10 (μg/m³) | | `us-epa-index` | string | US EPA Air Quality Index (1-6) | | `gb-defra-index` | string | UK DEFRA Air Quality Index | **US EPA Index Values:** | Index | Meaning | |-------|---------| | 1 | Good | | 2 | Moderate | | 3 | Unhealthy for Sensitive Groups | | 4 | Unhealthy | | 5 | Very Unhealthy | | 6 | Hazardous | ### Historical/Forecast Day Object | Field | Type | Unit (f) | Description | |-------|------|----------|-------------| | `date` | string | - | Date: `YYYY-MM-DD` | | `date_epoch` | integer | - | Unix timestamp | | `astro` | object | - | Astro data (see above) | | `mintemp` | integer | °F | Minimum temperature | | `maxtemp` | integer | °F | Maximum temperature | | `avgtemp` | integer | °F | Average temperature | | `totalsnow` | number | in | Total snowfall | | `sunhour` | number | hrs | Hours of sunshine | | `uv_index` | integer | - | UV index | | `hourly` | array | - | Hourly data (if requested) | ### Hourly Object | Field | Type | Description | |-------|------|-------------| | `time` | string | Hour: `0`, `100`, `200`...`2300` | | `temperature` | integer | Temperature | | `wind_speed` | integer | Wind speed | | `wind_degree` | integer | Wind direction degrees | | `wind_dir` | string | Compass direction | | `weather_code` | integer | Weather code | | `weather_icons` | array | Icon URLs | | `weather_descriptions` | array | Descriptions | | `precip` | number | Precipitation | | `humidity` | integer | Humidity % | | `visibility` | integer | Visibility | | `pressure` | integer | Pressure | | `cloudcover` | integer | Cloud cover % | | `heatindex` | integer | Heat index | | `dewpoint` | integer | Dew point | | `windchill` | integer | Wind chill | | `windgust` | integer | Wind gust speed | | `feelslike` | integer | Feels-like temp | | `chanceofrain` | integer | Rain probability % | | `chanceofremdry` | integer | Remain dry probability % | | `chanceofwindy` | integer | Windy probability % | | `chanceofovercast` | integer | Overcast probability % | | `chanceofsunshine` | integer | Sunshine probability % | | `chanceoffrost` | integer | Frost probability % | | `chanceofhightemp` | integer | High temp probability % | | `chanceoffog` | integer | Fog probability % | | `chanceofsnow` | integer | Snow probability % | | `chanceofthunder` | integer | Thunder probability % | | `uv_index` | integer | UV index | --- ## Weather Codes | Code | Condition | Icon (Day) | |------|-----------|------------| | 113 | Clear/Sunny | ☀️ | | 116 | Partly Cloudy | ⛅ | | 119 | Cloudy | ☁️ | | 122 | Overcast | ☁️ | | 143 | Mist | 🌫️ | | 176 | Patchy Rain Nearby | 🌦️ | | 179 | Patchy Snow Nearby | 🌨️ | | 182 | Patchy Sleet Nearby | 🌨️ | | 185 | Patchy Freezing Drizzle | 🌧️ | | 200 | Thundery Outbreaks | ⛈️ | | 227 | Blowing Snow | 🌬️ | | 230 | Blizzard | ❄️ | | 248 | Fog | 🌫️ | | 260 | Freezing Fog | 🌫️ | | 263 | Patchy Light Drizzle | 🌧️ | | 266 | Light Drizzle | 🌧️ | | 281 | Freezing Drizzle | 🌧️ | | 284 | Heavy Freezing Drizzle | 🌧️ | | 293 | Patchy Light Rain | 🌧️ | | 296 | Light Rain | 🌧️ | | 299 | Moderate Rain at Times | 🌧️ | | 302 | Moderate Rain | 🌧️ | | 305 | Heavy Rain at Times | 🌧️ | | 308 | Heavy Rain | 🌧️ | | 311 | Light Freezing Rain | 🌧️ | | 314 | Moderate/Heavy Freezing Rain | 🌧️ | | 317 | Light Sleet | 🌨️ | | 320 | Moderate/Heavy Sleet | 🌨️ | | 323 | Patchy Light Snow | 🌨️ | | 326 | Light Snow | 🌨️ | | 329 | Patchy Moderate Snow | 🌨️ | | 332 | Moderate Snow | 🌨️ | | 335 | Patchy Heavy Snow | 🌨️ | | 338 | Heavy Snow | 🌨️ | | 350 | Ice Pellets | 🌨️ | | 353 | Light Rain Shower | 🌦️ | | 356 | Moderate/Heavy Rain Shower | 🌦️ | | 359 | Torrential Rain Shower | 🌧️ | | 362 | Light Sleet Showers | 🌨️ | | 365 | Moderate/Heavy Sleet Showers | 🌨️ | | 368 | Light Snow Showers | 🌨️ | | 371 | Moderate/Heavy Snow Showers | 🌨️ | | 374 | Light Ice Pellet Showers | 🌨️ | | 377 | Moderate/Heavy Ice Pellet Showers | 🌨️ | | 386 | Patchy Light Rain with Thunder | ⛈️ | | 389 | Moderate/Heavy Rain with Thunder | ⛈️ | | 392 | Patchy Light Snow with Thunder | ⛈️ | | 395 | Moderate/Heavy Snow with Thunder | ⛈️ | --- ## Error Handling ### Error Response Format ```json { "success": false, "error": { "code": 101, "type": "unauthorized", "info": "Invalid API access key." } } ``` ### Error Codes | Code | Type | Description | |------|------|-------------| | 101 | `unauthorized` | Invalid or missing API key | | 104 | `usage_limit_reached` | Monthly API limit exceeded | | 105 | `function_access_restricted` | Feature not available on plan | | 404 | `404_not_found` | Resource not found | | 429 | `too_many_requests` | Rate limit exceeded | | 601 | `missing_query` | No location query provided | | 602 | `invalid_query` | Invalid location query | | 603 | `historical_queries_not_supported` | Historical not on plan | | 604 | `bulk_queries_not_supported` | Bulk queries not on plan | | 605 | `invalid_language` | Unsupported language code | | 606 | `invalid_unit` | Invalid unit parameter | | 607 | `invalid_interval` | Invalid interval parameter | | 608 | `invalid_forecast_days` | Invalid forecast_days value | | 609 | `forecast_days_not_supported` | Forecast not on plan | | 611 | `invalid_historical_date` | Invalid date format | | 612 | `invalid_historical_time_frame` | Invalid date range | | 613 | `historical_time_frame_too_long` | Date range > 60 days | | 614 | `missing_historical_date` | No date provided | | 615 | `request_failed` | Internal server error | --- ## Implementation Guide ### Required Data Sources | Data Type | Recommended Sources | |-----------|---------------------| | Current Weather | Open-Meteo, OpenWeatherMap, NWS (US) | | Location Data | GeoNames, OpenStreetMap Nominatim | | Time Zones | IANA tzdb, Google Time Zone API | | Sun/Moon Data | SunCalc library, USNO API | | Air Quality | OpenAQ, WAQI, IQAir | | Geocoding | Google Geocoding, Mapbox, HERE | ### Unit Conversions When `units=f` (Fahrenheit): - Temperature: Fahrenheit - Wind Speed: mph - Visibility: miles - Pressure: millibars (mb) - Precipitation: inches When `units=m` (Metric): - Temperature: Celsius - Wind Speed: km/h - Visibility: kilometers - Pressure: millibars (mb) - Precipitation: millimeters When `units=s` (Scientific): - Temperature: Kelvin - Wind Speed: m/s - Visibility: kilometers - Pressure: millibars (mb) - Precipitation: millimeters ### Caching Strategy | Endpoint | Recommended TTL | |----------|-----------------| | Current | 10-30 minutes | | Historical | 24+ hours (immutable) | | Forecast | 3-6 hours | | Location | 30+ days | ### Testing Checklist - [ ] `/current` returns all required fields - [ ] `/historical` returns properly nested date objects - [ ] Weather codes match the reference table - [ ] Times formatted as `HH:MM AM/PM` - [ ] Coordinates support both positive and negative values - [ ] Error responses include `success`, `error.code`, `error.type`, `error.info` - [ ] Unit conversions work correctly - [ ] Bulk queries parse semicolon-separated locations - [ ] CORS headers configured for browser access - [ ] Rate limiting implemented per API key ### Sample cURL Tests ```bash # Current weather curl "https://api.yourservice.com/current?access_key=test&query=40.7128,-74.0060&units=f" # Historical with astro curl "https://api.yourservice.com/historical?access_key=test&query=40.7128,-74.0060&historical_date=2026-01-30&units=f" # Test error handling curl "https://api.yourservice.com/current?access_key=invalid" ``` --- ## Appendix: Wind Directions | Direction | Degrees | Range | |-----------|---------|-------| | N | 0° | 348.75° - 11.25° | | NNE | 22.5° | 11.25° - 33.75° | | NE | 45° | 33.75° - 56.25° | | ENE | 67.5° | 56.25° - 78.75° | | E | 90° | 78.75° - 101.25° | | ESE | 112.5° | 101.25° - 123.75° | | SE | 135° | 123.75° - 146.25° | | SSE | 157.5° | 146.25° - 168.75° | | S | 180° | 168.75° - 191.25° | | SSW | 202.5° | 191.25° - 213.75° | | SW | 225° | 213.75° - 236.25° | | WSW | 247.5° | 236.25° - 258.75° | | W | 270° | 258.75° - 281.25° | | WNW | 292.5° | 281.25° - 303.75° | | NW | 315° | 303.75° - 326.25° | | NNW | 337.5° | 326.25° - 348.75° | --- *This specification enables complete compatibility with the Weatherstack API. A developer implementing this specification can provide a drop-in replacement requiring only a URL change in the consuming application.*