From 8750ba915c5af7bdf95019e87e8f339090a19cfc Mon Sep 17 00:00:00 2001 From: itaratukhin Date: Thu, 9 Apr 2026 21:18:20 +0200 Subject: [PATCH 1/2] feat: update APIv3 to Schema v3.1.0 --- .changeset/five-eggs-cheer.md | 5 ++ .changeset/tough-cherries-try.md | 5 ++ .schema-version | 2 +- docs/Tampering.md | 2 + docs/VirtualMachine.md | 1 + docs/WebhookJailbroken.md | 2 +- docs/WebhookTampering.md | 2 + docs/WebhookVirtualMachine.md | 1 + .../models/tampering.py | 64 ++++++++++++++++++- .../models/virtual_machine.py | 35 ++++++++-- .../models/webhook_jailbroken.py | 4 +- .../models/webhook_tampering.py | 62 +++++++++++++++++- .../models/webhook_virtual_machine.py | 35 ++++++++-- res/fingerprint-server-api.yaml | 64 ++++++++++++++++++- test/mocks/get_event_200.json | 24 +++++-- .../get_event_200_with_broken_format.json | 7 +- .../get_event_200_with_unknown_field.json | 6 +- test/mocks/get_event_search_200.json | 12 +++- test/mocks/webhook.json | 19 +++++- 19 files changed, 323 insertions(+), 29 deletions(-) create mode 100644 .changeset/five-eggs-cheer.md create mode 100644 .changeset/tough-cherries-try.md diff --git a/.changeset/five-eggs-cheer.md b/.changeset/five-eggs-cheer.md new file mode 100644 index 00000000..23ce19a4 --- /dev/null +++ b/.changeset/five-eggs-cheer.md @@ -0,0 +1,5 @@ +--- +"fingerprint-pro-server-api-python-sdk": minor +--- + +Add `ml_score` field to the `VirtualMachine` signal diff --git a/.changeset/tough-cherries-try.md b/.changeset/tough-cherries-try.md new file mode 100644 index 00000000..89e6e3b7 --- /dev/null +++ b/.changeset/tough-cherries-try.md @@ -0,0 +1,5 @@ +--- +"fingerprint-pro-server-api-python-sdk": minor +--- + +Add `confidence` and `ml_score` fields to the `Tampering` signal diff --git a/.schema-version b/.schema-version index a5db00c8..3a285c2b 100644 --- a/.schema-version +++ b/.schema-version @@ -1 +1 @@ -v2.12.0 \ No newline at end of file +v3.1.0 \ No newline at end of file diff --git a/docs/Tampering.md b/docs/Tampering.md index ddf8d492..84b6f718 100644 --- a/docs/Tampering.md +++ b/docs/Tampering.md @@ -4,7 +4,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **result** | **bool** | Indicates if an identification request from a browser or an Android SDK has been tampered with. Not supported in the iOS SDK, is always `false` for iOS requests. * `true` - If the request meets either of the following conditions: * Contains anomalous browser or device attributes that could not have been legitimately produced by the JavaScript agent or the Android SDK (see `anomalyScore`). * Originated from an anti-detect browser like Incognition (see `antiDetectBrowser`). * `false` - If the request is considered genuine or was generated by the iOS SDK. | +**confidence** | **str** | Confidence level of the tampering detection. If a tampering is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". | **anomaly_score** | **float** | A score that indicates the extent of anomalous data in the request. This field applies to requests originating from **both** browsers and Android SDKs. * Values above `0.5` indicate that the request has been tampered with. * Values below `0.5` indicate that the request is genuine. | +**ml_score** | **float** | A score that indicates the models calculated probability that an event is coming from an anti detect browser. * Values above `0.8` indicate that the request is an anti detect browser based on the ml model * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model | **anti_detect_browser** | **bool** | Anti-detect browsers try to evade identification by masking or manipulating their fingerprint to imitate legitimate browser configurations. This field does not apply to requests originating from mobile SDKs. * `true` - The browser resembles a known anti-detect browser, for example, Incognition. * `false` - The browser does not resemble an anti-detect browser or the request originates from a mobile SDK. | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/VirtualMachine.md b/docs/VirtualMachine.md index cdee06e3..713ed4fe 100644 --- a/docs/VirtualMachine.md +++ b/docs/VirtualMachine.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **result** | **bool** | `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. | +**ml_score** | **float** | Machine learning-based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/WebhookJailbroken.md b/docs/WebhookJailbroken.md index 9e375559..8d9b67e4 100644 --- a/docs/WebhookJailbroken.md +++ b/docs/WebhookJailbroken.md @@ -3,7 +3,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**result** | **bool** | iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. | [optional] +**result** | **bool** | iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/WebhookTampering.md b/docs/WebhookTampering.md index e1b5a5da..9f1ec3fd 100644 --- a/docs/WebhookTampering.md +++ b/docs/WebhookTampering.md @@ -4,7 +4,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **result** | **bool** | Indicates if an identification request from a browser or an Android SDK has been tampered with. Not supported in the iOS SDK, is always `false` for iOS requests. * `true` - If the request meets either of the following conditions: * Contains anomalous browser or device attributes that could not have been legitimately produced by the JavaScript agent or the Android SDK (see `anomalyScore`). * Originated from an anti-detect browser like Incognition (see `antiDetectBrowser`). * `false` - If the request is considered genuine or was generated by the iOS SDK. | [optional] +**confidence** | **str** | Confidence level of the tampering detection. If a tampering is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". | [optional] **anomaly_score** | **float** | A score that indicates the extent of anomalous data in the request. This field applies to requests originating from **both** browsers and Android SDKs. * Values above `0.5` indicate that the request has been tampered with. * Values below `0.5` indicate that the request is genuine. | [optional] +**ml_score** | **float** | A score that indicates the models calculated probability that an event is coming from an anti detect browser. * Values above `0.8` indicate that the request is an anti detect browser based on the ml model * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model | [optional] **anti_detect_browser** | **bool** | Anti-detect browsers try to evade identification by masking or manipulating their fingerprint to imitate legitimate browser configurations. This field does not apply to requests originating from mobile SDKs. * `true` - The browser resembles a known anti-detect browser, for example, Incognition. * `false` - The browser does not resemble an anti-detect browser or the request originates from a mobile SDK. | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/WebhookVirtualMachine.md b/docs/WebhookVirtualMachine.md index 3ab8faf2..6dbdaa70 100644 --- a/docs/WebhookVirtualMachine.md +++ b/docs/WebhookVirtualMachine.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **result** | **bool** | `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. | [optional] +**ml_score** | **float** | Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/fingerprint_pro_server_api_sdk/models/tampering.py b/fingerprint_pro_server_api_sdk/models/tampering.py index 43733c99..5c028440 100644 --- a/fingerprint_pro_server_api_sdk/models/tampering.py +++ b/fingerprint_pro_server_api_sdk/models/tampering.py @@ -29,30 +29,40 @@ class Tampering(BaseModel): """ swagger_types = { 'result': 'bool', + 'confidence': 'str', 'anomaly_score': 'float', + 'ml_score': 'float', 'anti_detect_browser': 'bool' } nullable_map = { 'result': False, + 'confidence': False, 'anomaly_score': False, + 'ml_score': False, 'anti_detect_browser': False } attribute_map = { 'result': 'result', + 'confidence': 'confidence', 'anomaly_score': 'anomalyScore', + 'ml_score': 'mlScore', 'anti_detect_browser': 'antiDetectBrowser' } - def __init__(self, result=None, anomaly_score=None, anti_detect_browser=None): # noqa: E501 + def __init__(self, result=None, confidence=None, anomaly_score=None, ml_score=None, anti_detect_browser=None): # noqa: E501 """Tampering - a model defined in Swagger""" # noqa: E501 self._result = None + self._confidence = None self._anomaly_score = None + self._ml_score = None self._anti_detect_browser = None self.discriminator = None self.result = result + self.confidence = confidence self.anomaly_score = anomaly_score + self.ml_score = ml_score self.anti_detect_browser = anti_detect_browser @property @@ -78,6 +88,35 @@ def result(self, result: bool): self._result = result + @property + def confidence(self) -> str: + """Gets the confidence of this Tampering. # noqa: E501 + + Confidence level of the tampering detection. If a tampering is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". # noqa: E501 + + :return: The confidence of this Tampering. # noqa: E501 + """ + return self._confidence + + @confidence.setter + def confidence(self, confidence: str): + """Sets the confidence of this Tampering. + + Confidence level of the tampering detection. If a tampering is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". # noqa: E501 + + :param confidence: The confidence of this Tampering. # noqa: E501 + """ + if confidence is None: + raise ValueError("Invalid value for `confidence`, must not be `None`") # noqa: E501 + allowed_values = ["low", "medium", "high"] # noqa: E501 + if (confidence not in allowed_values): + raise ValueError( + "Invalid value for `confidence` ({0}), must be one of {1}" # noqa: E501 + .format(confidence, allowed_values) + ) + + self._confidence = confidence + @property def anomaly_score(self) -> float: """Gets the anomaly_score of this Tampering. # noqa: E501 @@ -101,6 +140,29 @@ def anomaly_score(self, anomaly_score: float): self._anomaly_score = anomaly_score + @property + def ml_score(self) -> float: + """Gets the ml_score of this Tampering. # noqa: E501 + + A score that indicates the models calculated probability that an event is coming from an anti detect browser. * Values above `0.8` indicate that the request is an anti detect browser based on the ml model * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model # noqa: E501 + + :return: The ml_score of this Tampering. # noqa: E501 + """ + return self._ml_score + + @ml_score.setter + def ml_score(self, ml_score: float): + """Sets the ml_score of this Tampering. + + A score that indicates the models calculated probability that an event is coming from an anti detect browser. * Values above `0.8` indicate that the request is an anti detect browser based on the ml model * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model # noqa: E501 + + :param ml_score: The ml_score of this Tampering. # noqa: E501 + """ + if ml_score is None: + raise ValueError("Invalid value for `ml_score`, must not be `None`") # noqa: E501 + + self._ml_score = ml_score + @property def anti_detect_browser(self) -> bool: """Gets the anti_detect_browser of this Tampering. # noqa: E501 diff --git a/fingerprint_pro_server_api_sdk/models/virtual_machine.py b/fingerprint_pro_server_api_sdk/models/virtual_machine.py index 3469ad46..c1272266 100644 --- a/fingerprint_pro_server_api_sdk/models/virtual_machine.py +++ b/fingerprint_pro_server_api_sdk/models/virtual_machine.py @@ -28,22 +28,28 @@ class VirtualMachine(BaseModel): and the value is json key in definition. """ swagger_types = { - 'result': 'bool' + 'result': 'bool', + 'ml_score': 'float' } nullable_map = { - 'result': False + 'result': False, + 'ml_score': False } attribute_map = { - 'result': 'result' + 'result': 'result', + 'ml_score': 'mlScore' } - def __init__(self, result=None): # noqa: E501 + def __init__(self, result=None, ml_score=None): # noqa: E501 """VirtualMachine - a model defined in Swagger""" # noqa: E501 self._result = None + self._ml_score = None self.discriminator = None self.result = result + if ml_score is not None: + self.ml_score = ml_score @property def result(self) -> bool: @@ -68,3 +74,24 @@ def result(self, result: bool): self._result = result + @property + def ml_score(self) -> Optional[float]: + """Gets the ml_score of this VirtualMachine. # noqa: E501 + + Machine learning-based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result # noqa: E501 + + :return: The ml_score of this VirtualMachine. # noqa: E501 + """ + return self._ml_score + + @ml_score.setter + def ml_score(self, ml_score: Optional[float]): + """Sets the ml_score of this VirtualMachine. + + Machine learning-based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result # noqa: E501 + + :param ml_score: The ml_score of this VirtualMachine. # noqa: E501 + """ + + self._ml_score = ml_score + diff --git a/fingerprint_pro_server_api_sdk/models/webhook_jailbroken.py b/fingerprint_pro_server_api_sdk/models/webhook_jailbroken.py index bcd0e811..4da9edc2 100644 --- a/fingerprint_pro_server_api_sdk/models/webhook_jailbroken.py +++ b/fingerprint_pro_server_api_sdk/models/webhook_jailbroken.py @@ -50,7 +50,7 @@ def __init__(self, result=None): # noqa: E501 def result(self) -> Optional[bool]: """Gets the result of this WebhookJailbroken. # noqa: E501 - iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. # noqa: E501 + iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. # noqa: E501 :return: The result of this WebhookJailbroken. # noqa: E501 """ @@ -60,7 +60,7 @@ def result(self) -> Optional[bool]: def result(self, result: Optional[bool]): """Sets the result of this WebhookJailbroken. - iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. # noqa: E501 + iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. # noqa: E501 :param result: The result of this WebhookJailbroken. # noqa: E501 """ diff --git a/fingerprint_pro_server_api_sdk/models/webhook_tampering.py b/fingerprint_pro_server_api_sdk/models/webhook_tampering.py index 149b4059..6f5e2b2e 100644 --- a/fingerprint_pro_server_api_sdk/models/webhook_tampering.py +++ b/fingerprint_pro_server_api_sdk/models/webhook_tampering.py @@ -29,32 +29,44 @@ class WebhookTampering(BaseModel): """ swagger_types = { 'result': 'bool', + 'confidence': 'str', 'anomaly_score': 'float', + 'ml_score': 'float', 'anti_detect_browser': 'bool' } nullable_map = { 'result': False, + 'confidence': False, 'anomaly_score': False, + 'ml_score': False, 'anti_detect_browser': False } attribute_map = { 'result': 'result', + 'confidence': 'confidence', 'anomaly_score': 'anomalyScore', + 'ml_score': 'mlScore', 'anti_detect_browser': 'antiDetectBrowser' } - def __init__(self, result=None, anomaly_score=None, anti_detect_browser=None): # noqa: E501 + def __init__(self, result=None, confidence=None, anomaly_score=None, ml_score=None, anti_detect_browser=None): # noqa: E501 """WebhookTampering - a model defined in Swagger""" # noqa: E501 self._result = None + self._confidence = None self._anomaly_score = None + self._ml_score = None self._anti_detect_browser = None self.discriminator = None if result is not None: self.result = result + if confidence is not None: + self.confidence = confidence if anomaly_score is not None: self.anomaly_score = anomaly_score + if ml_score is not None: + self.ml_score = ml_score if anti_detect_browser is not None: self.anti_detect_browser = anti_detect_browser @@ -79,6 +91,33 @@ def result(self, result: Optional[bool]): self._result = result + @property + def confidence(self) -> Optional[str]: + """Gets the confidence of this WebhookTampering. # noqa: E501 + + Confidence level of the tampering detection. If a tampering is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". # noqa: E501 + + :return: The confidence of this WebhookTampering. # noqa: E501 + """ + return self._confidence + + @confidence.setter + def confidence(self, confidence: Optional[str]): + """Sets the confidence of this WebhookTampering. + + Confidence level of the tampering detection. If a tampering is not detected, confidence is \"high\". If it's detected, can be \"low\", \"medium\", or \"high\". # noqa: E501 + + :param confidence: The confidence of this WebhookTampering. # noqa: E501 + """ + allowed_values = ["low", "medium", "high"] # noqa: E501 + if (confidence not in allowed_values): + raise ValueError( + "Invalid value for `confidence` ({0}), must be one of {1}" # noqa: E501 + .format(confidence, allowed_values) + ) + + self._confidence = confidence + @property def anomaly_score(self) -> Optional[float]: """Gets the anomaly_score of this WebhookTampering. # noqa: E501 @@ -100,6 +139,27 @@ def anomaly_score(self, anomaly_score: Optional[float]): self._anomaly_score = anomaly_score + @property + def ml_score(self) -> Optional[float]: + """Gets the ml_score of this WebhookTampering. # noqa: E501 + + A score that indicates the models calculated probability that an event is coming from an anti detect browser. * Values above `0.8` indicate that the request is an anti detect browser based on the ml model * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model # noqa: E501 + + :return: The ml_score of this WebhookTampering. # noqa: E501 + """ + return self._ml_score + + @ml_score.setter + def ml_score(self, ml_score: Optional[float]): + """Sets the ml_score of this WebhookTampering. + + A score that indicates the models calculated probability that an event is coming from an anti detect browser. * Values above `0.8` indicate that the request is an anti detect browser based on the ml model * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model # noqa: E501 + + :param ml_score: The ml_score of this WebhookTampering. # noqa: E501 + """ + + self._ml_score = ml_score + @property def anti_detect_browser(self) -> Optional[bool]: """Gets the anti_detect_browser of this WebhookTampering. # noqa: E501 diff --git a/fingerprint_pro_server_api_sdk/models/webhook_virtual_machine.py b/fingerprint_pro_server_api_sdk/models/webhook_virtual_machine.py index 3b2d2ce1..5f77c749 100644 --- a/fingerprint_pro_server_api_sdk/models/webhook_virtual_machine.py +++ b/fingerprint_pro_server_api_sdk/models/webhook_virtual_machine.py @@ -28,23 +28,29 @@ class WebhookVirtualMachine(BaseModel): and the value is json key in definition. """ swagger_types = { - 'result': 'bool' + 'result': 'bool', + 'ml_score': 'float' } nullable_map = { - 'result': False + 'result': False, + 'ml_score': False } attribute_map = { - 'result': 'result' + 'result': 'result', + 'ml_score': 'mlScore' } - def __init__(self, result=None): # noqa: E501 + def __init__(self, result=None, ml_score=None): # noqa: E501 """WebhookVirtualMachine - a model defined in Swagger""" # noqa: E501 self._result = None + self._ml_score = None self.discriminator = None if result is not None: self.result = result + if ml_score is not None: + self.ml_score = ml_score @property def result(self) -> Optional[bool]: @@ -67,3 +73,24 @@ def result(self, result: Optional[bool]): self._result = result + @property + def ml_score(self) -> Optional[float]: + """Gets the ml_score of this WebhookVirtualMachine. # noqa: E501 + + Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result # noqa: E501 + + :return: The ml_score of this WebhookVirtualMachine. # noqa: E501 + """ + return self._ml_score + + @ml_score.setter + def ml_score(self, ml_score: Optional[float]): + """Sets the ml_score of this WebhookVirtualMachine. + + Machine learning–based virtual machine score, represented as a floating-point value between 0 and 1 (inclusive), with up to three decimal places of precision. A higher score means a higher confidence in the positive `virtual_machine` detection result # noqa: E501 + + :param ml_score: The ml_score of this WebhookVirtualMachine. # noqa: E501 + """ + + self._ml_score = ml_score + diff --git a/res/fingerprint-server-api.yaml b/res/fingerprint-server-api.yaml index 21caa11d..6f941ec3 100644 --- a/res/fingerprint-server-api.yaml +++ b/res/fingerprint-server-api.yaml @@ -1884,7 +1884,9 @@ components: additionalProperties: false required: - result + - confidence - anomalyScore + - mlScore - antiDetectBrowser properties: result: @@ -1897,6 +1899,16 @@ components: * Contains anomalous browser or device attributes that could not have been legitimately produced by the JavaScript agent or the Android SDK (see `anomalyScore`). * Originated from an anti-detect browser like Incognition (see `antiDetectBrowser`). * `false` - If the request is considered genuine or was generated by the iOS SDK. + confidence: + type: string + enum: + - low + - medium + - high + description: | + Confidence level of the tampering detection. + If a tampering is not detected, confidence is "high". + If it's detected, can be "low", "medium", or "high". anomalyScore: type: number format: double @@ -1908,6 +1920,16 @@ components: and Android SDKs. * Values above `0.5` indicate that the request has been tampered with. * Values below `0.5` indicate that the request is genuine. + mlScore: + type: number + format: double + minimum: 0 + maximum: 1 + description: > + A score that indicates the models calculated probability that an + event is coming from an anti detect browser. + * Values above `0.8` indicate that the request is an anti detect browser based on the ml model + * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model antiDetectBrowser: type: boolean description: > @@ -2055,6 +2077,16 @@ components: description: > `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. + mlScore: + type: number + format: double + minimum: 0 + maximum: 1 + description: > + Machine learning-based virtual machine score, represented as a + floating-point value between 0 and 1 (inclusive), with up to three + decimal places of precision. A higher score means a higher + confidence in the positive `virtual_machine` detection result ProductVirtualMachine: type: object additionalProperties: false @@ -2679,6 +2711,16 @@ components: * Contains anomalous browser or device attributes that could not have been legitimately produced by the JavaScript agent or the Android SDK (see `anomalyScore`). * Originated from an anti-detect browser like Incognition (see `antiDetectBrowser`). * `false` - If the request is considered genuine or was generated by the iOS SDK. + confidence: + type: string + enum: + - low + - medium + - high + description: | + Confidence level of the tampering detection. + If a tampering is not detected, confidence is "high". + If it's detected, can be "low", "medium", or "high". anomalyScore: type: number format: double @@ -2690,6 +2732,16 @@ components: and Android SDKs. * Values above `0.5` indicate that the request has been tampered with. * Values below `0.5` indicate that the request is genuine. + mlScore: + type: number + format: double + minimum: 0 + maximum: 1 + description: > + A score that indicates the models calculated probability that an + event is coming from an anti detect browser. + * Values above `0.8` indicate that the request is an anti detect browser based on the ml model + * Values below `0.8` indicate that the request is not an anti detect browser based on the ml model antiDetectBrowser: type: boolean description: > @@ -2743,7 +2795,7 @@ components: result: type: boolean description: | - iOS specific jailbreak detection. There are 2 values: + iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. WebhookFrida: @@ -2776,6 +2828,16 @@ components: description: > `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. + mlScore: + type: number + format: double + minimum: 0 + maximum: 1 + description: > + Machine learning–based virtual machine score, represented as a + floating-point value between 0 and 1 (inclusive), with up to three + decimal places of precision. A higher score means a higher + confidence in the positive `virtual_machine` detection result WebhookRawDeviceAttributes: type: object description: > diff --git a/test/mocks/get_event_200.json b/test/mocks/get_event_200.json index 7560b9a6..03e94df1 100644 --- a/test/mocks/get_event_200.json +++ b/test/mocks/get_event_200.json @@ -58,7 +58,17 @@ }, "sdk": { "platform": "js", - "version": "3.11.10" + "version": "3.11.10", + "integrations": [ + { + "name": "fingerprint-pro-react", + "version": "3.11.10", + "subintegration": { + "name": "preact", + "version": "10.21.0" + } + } + ] }, "replayed": false } @@ -116,7 +126,8 @@ "asn": { "asn": "7922", "name": "COMCAST-7922", - "network": "73.136.0.0/13" + "network": "73.136.0.0/13", + "type": "isp" }, "datacenter": { "result": true, @@ -152,7 +163,8 @@ "asn": { "asn": "6805", "name": "Telefonica Germany", - "network": "2a02:3100::/24" + "network": "2a02:3100::/24", + "type": "isp" }, "datacenter": { "result": false, @@ -194,6 +206,7 @@ "data": { "result": true, "confidence": "high", + "mlScore": 0.99, "details": { "proxyType": "residential", "lastSeenAt": "2025-08-12T13:00:00Z" @@ -208,6 +221,8 @@ "tampering": { "data": { "result": false, + "confidence": "high", + "mlScore": 0.3231, "anomalyScore": 0.1955, "antiDetectBrowser": false } @@ -240,7 +255,8 @@ }, "virtualMachine": { "data": { - "result": false + "result": true, + "mlScore": 0.2 } }, "rawDeviceAttributes": { diff --git a/test/mocks/get_event_200_with_broken_format.json b/test/mocks/get_event_200_with_broken_format.json index 58081140..74e137d7 100644 --- a/test/mocks/get_event_200_with_broken_format.json +++ b/test/mocks/get_event_200_with_broken_format.json @@ -114,7 +114,8 @@ "asn": { "asn": "7922", "name": "COMCAST-7922", - "network": "73.136.0.0/13" + "network": "73.136.0.0/13", + "type": "isp" }, "datacenter": { "result": true, @@ -150,7 +151,8 @@ "asn": { "asn": "6805", "name": "Telefonica Germany", - "network": "2a02:3100::/24" + "network": "2a02:3100::/24", + "type": "isp" }, "datacenter": { "result": false, @@ -189,6 +191,7 @@ "data": { "result": true, "confidence": "high", + "mlScore": 0.99, "details": { "proxyType": "residential", "lastSeenAt": "2025-08-12T13:00:00Z" diff --git a/test/mocks/get_event_200_with_unknown_field.json b/test/mocks/get_event_200_with_unknown_field.json index 6af6ad63..7464c591 100644 --- a/test/mocks/get_event_200_with_unknown_field.json +++ b/test/mocks/get_event_200_with_unknown_field.json @@ -116,7 +116,8 @@ "asn": { "asn": "7922", "name": "COMCAST-7922", - "network": "73.136.0.0/13" + "network": "73.136.0.0/13", + "type": "isp" }, "datacenter": { "result": true, @@ -152,7 +153,8 @@ "asn": { "asn": "6805", "name": "Telefonica Germany", - "network": "2a02:3100::/24" + "network": "2a02:3100::/24", + "type": "isp" }, "datacenter": { "result": false, diff --git a/test/mocks/get_event_search_200.json b/test/mocks/get_event_search_200.json index 27b7848d..84d29b55 100644 --- a/test/mocks/get_event_search_200.json +++ b/test/mocks/get_event_search_200.json @@ -114,7 +114,8 @@ "asn": { "asn": "7922", "name": "COMCAST-7922", - "network": "73.136.0.0/13" + "network": "73.136.0.0/13", + "type": "isp" }, "datacenter": { "result": true, @@ -150,7 +151,8 @@ "asn": { "asn": "6805", "name": "Telefonica Germany", - "network": "2a02:3100::/24" + "network": "2a02:3100::/24", + "type": "isp" }, "datacenter": { "result": false, @@ -192,6 +194,7 @@ "data": { "result": false, "confidence": "high", + "mlScore": 0.99, "details": { "proxyType": "residential", "lastSeenAt": "2025-08-12T13:00:00Z" @@ -206,6 +209,8 @@ "tampering": { "data": { "result": false, + "confidence": "high", + "mlScore": 0.3231, "anomalyScore": 0.1955, "antiDetectBrowser": false } @@ -238,7 +243,8 @@ }, "virtualMachine": { "data": { - "result": false + "result": true, + "mlScore": 0.2 } }, "rawDeviceAttributes": { diff --git a/test/mocks/webhook.json b/test/mocks/webhook.json index 1180fcdc..c1dd8a48 100644 --- a/test/mocks/webhook.json +++ b/test/mocks/webhook.json @@ -98,7 +98,8 @@ "asn": { "asn": "7922", "name": "COMCAST-7922", - "network": "73.136.0.0/13" + "network": "73.136.0.0/13", + "type": "isp" }, "datacenter": { "result": true, @@ -132,6 +133,7 @@ "proxy": { "result": true, "confidence": "high", + "mlScore": 0.99, "details": { "proxyType": "residential", "lastSeenAt": "2025-08-12T13:00:00Z" @@ -159,7 +161,8 @@ "result": false }, "virtualMachine": { - "result": false + "result": true, + "mlScore": 0.2 }, "rawDeviceAttributes": { "architecture": { @@ -250,7 +253,17 @@ }, "sdk": { "platform": "js", - "version": "3.11.10" + "version": "3.11.10", + "integrations": [ + { + "name": "fingerprint-pro-react", + "version": "3.11.10", + "subintegration": { + "name": "preact", + "version": "10.21.0" + } + } + ] }, "replayed": false, "supplementaryIds": { From cbd9e4fdc9790336d23df986337465394c9959b0 Mon Sep 17 00:00:00 2001 From: itaratukhin Date: Mon, 13 Apr 2026 14:28:02 +0200 Subject: [PATCH 2/2] chore: fix `pypy` tested version to 3.11 as 3.9 and 3.10 became unavailable --- .github/workflows/functional_tests.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/functional_tests.yml b/.github/workflows/functional_tests.yml index 88e81790..d03cad5c 100644 --- a/.github/workflows/functional_tests.yml +++ b/.github/workflows/functional_tests.yml @@ -23,7 +23,7 @@ jobs: fail-fast: false max-parallel: 1 matrix: - python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10" ] + python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.11" ] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 226e9452..712b384a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10" ] + python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.11" ] steps: - uses: actions/checkout@v4