Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/thick-toys-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fingerprint-pro-server-api-python-sdk": minor
---

Add `details` object to the `proxy` signal. This field includes the `type` of the detected proxy (`residential` or `data_center`) and the `lastSeenAt` timestamp of when an IP was last observed to show proxy-like behavior.
2 changes: 1 addition & 1 deletion .schema-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.9.0
2.10.0
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ Class | Method | HTTP request | Description
- [Products](docs/Products.md)
- [Proxy](docs/Proxy.md)
- [ProxyConfidence](docs/ProxyConfidence.md)
- [ProxyDetails](docs/ProxyDetails.md)
- [RawDeviceAttribute](docs/RawDeviceAttribute.md)
- [RawDeviceAttributeError](docs/RawDeviceAttributeError.md)
- [RawDeviceAttributes](docs/RawDeviceAttributes.md)
Expand Down
1 change: 1 addition & 0 deletions docs/Proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**result** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy |
**confidence** | [**ProxyConfidence**](ProxyConfidence.md) | |
**details** | [**ProxyDetails**](ProxyDetails.md) | | [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)

12 changes: 12 additions & 0 deletions docs/ProxyDetails.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ProxyDetails
Proxy detection details (present if proxy is detected)


## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**proxy_type** | **str** | Residential proxies use real user IP addresses to appear as legitimate traffic, while data center proxies are public proxies hosted in data centers |
**last_seen_at** | **datetime** | ISO 8601 formatted timestamp in UTC with hourly resolution of when this IP was last seen as a proxy when available. | [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)

1 change: 1 addition & 0 deletions docs/WebhookProxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**result** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional]
**confidence** | [**ProxyConfidence**](ProxyConfidence.md) | | [optional]
**details** | [**ProxyDetails**](ProxyDetails.md) | | [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)

1 change: 1 addition & 0 deletions fingerprint_pro_server_api_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
from fingerprint_pro_server_api_sdk.models.products import Products
from fingerprint_pro_server_api_sdk.models.proxy import Proxy
from fingerprint_pro_server_api_sdk.models.proxy_confidence import ProxyConfidence
from fingerprint_pro_server_api_sdk.models.proxy_details import ProxyDetails
from fingerprint_pro_server_api_sdk.models.raw_device_attribute import RawDeviceAttribute
from fingerprint_pro_server_api_sdk.models.raw_device_attribute_error import RawDeviceAttributeError
from fingerprint_pro_server_api_sdk.models.raw_device_attributes import RawDeviceAttributes
Expand Down
1 change: 1 addition & 0 deletions fingerprint_pro_server_api_sdk/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
from fingerprint_pro_server_api_sdk.models.products import Products
from fingerprint_pro_server_api_sdk.models.proxy import Proxy
from fingerprint_pro_server_api_sdk.models.proxy_confidence import ProxyConfidence
from fingerprint_pro_server_api_sdk.models.proxy_details import ProxyDetails
from fingerprint_pro_server_api_sdk.models.raw_device_attribute import RawDeviceAttribute
from fingerprint_pro_server_api_sdk.models.raw_device_attribute_error import RawDeviceAttributeError
from fingerprint_pro_server_api_sdk.models.raw_device_attributes import RawDeviceAttributes
Expand Down
34 changes: 30 additions & 4 deletions fingerprint_pro_server_api_sdk/models/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from typing import Dict, List, Optional # noqa: F401
from fingerprint_pro_server_api_sdk.base_model import BaseModel
from fingerprint_pro_server_api_sdk.models.proxy_confidence import ProxyConfidence
from fingerprint_pro_server_api_sdk.models.proxy_details import ProxyDetails


