REST API
A radius search API that returns postal codes and towns worldwide.
One endpoint. Send a postal code, town, or coordinates and a radius; get back every postal code and town inside it as JSON, CSV, or a newline-separated code list. Included in every subscription.
Quick start
Create a key on the Account page after signing in, then:
curl "https://ringfence.zinglab.com/api/v1/search?location=02139&country=US&radius=25&unit=mi" \
-H "Authorization: Bearer rf_live_YOUR_KEY"
The response tells you exactly what was searched and everything that matched:
{
"status": "ok",
"center": { "label": "02139 Cambridge, Massachusetts, United States", "lat": 42.3647, "lng": -71.1042 },
"radius": 25, "unit": "mi",
"counts": { "postal_codes": 264, "rows": 325 },
"truncated": false,
"postal_codes": ["02139", "..."],
"rows": [
{ "postal_code": "02139", "distance": 0, "town": "Cambridge", "state": "Massachusetts",
"county": "Middlesex", "country": "United States", "country_code": "US", "lat": 42.3647, "lng": -71.1042 },
"..."
]
}
Parameters
| Parameter | Description |
|---|---|
location | Postal code, town, or "Town, State" / "Town, Country". Required unless lat and lng are sent. |
lat, lng | Exact center coordinates. |
radius | Required. 0 to 150, inclusive, in the chosen unit (150 mi or 150 km). |
unit | mi (default) or km. |
country | ISO 3166-1 alpha-2 code (US, GB, DE…) to narrow location matching. |
auto_pick | true to use the best match when the location is ambiguous. |
format | json (default), csv, or zip_list. |
Every parameter works as a query string on GET or as a JSON body on POST.
Built for production code
- Explicit statuses.
ok,ambiguous(with candidates),not_found, or a 400 with a machine-readableerrorcode. No silent wrong answers. - Small payloads when you want them.
format=zip_listreturns one postal code per line, ready to paste into an ad platform or pipe into another system. - Simple key management. One active key per account, with last-used tracking. Rotate it any time; the old key stops working immediately.
- Fair-use limits. Generous rate limits protect the service. If you hit one, the API returns HTTP 429 with a
Retry-Afterheader telling you when to try again. - CORS enabled on
/api/v1/*for browser integrations.
Python
import requests
r = requests.get(
"https://ringfence.zinglab.com/api/v1/search",
params={"location": "Lyon", "country": "FR", "radius": 40, "unit": "km"},
headers={"Authorization": "Bearer rf_live_YOUR_KEY"},
)
data = r.json()
print(data["counts"], data["postal_codes"][:10])
JavaScript
const res = await fetch("https://ringfence.zinglab.com/api/v1/search", {
method: "POST",
headers: { "Authorization": "Bearer rf_live_YOUR_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ lat: 51.5074, lng: -0.1278, radius: 10, unit: "mi", format: "csv" }),
});
const csv = await res.text();
Frequently asked questions
How do I authenticate to the RingFence API?
Create an API key on the Account page of the web app and send it as an HTTP header: Authorization: Bearer rf_live_... Each account has one active key; rotating it on the Account page creates a new key and turns the old one off immediately.
What output formats does the API support?
JSON (default) with the center, counts, a unique postal code list, and full rows; CSV with postal_code, distance, town, state, and country; and zip_list, one postal code per line.
What happens if a location is ambiguous?
The API returns status "ambiguous" with a list of candidates and their coordinates. Resend with the chosen candidate's lat and lng, add a country code, or set auto_pick=true to use the best match.
Is there an OpenAPI specification?
Yes, at /openapi.yaml.