API Documentation
Overview
The Atmospore API provides real-time and forecast pollen data for locations worldwide. Data is updated daily and includes forecasts up to 7 days into the future at daily or hourly resolution. Our forecasts are continuously refined as the target date approaches, ensuring the highest possible accuracy.
Authentication, quotas and errors
Send your API key in the x-api-key header on every request. Create keys in your account; the free plan needs no credit card.
Each plan has a daily request quota (free: 100 calls a day), counted per account and reset at 00:00 UTC. Successful responses include X-RateLimit-Limit and X-RateLimit-Remaining headers.
Errors
Errors are JSON with an error message. Quota and plan errors also include upgrade_url.
| Status | When | Body |
|---|---|---|
400 | An invalid parameter, e.g. resolution=weekly | {"error": "Invalid resolution, must be 'daily' or 'hourly'"} |
401 | No x-api-key header | {"error": "Missing API key. Include x-api-key header."} |
403 | Unknown or revoked key | {"error": "Invalid API key"} |
403 | A paid feature (resolution=hourly, /v1/map-tiles) on the free plan | {"error": "Hourly resolution requires a paid plan.", "upgrade_url": "https://atmospore.com/plans"} (map tiles: "Map tiles are included in paid plans") |
429 | Daily quota used up | {"error": "Daily API quota exceeded", "limit": 100, "used": 101, "resets_at": "…T00:00:00.000Z", "upgrade_url": "…"} |
500 / 503 | A temporary problem on our side; retry with backoff | {"error": "Service temporarily unavailable"} |
API Tester
- Select the Query parameters for the request, location, time and forecast days
- Select the species you want to query for results
- Finally add your API key in the x-api-key header
Query Parameters
| Parameter | Value | Type | Description |
|---|---|---|---|
| lon * | number | Longitude coordinate | |
| lat * | number | Latitude coordinate | |
| dt * | string | Date (YYYY-MM-DD) | |
| forecast_days * | number | Days after dt to include (the forecast reaches 7 days ahead) | |
| resolution | string | daily (default) or hourly. Hourly adds 24 values per species and day (from 00:00 UTC) and needs a paid plan. | |
| species | string | Species or group (optional). Use the selector below. |
Available Pollen Species Options
(Click to add to the request; leave empty for all species)birchBirchbetulaceaeBirch familyhazelHazelalderAlderpinePinespruceSprucepinaceaePine familyelmElmsalixWillowoakOakmapleMaplehickoryHickorypopulusPoplarcypressCypressplatanusPlane treefraxinusAshtimothyTimothy GrassbermudaBermuda GrassloliumRyegrassdactylisCock's-footarrhenatherumFalse Oat-grasspoaBluegrassanthoxanthumSweet Vernal GrassalopecurusMeadow FoxtailholcusYorkshire FogurticaNettleartemisiaMugwortambrosiaRagweedHeaders
| Header | Value | Description |
|---|---|---|
| x-api-key | Required. Get a free key (no credit card) from your account. | |
| accept | Accept JSON response |
Endpoint Reference
GET /v1/pollen
Interpolated pollen forecast at a specific point. Returns species-level data with risk levels for up to 7 days. Use this as your primary endpoint for location-based allergy apps, widgets, and alerts.
| Parameter | Type | Required | Description |
|---|---|---|---|
lon | number | requiredYes | Longitude |
lat | number | requiredYes | Latitude |
dt | string | requiredYes | Start date (YYYY-MM-DD). About a month of past days is kept; older dates return an empty data array. |
forecast_days | number | requiredYes | Days after dt to include: the response has dt plus the next N days, up to the end of the 7-day forecast |
species | string | optionalNo | Comma-separated species, totals (tree_tot, grass_tot, weed_tot) or groups (tree, grass, weed, all). A group expands to its individual species and does not include the total. Defaults to all species. |
resolution | string | optionalNo | daily (default) or hourly. Hourly needs a paid plan; see below. |
curl "https://pollenapi.com/v1/pollen?lon=-0.13&lat=51.51&dt=2026-04-02&forecast_days=3&species=birch,grass" \
-H "x-api-key: YOUR_API_KEY"Example response
{
"meta": {
"location": { "lat": 51.51, "lon": -0.13 },
"units": "grains/m³",
"generated_at": "2026-04-02T07:11:00Z"
},
"data": [
{
"date": "2026-04-02",
"overall_risk": "moderate",
"species": {
"birch": {
"value": 12.5,
"risk_level": "low",
"display_name": "Birch",
"category": "tree"
},
"timothy": {
"value": 0,
"risk_level": "low",
"display_name": "Timothy Grass",
"category": "grass"
}
}
}
]
}Hourly resolutionPaid plans
- Add
resolution=hourlyto get a 24-valuehourlyarray for every species and day, alongside the dailyvalue. - Index 0 is 00:00 UTC (see
meta.hourly_timezone). For local time, shift by the location's UTC offset: in Orlando (UTC−5), 14:00 local time is index 19. - The hourly values are modelled estimates that average to the daily
value(they don't add up to it). Hourly needs a paid plan; on the free plan the request returns 403.
curl "https://pollenapi.com/v1/pollen?lon=-81.38&lat=28.54&dt=2026-11-03&forecast_days=1&species=grass_tot&resolution=hourly" \
-H "x-api-key: YOUR_API_KEY"Example response
{
"meta": {
"location": { "lat": 28.54, "lon": -81.38 },
"units": "grains/m³",
"resolution": "hourly",
"hourly_timezone": "UTC",
"generated_at": "2026-11-03T07:25:34Z"
},
"data": [
{
"date": "2026-11-03",
"overall_risk": "moderate",
"species": {
"grass_tot": {
"value": 5.465,
"risk_level": "moderate",
"display_name": "Grass Pollen (Total)",
"category": "grass",
"hourly": [3.719, 2.991, 2.805, 3.054, 3.514, 4.256, 4.463, 4.443,
4.072, 3.523, 3.03, 2.83, 3.385, 4.137, 5.014, 6.361,
7.943, 9.505, 10.494, 10.591, 9.792, 8.394, 7.196, 5.649]
}
}
}
]
}GET /v1/pollen-area
Average, minimum, and maximum pollen levels across a configurable radius. Ideal for regional dashboards, smart home systems, and health services that need area-wide risk assessment rather than a single point.
| Parameter | Type | Required | Description |
|---|---|---|---|
lon | number | requiredYes | Center longitude |
lat | number | requiredYes | Center latitude |
dt | string | requiredYes | Start date (YYYY-MM-DD). About a month of past days is kept; older dates return an empty data array. |
forecast_days | number | requiredYes | Days after dt to include: dt plus the next N days, up to the end of the 7-day forecast |
species | string | optionalNo | Comma-separated species, totals or groups (as for /v1/pollen). Defaults to all. |
radius | number | optionalNo | Search radius in meters (default: 25000, max: 50000) |
curl "https://pollenapi.com/v1/pollen-area?lon=-0.13&lat=51.51&dt=2026-04-02&forecast_days=3&species=tree_tot,grass_tot&radius=50000" \
-H "x-api-key: YOUR_API_KEY"Example response
{
"meta": {
"location": { "lat": 51.51, "lon": -0.13 },
"radius": 50000,
"units": "grains/m³",
"generated_at": "2026-04-02T07:11:01Z"
},
"data": [
{
"date": "2026-04-02",
"overall_risk": "moderate",
"species": {
"tree_tot": {
"avg": 77.5,
"min": 37,
"max": 151,
"risk_level": "moderate",
"display_name": "Tree Pollen (Total)",
"category": "tree"
},
"grass_tot": {
"avg": 0,
"min": 0,
"max": 0,
"risk_level": "low",
"display_name": "Grass Pollen (Total)",
"category": "grass"
}
}
}
]
}GET /v1/pollen-top
Top contributing pollen species in a date range, ranked by severity. Use this for "this week's worst allergens" cards, weekly email summaries, or highlighting what to watch out for.
| Parameter | Type | Required | Description |
|---|---|---|---|
lon | number | requiredYes | Longitude |
lat | number | requiredYes | Latitude |
dt | string | requiredYes | Start date (YYYY-MM-DD). About a month of past days is kept; older dates return an empty data array. |
forecast_days | number | requiredYes | Number of days in the range, starting at dt (up to 7) |
curl "https://pollenapi.com/v1/pollen-top?lon=-0.13&lat=51.51&dt=2026-03-26&forecast_days=7" \
-H "x-api-key: YOUR_API_KEY"Example response
{
"meta": {
"location": { "lat": 51.51, "lon": -0.13 },
"units": "grains/m³",
"date_range": ["2026-03-26", "2026-04-01"],
"generated_at": "2026-04-02T07:11:01Z"
},
"data": [
{
"species": "pinaceae",
"display_name": "Pine family",
"category": "tree",
"max": 48,
"avg": 35,
"risk_level": "moderate"
},
{
"species": "salix",
"display_name": "Willow",
"category": "tree",
"max": 28,
"avg": 22,
"risk_level": "moderate"
}
]
}GET /v1/map-tilesPaid plans
Returns TileJSON with signed URLs for global pollen vector tiles: every land area, 25 species plus totals, every forecast day. Call it from your backend and hand the result to your map library (MapLibre, Mapbox GL JS, OpenLayers, deck.gl). Your API key never reaches the browser.
| Parameter | Type | Required | Description |
|---|---|---|---|
step | string | optionalNo | Forecast day (YYYY-MM-DD) or hour (YYYY-MM-DDTHH, UTC) for the top-level tiles URL. Defaults to today. Every day is also listed in steps. |
resolution | string | optionalNo | hourly adds hourly_steps, one entry per UTC hour of the forecast. steps always lists days only. |
curl "https://pollenapi.com/v1/map-tiles" \
-H "x-api-key: YOUR_API_KEY"Example response
{
"tilejson": "3.0.0",
"name": "Atmospore pollen forecast",
"attribution": "© Atmospore",
"scheme": "xyz",
"tiles": [
"https://pollenapi.com/tiles/v1/20261025T0130Z/2026-10-25/{z}/{x}/{y}.mvt?t=…&Policy=…&Signature=…&Key-Pair-Id=…"
],
"minzoom": 0,
"maxzoom": 5,
"bounds": [-180, -85.0511287798066, 180, 85.0511287798066],
"vector_layers": [
{
"id": "pollen",
"minzoom": 0,
"maxzoom": 5,
"fields": { "birch": "level 0–16", "tree_tot": "level 0–16", "grass_tot": "level 0–16", "…": "…" }
}
],
"run": "20261025T0130Z",
"generated_at": "2026-10-25T01:31:15.506Z",
"encoding": "level",
"levels": {
"min": 0, "max": 16, "none": 0,
"bands": [
{ "risk": "low", "from": 1, "to": 4 },
{ "risk": "moderate", "from": 5, "to": 8 },
{ "risk": "high", "from": 9, "to": 12 },
{ "risk": "very_high", "from": 13, "to": 16 }
]
},
"step": "2026-10-25",
"steps": [
{ "step": "2026-10-25", "tiles": ["https://pollenapi.com/tiles/v1/…/2026-10-25/{z}/{x}/{y}.mvt?…"] },
{ "step": "2026-10-26", "tiles": ["https://pollenapi.com/tiles/v1/…/2026-10-26/{z}/{x}/{y}.mvt?…"] }
],
"expires": "2026-10-25T14:00:00.000Z"
}Response fields
| Field | Description |
|---|---|
tiles | Signed {z}/{x}/{y} URL template for step. Pass it to your map library as a vector source. |
steps | Every forecast day with its own tiles template. To change day, swap in that URL; no new API call is needed. |
hourly_steps | Only with resolution=hourly: every forecast hour (2026-10-25T14, UTC) with its own tiles template, for animating the day hour by hour. |
vector_layers | The tile layer (pollen) and its attributes: one per species, plus tree_tot, grass_tot and weed_tot, each a level from 0 to 16. |
encoding, levels | What the attributes hold (level) and which levels make up each risk band. |
minzoom, maxzoom | Tiles exist for zoom 0–5. Map libraries enlarge zoom 5 tiles when you zoom further. |
expires | When the signed URLs stop working (6–7 hours after the call). Call again before then; within the same hour you get identical URLs, so browser caches stay valid. |
run, generated_at | The forecast run the tiles were built from, and when. |
Tile format
- Mapbox Vector Tiles (
.mvt), one layer namedpollen. Each feature is a forecast grid cell (a square polygon). - Attributes are levels from 1 to 16 per species: 1–4 low, 5–8 moderate, 9–12 high, 13–16 very high. These are the same risk bands as
risk_levelin/v1/pollen, each split into four steps for smooth shading, so one colour scale fits every species. A species with no pollen in a cell is omitted: treat a missing attribute as 0. - Cells are 0.25° at zoom 3–5. At zoom 0–2 they are combined into 2°, 1° and 0.5° cells holding the highest value inside, so hotspots stay visible.
- Tiles that would be all ocean don't exist (404). Tiles are served with
Access-Control-Allow-Origin: *, so they load on any domain. - Tiles are for showing the forecast on a map. For values in grains/m³ at a place, use
/v1/pollen. Extracting values from tiles to store, resell or rebuild the dataset isn't allowed (see the terms).
Access and quota
Included in paid plans (active or trialing). Free plans get 403 with an upgrade link, and that refusal isn't counted. Each call to /v1/map-tiles counts as one request; tile downloads are free and unlimited. Calling it once an hour from your backend is plenty.
Use it in a web map
Serve the response from your own backend (for example at /pollen-tiles), then add it to the map as a vector source and colour the cells with the risk levels:
// Your backend fetches /v1/map-tiles with your key and serves it at /pollen-tiles.
const pollen = await (await fetch("/pollen-tiles")).json();
map.addSource("pollen", {
type: "vector",
tiles: pollen.tiles,
minzoom: pollen.minzoom,
maxzoom: pollen.maxzoom,
});
map.addLayer({
id: "pollen",
type: "fill",
source: "pollen",
"source-layer": "pollen",
paint: {
"fill-color": [
"step", ["coalesce", ["get", "grass_tot"], 0],
"rgba(0, 0, 0, 0)",
5, "#fde047", // moderate
9, "#f97316", // high
13, "#dc2626", // very high
],
"fill-opacity": 0.6,
"fill-antialias": false,
},
});
// Another day: map.getSource("pollen").setTiles(pollen.steps[2].tiles);GET /v1/species
Species metadata with display names in multiple languages, categories, and risk thresholds. No authentication required. Call once, cache client-side, and use for building localized UIs.
No parameters required. No API key required.
risk_level is low below the first threshold, moderate from the first, high from the second and very high from the fourth. The third value is an intermediate level and does not change risk_level.
curl "https://pollenapi.com/v1/species"Example response
{
"meta": {
"total_species": 28,
"categories": ["tree", "grass", "weed"],
"risk_levels": ["low", "moderate", "high", "very high"],
"units": "grains/m³"
},
"data": {
"birch": {
"display_name": "Birch",
"category": "tree",
"names": { "en": "Birch", "sv": "Björk", "no": "Bjørk" },
"risk_thresholds": [15, 90, 500, 1500],
"risk_labels": ["low", "moderate", "high", "very high"]
},
"artemisia": {
"display_name": "Mugwort",
"category": "weed",
"names": { "en": "Mugwort", "sv": "Gråbo", "no": "Burot" },
"risk_thresholds": [10, 50, 200, 500],
"risk_labels": ["low", "moderate", "high", "very high"]
}
}
}Species Catalog
28 species across 3 categories. Use the species key as the species parameter value.
birchBirchbetulaceaeBirch familyhazelHazelalderAlderpinePinespruceSprucepinaceaePine familyelmElmsalixWillowoakOakmapleMaplehickoryHickorypopulusPoplarcypressCypressplatanusPlane treefraxinusAshtimothyTimothy GrassbermudaBermuda GrassloliumRyegrassdactylisCock's-footarrhenatherumFalse Oat-grasspoaBluegrassanthoxanthumSweet Vernal GrassalopecurusMeadow FoxtailholcusYorkshire FogurticaNettleartemisiaMugwortambrosiaRagweedExample Use Cases
Health Apps
Integrate real-time pollen data into health and wellness applications to help users manage allergies and plan outdoor activities.
View Case Study →Smart Home Systems
Automate air purification systems based on local pollen levels to maintain optimal indoor air quality.
View Case Study →Education
Enhance biology education by integrating real-time data for teaching about plant life cycles and environmental science.
View Case Study →Ready to get started?
Sign up for an API key and start integrating pollen data into your applications.