class Proxy(BaseModel):
Expand All @@ -30,26 +31,32 @@ class Proxy(BaseModel):
"""
swagger_types = {
'result': 'bool',
'confidence': 'ProxyConfidence'
'confidence': 'ProxyConfidence',
'details': 'ProxyDetails'
}

nullable_map = {
'result': False,
'confidence': False
'confidence': False,
'details': False
}

attribute_map = {
'result': 'result',
'confidence': 'confidence'
'confidence': 'confidence',
'details': 'details'
}

def __init__(self, result=None, confidence=None): # noqa: E501
def __init__(self, result=None, confidence=None, details=None): # noqa: E501
"""Proxy - a model defined in Swagger""" # noqa: E501
self._result = None
self._confidence = None
self._details = None
self.discriminator = None
self.result = result
self.confidence = confidence
if details is not None:
self.details = details

@property
def result(self) -> bool:
Expand Down Expand Up @@ -95,3 +102,22 @@ def confidence(self, confidence: ProxyConfidence):

self._confidence = confidence

@property
def details(self) -> Optional[ProxyDetails]:
"""Gets the details of this Proxy. # noqa: E501


:return: The details of this Proxy. # noqa: E501
"""
return self._details

@details.setter
def details(self, details: Optional[ProxyDetails]):
"""Sets the details of this Proxy.


:param details: The details of this Proxy. # noqa: E501
"""

self._details = details

107 changes: 107 additions & 0 deletions fingerprint_pro_server_api_sdk/models/proxy_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# coding: utf-8

"""
Fingerprint Server API

Fingerprint Server API allows you to search, update, and delete identification events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device. # noqa: E501

OpenAPI spec version: 3
Contact: support@fingerprint.com
Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

import re # noqa: F401
from typing import Dict, List, Optional # noqa: F401
from fingerprint_pro_server_api_sdk.base_model import BaseModel
from datetime import datetime


class ProxyDetails(BaseModel):
"""
Proxy detection details (present if proxy is detected)

NOTE: This class is auto generated by the swagger code generator program.

Do not edit the class manually.
"""
"""
Attributes:
swagger_types (dict): The key is attribute name
and the value is attribute type.
attribute_map (dict): The key is attribute name
and the value is json key in definition.
"""
swagger_types = {
'proxy_type': 'str',
'last_seen_at': 'datetime'
}

nullable_map = {
'proxy_type': False,
'last_seen_at': False
}

attribute_map = {
'proxy_type': 'proxyType',
'last_seen_at': 'lastSeenAt'
}

def __init__(self, proxy_type=None, last_seen_at=None): # noqa: E501
"""ProxyDetails - a model defined in Swagger""" # noqa: E501
self._proxy_type = None
self._last_seen_at = None
self.discriminator = None
self.proxy_type = proxy_type
if last_seen_at is not None:
self.last_seen_at = last_seen_at

@property
def proxy_type(self) -> str:
"""Gets the proxy_type of this ProxyDetails. # noqa: E501

Residential proxies use real user IP addresses to appear as legitimate traffic, while data center proxies are public proxies hosted in data centers # noqa: E501

:return: The proxy_type of this ProxyDetails. # noqa: E501
"""
return self._proxy_type

@proxy_type.setter
def proxy_type(self, proxy_type: str):
"""Sets the proxy_type of this ProxyDetails.

Residential proxies use real user IP addresses to appear as legitimate traffic, while data center proxies are public proxies hosted in data centers # noqa: E501

:param proxy_type: The proxy_type of this ProxyDetails. # noqa: E501
"""
if proxy_type is None:
raise ValueError("Invalid value for `proxy_type`, must not be `None`") # noqa: E501
allowed_values = ["residential", "data_center"] # noqa: E501
if (proxy_type not in allowed_values):
raise ValueError(
"Invalid value for `proxy_type` ({0}), must be one of {1}" # noqa: E501
.format(proxy_type, allowed_values)
)

self._proxy_type = proxy_type

@property
def last_seen_at(self) -> Optional[datetime]:
"""Gets the last_seen_at of this ProxyDetails. # noqa: E501

ISO 8601 formatted timestamp in UTC with hourly resolution of when this IP was last seen as a proxy when available. # noqa: E501

:return: The last_seen_at of this ProxyDetails. # noqa: E501
"""
return self._last_seen_at

@last_seen_at.setter
def last_seen_at(self, last_seen_at: Optional[datetime]):
"""Sets the last_seen_at of this ProxyDetails.

ISO 8601 formatted timestamp in UTC with hourly resolution of when this IP was last seen as a proxy when available. # noqa: E501

:param last_seen_at: The last_seen_at of this ProxyDetails. # noqa: E501
"""

