This document provides detailed information about the APIs used in Weatherify and how to work with them.
- OpenWeatherMap API Overview
- API Key Setup
- Current Weather API
- 5-Day Forecast API
- Geocoding API
- UV Index API
- Air Pollution API
- Weather Map Tiles
- Rate Limits
- Error Handling
- Best Practices
Weatherify uses the OpenWeatherMap API to fetch weather data. This is a comprehensive weather data service that provides:
- Current weather conditions
- Weather forecasts
- Historical data
- Weather maps
- Air quality data
- UV index information
Official Documentation: https://openweathermap.org/api
-
Sign Up
- Visit OpenWeatherMap Sign Up
- Create a free account
- Verify your email address
-
Generate API Key
- Log in to your account
- Navigate to API Keys
- Copy your default API key or create a new one
- Note: New API keys may take up to 2 hours to activate
-
Configure in Weatherify
- Open
script.js - Find line 28:
const API_KEY = "your_api_key_here"; - Replace with your actual API key
- Save the file
- Open
- 60 calls/minute
- 1,000,000 calls/month
- Access to current weather, forecasts, and basic features
- Sufficient for personal projects and small applications
GET https://api.openweathermap.org/data/2.5/weather
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | Yes* | City name (e.g., "London" or "London,UK") |
lat |
number | Yes* | Latitude coordinate |
lon |
number | Yes* | Longitude coordinate |
appid |
string | Yes | Your API key |
units |
string | No | Units of measurement (metric, imperial, standard) |
lang |
string | No | Language for weather description |
*Either q or (lat and lon) is required
// By city name
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=London&units=metric&appid=${API_KEY}`
);
// By coordinates
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=51.5074&lon=-0.1278&units=metric&appid=${API_KEY}`
);{
"coord": {
"lon": -0.1278,
"lat": 51.5074
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 15.5,
"feels_like": 14.8,
"temp_min": 13.2,
"temp_max": 17.1,
"pressure": 1013,
"humidity": 72
},
"visibility": 10000,
"wind": {
"speed": 3.6,
"deg": 240
},
"clouds": {
"all": 0
},
"dt": 1633024800,
"sys": {
"type": 2,
"id": 2019646,
"country": "GB",
"sunrise": 1632982800,
"sunset": 1633025400
},
"timezone": 3600,
"id": 2643743,
"name": "London",
"cod": 200
}main.temp- Current temperaturemain.feels_like- Perceived temperaturemain.temp_min- Minimum temperaturemain.temp_max- Maximum temperaturemain.humidity- Humidity percentagemain.pressure- Atmospheric pressure (hPa)wind.speed- Wind speedwind.deg- Wind direction (degrees)weather[0].id- Weather condition IDweather[0].description- Weather descriptionvisibility- Visibility in meterssys.sunrise- Sunrise time (Unix timestamp)sys.sunset- Sunset time (Unix timestamp)
GET https://api.openweathermap.org/data/2.5/forecast
Same as Current Weather API
const response = await fetch(
`https://api.openweathermap.org/data/2.5/forecast?q=London&units=metric&appid=${API_KEY}`
);{
"cod": "200",
"message": 0,
"cnt": 40,
"list": [
{
"dt": 1633024800,
"main": {
"temp": 15.5,
"feels_like": 14.8,
"temp_min": 13.2,
"temp_max": 17.1,
"pressure": 1013,
"humidity": 72
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"clouds": {
"all": 0
},
"wind": {
"speed": 3.6,
"deg": 240
},
"visibility": 10000,
"pop": 0.15,
"dt_txt": "2021-10-01 12:00:00"
}
// ... 39 more entries (3-hour intervals)
],
"city": {
"id": 2643743,
"name": "London",
"coord": {
"lat": 51.5074,
"lon": -0.1278
},
"country": "GB",
"timezone": 3600,
"sunrise": 1632982800,
"sunset": 1633025400
}
}- Provides weather data in 3-hour intervals
- Covers 5 days (40 data points)
popfield indicates probability of precipitation (0-1)- Use
dt_txtfor human-readable timestamp
GET https://api.openweathermap.org/geo/1.0/direct
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | Yes | City name, state code, country code (e.g., "London,GB") |
limit |
number | No | Number of results (default: 5) |
appid |
string | Yes | Your API key |
const response = await fetch(
`https://api.openweathermap.org/geo/1.0/direct?q=London&limit=5&appid=${API_KEY}`
);[
{
"name": "London",
"local_names": {
"en": "London",
"fr": "Londres"
},
"lat": 51.5074,
"lon": -0.1278,
"country": "GB",
"state": "England"
}
]GET https://api.openweathermap.org/geo/1.0/reverse
| Parameter | Type | Required | Description |
|---|---|---|---|
lat |
number | Yes | Latitude |
lon |
number | Yes | Longitude |
limit |
number | No | Number of results (default: 5) |
appid |
string | Yes | Your API key |
const response = await fetch(
`https://api.openweathermap.org/geo/1.0/reverse?lat=51.5074&lon=-0.1278&limit=1&appid=${API_KEY}`
);GET https://api.openweathermap.org/data/2.5/uvi
| Parameter | Type | Required | Description |
|---|---|---|---|
lat |
number | Yes | Latitude |
lon |
number | Yes | Longitude |
appid |
string | Yes | Your API key |
const response = await fetch(
`https://api.openweathermap.org/data/2.5/uvi?lat=51.5074&lon=-0.1278&appid=${API_KEY}`
);{
"lat": 51.5074,
"lon": -0.1278,
"date_iso": "2021-10-01T12:00:00Z",
"date": 1633024800,
"value": 5.8
}| Value | Level | Recommendation |
|---|---|---|
| 0-2 | Low | No protection needed |
| 3-5 | Moderate | Wear sunscreen |
| 6-7 | High | Protection essential |
| 8-10 | Very High | Extra protection required |
| 11+ | Extreme | Avoid sun exposure |
GET https://api.openweathermap.org/data/2.5/air_pollution
| Parameter | Type | Required | Description |
|---|---|---|---|
lat |
number | Yes | Latitude |
lon |
number | Yes | Longitude |
appid |
string | Yes | Your API key |
const response = await fetch(
`https://api.openweathermap.org/data/2.5/air_pollution?lat=51.5074&lon=-0.1278&appid=${API_KEY}`
);{
"coord": {
"lon": -0.1278,
"lat": 51.5074
},
"list": [
{
"main": {
"aqi": 2
},
"components": {
"co": 230.31,
"no": 0.21,
"no2": 14.93,
"o3": 68.66,
"so2": 1.73,
"pm2_5": 5.83,
"pm10": 7.54,
"nh3": 0.92
},
"dt": 1633024800
}
]
}| Value | Level | Description |
|---|---|---|
| 1 | Good | Air quality is satisfactory |
| 2 | Fair | Acceptable air quality |
| 3 | Moderate | Sensitive groups should limit outdoor activity |
| 4 | Poor | Everyone should limit outdoor activity |
| 5 | Very Poor | Avoid outdoor activity |
co- Carbon monoxide (μg/m³)no- Nitrogen monoxide (μg/m³)no2- Nitrogen dioxide (μg/m³)o3- Ozone (μg/m³)so2- Sulphur dioxide (μg/m³)pm2_5- Fine particulate matter (μg/m³)pm10- Coarse particulate matter (μg/m³)nh3- Ammonia (μg/m³)
https://tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid={API_KEY}
https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid={API_KEY}
https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid={API_KEY}
https://tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid={API_KEY}
L.tileLayer(
`https://tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid=${API_KEY}`,
{
attribution: 'Weather data © OpenWeatherMap',
opacity: 0.5,
maxZoom: 18
}
).addTo(map);- 60 calls per minute
- 1,000,000 calls per month
- No credit card required
async function fetchWithRetry(url, retries = 3) {
try {
const response = await fetch(url);
if (response.status === 429) {
// Rate limit exceeded
if (retries > 0) {
await new Promise(resolve => setTimeout(resolve, 2000));
return fetchWithRetry(url, retries - 1);
}
throw new Error('Rate limit exceeded');
}
return response;
} catch (error) {
console.error('API Error:', error);
throw error;
}
}| Code | Message | Description |
|---|---|---|
| 200 | OK | Successful request |
| 400 | Bad Request | Invalid parameters |
| 401 | Unauthorized | Invalid API key |
| 404 | Not Found | City not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
async function fetchWeatherData(city) {
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}`
);
const data = await response.json();
if (data.cod !== 200) {
switch (data.cod) {
case '404':
throw new Error('City not found');
case '401':
throw new Error('Invalid API key');
case '429':
throw new Error('Rate limit exceeded. Please try again later.');
default:
throw new Error(data.message || 'Unknown error occurred');
}
}
return data;
} catch (error) {
console.error('Weather API Error:', error);
showErrorMessage(error.message);
throw error;
}
}const cache = new Map();
const CACHE_DURATION = 10 * 60 * 1000; // 10 minutes
async function getCachedWeather(city) {
const cacheKey = `weather_${city}`;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
return cached.data;
}
const data = await fetchWeatherData(city);
cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}let searchTimeout;
function debounceSearch(query, delay = 300) {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
fetchCitySuggestions(query);
}, delay);
}const units = {
metric: { temp: '°C', speed: 'km/h' },
imperial: { temp: '°F', speed: 'mph' },
standard: { temp: 'K', speed: 'm/s' }
};
const selectedUnit = 'metric';async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
return response;
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('Request timeout');
}
throw error;
}
}async function fetchAllWeatherData(lat, lon) {
const [weather, forecast, uv, airQuality] = await Promise.all([
fetchCurrentWeather(lat, lon),
fetchForecast(lat, lon),
fetchUVIndex(lat, lon),
fetchAirQuality(lat, lon)
]);
return { weather, forecast, uv, airQuality };
}- Official API Documentation: https://openweathermap.org/api
- API Status: https://status.openweathermap.org/
- Support: https://home.openweathermap.org/questions
- Pricing Plans: https://openweathermap.org/price
For questions about API integration in Weatherify:
- Email: montaquim.tbm@gmail.com
- GitHub: @AverageTaaf
Last Updated: September 30, 2025