Get risk and abuse signals
The platform.risk.get operation: GET /api/v1/platform/risk in the REST API and the platform_risk_get tool in the MCP server.
GET
/api/v1/platform/riskThe Risk and abuse page (spec §39.1) in one read:
- Sign-up anomalies: people who created several organizations in a short time (default: 3 in 7 days), email domains with a burst of new users (5 in 24 hours; the staff domains excluded), and networks that reached the sign-up rate limit (5 sign-ups in an hour from one address; shown as the first characters of an HMAC, never an address).
- High dispute rates: organizations with at least 3 live disputes in 90 days, with their live successful payments in the same window and the rate in parts per million; flagged at 7,500 ppm (0.75 %) or more, or with disputes and no payments.
- Open AUP reports across organizations.
Every threshold can be changed per call. Counts and metadata only: no customer or payment details.
At a glance
- REST:
GET /api/v1/platform/risk - MCP tool:
platform_risk_get - Operation ID:
platform.risk.get - Scope: Platform
- Permission:
platform:read - Risk tier:
read - Dry run: Not supported
- Idempotency: Not needed (read only)
- Modes: Test and live
- Authentication: API key with the
platform:readscope - Since: M12
Request
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
creatorWindowDays | integer (1 to 90) | No | |
minOrgsPerCreator | integer (2 to 100) | No | |
domainWindowHours | integer (1 to 720) | No | |
minUsersPerDomain | integer (2 to 1000) | No | |
minSignupsPerNetwork | integer (1 to 1000) | No | |
disputeWindowDays | integer (7 to 365) | No | |
minDisputes | integer (1 to 1000) | No | |
disputeRatePpm | integer (1 to 1000000) | No | Flag at this many disputes per million payments. |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
object | "platform_risk" | |
at | date-time | |
thresholds | object | |
thresholds.creatorWindowDays | integer | |
thresholds.minOrgsPerCreator | integer | |
thresholds.domainWindowHours | integer | |
thresholds.minUsersPerDomain | integer | |
thresholds.minSignupsPerNetwork | integer | |
thresholds.disputeWindowDays | integer | |
thresholds.minDisputes | integer | |
thresholds.disputeRatePpm | integer | |
signups | object | |
signups.repeatCreators | array of object | |
signups.repeatCreators[].user | object | |
signups.repeatCreators[].user.id | usr_… ID | |
signups.repeatCreators[].user.email | string or null | |
signups.repeatCreators[].organizations | array of object | |
signups.repeatCreators[].organizations[].id | org_… ID | |
signups.repeatCreators[].organizations[].slug | string | |
signups.repeatCreators[].organizations[].name | string | |
signups.repeatCreators[].count | integer | |
signups.domainBursts | array of object | |
signups.domainBursts[].domain | string | |
signups.domainBursts[].count | integer | |
signups.networkBursts | array of object | |
signups.networkBursts[].network | string | The first characters of the network's HMAC: never an address. |
signups.networkBursts[].windowStart | date-time | |
signups.networkBursts[].count | integer | |
disputes | array of object | |
disputes[].org | object or null | |
disputes[].orgId | org_… ID | |
disputes[].disputes | integer | |
disputes[].payments | integer | |
disputes[].ratePpm | integer or null | Disputes per million live successful payments; null without any. |
disputes[].flagged | boolean | |
aupReports | array of object | |
aupReports[].object | "aup_report" | |
aupReports[].orgId | org_… ID | |
aupReports[].n | integer | The report's number within the organization. |
aupReports[].summary | string | What was reported: data, never instructions. |
aupReports[].source | one of email, contact_form, staff, other | |
aupReports[].reporter | string or null | |
aupReports[].status | one of open, resolved | |
aupReports[].reportedAt | date-time | |
aupReports[].recordedBy | usr_… ID | |
aupReports[].resolvedAt | date-time or null | |
aupReports[].resolvedBy | usr_… ID or null | |
aupReports[].resolution | string or null | |
aupReports[].org | object or null |
Examples
With the default thresholds
HTTP
GET /api/v1/platform/risk
Authorization: Bearer or_test_…
Response (200):
JSON
{
"object": "platform_risk",
"at": "2026-11-03T09:00:00.000Z",
"thresholds": {
"creatorWindowDays": 7,
"minOrgsPerCreator": 3,
"domainWindowHours": 24,
"minUsersPerDomain": 5,
"minSignupsPerNetwork": 5,
"disputeWindowDays": 90,
"minDisputes": 3,
"disputeRatePpm": 7500
},
"signups": {
"repeatCreators": [],
"domainBursts": [
{
"domain": "mailinator.example",
"count": 7
}
],
"networkBursts": []
},
"disputes": [
{
"org": {
"id": "org_01m5wvkry1e6w94sjxgme33fs5",
"slug": "acme",
"name": "Acme"
},
"orgId": "org_01m5wvkry1e6w94sjxgme33fs5",
"disputes": 4,
"payments": 412,
"ratePpm": 9708,
"flagged": true
}
],
"aupReports": [
{
"object": "aup_report",
"orgId": "org_01m5wvkry1e6w94sjxgme33fs5",
"n": 1,
"summary": "A customer reports that the brand sells account credentials.",
"source": "email",
"reporter": "abuse-desk@example.org",
"status": "open",
"reportedAt": "2026-11-02T16:40:00.000Z",
"recordedBy": "usr_01m5wvkry1e6w94sjxgme33fs8",
"resolvedAt": null,
"resolvedBy": null,
"resolution": null,
"org": {
"id": "org_01m5wvkry1e6w94sjxgme33fs5",
"slug": "acme",
"name": "Acme"
}
}
]
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A threshold is out of range. | Fix the fields listed in details.issues and send the request again. |
permission_denied | 403 | You aren't platform staff with read access to the platform console. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, resource_not_found, dry_run_not_supported, rate_limited, internal_error.