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 04acfe8..a7080b0 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/python-sdk/compare/v0.15.0...v0.16.0) + +### Features + +* **api:** api update ([0dcc0e1](https://github.com/prelude-so/python-sdk/commit/0dcc0e103c3904f1b9d3384acf5d18a05e0f2987)) + ## 0.15.0 (2026-09-18) Full Changelog: [v0.14.0...v0.15.0](https://github.com/prelude-so/python-sdk/compare/v0.14.0...v0.15.0) diff --git a/pyproject.toml b/pyproject.toml index 090aafb..ea6649f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "prelude-python-sdk" -version = "0.15.0" +version = "0.16.0" description = "The official Python library for the Prelude API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/prelude_python_sdk/_version.py b/src/prelude_python_sdk/_version.py index 888f88c..2d14184 100644 --- a/src/prelude_python_sdk/_version.py +++ b/src/prelude_python_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "prelude_python_sdk" -__version__ = "0.15.0" # x-release-please-version +__version__ = "0.16.0" # x-release-please-version diff --git a/src/prelude_python_sdk/resources/watch.py b/src/prelude_python_sdk/resources/watch.py index a4e70ad..cd47593 100644 --- a/src/prelude_python_sdk/resources/watch.py +++ b/src/prelude_python_sdk/resources/watch.py @@ -70,10 +70,11 @@ def evaluate( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WatchEvaluateResponse: - """ - **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 @@ -307,10 +308,11 @@ async def evaluate( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WatchEvaluateResponse: - """ - **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 diff --git a/src/prelude_python_sdk/types/verification/phone/history_list_response.py b/src/prelude_python_sdk/types/verification/phone/history_list_response.py index 83b6d07..bc9044c 100644 --- a/src/prelude_python_sdk/types/verification/phone/history_list_response.py +++ b/src/prelude_python_sdk/types/verification/phone/history_list_response.py @@ -68,8 +68,8 @@ class Verification(BaseModel): - `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. """ diff --git a/src/prelude_python_sdk/types/verification/phone/history_retrieve_response.py b/src/prelude_python_sdk/types/verification/phone/history_retrieve_response.py index e2b8de1..c4c5e5a 100644 --- a/src/prelude_python_sdk/types/verification/phone/history_retrieve_response.py +++ b/src/prelude_python_sdk/types/verification/phone/history_retrieve_response.py @@ -229,8 +229,8 @@ class HistoryRetrieveResponse(BaseModel): - `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. """ @@ -241,46 +241,68 @@ class HistoryRetrieveResponse(BaseModel): block_reasons: Optional[ List[ Literal[ - "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", ] ] ] = None - """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. """ carrier: Optional[PhoneVerificationCarrier] = None diff --git a/src/prelude_python_sdk/types/verification_create_response.py b/src/prelude_python_sdk/types/verification_create_response.py index 44838b2..e320162 100644 --- a/src/prelude_python_sdk/types/verification_create_response.py +++ b/src/prelude_python_sdk/types/verification_create_response.py @@ -75,9 +75,10 @@ class VerificationCreateResponse(BaseModel): 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. """ @@ -87,15 +88,24 @@ class VerificationCreateResponse(BaseModel): risk_factors: Optional[ List[ Literal[ - "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", ] ] @@ -105,26 +115,41 @@ class VerificationCreateResponse(BaseModel): 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. """ silent: Optional[Silent] = None diff --git a/src/prelude_python_sdk/types/watch_evaluate_response.py b/src/prelude_python_sdk/types/watch_evaluate_response.py index a9b6def..d24703f 100644 --- a/src/prelude_python_sdk/types/watch_evaluate_response.py +++ b/src/prelude_python_sdk/types/watch_evaluate_response.py @@ -9,7 +9,7 @@ class RecipeRule(BaseModel): - outcome: Literal["TRIGGERED", "NOT_TRIGGERED", "NOT_EVALUATED"] + outcome: Literal["TRIGGERED", "NOT_TRIGGERED", "NOT_EVALUATED", "SKIPPED"] """What the rule concluded. - `TRIGGERED` - The condition held; `weight` was added to the score. @@ -17,6 +17,10 @@ class RecipeRule(BaseModel): - `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. """ rule_id: str @@ -26,6 +30,16 @@ class RecipeRule(BaseModel): of is still one you can reweight, switch off, or ask us about. """ + type: Literal["MANAGED", "CUSTOM"] + """ + 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. + """ + weight: int """What this rule contributes to the recipe's score when it triggers.""" @@ -51,6 +65,13 @@ class RecipeRule(BaseModel): request. `outcome` is `NOT_EVALUATED` and the failure is ours to fix. """ + version_id: Optional[str] = None + """ + 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. + """ + class Recipe(BaseModel): partial_evidence: bool @@ -67,7 +88,9 @@ class Recipe(BaseModel): """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. + 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. """ score: int diff --git a/src/prelude_python_sdk/types/watch_predict_response.py b/src/prelude_python_sdk/types/watch_predict_response.py index 499d6ed..13cfcf4 100644 --- a/src/prelude_python_sdk/types/watch_predict_response.py +++ b/src/prelude_python_sdk/types/watch_predict_response.py @@ -25,15 +25,24 @@ class WatchPredictResponse(BaseModel): List[ Literal[ "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", ] ] @@ -43,27 +52,41 @@ class WatchPredictResponse(BaseModel): 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. """