BBB API endpoint
Returns aggregate scam-report stats per US state and Canadian province for a given time window: report counts, dollar losses, per-capita rates, year-over-year change, and top scam-type breakdown.
/bbb/scamtracker/state-statsQuery parameters:
period (optional, default 90) — aggregation window. Allowed values: 30, 90, 365, all.Response includes aggregated_at (when the upstream computed these stats) and states[], one entry per US state/DC or Canadian province, each with:
reports / reports_with_loss / pct_reporting_loss — how many reports were filed, and what share reported a dollar loss.losses — total reported dollar losses for the period. median_loss — median loss among reports that reported one.population, reports_per_capita, losses_per_capita — per-capita rates so smaller states/provinces aren't masked by larger ones.yoy_change_pct — year-over-year change in report count.top_scam_type and scam_type_breakdown[] — the most common scam category and a full per-category count/share breakdown for that state.Example response (trimmed):
{"code":200,"msg":"OK","data":{"period":"90","aggregated_at":"2026-08-20T03:00:22.405Z","states":[{"country":"USA","code":"TX","name":"Texas","reports":4085,"reports_with_loss":1950,"pct_reporting_loss":47.7,"losses":3163720,"median_loss":97,"population":30503301,"reports_per_capita":0.00013391993214111481,"losses_per_capita":0.10371729931786727,"yoy_change_pct":-3.4,"top_scam_type":"Online Purchase","scam_type_breakdown":[{"type":"Online Purchase","count":1177,"pct":32.9},{"type":"Other","count":626,"pct":17.5}]}]}}
| Field | Filled in, of 64 checked | Values in the sample |
|---|---|---|
| country | 64 | USA (51), CAN (13) |
| code | 64 | |
| name | 64 | “Alberta” and 63 other values |
| reports | 64 | 1 to 5,008, median 524 |
| reports_with_loss | 64 | 0 to 2,706, median 288 |
| pct_reporting_loss | 64 | 0 to 100, median 53 |
| losses | 64 | 0 to 3,542,956, median 376,216 |
| median_loss | 64 | 0 to 443, median 83 |
| population | 64 | 41,070 to 38,965,193, median 3,617,176 |
| reports_per_capita | 64 | 0 to 0, median 0 |
| losses_per_capita | 64 | 0 to 1.51, median 0.08 |
| yoy_change_pct | 64 | -44 to 300, median -8.1 |
| top_scam_type | 64 | Online Purchase (61), Foreign Money Exchange (1), Employment (1) and 1 more |
| scam_type_breakdown | 64 | median 8 entries |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| period | string | No | Aggregation window, default 90 Allowed values: 30, 90, 365, all. | ||
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/bbb/scamtracker/state-stats?period=30" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"period": "90",
"aggregated_at": "2026-08-20T03:00:22.405Z",
"states": [
{
"country": "USA",
"code": "TX",
"name": "Texas",
"reports": 4085,
"reports_with_loss": 1950,
"pct_reporting_loss": 47.7,
"losses": 3163720,
"median_loss": 97,
"population": 30503301,
"reports_per_capita": 0.0001339199321411148,
"losses_per_capita": 0.10371729931786727,
"yoy_change_pct": -3.4,
"top_scam_type": "Online Purchase",
"scam_type_breakdown": [
{
"type": "Online Purchase",
"count": 1177,
"pct": 32.9
},
{
"type": "Other",
"count": 626,
"pct": 17.5
}
]
}
]
}
}Request schema
No body schema
Response schema
#/definitions/bbbscamtracker.stateStatsResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | bbbscamtracker.StateStatsResponse | No | ||||
| data.aggregated_at | string | No | 2026-08-20T03:00:22.405Z | |||
| data.period | string | No | 90 | |||
| data.states | array | No | ||||
| data.states[].code | string | No | TX | |||
| data.states[].country | string | No | USA | |||
| data.states[].losses | integer | No | ||||
| data.states[].losses_per_capita | number | No | ||||
| data.states[].median_loss | integer | No | ||||
| data.states[].name | string | No | Texas | |||
| data.states[].pct_reporting_loss | number | No | ||||
| data.states[].population | integer | No | ||||
| data.states[].reports | integer | No | ||||
| data.states[].reports_per_capita | number | No | ||||
| data.states[].reports_with_loss | integer | No | ||||
| data.states[].scam_type_breakdown | array | No | ||||
| data.states[].scam_type_breakdown[].count | integer | No | ||||
| data.states[].scam_type_breakdown[].pct | number | No | ||||
| data.states[].scam_type_breakdown[].type | string | No | Online Purchase | |||
| data.states[].top_scam_type | string | No | ||||
| data.states[].yoy_change_pct | number | No | ||||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 500 | Internal Server Error | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/bbb/scamtracker/state-stats?period=30" \
-H "x-api-key: $CRAWLORA_API_KEY"