# ROLLIN API

Accessibility data over REST. ROLLIN publishes a 0 to 100 physical accessibility score for 105,000+ US venues, with the six features behind each score. This page is the machine-readable version of the developer docs at https://joinrollin.com/developers. Get a key, send it in one header, and query scored venues from curl, JavaScript or Python.

- Base URL: `https://joinrollin.com/api/v1`
- API version: 1.2
- Authentication: an `X-Api-Key` header on every request
- Free keys, no credit card: https://joinrollin.com/portal
- OpenAPI 3.1 spec: https://joinrollin.com/openapi.yaml

## Authentication

Send your key in the `X-Api-Key` header. Keep it server-side, never in client code. The `/health` endpoint needs no key and is never counted against your quota.

```bash
# 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"
```

## Endpoints

| Method | Path | Tier | Description |
| --- | --- | --- | --- |
| GET | `/v1/locations` | Free and above | Search venues by coordinates, a place or landmark name, or a bounding box, then filter. Sorted by distance by default, and the response carries a cursor when there is another page. When near resolves the center, the response echoes searched_near; an unresolvable name returns 400 LOCATION_NOT_FOUND. |
| GET | `/v1/locations/:id` | Free and above | Full venue detail: the six accessibility features, the address, the verified flag and last_updated. assessment reads assessed, or insufficient_data when none of the four core features are known. Phone, website and hours from Starter, now populated on many venues. photo_url from Developer. data_confidence on Business. Free receives no feature set and a locked sensory stub. |
| POST | `/v1/locations/batch` | Free and above | Up to 50 venues by ID in one round trip, with the same shape and tier gating as detail. IDs must be UUIDs; anything else is dropped, so compare requested against count. |
| GET | `/v1/changes` | Developer and above | Incremental sync feed of venues whose profile or sensory data changed inside the window. Poll it daily instead of re-pulling whole regions. |
| GET | `/v1/regions` | Free and above | Coverage by state: how many scored venues each one holds, and a coverage level for each. total_locations carries the live corpus size, so read it rather than hard-coding a number. |
| GET | `/v1/score/:id` | Business and above | Score breakdown: each feature’s recorded value, a qualitative impact label, and whether it is one of the four critical features. Point weights are not exposed. |
| POST | `/v1/feedback` | Developer and above | Submit a correction for a venue. Every submission lands as pending and is reviewed by the ROLLIN team. One pending submission per venue, and 10 submissions per key per 24 hours. |
| GET | `/v1/usage` | Free and above | Usage for the authenticated key across the minute, day and month windows, plus the current tier. |
| GET | `/v1/trial/*` | No key | Public trial proxy with no API key, rate limited per IP to 5 requests a minute and 30 a day, with the radius capped at 5 miles and 5 results a search. It mirrors locations, detail, score, regions, feedback and health under free-tier restrictions, and the MCP server’s trial mode runs on it. |
| GET | `/v1/health` | No auth, uncounted | Status check for liveness probes. No key required, and it is never counted against your quota. The response also carries a data.locations count. |

## Errors

Errors come back as JSON with a stable `error.code`.

| Status | Name | Code | Meaning |
| --- | --- | --- | --- |
| 400 | Bad Request | `INVALID_PARAMS` | Missing or malformed parameters, or a body that is not valid JSON. |
| 400 | Bad Request | `LOCATION_NOT_FOUND` | A near place or landmark name could not be resolved to a center. Try a more specific name, or pass lat and lng. |
| 401 | Unauthorized | `INVALID_API_KEY` | No key, a key that fails the format check, a revoked key, or an expired one. |
| 403 | Forbidden | `TIER_REQUIRED` | The endpoint or the filter needs a higher plan. |
| 404 | Not Found | `LOCATION_NOT_FOUND` | That venue ID does not exist, or it has been removed. |
| 405 | Method Not Allowed | `METHOD_NOT_ALLOWED` | Wrong HTTP method for the endpoint. |
| 409 | Conflict | `FEEDBACK_PENDING` | You already have feedback pending for that venue. |
| 429 | Too Many Requests | `RATE_LIMIT_MINUTE` | A minute, day or month window is full. Honour Retry-After. |
| 500 | Internal Error | `INTERNAL_ERROR` | Our end. Retry with exponential backoff. |

```json
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_MINUTE",
    "message": "Rate limit exceeded: 30 requests per minute.",
    "retry_after": 60
  }
}
```

## MCP server

The MCP server lets Claude, Cursor, VS Code and other MCP clients query scored venues directly. It is published on npm as `rollin-mcp-server` and uses the same key as the REST API. There is also a hosted endpoint at https://joinrollin.com/api/mcp for any client that supports remote MCP servers, including ChatGPT connectors.

Local client config:

```json
{
  "mcpServers": {
    "rollin": {
      "command": "npx",
      "args": ["-y", "rollin-mcp-server"],
      "env": { "ROLLIN_API_KEY": "rls_..." }
    }
  }
}
```

Tools:

- `search_locations(q, near, lat, lng, radius, min_score, features, lighting, limit)`: Search venues around a center. Give the center as lat and lng, or as a place or landmark name in near (for example near "Madison Square Garden"). q matches the venue name, cuisine or category, with name matches ranked first. Everything else narrows the result.
- `get_location_details(id)`: Full detail for one venue: score, all six features, address, photo URL and sensory values, subject to your tier.
- `list_regions()`: Coverage by state, for scoping a search.
- `check_health()`: API status and version. Never counted against your quota.
- `submit_feedback(location_id, feedback_type, features, comment)` (Developer and above): Send a correction for the ROLLIN team to review.

Paste this prompt into a coding agent to have it set the server up for you:

```
Set up the ROLLIN accessibility MCP server for me.

1. Work out which tool you are running in and use its MCP config:
   - Claude Code: run  claude mcp add rollin -- npx -y rollin-mcp-server
   - Claude Desktop: claude_desktop_config.json, key "mcpServers"
   - Cursor: .cursor/mcp.json, key "mcpServers"
   - VS Code: .vscode/mcp.json, key "servers"
   - Anything else that supports remote MCP: use the hosted server
     https://joinrollin.com/api/mcp with header X-Api-Key
   For local setups use command "npx", args ["-y", "rollin-mcp-server"].

2. Ask me for my ROLLIN API key (it starts with rlf_, rls_, rld_ or rlb_).
   If I do not have one, send me to https://joinrollin.com/portal?signup=free.
   Store it as ROLLIN_API_KEY in env or the config’s "env" block.
   Never commit it or put it in client-side code. Add the file to .gitignore if needed.

3. Restart or reload the MCP server, then call check_health and
   search_locations(q="cafe", lat=40.758, lng=-73.985, limit=3).
   Show me the results with each score, on the 0 to 100 scale.

Tools: search_locations, get_location_details, list_regions,
check_health, submit_feedback (Developer and above).
Docs: https://joinrollin.com/mcp  ·  Spec: https://joinrollin.com/openapi.yaml
```

## Plans

One key works across the REST API and the MCP server. Month to month.

| Plan | Price | Requests / month | Per minute |
| --- | --- | --- | --- |
| Free | $0 | 1,000 | 10 |
| Starter | $9.99 / month | 5,000 | 30 |
| Developer | $29 / month | 50,000 | 60 |
| Business | $149 / month | 500,000 | 200 |

Full docs: https://joinrollin.com/developers
