Developer API
The Earth911 API turns a plain-language question — “where do I recycle batteries near me?” — into structured materials and nearby drop-off locations. One authenticated GET request, JSON back.
1. Create a key in the developer portal (it’s shown once — save it).
2. Call the search endpoint with your key in the X-API-Key header:
curl "https://earth911-web-production.up.railway.app/api/v2/search?q=recycle+batteries+near+me&lat=45.52&lng=-122.68" \
-H "X-API-Key: key_your_key_here"3. You get structured materials + nearby locations back as JSON (see below).
Send your key in the X-API-Key header to get your key’s rate limits. Requests without a key still work but share the anonymous web quota (a few searches per day) — fine for trying the API, not for an app. Keys are scoped (read:locations, read:materials) and rate-limited per key. Never embed a production key in client-side code you ship to users — proxy through your backend.
X-API-Key: key_xxxxxxxxxxxxxxxxxxxxxxxxGET https://earth911-web-production.up.railway.app/api/v2/search
Natural-language recycling search. Returns matched materials and nearby locations, ranked.
| Param | Type | Description |
|---|---|---|
| q | string · required | The plain-language query, e.g. "electronics recycling in Portland". |
| lat, lng | number | Caller coordinates — enables "near me" distance ranking. |
| types | string | Comma list of entity types to return: material,location (default both). |
| limit | number | Max results per type (default 20). |
Response
{
"query": "recycle batteries near me",
"parsed_query": {
"action": "recycle",
"material": "batteries",
"location_hint": "near_user",
"confidence": "high",
"detected_materials": ["batteries"]
},
"results": {
"materials": [
{ "entity_type": "material", "entity_id": "123",
"name": "Alkaline Batteries", "category": "Batteries",
"disposition": "recycle", "rank": 0.95 }
],
"locations": [
{ "entity_type": "location", "entity_id": "456",
"name": "Battery Recyclers Inc",
"description": "2.4 miles away", "rank": 0.92 }
]
},
"total_results": 15,
"execution_time_ms": 42
}Limits are enforced per key. The free tier allows 60 requests/minute and 10,000/day. Exceeding a window returns 429 Too Many Requests with a Retry-After header. Higher tiers are coming with paid plans — keys and current limits live in your dashboard’s Developer page.
| 400 | Missing or malformed query parameter. |
| 401 | Invalid X-API-Key (keyless requests fall back to the anonymous quota instead). |
| 403 | Key lacks the required scope. |
| 429 | Rate limit hit — back off and retry after Retry-After. |
| 5xx | Transient server error — retry with backoff. |
Errors return JSON: { "detail": "…" }.