Authentication
Authenticate your requests by including your API key as a key query parameter.
GET https://api.frostdates.com/frost-dates?key=YOUR_API_KEY&location=london,ukGet your API key from the API Keys page.
Base URL
https://api.frostdates.comGET /frost-dates
Returns frost dates, USDA hardiness zone, and optional average temperatures for a location.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Your API key |
location | string | Yes | Location query (city name, postal code, or lat/long) |
incavgtemps | boolean | No | Include monthly average min/max temperatures |
Response
{
"location": {
"latitude": 51.5,
"longitude": -0.1,
"areaName": "London",
"country": "United Kingdom",
"region": "Greater London"
},
"frostDates": {
"airFrost": {
"first": { "day": 310, "month": 11, "dateString": "6 November" },
"last": { "day": 95, "month": 4, "dateString": "5 April" }
},
"lightGroundFrost": {
"first": { "day": 285, "month": 10, "dateString": "12 October" },
"last": { "day": 120, "month": 4, "dateString": "30 April" }
},
"hardGroundFrost": {
"first": { "day": 335, "month": 12, "dateString": "1 December" },
"last": { "day": 65, "month": 3, "dateString": "6 March" }
}
},
"usdaZone": "8b"
}Frost Types
| Type | Threshold | Description |
|---|---|---|
airFrost | 0°C | Temperature at which exposed plants are damaged |
lightGroundFrost | -2°C | Light frost at ground level affecting tender plants |
hardGroundFrost | -5°C | Hard freeze damaging most plants |
GET /search-locations
Search for locations by name. Returns a list of matching locations with coordinates.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Your API key |
query | string | Yes | Search query (min 3 characters) |
Response
[
{
"areaName": "New York",
"country": "United States of America",
"region": "New York",
"latitude": "40.714",
"longitude": "-74.006",
"population": "8175133"
}
]GET /test-locations
Returns the list of free test locations. These locations can be queried without a paid subscription and don't count against your quota. No authentication required.
GET https://api.frostdates.com/test-locations14 curated locations covering all USDA zones and both hemispheres. Use the query field value as the location parameter in the /frost-dates endpoint.
Rate Limits & Quotas
| Plan | Price | Daily | Monthly | Rate Limit |
|---|---|---|---|---|
| Starter | $19/mo | 100 | 2,000 | 10/min |
| Pro | $49/mo | 500 | 10,000 | 30/min |
| Business | $99/mo | 1,000 | 30,000 | 60/min |
Response Headers
Successful developer requests include these headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Per-minute rate limit |
X-Quota-Daily-Limit | Daily request limit |
X-Quota-Daily-Remaining | Remaining daily requests |
X-Quota-Monthly-Limit | Monthly request limit |
X-Quota-Monthly-Remaining | Remaining monthly requests |
Error Codes
| Status | Meaning | Example |
|---|---|---|
400 | Bad Request | Missing or invalid parameters |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | No paid subscription (non-test location) |
404 | Not Found | Location not found or insufficient climate data |
429 | Too Many Requests | Daily, monthly, or per-minute limit exceeded |
500 | Internal Error | Server-side error |
All error responses return JSON:
{ "error": "Description of the error." }Code Examples
curl
curl "https://api.frostdates.com/frost-dates?key=YOUR_API_KEY&location=london,uk"JavaScript (fetch)
const API_KEY = 'YOUR_API_KEY';
const location = 'london,uk';
const response = await fetch(
`https://api.frostdates.com/frost-dates?key=${API_KEY}&location=${encodeURIComponent(location)}`
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error);
}
const data = await response.json();
console.log(data.frostDates.airFrost);
console.log('USDA Zone:', data.usdaZone);Python (requests)
import requests
API_KEY = "YOUR_API_KEY"
location = "london,uk"
response = requests.get(
"https://api.frostdates.com/frost-dates",
params={"key": API_KEY, "location": location}
)
response.raise_for_status()
data = response.json()
print(f"USDA Zone: {data['usdaZone']}")
print(f"First air frost: {data['frostDates']['airFrost']['first']['dateString']}")
print(f"Last air frost: {data['frostDates']['airFrost']['last']['dateString']}")