Real-time fog detection API for San Francisco. Updated hourly via GitHub Actions.
https://isitfoggyinsanfrancisco.com/api
Get current fog conditions for the Golden Gate / Western SF region.
{
"region": "golden-gate",
"fogLevel": "clear" | "light" | "moderate" | "heavy",
"visibilityScore": 0-100,
"timestamp": "2026-02-16T02:22:51.191Z",
"landmarks": [
{
"name": "gg-bridge-south-tower",
"visible": true,
"similarity": 0.85
},
...
]
}
Get current fog conditions for the Downtown / Northeast SF region.
{
"region": "downtown",
"fogLevel": "clear" | "light" | "moderate" | "heavy",
"visibilityScore": 0-100,
"timestamp": "2026-02-16T02:22:48.356Z",
"landmarks": [
{
"name": "transamerica-pyramid",
"visible": true,
"similarity": 0.73
},
...
]
}
Get current fog conditions for all regions combined.
[
{
"region": "golden-gate",
"fogLevel": "clear",
"visibilityScore": 67,
"timestamp": "2026-02-16T02:22:51.191Z",
"landmarks": [...]
},
{
"region": "downtown",
"fogLevel": "light",
"visibilityScore": 50,
"timestamp": "2026-02-16T02:22:48.356Z",
"landmarks": [...]
}
]
Get all hourly readings for a specific date (e.g., /api/history/2026-02-16).
{
"hours": [
{"timestamp": "2026-02-16T00:00:00.000Z", "regions": {...}}, // hour 0
{"timestamp": "2026-02-16T01:00:00.000Z", "regions": {...}}, // hour 1
{"timestamp": "2026-02-16T02:00:00.000Z", "regions": {...}}, // hour 2
null, // hour 3 - no data yet
...
null // hour 23 - no data yet
]
}
Note: Always contains exactly 24 items (indices 0-23 for hours 0-23 UTC). Future hours or missing data are null. Access by hour: data.hours[15] for 3pm UTC. File size ~2-5 KB.
Get the available date range for historical data. Use this to know what dates you can query.
{
"startDate": "2024-02-16",
"endDate": "2026-02-16",
"totalDays": 730,
"lastUpdated": "2026-02-16T11:00:00.000Z"
}
Note: Updated hourly with new data and daily when old data is cleaned up.
Data is updated hourly via GitHub Actions cron schedule.
GitHub Pages serves all files with CORS headers enabled, so you can fetch from any origin.
// Fetch Golden Gate region fog status
fetch('https://isitfoggyinsanfrancisco.com/api/regions/golden-gate')
.then(res => res.json())
.then(data => console.log(data.fogLevel));
// Fetch all regions
fetch('https://isitfoggyinsanfrancisco.com/api/regions/index')
.then(res => res.json())
.then(regions => {
regions.forEach(r => {
console.log(`${r.region}: ${r.fogLevel} (${r.visibilityScore}%)`);
});
});
// Fetch multiple days (e.g., last 3 days)
const dates = ['2026-02-14', '2026-02-15', '2026-02-16'];
Promise.all(dates.map(d =>
fetch(`https://isitfoggyinsanfrancisco.com/api/history/${d}`).then(r => r.json())
)).then(days => {
// Flatten all hours, filter nulls
const allHours = days.flatMap(day => day.hours.filter(h => h !== null));
const avgVisibility = allHours.reduce((sum, h) =>
sum + h.regions['golden-gate'].visibilityScore, 0) / allHours.length;
console.log(`Avg visibility: ${avgVisibility.toFixed(1)}%`);
});
// Fetch specific day and access by hour
fetch('https://isitfoggyinsanfrancisco.com/api/history/2026-02-16')
.then(res => res.json())
.then(data => {
// Access 3pm (hour 15) directly
const reading3pm = data.hours[15];
if (reading3pm) {
console.log(`3pm visibility: ${reading3pm.regions['golden-gate'].visibilityScore}%`);
} else {
console.log('3pm data not available yet');
}
// Count available hours
const available = data.hours.filter(h => h !== null).length;
console.log(`${available} of 24 hours recorded`);
});
// Check available date range
fetch('https://isitfoggyinsanfrancisco.com/api/history')
.then(res => res.json())
.then(range => {
console.log(`Data available from ${range.startDate} to ${range.endDate}`);
console.log(`Total days: ${range.totalDays}`);
});