CommunityShield
ML-powered crime pattern explorer for Chicago. 8.5M rows, 4 XGBoost models with SHAP explanations, beat-level heatmap, and an honest methodology page about what the data can and cannot tell you.
REST API Reference
CommunityShield exposes a FastAPI service with auto-generated OpenAPI docs at /docs. Every endpoint is unauthenticated and rate-limited — the data is public, but the compute isn't free.
Heatmap
| Endpoint | Method | Description |
|---|---|---|
/heatmap | GET | Per-beat aggregate counts for the requested time window and category. Picks the right rollup table based on window length. |
/heatmap/categories | GET | Available crime categories with citywide counts |
Example response:
{
"window": { "start": "2025-07-01T00:00:00Z", "end": "2025-08-01T00:00:00Z" },
"category": "THEFT",
"beats": [
{ "beat_id": 111, "beat_number": "0111", "count": 47, "intensity": 0.62 },
{ "beat_id": 112, "beat_number": "0112", "count": 23, "intensity": 0.31 }
]
}
Beat detail
| Endpoint | Method | Description |
|---|---|---|
/beats | GET | All 274 beats with metadata |
/beats/{beat_id} | GET | Single beat: geometry, district, ward |
/beats/{beat_id}/trend | GET | Time series for the beat over a configurable window |
/beats/{beat_id}/incidents | GET | Recent incidents at the beat, paginated, capped at 200 rows |
/beats/{beat_id}/comparison | GET | Beat vs. citywide median for each crime category |
Prediction
| Endpoint | Method | Description |
|---|---|---|
/predict/{beat_id} | GET | Run all four models for the beat, return predictions with SHAP attribution |
/predict/{beat_id}/{category} | GET | Single-category prediction with full SHAP breakdown |
Example response:
{
"beat_id": 111,
"window": { "start": "2025-08-01T00:00:00Z", "end": "2025-08-02T00:00:00Z" },
"category": "THEFT",
"prediction": { "above_median": true, "probability": 0.74 },
"top_features": [
{ "name": "theft_count_last_7d", "value": 18, "shap": 0.31 },
{ "name": "hour_of_week_baseline", "value": 4.2, "shap": 0.18 },
{ "name": "neighbor_beat_theft_24h", "value": 12, "shap": 0.11 }
],
"model_version": "theft_classifier_v1.2.3"
}
Methodology
| Endpoint | Method | Description |
|---|---|---|
/methodology/roc | GET | Pre-computed ROC curve points for all four classifiers |
/methodology/importance | GET | Global feature importance for the model ensemble |
/methodology/data-ceiling | GET | PR-AUC convergence data across hyperparameter trials |
Health
| Endpoint | Method | Description |
|---|---|---|
/health | GET | Liveness check |
/ready | GET | Readiness check (DB + all 4 models loaded) |
Design notes
Unauthenticated, rate-limited. Crime data is public. The API is public. Rate limits prevent abuse without requiring API keys.
OpenAPI for free. FastAPI generates the full spec from Pydantic schemas. /docs renders the interactive Swagger UI; /redoc renders a cleaner reference style.
Cursor pagination on /beats/{beat_id}/incidents. Some beats have hundreds of thousands of historical incidents. Cursor pagination keeps the endpoint fast at any offset.
Rollup-aware time windows. The /heatmap and /beats/{beat_id}/trend endpoints accept any window length and automatically pick the appropriate rollup table (hourly, daily, weekly, monthly) based on window size. The caller doesn't need to know about the rollup structure.