self._last_seen_at = last_seen_at

34 changes: 30 additions & 4 deletions fingerprint_pro_server_api_sdk/models/webhook_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from typing import Dict, List, Optional # noqa: F401
from fingerprint_pro_server_api_sdk.base_model import BaseModel
from fingerprint_pro_server_api_sdk.models.proxy_confidence import ProxyConfidence
from fingerprint_pro_server_api_sdk.models.proxy_details import ProxyDetails


class WebhookProxy(BaseModel):
Expand All @@ -30,28 +31,34 @@ class WebhookProxy(BaseModel):
"""
swagger_types = {
'result': 'bool',
'confidence': 'ProxyConfidence'
'confidence': 'ProxyConfidence',
'details': 'ProxyDetails'
}

nullable_map = {
'result': False,
'confidence': False
'confidence': False,
'details': False
}

attribute_map = {
'result': 'result',
'confidence': 'confidence'
'confidence': 'confidence',
'details': 'details'
}

def __init__(self, result=None, confidence=None): # noqa: E501
def __init__(self, result=None, confidence=None, details=None): # noqa: E501
"""WebhookProxy - a model defined in Swagger""" # noqa: E501
self._result = None
self._confidence = None
self._details = None
self.discriminator = None
if result is not None:
self.result = result
if confidence is not None:
self.confidence = confidence
if details is not None:
self.details = details

@property
def result(self) -> Optional[bool]:
Expand Down Expand Up @@ -93,3 +100,22 @@ def confidence(self, confidence: Optional[ProxyConfidence]):

self._confidence = confidence

@property
def details(self) -> Optional[ProxyDetails]:
"""Gets the details of this WebhookProxy. # noqa: E501


:return: The details of this WebhookProxy. # noqa: E501
"""
return self._details

@details.setter
def details(self, details: Optional[ProxyDetails]):
"""Sets the details of this WebhookProxy.


:param details: The details of this WebhookProxy. # noqa: E501
"""

self._details = details

29 changes: 29 additions & 0 deletions res/fingerprint-server-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,31 @@ components:
Confidence level of the proxy detection.
If a proxy is not detected, confidence is "high".
If it's detected, can be "low", "medium", or "high".
ProxyDetails:
type: object
nullable: true
additionalProperties: false
description: Proxy detection details (present if proxy is detected)
required:
- proxyType
properties:
proxyType:
type: string
enum:
- residential
- data_center
description: >
Residential proxies use real user IP addresses to appear as
legitimate traffic,

while data center proxies are public proxies hosted in data centers
lastSeenAt:
type: string
format: date-time
x-ogen-time-format: 2006-01-02T15:00:00.000Z
description: |
ISO 8601 formatted timestamp in UTC with hourly resolution
of when this IP was last seen as a proxy when available.
Proxy:
type: object
additionalProperties: false
Expand All @@ -1594,6 +1619,8 @@ components:
known recent residential proxy
confidence:
$ref: '#/components/schemas/ProxyConfidence'
details:
$ref: '#/components/schemas/ProxyDetails'
ProductProxy:
type: object
additionalProperties: false
Expand Down Expand Up @@ -2355,6 +2382,8 @@ components:
known recent residential proxy
confidence:
$ref: '#/components/schemas/ProxyConfidence'
details:
$ref: '#/components/schemas/ProxyDetails'
WebhookTampering:
type: object
additionalProperties: false
Expand Down
8 changes: 6 additions & 2 deletions test/mocks/get_event_200.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,12 @@
},
"proxy": {
"data": {
"result": false,
"confidence": "high"
"result": true,
"confidence": "high",
"details": {
"proxyType": "residential",
"lastSeenAt": "2025-08-12T13:00:00Z"
}
}
},
"incognito": {
Expand Down
8 changes: 6 additions & 2 deletions test/mocks/get_event_200_with_broken_format.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,12 @@
},
"proxy": {
"data": {
"result": false,
"confidence": "high"
"result": true,
"confidence": "high",
"details": {
"proxyType": "residential",
"lastSeenAt": "2025-08-12T13:00:00Z"
}
}
},
"incognito": {
Expand Down
Loading
Loading