Try Crime Data API without signup

Query the existing public MCP channel for a fixed Seattle location, then use a free key for REST queries.

Last updated: 2026-11-04

Fixed location: Pike Place Market, downtown Seattle (47.6097, -122.3422), within 500 metres. This live example uses the existing public MCP channel: last 180 days, at most 5 records, 60 tool calls per hour per IP.

Ready to query.

The response, including source metadata and newest record date, will appear here.

Empty results do not establish that no crime occurred. Review the source dates and licence in the response and city scope and freshness.

Use your own free key

Run these snippets locally. Key creation needs no email; keep the returned secret key server-side. Each query uses one request. Compare uses two points in Seattle.

curl (requires Python 3 to read the key)

export CRIME_API_KEY=$(curl --fail-with-body -sS -X POST 'https://crimedata.dev/v1/keys' | python3 -c 'import json,sys; print(json.load(sys.stdin)["api_key"])')
curl --fail-with-body -G 'https://crimedata.dev/v1/incidents' -H "x-api-key: $CRIME_API_KEY" --data-urlencode 'lat=47.6097' --data-urlencode 'lon=-122.3422' --data-urlencode 'radius_m=500' --data-urlencode 'limit=5'
curl --fail-with-body -G 'https://crimedata.dev/v1/stats' -H "x-api-key: $CRIME_API_KEY" --data-urlencode 'lat=47.6097' --data-urlencode 'lon=-122.3422' --data-urlencode 'radius_m=500'
curl --fail-with-body -G 'https://crimedata.dev/v1/compare' -H "x-api-key: $CRIME_API_KEY" --data-urlencode 'points=47.6097,-122.3422;47.6062,-122.3321' --data-urlencode 'radius_m=500'

Python 3 (standard library)

import json
from urllib.request import Request, urlopen
from urllib.parse import urlencode

BASE = "https://crimedata.dev"
def request(path, params=None, key=None, method="GET"):
    url = BASE + path + ("?" + urlencode(params) if params else "")
    headers = {"x-api-key": key} if key else {}
    with urlopen(Request(url, headers=headers, method=method), timeout=30) as response:
        return json.load(response)

key = request("/v1/keys", method="POST")["api_key"]
area = {"lat": 47.6097, "lon": -122.3422, "radius_m": 500}
print(json.dumps(request("/v1/incidents", dict(area, limit=5), key), indent=2))
print(json.dumps(request("/v1/stats", area, key), indent=2))
print(json.dumps(request("/v1/compare", {
    "points": "47.6097,-122.3422;47.6062,-122.3321", "radius_m": 500
}, key), indent=2))

401: check your key. 429: quota or rate limit reached; wait for reset. Unsupported locations return a coverage error; unavailable feeds should be retried later. Full API reference.

What should I know about this data?

Where does the incident data come from?

Incident data comes from city open-data portals under the licence shown for each city. It is police-reported data, not convictions, and sources can revise it.

Where can I check coverage and freshness?

The city coverage pages and GET /v1/cities identify covered cities, source licences and newest record dates.

Do scores predict personal risk?

No. Scores describe incident density within a city, are not comparable across cities and do not predict personal risk.

Where can I find related information?

Crime API reference · Incident density methodology · MCP setup for AI agents