Update the risk settings
The risk.settings.update operation: PATCH /api/v1/risk/settings in the REST API and the risk_settings_update tool in the MCP server.
/api/v1/risk/settingsChanges the brand's risk rules in the mode of the request. Give only what changes: any group
(newCustomer, velocity, points, thresholds, disposableEmail, wallet) and, within it, any field;
the rest keeps its value (the defaults until the first change). Per-currency amounts (firstTopupMax.amounts,
wallet.usageCap, integer micros as strings) and velocity.emailDomain.exemptDomains are replaced as a whole.
Each rule's action is block (the payment is refused before it reaches the card), review (it goes through,
and waits in the review queue with the customer's wallet frozen) or require_3ds (the bank authenticates the
customer). Thresholds must rise: threeDSecure ≤ review ≤ block (null: no score blocks). Windows are 1–168
hours. A usage cap for fresh balances (wallet.usageCapUntilAgeHours, 1–720, with wallet.usageCap) limits
how much of the credits bought in that time can be reserved or spent; null turns it off.
Pass expectedVersion to refuse the change if someone else changed the settings meanwhile. Test and live mode
have their own settings. Needs brands:write (owners and admins).
At a glance
- REST:
PATCH /api/v1/risk/settings - MCP tool:
risk_settings_update - Operation ID:
risk.settings.update - Scope: Brand
- Permission:
brands:write - Risk tier:
write - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyoptional - Modes: Test and live
- Authentication: API key with the
brands:writescope - Since: M9
Request
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
newCustomer | object | No | |
newCustomer.ageHours | integer (1 to 8760) | No | |
newCustomer.topups | object | No | |
newCustomer.topups.enabled | boolean | No | |
newCustomer.topups.limit | integer (1 to 10000) | No | |
newCustomer.topups.windowHours | integer (1 to 168) | No | |
newCustomer.topups.action | one of block, review, require_3ds | No | |
newCustomer.firstTopupMax | object | No | |
newCustomer.firstTopupMax.enabled | boolean | No | |
newCustomer.firstTopupMax.amounts | object | No | |
newCustomer.firstTopupMax.action | one of block, review, require_3ds | No | |
newCustomer.threeDSecureFirstPayment | boolean | No | |
velocity | object | No | |
velocity.ipNetwork | object | No | |
velocity.ipNetwork.enabled | boolean | No | |
velocity.ipNetwork.limit | integer (1 to 10000) | No | |
velocity.ipNetwork.windowHours | integer (1 to 168) | No | |
velocity.ipNetwork.action | one of block, review, require_3ds | No | |
velocity.ipNetwork.cardLimit | integer (1 to 10000) | No | |
velocity.cardFingerprint | object | No | |
velocity.cardFingerprint.enabled | boolean | No | |
velocity.cardFingerprint.limit | integer (1 to 10000) | No | |
velocity.cardFingerprint.windowHours | integer (1 to 168) | No | |
velocity.cardFingerprint.action | one of block, review, require_3ds | No | |
velocity.emailDomain | object | No | |
velocity.emailDomain.enabled | boolean | No | |
velocity.emailDomain.limit | integer (1 to 10000) | No | |
velocity.emailDomain.windowHours | integer (1 to 168) | No | |
velocity.emailDomain.action | one of block, review, require_3ds | No | |
velocity.emailDomain.exemptDomains | array of string | No | |
points | object | No | |
points.ipBillingMismatch | integer (0 to 100) | No | |
points.cardBillingMismatch | integer (0 to 100) | No | |
points.ipCardMismatch | integer (0 to 100) | No | |
points.elevatedCustomer | integer (0 to 100) | No | |
points.newCustomer | integer (0 to 100) | No | |
thresholds | object | No | |
thresholds.threeDSecure | integer (1 to 1000) | No | |
thresholds.review | integer (1 to 1000) | No | |
thresholds.block | integer (1 to 1000) or null | No | |
disposableEmail | object | No | |
disposableEmail.enabled | boolean | No | |
disposableEmail.action | one of block, review, require_3ds | No | |
wallet | object | No | |
wallet.usageCapUntilAgeHours | integer (1 to 720) or null | No | |
wallet.usageCap | object | No | |
expectedVersion | integer (at least 0) | No |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
object | "risk_settings" | |
brandId | brd_… ID | |
livemode | boolean | |
isDefault | boolean | |
version | integer (at least 0) | |
updatedAt | date-time or null | |
newCustomer | object | |
newCustomer.ageHours | integer | |
newCustomer.topups | object | |
newCustomer.topups.enabled | boolean | |
newCustomer.topups.limit | integer | |
newCustomer.topups.windowHours | integer | |
newCustomer.topups.action | one of block, review, require_3ds | |
newCustomer.firstTopupMax | object | |
newCustomer.firstTopupMax.enabled | boolean | |
newCustomer.firstTopupMax.amounts | object | |
newCustomer.firstTopupMax.action | one of block, review, require_3ds | |
newCustomer.threeDSecureFirstPayment | boolean | |
velocity | object | |
velocity.ipNetwork | object | |
velocity.ipNetwork.enabled | boolean | |
velocity.ipNetwork.limit | integer | |
velocity.ipNetwork.windowHours | integer | |
velocity.ipNetwork.action | one of block, review, require_3ds | |
velocity.ipNetwork.cardLimit | integer | |
velocity.cardFingerprint | object | |
velocity.cardFingerprint.enabled | boolean | |
velocity.cardFingerprint.limit | integer | |
velocity.cardFingerprint.windowHours | integer | |
velocity.cardFingerprint.action | one of block, review, require_3ds | |
velocity.emailDomain | object | |
velocity.emailDomain.enabled | boolean | |
velocity.emailDomain.limit | integer | |
velocity.emailDomain.windowHours | integer | |
velocity.emailDomain.action | one of block, review, require_3ds | |
velocity.emailDomain.exemptDomains | array of string | |
points | object | |
points.ipBillingMismatch | integer | |
points.cardBillingMismatch | integer | |
points.ipCardMismatch | integer | |
points.elevatedCustomer | integer | |
points.newCustomer | integer | |
thresholds | object | |
thresholds.threeDSecure | integer | |
thresholds.review | integer | |
thresholds.block | integer or null | |
disposableEmail | object | |
disposableEmail.enabled | boolean | |
disposableEmail.action | one of block, review, require_3ds | |
wallet | object | |
wallet.usageCapUntilAgeHours | integer or null | |
wallet.usageCap | object |
Examples
Hold riskier payments sooner and cap fresh balances
PATCH /api/v1/risk/settings
Authorization: Bearer or_test_…
Content-Type: application/json
{
"thresholds": {
"review": 60
},
"wallet": {
"usageCapUntilAgeHours": 24,
"usageCap": {
"EUR": "20000000"
}
},
"expectedVersion": 0
}
Response (200):
{
"object": "risk_settings",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"livemode": true,
"isDefault": false,
"version": 1,
"updatedAt": "2026-10-20T09:00:00.000Z",
"newCustomer": {
"ageHours": 168,
"topups": {
"enabled": true,
"limit": 2,
"windowHours": 24,
"action": "block"
},
"firstTopupMax": {
"enabled": true,
"amounts": {
"CHF": "100000000",
"EUR": "100000000",
"GBP": "100000000",
"USD": "100000000"
},
"action": "block"
},
"threeDSecureFirstPayment": true
},
"velocity": {
"ipNetwork": {
"enabled": true,
"limit": 10,
"windowHours": 1,
"action": "block",
"cardLimit": 3
},
"cardFingerprint": {
"enabled": true,
"limit": 5,
"windowHours": 24,
"action": "block"
},
"emailDomain": {
"enabled": true,
"limit": 10,
"windowHours": 1,
"action": "block",
"exemptDomains": [
"aol.com",
"gmail.com",
"gmx.at",
"gmx.de",
"gmx.net",
"googlemail.com",
"hotmail.com",
"icloud.com",
"live.com",
"mail.com",
"me.com",
"msn.com",
"outlook.com",
"proton.me",
"protonmail.com",
"t-online.de",
"web.de",
"yahoo.com",
"yandex.com"
]
}
},
"points": {
"ipBillingMismatch": 20,
"cardBillingMismatch": 25,
"ipCardMismatch": 15,
"elevatedCustomer": 40,
"newCustomer": 10
},
"thresholds": {
"threeDSecure": 20,
"review": 60,
"block": null
},
"disposableEmail": {
"enabled": true,
"action": "block"
},
"wallet": {
"usageCapUntilAgeHours": 24,
"usageCap": {
"EUR": "20000000"
}
}
}
Try the velocity rules in test mode
PATCH /api/v1/risk/settings
Authorization: Bearer or_test_…
Content-Type: application/json
{
"velocity": {
"ipNetwork": {
"enabled": true
},
"cardFingerprint": {
"enabled": true
},
"emailDomain": {
"enabled": true
}
}
}
Response (200):
{
"object": "risk_settings",
"brandId": "brd_01m4ttwd3veh9apbewxheq5xh5",
"livemode": false,
"isDefault": false,
"version": 1,
"updatedAt": "2026-10-20T09:00:00.000Z",
"newCustomer": {
"ageHours": 168,
"topups": {
"enabled": false,
"limit": 2,
"windowHours": 24,
"action": "block"
},
"firstTopupMax": {
"enabled": false,
"amounts": {
"CHF": "100000000",
"EUR": "100000000",
"GBP": "100000000",
"USD": "100000000"
},
"action": "block"
},
"threeDSecureFirstPayment": true
},
"velocity": {
"ipNetwork": {
"enabled": true,
"limit": 10,
"windowHours": 1,
"action": "block",
"cardLimit": 3
},
"cardFingerprint": {
"enabled": true,
"limit": 5,
"windowHours": 24,
"action": "block"
},
"emailDomain": {
"enabled": true,
"limit": 10,
"windowHours": 1,
"action": "block",
"exemptDomains": [
"aol.com",
"gmail.com",
"gmx.at",
"gmx.de",
"gmx.net",
"googlemail.com",
"hotmail.com",
"icloud.com",
"live.com",
"mail.com",
"me.com",
"msn.com",
"outlook.com",
"proton.me",
"protonmail.com",
"t-online.de",
"web.de",
"yahoo.com",
"yandex.com"
]
}
},
"points": {
"ipBillingMismatch": 20,
"cardBillingMismatch": 25,
"ipCardMismatch": 15,
"elevatedCustomer": 40,
"newCustomer": 10
},
"thresholds": {
"threeDSecure": 20,
"review": 75,
"block": null
},
"disposableEmail": {
"enabled": true,
"action": "block"
},
"wallet": {
"usageCapUntilAgeHours": null,
"usageCap": {}
}
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
validation_failed | 400 | A value is out of range, a currency is unknown, or the thresholds don't rise. | Fix the fields listed in details.issues and send the request again. |
version_conflict | 409 | The settings changed since expectedVersion, or at the same moment. | Fetch the object again and retry the change. |
permission_denied | 403 | You can't change this brand's settings. | 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, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, scope_required, resource_not_found, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.