API Documentation · v1.4

The ROLLIN API, documented.

Verified accessibility data over REST. Get a key, send it in one header, and query 105,000+ scored venues from curl, JavaScript, or Python. This page covers everything from your first request to production.

01

Getting started

Three steps to your first response.

01

Get a key

The free tier includes 1,000 requests a month with no credit card. Sign up at the portal.

Get free key
02

Authenticate

Send your key in the X-Api-Key header. Keep it in environment variables and never commit secrets.

03

Make a call

Request /v1/locations with a lat and lng. You get scored venues back as JSON.

02

Authentication

Send your key in X-Api-Key.

Pull the key from environment variables. Never commit secrets. The unauthenticated /v1/health endpoint is the easiest sanity check.

# Set once in your shell export ROLLIN_API_KEY="rls_..." # Use in any request curl -H "X-Api-Key: $ROLLIN_API_KEY" \ "https://joinrollin.com/api/v1/health"
// Pull from env, never hardcode const KEY = process.env.ROLLIN_API_KEY; const res = await fetch( 'https://joinrollin.com/api/v1/health', { headers: { 'X-Api-Key': KEY } } ); const health = await res.json();
# Pull from env, never hardcode import os from rollin import Rollin client = Rollin(api_key=os.environ["ROLLIN_API_KEY"]) health = client.health.check()
03

Recipes

The four calls most integrations start with.

recipe · 01

Search nearby venues.

Pass a lat and lng with a radius in meters, filter by minimum score, and paginate with limit. Results come back sorted by accessibility score.

curl -H "X-Api-Key: $ROLLIN_API_KEY" \ "https://joinrollin.com/api/v1/locations?lat=40.7580&lng=-73.9855&radius=500&min_score=70&limit=20"
const params = new URLSearchParams({ lat: 40.7580, lng: -73.9855, radius: 500, min_score: 70, limit: 20 }); const res = await fetch( `https://joinrollin.com/api/v1/locations?${params}`, { headers: { 'X-Api-Key': KEY } } ); const { locations } = await res.json();
results = client.locations.search( lat=40.7580, lng=-73.9855, radius=500, min_score=70, limit=20 ) for loc in results.locations: print(loc.name, loc.score)
recipe · 02

Get full venue detail.

Retrieve one venue by ID: the score, all six features, address, cuisine tags, and last verified timestamp, plus photos and hours on Starter and above.

curl -H "X-Api-Key: $ROLLIN_API_KEY" \ "https://joinrollin.com/api/v1/locations/abc-123-def"
const id = 'abc-123-def'; const res = await fetch( `https://joinrollin.com/api/v1/locations/${id}`, { headers: { 'X-Api-Key': KEY } } ); const location = await res.json();
loc = client.locations.retrieve("abc-123-def") print(loc.score, loc.features)
recipe · 03 · Developer+

Submit feedback.

POST corrections, missing venue reports, or verification confirmations. The ROLLIN team reviews every submission, and accurate reports feed back into the score.

curl -X POST -H "X-Api-Key: $ROLLIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"location_id":"abc-123","type":"correction","message":"..."}' \ "https://joinrollin.com/api/v1/feedback"
const res = await fetch( 'https://joinrollin.com/api/v1/feedback', { method: 'POST', headers: { 'X-Api-Key': KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ location_id: 'abc-123', type: 'correction', message: 'Restroom is no longer step-free as of last visit.' }) } );
client.feedback.submit( location_id="abc-123", type="correction", message="Restroom is no longer step-free as of last visit." )
recipe · 04

Check your quota.

Returns current usage across the per-minute, per-day, and per-month windows for your key, plus your current tier. Useful for showing remaining quota in your own UI.

# Check current quota usage for your key curl -H "X-Api-Key: $ROLLIN_API_KEY" \ "https://joinrollin.com/api/v1/usage"
const res = await fetch( 'https://joinrollin.com/api/v1/usage', { headers: { 'X-Api-Key': KEY } } ); const usage = await res.json(); // usage.tier, usage.minute, usage.day, usage.month
usage = client.usage.retrieve() print(usage.tier, usage.month.used, usage.month.limit)
04

Endpoints

Eight endpoints cover the whole surface.

The short version. Schemas, parameters, and response shapes for every endpoint live in the full reference.

GET/api/v1/locationsSearch by lat/lng, city/state, or query string. Paginated.
GET/api/v1/locations/:idFull venue detail: score, features, address, photos.
GET/api/v1/regionsCoverage stats by state and metro region.
GET/api/v1/score/:idDetailed score breakdown by category (Business+).
POST/api/v1/feedbackSubmit accessibility feedback (Developer+).
GET/api/v1/usageCurrent key usage across rate-limit windows.
GET/api/v1/trial/*Public trial proxy. IP rate limited, no key required.
GET/api/v1/healthAPI status. No auth needed and no quota cost.
05

Rate limits

Per-minute and per-month scale with tier.

Hit a limit and you get a 429 with a Retry-After header. Calls to /v1/health are never counted. Change tiers any time in the portal.

Free
1K
requests / month
10 / minute
Starter · $9.99
5K
requests / month
30 / minute
Developer · $29
50K
requests / month
60 / minute
Business · $149
500K
requests / month
200 / minute
06

Error codes

Standard HTTP, structured payloads.

Every error returns a JSON body with a code, a message, and hints for resolution when they apply.

400 Bad Request Invalid params: missing lat/lng, malformed coordinates, or an unknown query.
401 Unauthorized Missing or invalid X-Api-Key header.
402 Payment Required Endpoint requires a higher tier. Upgrade in the portal.
403 Forbidden Key revoked, expired, or origin-locked to a different domain.
404 Not Found Venue ID does not exist or has been removed.
429 Too Many Requests Rate limit hit. Honor the Retry-After header.
500 Internal Error Something on our end. Retry with exponential backoff.
07

Production checklist

Before you ship to real users.

Six things that turn a working integration into one you can put in front of real users.

  1. 01

    Keep keys in env vars, never in source

    Set ROLLIN_API_KEY in your platform’s secret store (Netlify env, Vercel env, Doppler, 1Password). Never commit the key. Rotate from the portal if it leaks.

  2. 02

    Honor 429 with Retry-After

    Rate limit hits return 429 with a Retry-After header in seconds. Wait that long before retrying. Use exponential backoff with jitter for 5xx errors.

  3. 03

    Cache aggressively client-side

    Venue data changes daily to monthly, not by the second. Cache /v1/locations/:id responses for 24 hours. The /v1/usage endpoint shows your remaining quota, so display it in your dashboard.

  4. 04

    Surface scores honestly to users

    A score of 60 is not the same as a score of 90. Show the number rather than a binary yes or no, and link to ROLLIN for the full breakdown. Your users will trust your app more when the data keeps its nuance.

  5. 05

    Forward feedback to /v1/feedback

    If your users tell you a venue’s data is wrong, send it back to ROLLIN via POST /v1/feedback (Developer+). It makes the score more accurate for everyone, including you next time.

  6. 06

    Plan for tier limits before launch day

    Estimate monthly call volume from your projected daily actives. If it lands above 5K a month, upgrade to Starter before launch day. Annual billing on Developer and above saves 20 percent.

Start with the free tier.

1,000 requests a month, no credit card. If you are shipping at scale, talk to us about annual pricing and onboarding.