diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 8f3e0a4..b4e9013 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.15.0"
+ ".": "0.16.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index cce5f55..73ca5fa 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 27
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude/prelude-33b70f86404b99046db5c61d3142b149dd7dec7eefe5e62ff3b397c7274aa5dc.yml
-openapi_spec_hash: fb72aba38ec55a3b6b5162c9f5b4228d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude/prelude-fdbaf5386743020c305990b67afae97f62c69478baafc39c3efbd296cb62770c.yml
+openapi_spec_hash: 14d5b04b5dfa004a9cb0b1317e928abe
config_hash: 707d65d2f456a2b5ba5b2c565b60128a
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8317f99..235aa30 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.16.0 (2026-09-18)
+
+Full Changelog: [v0.15.0...v0.16.0](https://github.com/prelude-so/java-sdk/compare/v0.15.0...v0.16.0)
+
+### Features
+
+* **api:** api update ([9425a63](https://github.com/prelude-so/java-sdk/commit/9425a6319edcfcf7476b5be0b448663cbf653e6e))
+
## 0.15.0 (2026-09-18)
Full Changelog: [v0.14.0...v0.15.0](https://github.com/prelude-so/java-sdk/compare/v0.14.0...v0.15.0)
diff --git a/README.md b/README.md
index b560586..7250b50 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/so.prelude.sdk/prelude-java/0.15.0)
-[](https://javadoc.io/doc/so.prelude.sdk/prelude-java/0.15.0)
+[](https://central.sonatype.com/artifact/so.prelude.sdk/prelude-java/0.16.0)
+[](https://javadoc.io/doc/so.prelude.sdk/prelude-java/0.16.0)
@@ -13,7 +13,7 @@ It is generated with [Stainless](https://www.stainless.com/).
-The REST API documentation can be found on [docs.prelude.so](https://docs.prelude.so). Javadocs are available on [javadoc.io](https://javadoc.io/doc/so.prelude.sdk/prelude-java/0.15.0).
+The REST API documentation can be found on [docs.prelude.so](https://docs.prelude.so). Javadocs are available on [javadoc.io](https://javadoc.io/doc/so.prelude.sdk/prelude-java/0.16.0).
@@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.prelude.so](https://docs.prelud
### Gradle
```kotlin
-implementation("so.prelude.sdk:prelude-java:0.15.0")
+implementation("so.prelude.sdk:prelude-java:0.16.0")
```
### Maven
@@ -33,7 +33,7 @@ implementation("so.prelude.sdk:prelude-java:0.15.0")
so.prelude.sdk
prelude-java
- 0.15.0
+ 0.16.0
```
diff --git a/build.gradle.kts b/build.gradle.kts
index f2d0c2e..195f753 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "so.prelude.sdk"
- version = "0.15.0" // x-release-please-version
+ version = "0.16.0" // x-release-please-version
}
subprojects {
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationCreateResponse.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationCreateResponse.kt
index 688add6..67e9d22 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationCreateResponse.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationCreateResponse.kt
@@ -120,8 +120,10 @@ private constructor(
* * `invalid_phone_line` - The phone number is not a valid line number (e.g. landline).
* * `invalid_phone_number` - The phone number is not a valid phone number (e.g. unallocated
* range).
- * * `invalid_signature` - The signature of the SDK signals is invalid.
- * * `repeated_attempts` - The phone number has made too many verification attempts.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be attributed
+ * to the device it claims to come from.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification attempts
+ * in a short period.
* * `suspicious` - The verification attempt was deemed suspicious by the anti-fraud system.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type (e.g. if the
@@ -138,26 +140,37 @@ private constructor(
/**
* The risk factors that contributed to the verification being blocked. Only present when status
* is "blocked" or "shadow_blocked" and the anti-fraud system detected specific risk signals.
- * * `behavioral_pattern` - The phone number past behavior during verification flows exhibits
- * suspicious patterns.
- * * `device_attribute` - The device exhibits characteristics associated with suspicious
- * activity patterns.
- * * `fraud_database` - The phone number has been flagged as suspicious in one or more of our
- * fraud databases.
- * * `location_discrepancy` - The phone number prefix and IP address discrepancy indicates
- * potential fraud.
- * * `network_fingerprint` - The network connection exhibits characteristics associated with
- * suspicious activity patterns.
- * * `poor_conversion_history` - The phone number has a history of poorly converting to a
- * verified phone number.
- * * `prefix_concentration` - The phone number is part of a range known to be associated with
- * suspicious activity patterns.
- * * `suspected_request_tampering` - The SDK signature is invalid and the request is considered
- * to be tampered with.
- * * `suspicious_ip_address` - The IP address is deemed to be associated with suspicious
- * activity patterns.
- * * `temporary_phone_number` - The phone number is known to be a temporary or disposable
- * number.
+ * * `automation_signature` - The request appears to come from an automated client rather than a
+ * person.
+ * * `carrier_not_permitted` - The destination carrier is one this account does not accept
+ * traffic for.
+ * * `client_fingerprint_mismatch` - The client does not appear to be the platform it identifies
+ * itself as.
+ * * `custom_policy` - A rule configured for your account matched this request.
+ * * `device_emulator` - The request appears to come from an emulator rather than a physical
+ * device.
+ * * `device_not_permitted` - The device platform is one your account blocks.
+ * * `device_reuse` - One device is driving verifications for an unusual number of phone
+ * numbers.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
+ * * `fraud_database` - The phone number is flagged in one or more of the fraud databases
+ * Prelude consults.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be attributed
+ * to the device it claims to come from.
+ * * `ip_concentration` - The request shares its origin with an unusual volume of other
+ * verifications.
+ * * `ip_reputation` - The originating IP address is not trusted.
+ * * `location_mismatch` - The network location and the phone number's country are inconsistent.
+ * * `missing_signals` - The verification expected Prelude SDK signals and none arrived.
+ * * `number_range_abuse` - The phone number belongs to a range currently associated with abuse.
+ * * `poor_conversion_history` - Traffic resembling this request rarely completes a
+ * verification.
+ * * `proxy_network` - The request did not arrive over the subscriber's own access network.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification attempts
+ * in a short period.
+ * * `temporary_phone_number` - The phone number belongs to a disposable or short-lived
+ * numbering service.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -383,8 +396,10 @@ private constructor(
* * `invalid_phone_line` - The phone number is not a valid line number (e.g. landline).
* * `invalid_phone_number` - The phone number is not a valid phone number (e.g. unallocated
* range).
- * * `invalid_signature` - The signature of the SDK signals is invalid.
- * * `repeated_attempts` - The phone number has made too many verification attempts.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be
+ * attributed to the device it claims to come from.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification
+ * attempts in a short period.
* * `suspicious` - The verification attempt was deemed suspicious by the anti-fraud system.
*/
fun reason(reason: Reason) = reason(JsonField.of(reason))
@@ -412,26 +427,39 @@ private constructor(
* The risk factors that contributed to the verification being blocked. Only present when
* status is "blocked" or "shadow_blocked" and the anti-fraud system detected specific risk
* signals.
- * * `behavioral_pattern` - The phone number past behavior during verification flows
- * exhibits suspicious patterns.
- * * `device_attribute` - The device exhibits characteristics associated with suspicious
- * activity patterns.
- * * `fraud_database` - The phone number has been flagged as suspicious in one or more of
- * our fraud databases.
- * * `location_discrepancy` - The phone number prefix and IP address discrepancy indicates
- * potential fraud.
- * * `network_fingerprint` - The network connection exhibits characteristics associated with
- * suspicious activity patterns.
- * * `poor_conversion_history` - The phone number has a history of poorly converting to a
- * verified phone number.
- * * `prefix_concentration` - The phone number is part of a range known to be associated
- * with suspicious activity patterns.
- * * `suspected_request_tampering` - The SDK signature is invalid and the request is
- * considered to be tampered with.
- * * `suspicious_ip_address` - The IP address is deemed to be associated with suspicious
- * activity patterns.
- * * `temporary_phone_number` - The phone number is known to be a temporary or disposable
- * number.
+ * * `automation_signature` - The request appears to come from an automated client rather
+ * than a person.
+ * * `carrier_not_permitted` - The destination carrier is one this account does not accept
+ * traffic for.
+ * * `client_fingerprint_mismatch` - The client does not appear to be the platform it
+ * identifies itself as.
+ * * `custom_policy` - A rule configured for your account matched this request.
+ * * `device_emulator` - The request appears to come from an emulator rather than a physical
+ * device.
+ * * `device_not_permitted` - The device platform is one your account blocks.
+ * * `device_reuse` - One device is driving verifications for an unusual number of phone
+ * numbers.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
+ * * `fraud_database` - The phone number is flagged in one or more of the fraud databases
+ * Prelude consults.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be
+ * attributed to the device it claims to come from.
+ * * `ip_concentration` - The request shares its origin with an unusual volume of other
+ * verifications.
+ * * `ip_reputation` - The originating IP address is not trusted.
+ * * `location_mismatch` - The network location and the phone number's country are
+ * inconsistent.
+ * * `missing_signals` - The verification expected Prelude SDK signals and none arrived.
+ * * `number_range_abuse` - The phone number belongs to a range currently associated with
+ * abuse.
+ * * `poor_conversion_history` - Traffic resembling this request rarely completes a
+ * verification.
+ * * `proxy_network` - The request did not arrive over the subscriber's own access network.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification
+ * attempts in a short period.
+ * * `temporary_phone_number` - The phone number belongs to a disposable or short-lived
+ * numbering service.
*/
fun riskFactors(riskFactors: List) = riskFactors(JsonField.of(riskFactors))
@@ -1221,8 +1249,10 @@ private constructor(
* * `invalid_phone_line` - The phone number is not a valid line number (e.g. landline).
* * `invalid_phone_number` - The phone number is not a valid phone number (e.g. unallocated
* range).
- * * `invalid_signature` - The signature of the SDK signals is invalid.
- * * `repeated_attempts` - The phone number has made too many verification attempts.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be attributed
+ * to the device it claims to come from.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification attempts
+ * in a short period.
* * `suspicious` - The verification attempt was deemed suspicious by the anti-fraud system.
*/
class Reason @JsonCreator private constructor(private val value: JsonField) : Enum {
@@ -1403,23 +1433,41 @@ private constructor(
companion object {
- @JvmField val BEHAVIORAL_PATTERN = of("behavioral_pattern")
+ @JvmField val AUTOMATION_SIGNATURE = of("automation_signature")
- @JvmField val DEVICE_ATTRIBUTE = of("device_attribute")
+ @JvmField val CARRIER_NOT_PERMITTED = of("carrier_not_permitted")
+
+ @JvmField val CLIENT_FINGERPRINT_MISMATCH = of("client_fingerprint_mismatch")
+
+ @JvmField val CUSTOM_POLICY = of("custom_policy")
+
+ @JvmField val DEVICE_EMULATOR = of("device_emulator")
+
+ @JvmField val DEVICE_NOT_PERMITTED = of("device_not_permitted")
+
+ @JvmField val DEVICE_REUSE = of("device_reuse")
+
+ @JvmField val EXPIRED_SIGNALS = of("expired_signals")
@JvmField val FRAUD_DATABASE = of("fraud_database")
- @JvmField val LOCATION_DISCREPANCY = of("location_discrepancy")
+ @JvmField val INVALID_SIGNATURE = of("invalid_signature")
- @JvmField val NETWORK_FINGERPRINT = of("network_fingerprint")
+ @JvmField val IP_CONCENTRATION = of("ip_concentration")
- @JvmField val POOR_CONVERSION_HISTORY = of("poor_conversion_history")
+ @JvmField val IP_REPUTATION = of("ip_reputation")
+
+ @JvmField val LOCATION_MISMATCH = of("location_mismatch")
- @JvmField val PREFIX_CONCENTRATION = of("prefix_concentration")
+ @JvmField val MISSING_SIGNALS = of("missing_signals")
- @JvmField val SUSPECTED_REQUEST_TAMPERING = of("suspected_request_tampering")
+ @JvmField val NUMBER_RANGE_ABUSE = of("number_range_abuse")
+
+ @JvmField val POOR_CONVERSION_HISTORY = of("poor_conversion_history")
- @JvmField val SUSPICIOUS_IP_ADDRESS = of("suspicious_ip_address")
+ @JvmField val PROXY_NETWORK = of("proxy_network")
+
+ @JvmField val REPEATED_ATTEMPTS = of("repeated_attempts")
@JvmField val TEMPORARY_PHONE_NUMBER = of("temporary_phone_number")
@@ -1428,15 +1476,24 @@ private constructor(
/** An enum containing [RiskFactor]'s known values. */
enum class Known {
- BEHAVIORAL_PATTERN,
- DEVICE_ATTRIBUTE,
+ AUTOMATION_SIGNATURE,
+ CARRIER_NOT_PERMITTED,
+ CLIENT_FINGERPRINT_MISMATCH,
+ CUSTOM_POLICY,
+ DEVICE_EMULATOR,
+ DEVICE_NOT_PERMITTED,
+ DEVICE_REUSE,
+ EXPIRED_SIGNALS,
FRAUD_DATABASE,
- LOCATION_DISCREPANCY,
- NETWORK_FINGERPRINT,
+ INVALID_SIGNATURE,
+ IP_CONCENTRATION,
+ IP_REPUTATION,
+ LOCATION_MISMATCH,
+ MISSING_SIGNALS,
+ NUMBER_RANGE_ABUSE,
POOR_CONVERSION_HISTORY,
- PREFIX_CONCENTRATION,
- SUSPECTED_REQUEST_TAMPERING,
- SUSPICIOUS_IP_ADDRESS,
+ PROXY_NETWORK,
+ REPEATED_ATTEMPTS,
TEMPORARY_PHONE_NUMBER,
}
@@ -1450,15 +1507,24 @@ private constructor(
* - It was constructed with an arbitrary value using the [of] method.
*/
enum class Value {
- BEHAVIORAL_PATTERN,
- DEVICE_ATTRIBUTE,
+ AUTOMATION_SIGNATURE,
+ CARRIER_NOT_PERMITTED,
+ CLIENT_FINGERPRINT_MISMATCH,
+ CUSTOM_POLICY,
+ DEVICE_EMULATOR,
+ DEVICE_NOT_PERMITTED,
+ DEVICE_REUSE,
+ EXPIRED_SIGNALS,
FRAUD_DATABASE,
- LOCATION_DISCREPANCY,
- NETWORK_FINGERPRINT,
+ INVALID_SIGNATURE,
+ IP_CONCENTRATION,
+ IP_REPUTATION,
+ LOCATION_MISMATCH,
+ MISSING_SIGNALS,
+ NUMBER_RANGE_ABUSE,
POOR_CONVERSION_HISTORY,
- PREFIX_CONCENTRATION,
- SUSPECTED_REQUEST_TAMPERING,
- SUSPICIOUS_IP_ADDRESS,
+ PROXY_NETWORK,
+ REPEATED_ATTEMPTS,
TEMPORARY_PHONE_NUMBER,
/**
* An enum member indicating that [RiskFactor] was instantiated with an unknown value.
@@ -1475,15 +1541,24 @@ private constructor(
*/
fun value(): Value =
when (this) {
- BEHAVIORAL_PATTERN -> Value.BEHAVIORAL_PATTERN
- DEVICE_ATTRIBUTE -> Value.DEVICE_ATTRIBUTE
+ AUTOMATION_SIGNATURE -> Value.AUTOMATION_SIGNATURE
+ CARRIER_NOT_PERMITTED -> Value.CARRIER_NOT_PERMITTED
+ CLIENT_FINGERPRINT_MISMATCH -> Value.CLIENT_FINGERPRINT_MISMATCH
+ CUSTOM_POLICY -> Value.CUSTOM_POLICY
+ DEVICE_EMULATOR -> Value.DEVICE_EMULATOR
+ DEVICE_NOT_PERMITTED -> Value.DEVICE_NOT_PERMITTED
+ DEVICE_REUSE -> Value.DEVICE_REUSE
+ EXPIRED_SIGNALS -> Value.EXPIRED_SIGNALS
FRAUD_DATABASE -> Value.FRAUD_DATABASE
- LOCATION_DISCREPANCY -> Value.LOCATION_DISCREPANCY
- NETWORK_FINGERPRINT -> Value.NETWORK_FINGERPRINT
+ INVALID_SIGNATURE -> Value.INVALID_SIGNATURE
+ IP_CONCENTRATION -> Value.IP_CONCENTRATION
+ IP_REPUTATION -> Value.IP_REPUTATION
+ LOCATION_MISMATCH -> Value.LOCATION_MISMATCH
+ MISSING_SIGNALS -> Value.MISSING_SIGNALS
+ NUMBER_RANGE_ABUSE -> Value.NUMBER_RANGE_ABUSE
POOR_CONVERSION_HISTORY -> Value.POOR_CONVERSION_HISTORY
- PREFIX_CONCENTRATION -> Value.PREFIX_CONCENTRATION
- SUSPECTED_REQUEST_TAMPERING -> Value.SUSPECTED_REQUEST_TAMPERING
- SUSPICIOUS_IP_ADDRESS -> Value.SUSPICIOUS_IP_ADDRESS
+ PROXY_NETWORK -> Value.PROXY_NETWORK
+ REPEATED_ATTEMPTS -> Value.REPEATED_ATTEMPTS
TEMPORARY_PHONE_NUMBER -> Value.TEMPORARY_PHONE_NUMBER
else -> Value._UNKNOWN
}
@@ -1499,15 +1574,24 @@ private constructor(
*/
fun known(): Known =
when (this) {
- BEHAVIORAL_PATTERN -> Known.BEHAVIORAL_PATTERN
- DEVICE_ATTRIBUTE -> Known.DEVICE_ATTRIBUTE
+ AUTOMATION_SIGNATURE -> Known.AUTOMATION_SIGNATURE
+ CARRIER_NOT_PERMITTED -> Known.CARRIER_NOT_PERMITTED
+ CLIENT_FINGERPRINT_MISMATCH -> Known.CLIENT_FINGERPRINT_MISMATCH
+ CUSTOM_POLICY -> Known.CUSTOM_POLICY
+ DEVICE_EMULATOR -> Known.DEVICE_EMULATOR
+ DEVICE_NOT_PERMITTED -> Known.DEVICE_NOT_PERMITTED
+ DEVICE_REUSE -> Known.DEVICE_REUSE
+ EXPIRED_SIGNALS -> Known.EXPIRED_SIGNALS
FRAUD_DATABASE -> Known.FRAUD_DATABASE
- LOCATION_DISCREPANCY -> Known.LOCATION_DISCREPANCY
- NETWORK_FINGERPRINT -> Known.NETWORK_FINGERPRINT
+ INVALID_SIGNATURE -> Known.INVALID_SIGNATURE
+ IP_CONCENTRATION -> Known.IP_CONCENTRATION
+ IP_REPUTATION -> Known.IP_REPUTATION
+ LOCATION_MISMATCH -> Known.LOCATION_MISMATCH
+ MISSING_SIGNALS -> Known.MISSING_SIGNALS
+ NUMBER_RANGE_ABUSE -> Known.NUMBER_RANGE_ABUSE
POOR_CONVERSION_HISTORY -> Known.POOR_CONVERSION_HISTORY
- PREFIX_CONCENTRATION -> Known.PREFIX_CONCENTRATION
- SUSPECTED_REQUEST_TAMPERING -> Known.SUSPECTED_REQUEST_TAMPERING
- SUSPICIOUS_IP_ADDRESS -> Known.SUSPICIOUS_IP_ADDRESS
+ PROXY_NETWORK -> Known.PROXY_NETWORK
+ REPEATED_ATTEMPTS -> Known.REPEATED_ATTEMPTS
TEMPORARY_PHONE_NUMBER -> Known.TEMPORARY_PHONE_NUMBER
else -> throw PreludeInvalidDataException("Unknown RiskFactor: $value")
}
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryListResponse.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryListResponse.kt
index e6f808d..48783ef 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryListResponse.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryListResponse.kt
@@ -353,7 +353,8 @@ private constructor(
* * `invalid_line` - The phone number is not a valid line type.
* * `invalid_number` - The phone number is not a valid number.
* * `rate_limited` - The verification was refused by a rate limit.
- * * `expired_signals` - The SDK signals were collected too long before the request.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
* * `shadowed` - The anti-fraud system flagged the verification without blocking it.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type or is
@@ -671,7 +672,8 @@ private constructor(
* * `invalid_line` - The phone number is not a valid line type.
* * `invalid_number` - The phone number is not a valid number.
* * `rate_limited` - The verification was refused by a rate limit.
- * * `expired_signals` - The SDK signals were collected too long before the request.
+ * * `expired_signals` - The SDK signals were collected too long before the request to
+ * still attest to it.
* * `shadowed` - The anti-fraud system flagged the verification without blocking it.
*/
fun status(status: Status) = status(JsonField.of(status))
@@ -1303,7 +1305,8 @@ private constructor(
* * `invalid_line` - The phone number is not a valid line type.
* * `invalid_number` - The phone number is not a valid number.
* * `rate_limited` - The verification was refused by a rate limit.
- * * `expired_signals` - The SDK signals were collected too long before the request.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
* * `shadowed` - The anti-fraud system flagged the verification without blocking it.
*/
class Status @JsonCreator private constructor(private val value: JsonField) : Enum {
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponse.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponse.kt
index e40b360..977c872 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponse.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponse.kt
@@ -171,7 +171,8 @@ private constructor(
* * `invalid_line` - The phone number is not a valid line type.
* * `invalid_number` - The phone number is not a valid number.
* * `rate_limited` - The verification was refused by a rate limit.
- * * `expired_signals` - The SDK signals were collected too long before the request.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
* * `shadowed` - The anti-fraud system flagged the verification without blocking it.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type or is
@@ -188,26 +189,39 @@ private constructor(
fun appVersion(): Optional = appVersion.getOptional("app_version")
/**
- * Why the anti-fraud system blocked the verification. Empty unless it did.
- * * `behavioral_pattern` - The phone number past behavior during verification flows exhibits
- * suspicious patterns.
- * * `device_attribute` - The end-user device reported attributes associated with fraud or
- * emulation.
- * * `fraud_database` - The phone number appears in a fraud database.
- * * `location_discrepancy` - The phone number region and the observed location disagree.
+ * Why the anti-fraud system blocked the verification. Empty unless it did. These are the same
+ * labels the Verify and Watch APIs serve as `risk_factors`.
+ * * `automation_signature` - The request appears to come from an automated client rather than a
+ * person.
+ * * `carrier_not_permitted` - The destination carrier is one this account does not accept
+ * traffic for.
+ * * `client_fingerprint_mismatch` - The client does not appear to be the platform it identifies
+ * itself as.
+ * * `custom_policy` - A rule configured for your account matched this request.
+ * * `device_emulator` - The request appears to come from an emulator rather than a physical
+ * device.
+ * * `device_not_permitted` - The device platform is one your account blocks.
+ * * `device_reuse` - One device is driving verifications for an unusual number of phone
+ * numbers.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
+ * * `fraud_database` - The phone number is flagged in one or more of the fraud databases
+ * Prelude consults.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be attributed
+ * to the device it claims to come from.
+ * * `ip_concentration` - The request shares its origin with an unusual volume of other
+ * verifications.
+ * * `ip_reputation` - The originating IP address is not trusted.
+ * * `location_mismatch` - The network location and the phone number's country are inconsistent.
* * `missing_signals` - The verification expected Prelude SDK signals and none arrived.
- * * `network_fingerprint` - The network fingerprint matches known fraudulent traffic.
- * * `poor_conversion_history` - The phone number rarely completes the verifications it starts.
- * * `prefix_concentration` - The phone number is part of a range known to be associated with
- * suspicious activity patterns.
- * * `repeated_number` - The phone number was used far more often than normal traffic would
- * explain.
- * * `suspected_request_tampering` - The SDK signals were altered or expired between collection
- * and use.
- * * `suspicious_ip_address` - The originating IP address is associated with suspicious
- * activity.
- * * `temporary_phone_number` - The phone number is known to be a temporary or disposable
- * number.
+ * * `number_range_abuse` - The phone number belongs to a range currently associated with abuse.
+ * * `poor_conversion_history` - Traffic resembling this request rarely completes a
+ * verification.
+ * * `proxy_network` - The request did not arrive over the subscriber's own access network.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification attempts
+ * in a short period.
+ * * `temporary_phone_number` - The phone number belongs to a disposable or short-lived
+ * numbering service.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -657,7 +671,8 @@ private constructor(
* * `invalid_line` - The phone number is not a valid line type.
* * `invalid_number` - The phone number is not a valid number.
* * `rate_limited` - The verification was refused by a rate limit.
- * * `expired_signals` - The SDK signals were collected too long before the request.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
* * `shadowed` - The anti-fraud system flagged the verification without blocking it.
*/
fun status(status: Status) = status(JsonField.of(status))
@@ -683,27 +698,41 @@ private constructor(
fun appVersion(appVersion: JsonField) = apply { this.appVersion = appVersion }
/**
- * Why the anti-fraud system blocked the verification. Empty unless it did.
- * * `behavioral_pattern` - The phone number past behavior during verification flows
- * exhibits suspicious patterns.
- * * `device_attribute` - The end-user device reported attributes associated with fraud or
- * emulation.
- * * `fraud_database` - The phone number appears in a fraud database.
- * * `location_discrepancy` - The phone number region and the observed location disagree.
+ * Why the anti-fraud system blocked the verification. Empty unless it did. These are the
+ * same labels the Verify and Watch APIs serve as `risk_factors`.
+ * * `automation_signature` - The request appears to come from an automated client rather
+ * than a person.
+ * * `carrier_not_permitted` - The destination carrier is one this account does not accept
+ * traffic for.
+ * * `client_fingerprint_mismatch` - The client does not appear to be the platform it
+ * identifies itself as.
+ * * `custom_policy` - A rule configured for your account matched this request.
+ * * `device_emulator` - The request appears to come from an emulator rather than a physical
+ * device.
+ * * `device_not_permitted` - The device platform is one your account blocks.
+ * * `device_reuse` - One device is driving verifications for an unusual number of phone
+ * numbers.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
+ * * `fraud_database` - The phone number is flagged in one or more of the fraud databases
+ * Prelude consults.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be
+ * attributed to the device it claims to come from.
+ * * `ip_concentration` - The request shares its origin with an unusual volume of other
+ * verifications.
+ * * `ip_reputation` - The originating IP address is not trusted.
+ * * `location_mismatch` - The network location and the phone number's country are
+ * inconsistent.
* * `missing_signals` - The verification expected Prelude SDK signals and none arrived.
- * * `network_fingerprint` - The network fingerprint matches known fraudulent traffic.
- * * `poor_conversion_history` - The phone number rarely completes the verifications it
- * starts.
- * * `prefix_concentration` - The phone number is part of a range known to be associated
- * with suspicious activity patterns.
- * * `repeated_number` - The phone number was used far more often than normal traffic would
- * explain.
- * * `suspected_request_tampering` - The SDK signals were altered or expired between
- * collection and use.
- * * `suspicious_ip_address` - The originating IP address is associated with suspicious
- * activity.
- * * `temporary_phone_number` - The phone number is known to be a temporary or disposable
- * number.
+ * * `number_range_abuse` - The phone number belongs to a range currently associated with
+ * abuse.
+ * * `poor_conversion_history` - Traffic resembling this request rarely completes a
+ * verification.
+ * * `proxy_network` - The request did not arrive over the subscriber's own access network.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification
+ * attempts in a short period.
+ * * `temporary_phone_number` - The phone number belongs to a disposable or short-lived
+ * numbering service.
*/
fun blockReasons(blockReasons: List) = blockReasons(JsonField.of(blockReasons))
@@ -1077,7 +1106,8 @@ private constructor(
* * `invalid_line` - The phone number is not a valid line type.
* * `invalid_number` - The phone number is not a valid number.
* * `rate_limited` - The verification was refused by a rate limit.
- * * `expired_signals` - The SDK signals were collected too long before the request.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
* * `shadowed` - The anti-fraud system flagged the verification without blocking it.
*/
class Status @JsonCreator private constructor(private val value: JsonField) : Enum {
@@ -1289,27 +1319,41 @@ private constructor(
companion object {
- @JvmField val BEHAVIORAL_PATTERN = of("behavioral_pattern")
+ @JvmField val AUTOMATION_SIGNATURE = of("automation_signature")
- @JvmField val DEVICE_ATTRIBUTE = of("device_attribute")
+ @JvmField val CARRIER_NOT_PERMITTED = of("carrier_not_permitted")
+
+ @JvmField val CLIENT_FINGERPRINT_MISMATCH = of("client_fingerprint_mismatch")
+
+ @JvmField val CUSTOM_POLICY = of("custom_policy")
+
+ @JvmField val DEVICE_EMULATOR = of("device_emulator")
+
+ @JvmField val DEVICE_NOT_PERMITTED = of("device_not_permitted")
+
+ @JvmField val DEVICE_REUSE = of("device_reuse")
+
+ @JvmField val EXPIRED_SIGNALS = of("expired_signals")
@JvmField val FRAUD_DATABASE = of("fraud_database")
- @JvmField val LOCATION_DISCREPANCY = of("location_discrepancy")
+ @JvmField val INVALID_SIGNATURE = of("invalid_signature")
- @JvmField val MISSING_SIGNALS = of("missing_signals")
+ @JvmField val IP_CONCENTRATION = of("ip_concentration")
- @JvmField val NETWORK_FINGERPRINT = of("network_fingerprint")
+ @JvmField val IP_REPUTATION = of("ip_reputation")
- @JvmField val POOR_CONVERSION_HISTORY = of("poor_conversion_history")
+ @JvmField val LOCATION_MISMATCH = of("location_mismatch")
+
+ @JvmField val MISSING_SIGNALS = of("missing_signals")
- @JvmField val PREFIX_CONCENTRATION = of("prefix_concentration")
+ @JvmField val NUMBER_RANGE_ABUSE = of("number_range_abuse")
- @JvmField val REPEATED_NUMBER = of("repeated_number")
+ @JvmField val POOR_CONVERSION_HISTORY = of("poor_conversion_history")
- @JvmField val SUSPECTED_REQUEST_TAMPERING = of("suspected_request_tampering")
+ @JvmField val PROXY_NETWORK = of("proxy_network")
- @JvmField val SUSPICIOUS_IP_ADDRESS = of("suspicious_ip_address")
+ @JvmField val REPEATED_ATTEMPTS = of("repeated_attempts")
@JvmField val TEMPORARY_PHONE_NUMBER = of("temporary_phone_number")
@@ -1318,17 +1362,24 @@ private constructor(
/** An enum containing [BlockReason]'s known values. */
enum class Known {
- BEHAVIORAL_PATTERN,
- DEVICE_ATTRIBUTE,
+ AUTOMATION_SIGNATURE,
+ CARRIER_NOT_PERMITTED,
+ CLIENT_FINGERPRINT_MISMATCH,
+ CUSTOM_POLICY,
+ DEVICE_EMULATOR,
+ DEVICE_NOT_PERMITTED,
+ DEVICE_REUSE,
+ EXPIRED_SIGNALS,
FRAUD_DATABASE,
- LOCATION_DISCREPANCY,
+ INVALID_SIGNATURE,
+ IP_CONCENTRATION,
+ IP_REPUTATION,
+ LOCATION_MISMATCH,
MISSING_SIGNALS,
- NETWORK_FINGERPRINT,
+ NUMBER_RANGE_ABUSE,
POOR_CONVERSION_HISTORY,
- PREFIX_CONCENTRATION,
- REPEATED_NUMBER,
- SUSPECTED_REQUEST_TAMPERING,
- SUSPICIOUS_IP_ADDRESS,
+ PROXY_NETWORK,
+ REPEATED_ATTEMPTS,
TEMPORARY_PHONE_NUMBER,
}
@@ -1342,17 +1393,24 @@ private constructor(
* - It was constructed with an arbitrary value using the [of] method.
*/
enum class Value {
- BEHAVIORAL_PATTERN,
- DEVICE_ATTRIBUTE,
+ AUTOMATION_SIGNATURE,
+ CARRIER_NOT_PERMITTED,
+ CLIENT_FINGERPRINT_MISMATCH,
+ CUSTOM_POLICY,
+ DEVICE_EMULATOR,
+ DEVICE_NOT_PERMITTED,
+ DEVICE_REUSE,
+ EXPIRED_SIGNALS,
FRAUD_DATABASE,
- LOCATION_DISCREPANCY,
+ INVALID_SIGNATURE,
+ IP_CONCENTRATION,
+ IP_REPUTATION,
+ LOCATION_MISMATCH,
MISSING_SIGNALS,
- NETWORK_FINGERPRINT,
+ NUMBER_RANGE_ABUSE,
POOR_CONVERSION_HISTORY,
- PREFIX_CONCENTRATION,
- REPEATED_NUMBER,
- SUSPECTED_REQUEST_TAMPERING,
- SUSPICIOUS_IP_ADDRESS,
+ PROXY_NETWORK,
+ REPEATED_ATTEMPTS,
TEMPORARY_PHONE_NUMBER,
/**
* An enum member indicating that [BlockReason] was instantiated with an unknown value.
@@ -1369,17 +1427,24 @@ private constructor(
*/
fun value(): Value =
when (this) {
- BEHAVIORAL_PATTERN -> Value.BEHAVIORAL_PATTERN
- DEVICE_ATTRIBUTE -> Value.DEVICE_ATTRIBUTE
+ AUTOMATION_SIGNATURE -> Value.AUTOMATION_SIGNATURE
+ CARRIER_NOT_PERMITTED -> Value.CARRIER_NOT_PERMITTED
+ CLIENT_FINGERPRINT_MISMATCH -> Value.CLIENT_FINGERPRINT_MISMATCH
+ CUSTOM_POLICY -> Value.CUSTOM_POLICY
+ DEVICE_EMULATOR -> Value.DEVICE_EMULATOR
+ DEVICE_NOT_PERMITTED -> Value.DEVICE_NOT_PERMITTED
+ DEVICE_REUSE -> Value.DEVICE_REUSE
+ EXPIRED_SIGNALS -> Value.EXPIRED_SIGNALS
FRAUD_DATABASE -> Value.FRAUD_DATABASE
- LOCATION_DISCREPANCY -> Value.LOCATION_DISCREPANCY
+ INVALID_SIGNATURE -> Value.INVALID_SIGNATURE
+ IP_CONCENTRATION -> Value.IP_CONCENTRATION
+ IP_REPUTATION -> Value.IP_REPUTATION
+ LOCATION_MISMATCH -> Value.LOCATION_MISMATCH
MISSING_SIGNALS -> Value.MISSING_SIGNALS
- NETWORK_FINGERPRINT -> Value.NETWORK_FINGERPRINT
+ NUMBER_RANGE_ABUSE -> Value.NUMBER_RANGE_ABUSE
POOR_CONVERSION_HISTORY -> Value.POOR_CONVERSION_HISTORY
- PREFIX_CONCENTRATION -> Value.PREFIX_CONCENTRATION
- REPEATED_NUMBER -> Value.REPEATED_NUMBER
- SUSPECTED_REQUEST_TAMPERING -> Value.SUSPECTED_REQUEST_TAMPERING
- SUSPICIOUS_IP_ADDRESS -> Value.SUSPICIOUS_IP_ADDRESS
+ PROXY_NETWORK -> Value.PROXY_NETWORK
+ REPEATED_ATTEMPTS -> Value.REPEATED_ATTEMPTS
TEMPORARY_PHONE_NUMBER -> Value.TEMPORARY_PHONE_NUMBER
else -> Value._UNKNOWN
}
@@ -1395,17 +1460,24 @@ private constructor(
*/
fun known(): Known =
when (this) {
- BEHAVIORAL_PATTERN -> Known.BEHAVIORAL_PATTERN
- DEVICE_ATTRIBUTE -> Known.DEVICE_ATTRIBUTE
+ AUTOMATION_SIGNATURE -> Known.AUTOMATION_SIGNATURE
+ CARRIER_NOT_PERMITTED -> Known.CARRIER_NOT_PERMITTED
+ CLIENT_FINGERPRINT_MISMATCH -> Known.CLIENT_FINGERPRINT_MISMATCH
+ CUSTOM_POLICY -> Known.CUSTOM_POLICY
+ DEVICE_EMULATOR -> Known.DEVICE_EMULATOR
+ DEVICE_NOT_PERMITTED -> Known.DEVICE_NOT_PERMITTED
+ DEVICE_REUSE -> Known.DEVICE_REUSE
+ EXPIRED_SIGNALS -> Known.EXPIRED_SIGNALS
FRAUD_DATABASE -> Known.FRAUD_DATABASE
- LOCATION_DISCREPANCY -> Known.LOCATION_DISCREPANCY
+ INVALID_SIGNATURE -> Known.INVALID_SIGNATURE
+ IP_CONCENTRATION -> Known.IP_CONCENTRATION
+ IP_REPUTATION -> Known.IP_REPUTATION
+ LOCATION_MISMATCH -> Known.LOCATION_MISMATCH
MISSING_SIGNALS -> Known.MISSING_SIGNALS
- NETWORK_FINGERPRINT -> Known.NETWORK_FINGERPRINT
+ NUMBER_RANGE_ABUSE -> Known.NUMBER_RANGE_ABUSE
POOR_CONVERSION_HISTORY -> Known.POOR_CONVERSION_HISTORY
- PREFIX_CONCENTRATION -> Known.PREFIX_CONCENTRATION
- REPEATED_NUMBER -> Known.REPEATED_NUMBER
- SUSPECTED_REQUEST_TAMPERING -> Known.SUSPECTED_REQUEST_TAMPERING
- SUSPICIOUS_IP_ADDRESS -> Known.SUSPICIOUS_IP_ADDRESS
+ PROXY_NETWORK -> Known.PROXY_NETWORK
+ REPEATED_ATTEMPTS -> Known.REPEATED_ATTEMPTS
TEMPORARY_PHONE_NUMBER -> Known.TEMPORARY_PHONE_NUMBER
else -> throw PreludeInvalidDataException("Unknown BlockReason: $value")
}
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateParams.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateParams.kt
index b6cbb0a..1e80496 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateParams.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateParams.kt
@@ -22,8 +22,9 @@ import so.prelude.sdk.core.toImmutable
import so.prelude.sdk.errors.PreludeInvalidDataException
/**
- * **Beta.** The request and response shapes may still change, and flows and recipes are configured
- * by Prelude on your behalf for now. Talk to us before you build against it.
+ * **Beta.** The request and response shapes may still change. Talk to us before you build against
+ * it. Flows, recipes and rules are authored through the Watch Management API, or configured by
+ * Prelude on your behalf.
*
* Score a target against the rules configured for one moment in your product — signup, checkout,
* password reset. The flow selects which recipes run; each recipe scores its rules against a
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateResponse.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateResponse.kt
index b1f9e16..da6fa35 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateResponse.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchEvaluateResponse.kt
@@ -519,7 +519,9 @@ private constructor(
/**
* One result per rule in the recipe, in membership order. Every rule runs — a score is only
- * meaningful when complete, so there is no short-circuit on the first trigger.
+ * meaningful when complete, so there is no short-circuit on the first trigger. The
+ * exception is a recipe whose verdict a preempting rule has already determined, where a
+ * rule that could no longer change it may report `SKIPPED` instead.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type or is
* unexpectedly missing or null (e.g. if the server responded with an unexpected value).
@@ -704,7 +706,9 @@ private constructor(
/**
* One result per rule in the recipe, in membership order. Every rule runs — a score is
- * only meaningful when complete, so there is no short-circuit on the first trigger.
+ * only meaningful when complete, so there is no short-circuit on the first trigger. The
+ * exception is a recipe whose verdict a preempting rule has already determined, where a
+ * rule that could no longer change it may report `SKIPPED` instead.
*/
fun rules(rules: List) = rules(JsonField.of(rules))
@@ -895,10 +899,12 @@ private constructor(
private constructor(
private val outcome: JsonField,
private val ruleId: JsonField,
+ private val type: JsonField,
private val weight: JsonField,
private val blockedBy: JsonField,
private val name: JsonField,
private val unavailable: JsonField,
+ private val versionId: JsonField,
private val additionalProperties: MutableMap,
) {
@@ -910,6 +916,7 @@ private constructor(
@JsonProperty("rule_id")
@ExcludeMissing
ruleId: JsonField = JsonMissing.of(),
+ @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(),
@JsonProperty("weight") @ExcludeMissing weight: JsonField = JsonMissing.of(),
@JsonProperty("blocked_by")
@ExcludeMissing
@@ -918,7 +925,20 @@ private constructor(
@JsonProperty("unavailable")
@ExcludeMissing
unavailable: JsonField = JsonMissing.of(),
- ) : this(outcome, ruleId, weight, blockedBy, name, unavailable, mutableMapOf())
+ @JsonProperty("version_id")
+ @ExcludeMissing
+ versionId: JsonField = JsonMissing.of(),
+ ) : this(
+ outcome,
+ ruleId,
+ type,
+ weight,
+ blockedBy,
+ name,
+ unavailable,
+ versionId,
+ mutableMapOf(),
+ )
/**
* What the rule concluded.
@@ -927,6 +947,10 @@ private constructor(
* * `NOT_EVALUATED` - The rule could not run, because something it reads never arrived.
* This is not a quieter `NOT_TRIGGERED`: it contributed nothing either way, and it is
* why `partial_evidence` is set on the recipe.
+ * * `SKIPPED` - The rule was not run, because another rule had already determined the
+ * recipe's verdict — see `determined_by`. Nothing was missing and nothing failed, so
+ * `partial_evidence` is not set: `determined_by` is what accounts for the recipe's
+ * score resting on fewer rules.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type or is
* unexpectedly missing or null (e.g. if the server responded with an unexpected
@@ -945,6 +969,19 @@ private constructor(
*/
fun ruleId(): String = ruleId.getRequired("rule_id")
+ /**
+ * Who authored the rule, which is what says how much of the rest of this result you
+ * get.
+ * * `MANAGED` - Prelude-owned, shared with customers: `name` and `version_id` are
+ * omitted, and `blocked_by` reports only `missing_data`.
+ * * `CUSTOM` - Yours: every field is returned.
+ *
+ * @throws PreludeInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected
+ * value).
+ */
+ fun type(): Type = type.getRequired("type")
+
/**
* What this rule contributes to the recipe's score when it triggers.
*
@@ -985,6 +1022,16 @@ private constructor(
*/
fun unavailable(): Optional = unavailable.getOptional("unavailable")
+ /**
+ * The version of the rule that scored — the one this recipe is pinned to, or the
+ * version current at evaluation time when it is not pinned. Present for a rule you
+ * authored, and omitted for a Prelude-managed one.
+ *
+ * @throws PreludeInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun versionId(): Optional = versionId.getOptional("version_id")
+
/**
* Returns the raw JSON value of [outcome].
*
@@ -999,6 +1046,13 @@ private constructor(
*/
@JsonProperty("rule_id") @ExcludeMissing fun _ruleId(): JsonField = ruleId
+ /**
+ * Returns the raw JSON value of [type].
+ *
+ * Unlike [type], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type
+
/**
* Returns the raw JSON value of [weight].
*
@@ -1033,6 +1087,16 @@ private constructor(
@ExcludeMissing
fun _unavailable(): JsonField = unavailable
+ /**
+ * Returns the raw JSON value of [versionId].
+ *
+ * Unlike [versionId], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("version_id")
+ @ExcludeMissing
+ fun _versionId(): JsonField = versionId
+
@JsonAnySetter
private fun putAdditionalProperty(key: String, value: JsonValue) {
additionalProperties.put(key, value)
@@ -1054,6 +1118,7 @@ private constructor(
* ```java
* .outcome()
* .ruleId()
+ * .type()
* .weight()
* ```
*/
@@ -1065,20 +1130,24 @@ private constructor(
private var outcome: JsonField? = null
private var ruleId: JsonField? = null
+ private var type: JsonField? = null
private var weight: JsonField? = null
private var blockedBy: JsonField = JsonMissing.of()
private var name: JsonField = JsonMissing.of()
private var unavailable: JsonField = JsonMissing.of()
+ private var versionId: JsonField = JsonMissing.of()
private var additionalProperties: MutableMap = mutableMapOf()
@JvmSynthetic
internal fun from(rule: Rule) = apply {
outcome = rule.outcome
ruleId = rule.ruleId
+ type = rule.type
weight = rule.weight
blockedBy = rule.blockedBy
name = rule.name
unavailable = rule.unavailable
+ versionId = rule.versionId
additionalProperties = rule.additionalProperties.toMutableMap()
}
@@ -1089,6 +1158,10 @@ private constructor(
* * `NOT_EVALUATED` - The rule could not run, because something it reads never
* arrived. This is not a quieter `NOT_TRIGGERED`: it contributed nothing either
* way, and it is why `partial_evidence` is set on the recipe.
+ * * `SKIPPED` - The rule was not run, because another rule had already determined
+ * the recipe's verdict — see `determined_by`. Nothing was missing and nothing
+ * failed, so `partial_evidence` is not set: `determined_by` is what accounts for
+ * the recipe's score resting on fewer rules.
*/
fun outcome(outcome: Outcome) = outcome(JsonField.of(outcome))
@@ -1117,6 +1190,24 @@ private constructor(
*/
fun ruleId(ruleId: JsonField) = apply { this.ruleId = ruleId }
+ /**
+ * Who authored the rule, which is what says how much of the rest of this result you
+ * get.
+ * * `MANAGED` - Prelude-owned, shared with customers: `name` and `version_id` are
+ * omitted, and `blocked_by` reports only `missing_data`.
+ * * `CUSTOM` - Yours: every field is returned.
+ */
+ fun type(type: Type) = type(JsonField.of(type))
+
+ /**
+ * Sets [Builder.type] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.type] with a well-typed [Type] value instead.
+ * This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun type(type: JsonField) = apply { this.type = type }
+
/** What this rule contributes to the recipe's score when it triggers. */
fun weight(weight: Long) = weight(JsonField.of(weight))
@@ -1181,6 +1272,22 @@ private constructor(
this.unavailable = unavailable
}
+ /**
+ * The version of the rule that scored — the one this recipe is pinned to, or the
+ * version current at evaluation time when it is not pinned. Present for a rule you
+ * authored, and omitted for a Prelude-managed one.
+ */
+ fun versionId(versionId: String) = versionId(JsonField.of(versionId))
+
+ /**
+ * Sets [Builder.versionId] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.versionId] with a well-typed [String] value
+ * instead. This method is primarily for setting the field to an undocumented or not
+ * yet supported value.
+ */
+ fun versionId(versionId: JsonField) = apply { this.versionId = versionId }
+
fun additionalProperties(additionalProperties: Map) = apply {
this.additionalProperties.clear()
putAllAdditionalProperties(additionalProperties)
@@ -1212,6 +1319,7 @@ private constructor(
* ```java
* .outcome()
* .ruleId()
+ * .type()
* .weight()
* ```
*
@@ -1221,10 +1329,12 @@ private constructor(
Rule(
checkRequired("outcome", outcome),
checkRequired("ruleId", ruleId),
+ checkRequired("type", type),
checkRequired("weight", weight),
blockedBy,
name,
unavailable,
+ versionId,
additionalProperties.toMutableMap(),
)
}
@@ -1248,10 +1358,12 @@ private constructor(
outcome().validate()
ruleId()
+ type().validate()
weight()
blockedBy()
name()
unavailable()
+ versionId()
validated = true
}
@@ -1273,10 +1385,12 @@ private constructor(
internal fun validity(): Int =
(outcome.asKnown().getOrNull()?.validity() ?: 0) +
(if (ruleId.asKnown().isPresent) 1 else 0) +
+ (type.asKnown().getOrNull()?.validity() ?: 0) +
(if (weight.asKnown().isPresent) 1 else 0) +
(if (blockedBy.asKnown().isPresent) 1 else 0) +
(if (name.asKnown().isPresent) 1 else 0) +
- (if (unavailable.asKnown().isPresent) 1 else 0)
+ (if (unavailable.asKnown().isPresent) 1 else 0) +
+ (if (versionId.asKnown().isPresent) 1 else 0)
/**
* What the rule concluded.
@@ -1285,6 +1399,10 @@ private constructor(
* * `NOT_EVALUATED` - The rule could not run, because something it reads never arrived.
* This is not a quieter `NOT_TRIGGERED`: it contributed nothing either way, and it is
* why `partial_evidence` is set on the recipe.
+ * * `SKIPPED` - The rule was not run, because another rule had already determined the
+ * recipe's verdict — see `determined_by`. Nothing was missing and nothing failed, so
+ * `partial_evidence` is not set: `determined_by` is what accounts for the recipe's
+ * score resting on fewer rules.
*/
class Outcome @JsonCreator private constructor(private val value: JsonField) :
Enum {
@@ -1307,6 +1425,8 @@ private constructor(
@JvmField val NOT_EVALUATED = of("NOT_EVALUATED")
+ @JvmField val SKIPPED = of("SKIPPED")
+
@JvmStatic fun of(value: String) = Outcome(JsonField.of(value))
}
@@ -1315,6 +1435,7 @@ private constructor(
TRIGGERED,
NOT_TRIGGERED,
NOT_EVALUATED,
+ SKIPPED,
}
/**
@@ -1330,6 +1451,7 @@ private constructor(
TRIGGERED,
NOT_TRIGGERED,
NOT_EVALUATED,
+ SKIPPED,
/**
* An enum member indicating that [Outcome] was instantiated with an unknown
* value.
@@ -1349,6 +1471,7 @@ private constructor(
TRIGGERED -> Value.TRIGGERED
NOT_TRIGGERED -> Value.NOT_TRIGGERED
NOT_EVALUATED -> Value.NOT_EVALUATED
+ SKIPPED -> Value.SKIPPED
else -> Value._UNKNOWN
}
@@ -1366,6 +1489,7 @@ private constructor(
TRIGGERED -> Known.TRIGGERED
NOT_TRIGGERED -> Known.NOT_TRIGGERED
NOT_EVALUATED -> Known.NOT_EVALUATED
+ SKIPPED -> Known.SKIPPED
else -> throw PreludeInvalidDataException("Unknown Outcome: $value")
}
@@ -1433,6 +1557,153 @@ private constructor(
override fun toString() = value.toString()
}
+ /**
+ * Who authored the rule, which is what says how much of the rest of this result you
+ * get.
+ * * `MANAGED` - Prelude-owned, shared with customers: `name` and `version_id` are
+ * omitted, and `blocked_by` reports only `missing_data`.
+ * * `CUSTOM` - Yours: every field is returned.
+ */
+ class Type @JsonCreator private constructor(private val value: JsonField) :
+ Enum {
+
+ /**
+ * Returns this class instance's raw value.
+ *
+ * This is usually only useful if this instance was deserialized from data that
+ * doesn't match any known member, and you want to know that value. For example, if
+ * the SDK is on an older version than the API, then the API may respond with new
+ * members that the SDK is unaware of.
+ */
+ @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value
+
+ companion object {
+
+ @JvmField val MANAGED = of("MANAGED")
+
+ @JvmField val CUSTOM = of("CUSTOM")
+
+ @JvmStatic fun of(value: String) = Type(JsonField.of(value))
+ }
+
+ /** An enum containing [Type]'s known values. */
+ enum class Known {
+ MANAGED,
+ CUSTOM,
+ }
+
+ /**
+ * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member.
+ *
+ * An instance of [Type] can contain an unknown value in a couple of cases:
+ * - It was deserialized from data that doesn't match any known member. For example,
+ * if the SDK is on an older version than the API, then the API may respond with
+ * new members that the SDK is unaware of.
+ * - It was constructed with an arbitrary value using the [of] method.
+ */
+ enum class Value {
+ MANAGED,
+ CUSTOM,
+ /**
+ * An enum member indicating that [Type] was instantiated with an unknown value.
+ */
+ _UNKNOWN,
+ }
+
+ /**
+ * Returns an enum member corresponding to this class instance's value, or
+ * [Value._UNKNOWN] if the class was instantiated with an unknown value.
+ *
+ * Use the [known] method instead if you're certain the value is always known or if
+ * you want to throw for the unknown case.
+ */
+ fun value(): Value =
+ when (this) {
+ MANAGED -> Value.MANAGED
+ CUSTOM -> Value.CUSTOM
+ else -> Value._UNKNOWN
+ }
+
+ /**
+ * Returns an enum member corresponding to this class instance's value.
+ *
+ * Use the [value] method instead if you're uncertain the value is always known and
+ * don't want to throw for the unknown case.
+ *
+ * @throws PreludeInvalidDataException if this class instance's value is a not a
+ * known member.
+ */
+ fun known(): Known =
+ when (this) {
+ MANAGED -> Known.MANAGED
+ CUSTOM -> Known.CUSTOM
+ else -> throw PreludeInvalidDataException("Unknown Type: $value")
+ }
+
+ /**
+ * Returns this class instance's primitive wire representation.
+ *
+ * This differs from the [toString] method because that method is primarily for
+ * debugging and generally doesn't throw.
+ *
+ * @throws PreludeInvalidDataException if this class instance's value does not have
+ * the expected primitive type.
+ */
+ fun asString(): String =
+ _value().asString().orElseThrow {
+ PreludeInvalidDataException("Value is not a String")
+ }
+
+ private var validated: Boolean = false
+
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws PreludeInvalidDataException if any value type in this object doesn't
+ * match its expected type.
+ */
+ fun validate(): Type = apply {
+ if (validated) {
+ return@apply
+ }
+
+ known()
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: PreludeInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Type && value == other.value
+ }
+
+ override fun hashCode() = value.hashCode()
+
+ override fun toString() = value.toString()
+ }
+
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
@@ -1441,10 +1712,12 @@ private constructor(
return other is Rule &&
outcome == other.outcome &&
ruleId == other.ruleId &&
+ type == other.type &&
weight == other.weight &&
blockedBy == other.blockedBy &&
name == other.name &&
unavailable == other.unavailable &&
+ versionId == other.versionId &&
additionalProperties == other.additionalProperties
}
@@ -1452,10 +1725,12 @@ private constructor(
Objects.hash(
outcome,
ruleId,
+ type,
weight,
blockedBy,
name,
unavailable,
+ versionId,
additionalProperties,
)
}
@@ -1463,7 +1738,7 @@ private constructor(
override fun hashCode(): Int = hashCode
override fun toString() =
- "Rule{outcome=$outcome, ruleId=$ruleId, weight=$weight, blockedBy=$blockedBy, name=$name, unavailable=$unavailable, additionalProperties=$additionalProperties}"
+ "Rule{outcome=$outcome, ruleId=$ruleId, type=$type, weight=$weight, blockedBy=$blockedBy, name=$name, unavailable=$unavailable, versionId=$versionId, additionalProperties=$additionalProperties}"
}
/**
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchPredictResponse.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchPredictResponse.kt
index 5e4f5c5..dc35a48 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchPredictResponse.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/models/WatchPredictResponse.kt
@@ -70,28 +70,39 @@ private constructor(
/**
* The risk factors that contributed to the suspicious prediction. Only present when prediction
* is "suspicious" and the anti-fraud system detected specific risk signals.
- * * `account_risk_profile` - The target matches a risk profile derived from the outcomes
- * reported on your own account, rather than from a signal shared across accounts.
- * * `behavioral_pattern` - The phone number past behavior during verification flows exhibits
- * suspicious patterns.
- * * `device_attribute` - The device exhibits characteristics associated with suspicious
- * activity patterns.
- * * `fraud_database` - The phone number has been flagged as suspicious in one or more of our
- * fraud databases.
- * * `location_discrepancy` - The phone number prefix and IP address discrepancy indicates
- * potential fraud.
- * * `network_fingerprint` - The network connection exhibits characteristics associated with
- * suspicious activity patterns.
- * * `poor_conversion_history` - The phone number has a history of poorly converting to a
- * verified phone number.
- * * `prefix_concentration` - The phone number is part of a range known to be associated with
- * suspicious activity patterns.
- * * `suspected_request_tampering` - The SDK signature is invalid and the request is considered
- * to be tampered with.
- * * `suspicious_ip_address` - The IP address is deemed to be associated with suspicious
- * activity patterns.
- * * `temporary_phone_number` - The phone number is known to be a temporary or disposable
- * number.
+ * * `account_risk_profile` - The request matches a risk profile derived from the outcomes
+ * reported on your own account.
+ * * `automation_signature` - The request appears to come from an automated client rather than a
+ * person.
+ * * `carrier_not_permitted` - The destination carrier is one this account does not accept
+ * traffic for.
+ * * `client_fingerprint_mismatch` - The client does not appear to be the platform it identifies
+ * itself as.
+ * * `custom_policy` - A rule configured for your account matched this request.
+ * * `device_emulator` - The request appears to come from an emulator rather than a physical
+ * device.
+ * * `device_not_permitted` - The device platform is one your account blocks.
+ * * `device_reuse` - One device is driving verifications for an unusual number of phone
+ * numbers.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
+ * * `fraud_database` - The phone number is flagged in one or more of the fraud databases
+ * Prelude consults.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be attributed
+ * to the device it claims to come from.
+ * * `ip_concentration` - The request shares its origin with an unusual volume of other
+ * verifications.
+ * * `ip_reputation` - The originating IP address is not trusted.
+ * * `location_mismatch` - The network location and the phone number's country are inconsistent.
+ * * `missing_signals` - The verification expected Prelude SDK signals and none arrived.
+ * * `number_range_abuse` - The phone number belongs to a range currently associated with abuse.
+ * * `poor_conversion_history` - Traffic resembling this request rarely completes a
+ * verification.
+ * * `proxy_network` - The request did not arrive over the subscriber's own access network.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification attempts
+ * in a short period.
+ * * `temporary_phone_number` - The phone number belongs to a disposable or short-lived
+ * numbering service.
*
* @throws PreludeInvalidDataException if the JSON field has an unexpected type (e.g. if the
* server responded with an unexpected value).
@@ -216,28 +227,41 @@ private constructor(
/**
* The risk factors that contributed to the suspicious prediction. Only present when
* prediction is "suspicious" and the anti-fraud system detected specific risk signals.
- * * `account_risk_profile` - The target matches a risk profile derived from the outcomes
- * reported on your own account, rather than from a signal shared across accounts.
- * * `behavioral_pattern` - The phone number past behavior during verification flows
- * exhibits suspicious patterns.
- * * `device_attribute` - The device exhibits characteristics associated with suspicious
- * activity patterns.
- * * `fraud_database` - The phone number has been flagged as suspicious in one or more of
- * our fraud databases.
- * * `location_discrepancy` - The phone number prefix and IP address discrepancy indicates
- * potential fraud.
- * * `network_fingerprint` - The network connection exhibits characteristics associated with
- * suspicious activity patterns.
- * * `poor_conversion_history` - The phone number has a history of poorly converting to a
- * verified phone number.
- * * `prefix_concentration` - The phone number is part of a range known to be associated
- * with suspicious activity patterns.
- * * `suspected_request_tampering` - The SDK signature is invalid and the request is
- * considered to be tampered with.
- * * `suspicious_ip_address` - The IP address is deemed to be associated with suspicious
- * activity patterns.
- * * `temporary_phone_number` - The phone number is known to be a temporary or disposable
- * number.
+ * * `account_risk_profile` - The request matches a risk profile derived from the outcomes
+ * reported on your own account.
+ * * `automation_signature` - The request appears to come from an automated client rather
+ * than a person.
+ * * `carrier_not_permitted` - The destination carrier is one this account does not accept
+ * traffic for.
+ * * `client_fingerprint_mismatch` - The client does not appear to be the platform it
+ * identifies itself as.
+ * * `custom_policy` - A rule configured for your account matched this request.
+ * * `device_emulator` - The request appears to come from an emulator rather than a physical
+ * device.
+ * * `device_not_permitted` - The device platform is one your account blocks.
+ * * `device_reuse` - One device is driving verifications for an unusual number of phone
+ * numbers.
+ * * `expired_signals` - The SDK signals were collected too long before the request to still
+ * attest to it.
+ * * `fraud_database` - The phone number is flagged in one or more of the fraud databases
+ * Prelude consults.
+ * * `invalid_signature` - The SDK signature did not verify, so the request cannot be
+ * attributed to the device it claims to come from.
+ * * `ip_concentration` - The request shares its origin with an unusual volume of other
+ * verifications.
+ * * `ip_reputation` - The originating IP address is not trusted.
+ * * `location_mismatch` - The network location and the phone number's country are
+ * inconsistent.
+ * * `missing_signals` - The verification expected Prelude SDK signals and none arrived.
+ * * `number_range_abuse` - The phone number belongs to a range currently associated with
+ * abuse.
+ * * `poor_conversion_history` - Traffic resembling this request rarely completes a
+ * verification.
+ * * `proxy_network` - The request did not arrive over the subscriber's own access network.
+ * * `repeated_attempts` - The phone number exceeded the allowed number of verification
+ * attempts in a short period.
+ * * `temporary_phone_number` - The phone number belongs to a disposable or short-lived
+ * numbering service.
*/
fun riskFactors(riskFactors: List) = riskFactors(JsonField.of(riskFactors))
@@ -502,23 +526,41 @@ private constructor(
@JvmField val ACCOUNT_RISK_PROFILE = of("account_risk_profile")
- @JvmField val BEHAVIORAL_PATTERN = of("behavioral_pattern")
+ @JvmField val AUTOMATION_SIGNATURE = of("automation_signature")
- @JvmField val DEVICE_ATTRIBUTE = of("device_attribute")
+ @JvmField val CARRIER_NOT_PERMITTED = of("carrier_not_permitted")
+
+ @JvmField val CLIENT_FINGERPRINT_MISMATCH = of("client_fingerprint_mismatch")
+
+ @JvmField val CUSTOM_POLICY = of("custom_policy")
+
+ @JvmField val DEVICE_EMULATOR = of("device_emulator")
+
+ @JvmField val DEVICE_NOT_PERMITTED = of("device_not_permitted")
+
+ @JvmField val DEVICE_REUSE = of("device_reuse")
+
+ @JvmField val EXPIRED_SIGNALS = of("expired_signals")
@JvmField val FRAUD_DATABASE = of("fraud_database")
- @JvmField val LOCATION_DISCREPANCY = of("location_discrepancy")
+ @JvmField val INVALID_SIGNATURE = of("invalid_signature")
- @JvmField val NETWORK_FINGERPRINT = of("network_fingerprint")
+ @JvmField val IP_CONCENTRATION = of("ip_concentration")
- @JvmField val POOR_CONVERSION_HISTORY = of("poor_conversion_history")
+ @JvmField val IP_REPUTATION = of("ip_reputation")
+
+ @JvmField val LOCATION_MISMATCH = of("location_mismatch")
+
+ @JvmField val MISSING_SIGNALS = of("missing_signals")
- @JvmField val PREFIX_CONCENTRATION = of("prefix_concentration")
+ @JvmField val NUMBER_RANGE_ABUSE = of("number_range_abuse")
+
+ @JvmField val POOR_CONVERSION_HISTORY = of("poor_conversion_history")
- @JvmField val SUSPECTED_REQUEST_TAMPERING = of("suspected_request_tampering")
+ @JvmField val PROXY_NETWORK = of("proxy_network")
- @JvmField val SUSPICIOUS_IP_ADDRESS = of("suspicious_ip_address")
+ @JvmField val REPEATED_ATTEMPTS = of("repeated_attempts")
@JvmField val TEMPORARY_PHONE_NUMBER = of("temporary_phone_number")
@@ -528,15 +570,24 @@ private constructor(
/** An enum containing [RiskFactor]'s known values. */
enum class Known {
ACCOUNT_RISK_PROFILE,
- BEHAVIORAL_PATTERN,
- DEVICE_ATTRIBUTE,
+ AUTOMATION_SIGNATURE,
+ CARRIER_NOT_PERMITTED,
+ CLIENT_FINGERPRINT_MISMATCH,
+ CUSTOM_POLICY,
+ DEVICE_EMULATOR,
+ DEVICE_NOT_PERMITTED,
+ DEVICE_REUSE,
+ EXPIRED_SIGNALS,
FRAUD_DATABASE,
- LOCATION_DISCREPANCY,
- NETWORK_FINGERPRINT,
+ INVALID_SIGNATURE,
+ IP_CONCENTRATION,
+ IP_REPUTATION,
+ LOCATION_MISMATCH,
+ MISSING_SIGNALS,
+ NUMBER_RANGE_ABUSE,
POOR_CONVERSION_HISTORY,
- PREFIX_CONCENTRATION,
- SUSPECTED_REQUEST_TAMPERING,
- SUSPICIOUS_IP_ADDRESS,
+ PROXY_NETWORK,
+ REPEATED_ATTEMPTS,
TEMPORARY_PHONE_NUMBER,
}
@@ -551,15 +602,24 @@ private constructor(
*/
enum class Value {
ACCOUNT_RISK_PROFILE,
- BEHAVIORAL_PATTERN,
- DEVICE_ATTRIBUTE,
+ AUTOMATION_SIGNATURE,
+ CARRIER_NOT_PERMITTED,
+ CLIENT_FINGERPRINT_MISMATCH,
+ CUSTOM_POLICY,
+ DEVICE_EMULATOR,
+ DEVICE_NOT_PERMITTED,
+ DEVICE_REUSE,
+ EXPIRED_SIGNALS,
FRAUD_DATABASE,
- LOCATION_DISCREPANCY,
- NETWORK_FINGERPRINT,
+ INVALID_SIGNATURE,
+ IP_CONCENTRATION,
+ IP_REPUTATION,
+ LOCATION_MISMATCH,
+ MISSING_SIGNALS,
+ NUMBER_RANGE_ABUSE,
POOR_CONVERSION_HISTORY,
- PREFIX_CONCENTRATION,
- SUSPECTED_REQUEST_TAMPERING,
- SUSPICIOUS_IP_ADDRESS,
+ PROXY_NETWORK,
+ REPEATED_ATTEMPTS,
TEMPORARY_PHONE_NUMBER,
/**
* An enum member indicating that [RiskFactor] was instantiated with an unknown value.
@@ -577,15 +637,24 @@ private constructor(
fun value(): Value =
when (this) {
ACCOUNT_RISK_PROFILE -> Value.ACCOUNT_RISK_PROFILE
- BEHAVIORAL_PATTERN -> Value.BEHAVIORAL_PATTERN
- DEVICE_ATTRIBUTE -> Value.DEVICE_ATTRIBUTE
+ AUTOMATION_SIGNATURE -> Value.AUTOMATION_SIGNATURE
+ CARRIER_NOT_PERMITTED -> Value.CARRIER_NOT_PERMITTED
+ CLIENT_FINGERPRINT_MISMATCH -> Value.CLIENT_FINGERPRINT_MISMATCH
+ CUSTOM_POLICY -> Value.CUSTOM_POLICY
+ DEVICE_EMULATOR -> Value.DEVICE_EMULATOR
+ DEVICE_NOT_PERMITTED -> Value.DEVICE_NOT_PERMITTED
+ DEVICE_REUSE -> Value.DEVICE_REUSE
+ EXPIRED_SIGNALS -> Value.EXPIRED_SIGNALS
FRAUD_DATABASE -> Value.FRAUD_DATABASE
- LOCATION_DISCREPANCY -> Value.LOCATION_DISCREPANCY
- NETWORK_FINGERPRINT -> Value.NETWORK_FINGERPRINT
+ INVALID_SIGNATURE -> Value.INVALID_SIGNATURE
+ IP_CONCENTRATION -> Value.IP_CONCENTRATION
+ IP_REPUTATION -> Value.IP_REPUTATION
+ LOCATION_MISMATCH -> Value.LOCATION_MISMATCH
+ MISSING_SIGNALS -> Value.MISSING_SIGNALS
+ NUMBER_RANGE_ABUSE -> Value.NUMBER_RANGE_ABUSE
POOR_CONVERSION_HISTORY -> Value.POOR_CONVERSION_HISTORY
- PREFIX_CONCENTRATION -> Value.PREFIX_CONCENTRATION
- SUSPECTED_REQUEST_TAMPERING -> Value.SUSPECTED_REQUEST_TAMPERING
- SUSPICIOUS_IP_ADDRESS -> Value.SUSPICIOUS_IP_ADDRESS
+ PROXY_NETWORK -> Value.PROXY_NETWORK
+ REPEATED_ATTEMPTS -> Value.REPEATED_ATTEMPTS
TEMPORARY_PHONE_NUMBER -> Value.TEMPORARY_PHONE_NUMBER
else -> Value._UNKNOWN
}
@@ -602,15 +671,24 @@ private constructor(
fun known(): Known =
when (this) {
ACCOUNT_RISK_PROFILE -> Known.ACCOUNT_RISK_PROFILE
- BEHAVIORAL_PATTERN -> Known.BEHAVIORAL_PATTERN
- DEVICE_ATTRIBUTE -> Known.DEVICE_ATTRIBUTE
+ AUTOMATION_SIGNATURE -> Known.AUTOMATION_SIGNATURE
+ CARRIER_NOT_PERMITTED -> Known.CARRIER_NOT_PERMITTED
+ CLIENT_FINGERPRINT_MISMATCH -> Known.CLIENT_FINGERPRINT_MISMATCH
+ CUSTOM_POLICY -> Known.CUSTOM_POLICY
+ DEVICE_EMULATOR -> Known.DEVICE_EMULATOR
+ DEVICE_NOT_PERMITTED -> Known.DEVICE_NOT_PERMITTED
+ DEVICE_REUSE -> Known.DEVICE_REUSE
+ EXPIRED_SIGNALS -> Known.EXPIRED_SIGNALS
FRAUD_DATABASE -> Known.FRAUD_DATABASE
- LOCATION_DISCREPANCY -> Known.LOCATION_DISCREPANCY
- NETWORK_FINGERPRINT -> Known.NETWORK_FINGERPRINT
+ INVALID_SIGNATURE -> Known.INVALID_SIGNATURE
+ IP_CONCENTRATION -> Known.IP_CONCENTRATION
+ IP_REPUTATION -> Known.IP_REPUTATION
+ LOCATION_MISMATCH -> Known.LOCATION_MISMATCH
+ MISSING_SIGNALS -> Known.MISSING_SIGNALS
+ NUMBER_RANGE_ABUSE -> Known.NUMBER_RANGE_ABUSE
POOR_CONVERSION_HISTORY -> Known.POOR_CONVERSION_HISTORY
- PREFIX_CONCENTRATION -> Known.PREFIX_CONCENTRATION
- SUSPECTED_REQUEST_TAMPERING -> Known.SUSPECTED_REQUEST_TAMPERING
- SUSPICIOUS_IP_ADDRESS -> Known.SUSPICIOUS_IP_ADDRESS
+ PROXY_NETWORK -> Known.PROXY_NETWORK
+ REPEATED_ATTEMPTS -> Known.REPEATED_ATTEMPTS
TEMPORARY_PHONE_NUMBER -> Known.TEMPORARY_PHONE_NUMBER
else -> throw PreludeInvalidDataException("Unknown RiskFactor: $value")
}
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/async/WatchServiceAsync.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/async/WatchServiceAsync.kt
index 4cc7175..76c375c 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/async/WatchServiceAsync.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/async/WatchServiceAsync.kt
@@ -32,8 +32,9 @@ interface WatchServiceAsync {
fun withOptions(modifier: Consumer): WatchServiceAsync
/**
- * **Beta.** The request and response shapes may still change, and flows and recipes are
- * configured by Prelude on your behalf for now. Talk to us before you build against it.
+ * **Beta.** The request and response shapes may still change. Talk to us before you build
+ * against it. Flows, recipes and rules are authored through the Watch Management API, or
+ * configured by Prelude on your behalf.
*
* Score a target against the rules configured for one moment in your product — signup,
* checkout, password reset. The flow selects which recipes run; each recipe scores its rules
diff --git a/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/blocking/WatchService.kt b/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/blocking/WatchService.kt
index c0cdd83..21d58a7 100644
--- a/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/blocking/WatchService.kt
+++ b/prelude-java-core/src/main/kotlin/so/prelude/sdk/services/blocking/WatchService.kt
@@ -32,8 +32,9 @@ interface WatchService {
fun withOptions(modifier: Consumer): WatchService
/**
- * **Beta.** The request and response shapes may still change, and flows and recipes are
- * configured by Prelude on your behalf for now. Talk to us before you build against it.
+ * **Beta.** The request and response shapes may still change. Talk to us before you build
+ * against it. Flows, recipes and rules are authored through the Watch Management API, or
+ * configured by Prelude on your behalf.
*
* Score a target against the rules configured for one moment in your product — signup,
* checkout, password reset. The flow selects which recipes run; each recipe scores its rules
diff --git a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationCreateResponseTest.kt b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationCreateResponseTest.kt
index e42a689..c535d99 100644
--- a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationCreateResponseTest.kt
+++ b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationCreateResponseTest.kt
@@ -25,7 +25,7 @@ internal class VerificationCreateResponseTest {
)
.reason(VerificationCreateResponse.Reason.INVALID_PHONE_NUMBER)
.requestId("request_id")
- .addRiskFactor(VerificationCreateResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS)
+ .addRiskFactor(VerificationCreateResponse.RiskFactor.PROXY_NETWORK)
.addRiskFactor(VerificationCreateResponse.RiskFactor.FRAUD_DATABASE)
.silent(
VerificationCreateResponse.Silent.builder().requestUrl("request_url").build()
@@ -50,7 +50,7 @@ internal class VerificationCreateResponseTest {
assertThat(verificationCreateResponse.requestId()).contains("request_id")
assertThat(verificationCreateResponse.riskFactors().getOrNull())
.containsExactly(
- VerificationCreateResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS,
+ VerificationCreateResponse.RiskFactor.PROXY_NETWORK,
VerificationCreateResponse.RiskFactor.FRAUD_DATABASE,
)
assertThat(verificationCreateResponse.silent())
@@ -73,7 +73,7 @@ internal class VerificationCreateResponseTest {
)
.reason(VerificationCreateResponse.Reason.INVALID_PHONE_NUMBER)
.requestId("request_id")
- .addRiskFactor(VerificationCreateResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS)
+ .addRiskFactor(VerificationCreateResponse.RiskFactor.PROXY_NETWORK)
.addRiskFactor(VerificationCreateResponse.RiskFactor.FRAUD_DATABASE)
.silent(
VerificationCreateResponse.Silent.builder().requestUrl("request_url").build()
diff --git a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponseTest.kt b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponseTest.kt
index 3e51d76..707c86f 100644
--- a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponseTest.kt
+++ b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/VerificationPhoneHistoryRetrieveResponseTest.kt
@@ -22,7 +22,7 @@ internal class VerificationPhoneHistoryRetrieveResponseTest {
.status(VerificationPhoneHistoryRetrieveResponse.Status.CONVERTED)
.appVersion("app_version")
.addBlockReason(
- VerificationPhoneHistoryRetrieveResponse.BlockReason.BEHAVIORAL_PATTERN
+ VerificationPhoneHistoryRetrieveResponse.BlockReason.AUTOMATION_SIGNATURE
)
.carrier(PhoneVerificationCarrier.builder().mccmnc("208-01").name("Orange").build())
.correlationId("correlation_id")
@@ -225,7 +225,7 @@ internal class VerificationPhoneHistoryRetrieveResponseTest {
assertThat(verificationPhoneHistoryRetrieveResponse.appVersion()).contains("app_version")
assertThat(verificationPhoneHistoryRetrieveResponse.blockReasons().getOrNull())
.containsExactly(
- VerificationPhoneHistoryRetrieveResponse.BlockReason.BEHAVIORAL_PATTERN
+ VerificationPhoneHistoryRetrieveResponse.BlockReason.AUTOMATION_SIGNATURE
)
assertThat(verificationPhoneHistoryRetrieveResponse.carrier())
.contains(PhoneVerificationCarrier.builder().mccmnc("208-01").name("Orange").build())
@@ -429,7 +429,7 @@ internal class VerificationPhoneHistoryRetrieveResponseTest {
.status(VerificationPhoneHistoryRetrieveResponse.Status.CONVERTED)
.appVersion("app_version")
.addBlockReason(
- VerificationPhoneHistoryRetrieveResponse.BlockReason.BEHAVIORAL_PATTERN
+ VerificationPhoneHistoryRetrieveResponse.BlockReason.AUTOMATION_SIGNATURE
)
.carrier(PhoneVerificationCarrier.builder().mccmnc("208-01").name("Orange").build())
.correlationId("correlation_id")
diff --git a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchEvaluateResponseTest.kt b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchEvaluateResponseTest.kt
index d04670f..8f34bd8 100644
--- a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchEvaluateResponseTest.kt
+++ b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchEvaluateResponseTest.kt
@@ -23,10 +23,12 @@ internal class WatchEvaluateResponseTest {
WatchEvaluateResponse.Recipe.Rule.builder()
.outcome(WatchEvaluateResponse.Recipe.Rule.Outcome.TRIGGERED)
.ruleId("rul_01jc0t6fwwfgfsq1md24mhyztj")
+ .type(WatchEvaluateResponse.Recipe.Rule.Type.MANAGED)
.weight(10L)
.blockedBy("missing_data")
.name("high_value_cart_new_account")
.unavailable(true)
+ .versionId("3sL4kqtJlcpXroDTDmJ.o.Jj7bB5dGH6")
.build()
)
.score(20L)
@@ -49,10 +51,12 @@ internal class WatchEvaluateResponseTest {
WatchEvaluateResponse.Recipe.Rule.builder()
.outcome(WatchEvaluateResponse.Recipe.Rule.Outcome.TRIGGERED)
.ruleId("rul_01jc0t6fwwfgfsq1md24mhyztj")
+ .type(WatchEvaluateResponse.Recipe.Rule.Type.MANAGED)
.weight(10L)
.blockedBy("missing_data")
.name("high_value_cart_new_account")
.unavailable(true)
+ .versionId("3sL4kqtJlcpXroDTDmJ.o.Jj7bB5dGH6")
.build()
)
.score(20L)
@@ -79,10 +83,12 @@ internal class WatchEvaluateResponseTest {
WatchEvaluateResponse.Recipe.Rule.builder()
.outcome(WatchEvaluateResponse.Recipe.Rule.Outcome.TRIGGERED)
.ruleId("rul_01jc0t6fwwfgfsq1md24mhyztj")
+ .type(WatchEvaluateResponse.Recipe.Rule.Type.MANAGED)
.weight(10L)
.blockedBy("missing_data")
.name("high_value_cart_new_account")
.unavailable(true)
+ .versionId("3sL4kqtJlcpXroDTDmJ.o.Jj7bB5dGH6")
.build()
)
.score(20L)
diff --git a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchPredictResponseTest.kt b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchPredictResponseTest.kt
index a3ec651..7226f57 100644
--- a/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchPredictResponseTest.kt
+++ b/prelude-java-core/src/test/kotlin/so/prelude/sdk/models/WatchPredictResponseTest.kt
@@ -17,7 +17,7 @@ internal class WatchPredictResponseTest {
.id("prd_01jc0t6fwwfgfsq1md24mhyztj")
.prediction(WatchPredictResponse.Prediction.LEGITIMATE)
.requestId("3d19215e-2991-4a05-a41a-527314e6ff6a")
- .addRiskFactor(WatchPredictResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS)
+ .addRiskFactor(WatchPredictResponse.RiskFactor.PROXY_NETWORK)
.addRiskFactor(WatchPredictResponse.RiskFactor.FRAUD_DATABASE)
.build()
@@ -28,7 +28,7 @@ internal class WatchPredictResponseTest {
.isEqualTo("3d19215e-2991-4a05-a41a-527314e6ff6a")
assertThat(watchPredictResponse.riskFactors().getOrNull())
.containsExactly(
- WatchPredictResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS,
+ WatchPredictResponse.RiskFactor.PROXY_NETWORK,
WatchPredictResponse.RiskFactor.FRAUD_DATABASE,
)
}
@@ -41,7 +41,7 @@ internal class WatchPredictResponseTest {
.id("prd_01jc0t6fwwfgfsq1md24mhyztj")
.prediction(WatchPredictResponse.Prediction.LEGITIMATE)
.requestId("3d19215e-2991-4a05-a41a-527314e6ff6a")
- .addRiskFactor(WatchPredictResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS)
+ .addRiskFactor(WatchPredictResponse.RiskFactor.PROXY_NETWORK)
.addRiskFactor(WatchPredictResponse.RiskFactor.FRAUD_DATABASE)
.build()
diff --git a/prelude-java-proguard-test/src/test/kotlin/so/prelude/sdk/proguard/ProGuardCompatibilityTest.kt b/prelude-java-proguard-test/src/test/kotlin/so/prelude/sdk/proguard/ProGuardCompatibilityTest.kt
index 9df77a5..f6bcd8c 100644
--- a/prelude-java-proguard-test/src/test/kotlin/so/prelude/sdk/proguard/ProGuardCompatibilityTest.kt
+++ b/prelude-java-proguard-test/src/test/kotlin/so/prelude/sdk/proguard/ProGuardCompatibilityTest.kt
@@ -72,7 +72,7 @@ internal class ProGuardCompatibilityTest {
)
.reason(VerificationCreateResponse.Reason.INVALID_PHONE_NUMBER)
.requestId("request_id")
- .addRiskFactor(VerificationCreateResponse.RiskFactor.SUSPICIOUS_IP_ADDRESS)
+ .addRiskFactor(VerificationCreateResponse.RiskFactor.PROXY_NETWORK)
.addRiskFactor(VerificationCreateResponse.RiskFactor.FRAUD_DATABASE)
.silent(
VerificationCreateResponse.Silent.builder().requestUrl("request_url").build()