diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES index 9b1fe46b..c2f3754f 100644 --- a/.openapi-generator/FILES +++ b/.openapi-generator/FILES @@ -9,11 +9,14 @@ docs/models/BotResult.md docs/models/BrowserDetails.md docs/models/Canvas.md docs/models/DecryptionKey.md +docs/models/EdgeRequest.md +docs/models/EdgeRequestHeadersInner.md docs/models/Emoji.md docs/models/Error.md docs/models/ErrorCode.md docs/models/ErrorResponse.md docs/models/Event.md +docs/models/EventEdge.md docs/models/EventRuleAction.md docs/models/EventRuleActionAllow.md docs/models/EventRuleActionBlock.md @@ -96,11 +99,14 @@ src/Fingerprint.ServerSdk/Model/BotInfoIdentity.cs src/Fingerprint.ServerSdk/Model/BotResult.cs src/Fingerprint.ServerSdk/Model/BrowserDetails.cs src/Fingerprint.ServerSdk/Model/Canvas.cs +src/Fingerprint.ServerSdk/Model/EdgeRequest.cs +src/Fingerprint.ServerSdk/Model/EdgeRequestHeadersInner.cs src/Fingerprint.ServerSdk/Model/Emoji.cs src/Fingerprint.ServerSdk/Model/Error.cs src/Fingerprint.ServerSdk/Model/ErrorCode.cs src/Fingerprint.ServerSdk/Model/ErrorResponse.cs src/Fingerprint.ServerSdk/Model/Event.cs +src/Fingerprint.ServerSdk/Model/EventEdge.cs src/Fingerprint.ServerSdk/Model/EventRuleAction.cs src/Fingerprint.ServerSdk/Model/EventRuleActionAllow.cs src/Fingerprint.ServerSdk/Model/EventRuleActionBlock.cs diff --git a/README.md b/README.md index 1cf9f001..f1ec4a10 100644 --- a/README.md +++ b/README.md @@ -299,6 +299,7 @@ All URIs are relative to *https://api.fpjs.io/v4* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- +*FingerprintApi* | [**AnalyzeRequestForAutomationIntelligenceAsync**](docs/FingerprintApi.md#analyzerequestforautomationintelligence) | **POST** /edge | Collect Automation Intelligence. *FingerprintApi* | [**DeleteVisitorDataAsync**](docs/FingerprintApi.md#deletevisitordata) | **DELETE** /visitors/{visitor_id} | Delete a visitor ID *FingerprintApi* | [**GetEventAsync**](docs/FingerprintApi.md#getevent) | **GET** /events/{event_id} | Get an event by event ID *FingerprintApi* | [**SearchEventsAsync**](docs/FingerprintApi.md#searchevents) | **GET** /events | Search events @@ -315,11 +316,14 @@ Class | Method | HTTP request | Description - [Model.BotResult](docs/models/BotResult.md) - [Model.BrowserDetails](docs/models/BrowserDetails.md) - [Model.Canvas](docs/models/Canvas.md) + - [Model.EdgeRequest](docs/models/EdgeRequest.md) + - [Model.EdgeRequestHeadersInner](docs/models/EdgeRequestHeadersInner.md) - [Model.Emoji](docs/models/Emoji.md) - [Model.Error](docs/models/Error.md) - [Model.ErrorCode](docs/models/ErrorCode.md) - [Model.ErrorResponse](docs/models/ErrorResponse.md) - [Model.Event](docs/models/Event.md) + - [Model.EventEdge](docs/models/EventEdge.md) - [Model.EventRuleAction](docs/models/EventRuleAction.md) - [Model.EventRuleActionAllow](docs/models/EventRuleActionAllow.md) - [Model.EventRuleActionBlock](docs/models/EventRuleActionBlock.md) diff --git a/docs/FingerprintApi.md b/docs/FingerprintApi.md index c65ac967..3349376d 100644 --- a/docs/FingerprintApi.md +++ b/docs/FingerprintApi.md @@ -4,11 +4,108 @@ All URIs are relative to *https://api.fpjs.io/v4* | Method | HTTP request | Description | |--------|--------------|-------------| +| [**AnalyzeRequestForAutomationIntelligence**](FingerprintApi.md#analyzerequestforautomationintelligence) | **POST** /edge | Collect Automation Intelligence. | | [**DeleteVisitorData**](FingerprintApi.md#deletevisitordata) | **DELETE** /visitors/{visitor_id} | Delete a visitor ID | | [**GetEvent**](FingerprintApi.md#getevent) | **GET** /events/{event_id} | Get an event by event ID | | [**SearchEvents**](FingerprintApi.md#searchevents) | **GET** /events | Search events | | [**UpdateEvent**](FingerprintApi.md#updateevent) | **PATCH** /events/{event_id} | Update an event | + +# **AnalyzeRequestForAutomationIntelligence** +> EventEdge AnalyzeRequestForAutomationIntelligence (EdgeRequest edgeRequest) + +Collect Automation Intelligence. + +The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. + +This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). + +The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. + +Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. + +The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. + +Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. + +### Event Retrieval + +Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. + +Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + + +### Example +```csharp +using System.Collections.Generic; +using System.Diagnostics; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Fingerprint.ServerSdk.Api; +using Fingerprint.ServerSdk.Client; +using Fingerprint.ServerSdk.Extensions; +using Fingerprint.ServerSdk.Model; + +namespace AnalyzeRequestForAutomationIntelligenceExample +{ + public static async Task Main(string[] args) + { + var host = CreateHostBuilder(args).Build(); + var api = host.Services.GetRequiredService(); + + var edgeRequest = new EdgeRequest( + headers: new List { new EdgeRequestHeadersInner("Host", "example.com") }, + method: "GET", + url: "https://example.com/login", + ipv4Address: "34.162.244.71" + ); // EdgeRequest | + + // Collect Automation Intelligence. + IAnalyzeRequestForAutomationIntelligenceApiResponse result = await api.AnalyzeRequestForAutomationIntelligenceAsync(edgeRequest); + Debug.WriteLine(result.Ok()); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .ConfigureApi((_, _, options) => + { + BearerToken token = new("YOUR_API_KEY"); + options.AddTokens(token); + }); +} +``` + +### Parameters + +| Name | Type | Description | Notes | +|------|------|-------------|-------| +| **edgeRequest** | [**EdgeRequest**](EdgeRequest.md) | | | + +### Return type + +[**EventEdge**](EventEdge.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **200** | OK. | - | +| **400** | Bad request. The request payload is not valid. | - | +| **403** | Forbidden. Access to this API is denied. | - | +| **413** | Bad request. The request payload is too large. | - | +| **429** | Too Many Requests. The request is throttled. | - | +| **500** | Workspace error. | - | + +[[Back to top]](#) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to Model list]](../../README.md#documentation-for-models) [[Back to README]](../../README.md) + # **DeleteVisitorData** > void DeleteVisitorData (string visitorId) @@ -61,7 +158,7 @@ namespace DeleteVisitorDataExample var host = CreateHostBuilder(args).Build(); var api = host.Services.GetRequiredService(); - var visitorId = Ibk1527CUFmcnjLwIs4A9; // string | The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. + var visitorId = Ibk1527CUFmcnjLwIs4A9; // string | The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. // Delete a visitor ID await api.DeleteVisitorDataAsync(visitorId); @@ -80,7 +177,7 @@ namespace DeleteVisitorDataExample | Name | Type | Description | Notes | |------|------|-------------|-------| -| **visitorId** | **string** | The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. | | +| **visitorId** | **string** | The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. | | ### Return type @@ -113,10 +210,12 @@ void (empty response body) Get an event by event ID -Get a detailed analysis of an individual identification event, including Smart Signals. +Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. +Use `source` to tell identification events (`device`) from Automation Intelligence events (`edge`). + ### Example ```csharp @@ -135,7 +234,7 @@ namespace GetEventExample var host = CreateHostBuilder(args).Build(); var api = host.Services.GetRequiredService(); - var eventId = 1708102555327.NLOjmg; // string | The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). + var eventId = 1708102555327.NLOjmg; // string | The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). var rulesetId = D6N9Kbk9HRWrIWGz; // string | The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. (optional) // Get an event by event ID @@ -156,7 +255,7 @@ namespace GetEventExample | Name | Type | Description | Notes | |------|------|-------------|-------| -| **eventId** | **string** | The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). | | +| **eventId** | **string** | The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). | | | **rulesetId** | **string** | The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. | [optional] | ### Return type @@ -239,7 +338,7 @@ namespace SearchEventsExample var limit = 10; // int | Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. (optional) var paginationKey = S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q; // string | Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` (optional) - var visitorId = Ibk1527CUFmcnjLwIs4A9; // string | Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). (optional) + var visitorId = Ibk1527CUFmcnjLwIs4A9; // string | Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). (optional) var highRecallId = Ibk1527CUFmcnjLwIs4A9; // string | The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). (optional) var bot = (SearchEventsBot) "all"; // SearchEventsBot | Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. (optional) var botInfo = (SearchEventsBotInfo) "all"; // SearchEventsBotInfo | Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. (optional) @@ -250,7 +349,7 @@ namespace SearchEventsExample var botInfoName = new List(); // List | Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. (optional) var ipAddress = 61.127.217.15; // string | Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 (optional) var asn = 12876; // string | Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. (optional) - var linkedId = somelinkedId; // string | Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) + var linkedId = somelinkedId; // string | Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) var url = https://example.com/login; // string | Filter events by the URL (`url` property) associated with the event. (optional) var bundleId = com.example.app; // string | Filter events by the Bundle ID (iOS) associated with the event. (optional) var packageName = com.example.app; // string | Filter events by the Package Name (Android) associated with the event. (optional) @@ -312,7 +411,7 @@ namespace SearchEventsExample |------|------|-------------|-------| | **limit** | **int** | Maximum number of events to return. Defaults to 10 when omitted. Results are selected from the time range (`start`, `end`), ordered by `reverse`, then truncated to provided `limit` size. So `reverse=true` returns the oldest N=`limit` events, otherwise the newest N=`limit` events. | [optional] | | **paginationKey** | **string** | Use `pagination_key` to get the next page of results. When more results are available (e.g., you requested up to 100 results for your query using `limit`, but there are more than 100 events total matching your request), the `pagination_key` field is added to the response. The pagination key is an arbitrary string that should not be interpreted in any way and should be passed as-is. In the following request, use that value in the `pagination_key` parameter to get the next page of results: 1. First request, returning most recent 100 events: `GET api-base-url/events?limit=100` 2. Use `response.pagination_key` to get the next page of results: `GET api-base-url/events?limit=100&pagination_key=S9rgMMUb4z3X5t5pr_tSgoSZlmyF0O8X7kCV2m981-iY1LmRTjraa1rTk3L-hQExnDWCi0RA-zAIjaVSTNO2AN2eqQWgzT0RjbieMxRfSdkM-HmOhdOgdQvYfPG3vqU1DJKh4Q` | [optional] | -| **visitorId** | **string** | Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). | [optional] | +| **visitorId** | **string** | Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). | [optional] | | **highRecallId** | **string** | The High Recall ID is a supplementary browser identifier designed for use cases that require wider coverage over precision. Compared to the standard visitor ID, the High Recall ID strives to match incoming browsers more generously (rather than precisely) with existing browsers and thus identifies fewer browsers as new. The High Recall ID is best suited for use cases that are sensitive to browsers being identified as new and where mismatched browsers are not detrimental. Filter events by matching High Recall ID (`supplementary_id_high_recall.visitor_id` property). | [optional] | | **bot** | **SearchEventsBot** | Filter events by the Bot Detection result, specifically: `all` - events where any kind of bot was detected. `good` - events where a good bot was detected. `bad` - events where a bad bot was detected. `none` - events where no bot was detected. > Note: When using this parameter, only events with the `bot` property set to a valid value are returned. Events without a `bot` Smart Signal result are left out of the response. | [optional] | | **botInfo** | **SearchEventsBotInfo** | Filter events by their Bot Info result, specifically: - `all` - events where any kind of bot was detected. - `none` - events where no bot was detected, and no `bot_info` was present. | [optional] | @@ -323,7 +422,7 @@ namespace SearchEventsExample | **botInfoName** | [**List<string>**](string.md) | Filter events by their Bot Info Name. The name must match exactly, partial or wildcard matching is not supported. Multiple Names can be provided using the repeated keys syntax. For example, `bot_info_name=ChatGPT%20Agent&bot_info_name=Bedrock%20AgentCore`, will match events with a Bot Info Name of `ChatGPT Agent` or `Bedrock AgentCore`. Other notations like comma-separated or bracket notation are not supported. | [optional] | | **ipAddress** | **string** | Filter events by IP address or IP range (if CIDR notation is used). If CIDR notation is not used, a /32 for IPv4 or /128 for IPv6 is assumed. Examples of range based queries: 10.0.0.0/24, 192.168.0.1/32 | [optional] | | **asn** | **string** | Filter events by the ASN associated with the event's IP address. This corresponds to the `ip_info.(v4|v6).asn` property in the response. | [optional] | -| **linkedId** | **string** | Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. | [optional] | +| **linkedId** | **string** | Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. | [optional] | | **url** | **string** | Filter events by the URL (`url` property) associated with the event. | [optional] | | **bundleId** | **string** | Filter events by the Bundle ID (iOS) associated with the event. | [optional] | | **packageName** | **string** | Filter events by the Package Name (Android) associated with the event. | [optional] | @@ -426,7 +525,7 @@ namespace UpdateEventExample var host = CreateHostBuilder(args).Build(); var api = host.Services.GetRequiredService(); - var eventId = 1708102555327.NLOjmg; // string | The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + var eventId = 1708102555327.NLOjmg; // string | The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). var eventUpdate = new EventUpdate(); // EventUpdate | // Update an event @@ -446,7 +545,7 @@ namespace UpdateEventExample | Name | Type | Description | Notes | |------|------|-------------|-------| -| **eventId** | **string** | The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). | | +| **eventId** | **string** | The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). | | | **eventUpdate** | [**EventUpdate**](EventUpdate.md) | | | ### Return type diff --git a/docs/models/EdgeRequest.md b/docs/models/EdgeRequest.md new file mode 100644 index 00000000..2383115f --- /dev/null +++ b/docs/models/EdgeRequest.md @@ -0,0 +1,18 @@ +# Fingerprint.ServerSdk.Model.EdgeRequest +HTTP request metadata (including the HTTP method, headers and IP address) sent by you (your server) to the Fingerprint API for IP and bot analysis. To improve accuracy, retain as much of the original semantics of the HTTP request as possible. For example, preserve the order of the request headers and their capitalization. +At least one of `ipv4_address` or `ipv6_address` must be provided; a request with neither is rejected with a `400` error. If both IPv4 and IPv6 are provided, IP intelligence will be provided for each address. If an IPv4-mapped IPv6 address is provided in the `ipv6_address` request property, the IP intelligence will be provided in the `ipv4_address` property of the response. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Headers** | [**List<EdgeRequestHeadersInner>**](EdgeRequestHeadersInner.md) | Ordered header entries from the request made to your server. Each entry represents one header line. If one header name appears as multiple lines, send each as a separate item in the array. Headers that contain authentication or session data must still be included, but with their value set to an empty string. This includes headers like `Authorization` and `Cookie`, but may contain more depending on your specific project, for instance `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely changes the shape of the request and can affect detection. Never forward the real secret values. Whenever possible, we recommend preserving header order and capitalization to provide the best accuracy, however it’s not a strict requirement if your runtime does not maintain http header order or canonicalizes header names. | +**Method** | **string** | The original HTTP method of the request. If supported in your runtime, preserve the original casing. | +**Url** | **string** | Absolute URL of the request, without a \\#fragment suffix. Only HTTP and HTTPS schemes are supported. | +**Ipv4Address** | **string** | Client IPv4 address observed by your server. | [optional] +**Ipv6Address** | **string** | Client IPv6 address observed by your server. | [optional] +**LinkedId** | **string** | A customer-provided id that was sent with the request. | [optional] +**Tags** | **Dictionary<string, Object>** | A customer-provided value or an object that was sent with the identification request or updated later. | [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/models/EdgeRequestHeadersInner.md b/docs/models/EdgeRequestHeadersInner.md new file mode 100644 index 00000000..614f8aec --- /dev/null +++ b/docs/models/EdgeRequestHeadersInner.md @@ -0,0 +1,11 @@ +# Fingerprint.ServerSdk.Model.EdgeRequestHeadersInner + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | **string** | Header name as forwarded by your server. Headers must be valid according to RFC 7230 and will be canonicalized according to RFC 9112. | +**Value** | **string** | Value of a single forwarded header entry. Be careful to preserve the original encoding and escaping. For example, do not double escape quotes. | + +[[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/models/Event.md b/docs/models/Event.md index fa8a9b06..657a69e5 100644 --- a/docs/models/Event.md +++ b/docs/models/Event.md @@ -1,5 +1,10 @@ # Fingerprint.ServerSdk.Model.Event -Contains results from Fingerprint Identification and all active Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. +An identification event (`source: device`) or an Automation Intelligence event (`source: edge`). + +Use `source` to tell them apart. Device events include Identification and device-derived Smart Signals. Edge events do not. + +Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. + ## Properties @@ -7,17 +12,25 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **EventId** | **string** | Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. | **Timestamp** | **long** | Timestamp of the event with millisecond precision in Unix time. | +**LinkedId** | **string** | A customer-provided id that was sent with the request. | [optional] +**Tags** | **Dictionary<string, Object>** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] +**Url** | **string** | Page URL from which the request was sent. | [optional] +**BotInfo** | [**BotInfo**](BotInfo.md) | | [optional] +**IpInfo** | [**IPInfo**](IPInfo.md) | | [optional] +**Proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] +**ProxyConfidence** | **ProxyConfidence** | | [optional] +**ProxyDetails** | [**ProxyDetails**](ProxyDetails.md) | | [optional] +**Vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] +**VpnConfidence** | **VpnConfidence** | | [optional] +**VpnMethods** | [**VpnMethods**](VpnMethods.md) | | [optional] **Source** | **EventSource** | | [optional] **IncrementalIdentificationStatus** | **IncrementalIdentificationStatus** | | [optional] -**LinkedId** | **string** | A customer-provided id that was sent with the request. | [optional] **EnvironmentId** | **string** | Environment Id of the event. | [optional] -**Suspect** | **bool** | Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event). | [optional] +**Suspect** | **bool** | Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event). | [optional] **Sdk** | [**SDK**](SDK.md) | | [optional] **Replayed** | **bool** | `true` if we determined that this payload was replayed, `false` otherwise. | [optional] **Identification** | [**Identification**](Identification.md) | | [optional] **SupplementaryIdHighRecall** | [**SupplementaryIDHighRecall**](SupplementaryIDHighRecall.md) | | [optional] -**Tags** | **Dictionary<string, Object>** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] -**Url** | **string** | Page URL from which the request was sent. | [optional] **BundleId** | **string** | Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. | [optional] **PackageName** | **string** | Package name of the Android application integrated with the Fingerprint SDK for the event. | [optional] **IpAddress** | **string** | IP address of the requesting browser or bot. | [optional] @@ -31,17 +44,12 @@ Name | Type | Description | Notes **ActiveCall** | **bool** | Indicates whether the mobile device had an active call (cellular or VoIP) at the time of the request. Available from SDK 2.16.0+ on iOS and Android. | [optional] **Bot** | **BotResult** | | [optional] **BotType** | **string** | Additional classification of the bot type if detected. | [optional] -**BotInfo** | [**BotInfo**](BotInfo.md) | | [optional] **ClonedApp** | **bool** | Android specific cloned application detection. There are 2 values: * `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). * `false` - No signs of cloned application detected or the client is not Android. | [optional] **DeveloperTools** | **bool** | `true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. | [optional] **Emulator** | **bool** | Android specific emulator detection. There are 2 values: * `true` - Emulated environment detected (e.g. launch inside of AVD). * `false` - No signs of emulated environment detected or the client is not Android. | [optional] **FactoryResetTimestamp** | **long** | The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC) as a value of 0. See [Factory Reset Detection](https://docs.fingerprint.com/docs/smart-signals-reference#factory-reset-detection) to learn more about this Smart Signal. | [optional] **Frida** | **bool** | [Frida](https://frida.re/docs/) detection for Android and iOS devices. There are 2 values: * `true` - Frida detected * `false` - No signs of Frida or the client is not a mobile device. | [optional] **IpBlocklist** | [**IPBlockList**](IPBlockList.md) | | [optional] -**IpInfo** | [**IPInfo**](IPInfo.md) | | [optional] -**Proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] -**ProxyConfidence** | **ProxyConfidence** | | [optional] -**ProxyDetails** | [**ProxyDetails**](ProxyDetails.md) | | [optional] **ProxyMlScore** | **double** | Machine learning–based proxy 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 `proxy` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] **Incognito** | **bool** | `true` if we detected incognito mode used in the browser, `false` otherwise. | [optional] **Jailbroken** | **bool** | iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. | [optional] @@ -59,12 +67,9 @@ Name | Type | Description | Notes **Velocity** | [**Velocity**](Velocity.md) | | [optional] **VirtualMachine** | **bool** | `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. | [optional] **VirtualMachineMlScore** | **double** | 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. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] -**Vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] -**VpnConfidence** | **VpnConfidence** | | [optional] **VpnMlScore** | **double** | Machine learning–based VPN 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 `vpn` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] **VpnOriginTimezone** | **string** | Local timezone which is used in timezone_mismatch method. | [optional] **VpnOriginCountry** | **string** | Country of the request (Android SDK version >= 2.4.0, iOS SDK version >= 2.9.0, JS agent >= 3.12.9 / 4.0.2), ISO 3166 format or unknown. | [optional] -**VpnMethods** | [**VpnMethods**](VpnMethods.md) | | [optional] **HighActivityDevice** | **bool** | Flag indicating if the request came from a high-activity visitor. | [optional] **RareDevice** | **bool** | `true` if the device is considered rare based on its combination of hardware and software attributes. A device is classified as rare if it falls within the top 99.9 percentile (lowest-frequency segment) of observed traffic, or if its configuration has not been previously seen (`not_seen`). > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). | [optional] **RareDevicePercentileBucket** | **RareDevicePercentileBucket** | | [optional] diff --git a/docs/models/EventEdge.md b/docs/models/EventEdge.md new file mode 100644 index 00000000..dcb2fd04 --- /dev/null +++ b/docs/models/EventEdge.md @@ -0,0 +1,25 @@ +# Fingerprint.ServerSdk.Model.EventEdge +IP and bot analysis for an event generated by the Automation Intelligence API (`/edge` endpoint). No client-side collection agent is involved, so Identification (`visitor_id`) and device-telemetry-derived Smart Signals are not available. + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**EventId** | **string** | Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. | +**Timestamp** | **long** | Timestamp of the event with millisecond precision in Unix time. | +**IpInfo** | [**IPInfo**](IPInfo.md) | | +**Source** | **EventSource** | | +**LinkedId** | **string** | A customer-provided id that was sent with the request. | [optional] +**Tags** | **Dictionary<string, Object>** | A customer-provided value or an object that was sent with the identification request or updated later. | [optional] +**Url** | **string** | Page URL from which the request was sent. | [optional] +**BotInfo** | [**BotInfo**](BotInfo.md) | | [optional] +**Proxy** | **bool** | IP address was used by a public proxy provider or belonged to a known recent residential proxy | [optional] +**ProxyConfidence** | **ProxyConfidence** | | [optional] +**ProxyDetails** | [**ProxyDetails**](ProxyDetails.md) | | [optional] +**Vpn** | **bool** | VPN or other anonymizing service has been used when sending the request. | [optional] +**VpnConfidence** | **VpnConfidence** | | [optional] +**VpnMethods** | [**VpnMethods**](VpnMethods.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) + diff --git a/res/fingerprint-server-api.yaml b/res/fingerprint-server-api.yaml index 842bfbb9..71a1c13d 100644 --- a/res/fingerprint-server-api.yaml +++ b/res/fingerprint-server-api.yaml @@ -37,6 +37,97 @@ servers: security: - bearerAuth: [] paths: + /edge: + post: + tags: + - Fingerprint + operationId: analyzeRequestForAutomationIntelligence + summary: Collect Automation Intelligence. + description: > + The Automation Intelligence API gives you the tools to determine whether + traffic is legitimate and should be accepted by your application. + + + This feature is currently in a Public Preview testing phase. All + feedback is welcome! If you encounter any issues, please [contact our + support team](https://fingerprint.com/support/). + + + The API detects automation tools like AI Agents, AI Assistants, AI + Browsers, and other bots. Additionally, it provides IP intelligence like + geolocation, residential proxy, VPN and data center detection. + + + Automation Intelligence is derived from HTTP request metadata that + reaches your server. It does not require the use of a JavaScript + client-side agent or mobile SDKs to collect device context. + + + The API is fast, with average response times of less than 30ms, making + it a great fit for edge, pre-origin or middleware contexts. The API is + platform-agnostic and can be used with different CDN providers, cloud + platforms, or any server backend. + + + Because this API doesn’t require the use of a client-side device + collection agent, it doesn’t support device identification via + `visitor_id` and a few Smart Signals derived from deep device telemetry. + + + ### Event Retrieval + + + Events created by the Automation Intelligence API can be fetched via the + [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) + API using the `event_id` present in the API response. + + + Fetch all Automation Intelligence API events via the + [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) + API. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EdgeRequest' + responses: + '200': + description: OK. + content: + application/json: + schema: + $ref: '#/components/schemas/EventEdge' + '400': + description: Bad request. The request payload is not valid. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden. Access to this API is denied. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '413': + description: Bad request. The request payload is too large. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '429': + description: Too Many Requests. The request is throttled. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Workspace error. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /events/{event_id}: get: tags: @@ -44,12 +135,15 @@ paths: operationId: getEvent summary: Get an event by event ID description: > - Get a detailed analysis of an individual identification event, including - Smart Signals. + Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + + + Use `source` to tell identification events (`device`) from Automation + Intelligence events (`edge`). parameters: - name: event_id in: path @@ -61,7 +155,7 @@ paths: example: 1708102555327.NLOjmg description: >- The unique - [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) + [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). - name: ruleset_id @@ -165,7 +259,7 @@ paths: example: 1708102555327.NLOjmg description: >- The unique event - [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). requestBody: required: true content: @@ -317,7 +411,7 @@ paths: example: Ibk1527CUFmcnjLwIs4A9 description: > Unique [visitor - identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) + identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. @@ -492,7 +586,7 @@ paths: You can use [linked - Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) + Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated @@ -1124,7 +1218,7 @@ paths: example: Ibk1527CUFmcnjLwIs4A9 description: >- The [visitor - ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) + ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. responses: '200': @@ -1177,6 +1271,138 @@ components: identification request or updated later. additionalProperties: true required: [] + EdgeRequest: + type: object + description: >- + HTTP request metadata (including the HTTP method, headers and IP + address) sent by you (your server) to the Fingerprint API for IP and bot + analysis. To improve accuracy, retain as much of the original semantics + of the HTTP request as possible. For example, preserve the order of the + request headers and their capitalization. + + At least one of `ipv4_address` or `ipv6_address` must be provided; a + request with neither is rejected with a `400` error. If both IPv4 and + IPv6 are provided, IP intelligence will be provided for each address. If + an IPv4-mapped IPv6 address is provided in the `ipv6_address` request + property, the IP intelligence will be provided in the `ipv4_address` + property of the response. + example: + method: GET + url: https://example.com/login + ipv4_address: 34.162.244.71 + headers: + - name: Host + value: example.com + - name: User-Agent + value: Mozilla/5.0 + - name: Authorization + value: '' + required: + - headers + - method + - url + properties: + headers: + type: array + description: > + Ordered header entries from the request made to your server. Each + entry represents one header line. If one header name appears as + multiple lines, send each as a separate item in the array. + + + Headers that contain authentication or session data must still be + included, but with their value set to an empty string. This includes + headers like `Authorization` and `Cookie`, but may contain more + depending on your specific project, for instance + `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely + changes the shape of the request and can affect detection. Never + forward the real secret values. + + + Whenever possible, we recommend preserving header order and + capitalization to provide the best accuracy, however it’s not a + strict requirement if your runtime does not maintain http header + order or canonicalizes header names. + minItems: 1 + items: + type: object + required: + - name + - value + properties: + name: + type: string + examples: + - User-Agent + description: >- + Header name as forwarded by your server. Headers must be valid + according to RFC 7230 and will be canonicalized according to + RFC 9112. + value: + type: string + examples: + - Mozilla/5.0 + description: >- + Value of a single forwarded header entry. Be careful to + preserve the original encoding and escaping. For example, do + not double escape quotes. + examples: + - - name: Host + value: example.com + - name: User-Agent + value: Mozilla/5.0 + - name: Accept-Language + value: en-US,en;q=0.9 + - - name: Host + value: example.com + - name: User-Agent + value: Mozilla/5.0 + - name: Accept-Encoding + value: gzip + - name: Accept-Encoding + value: deflate + method: + type: string + description: >- + The original HTTP method of the request. If supported in your + runtime, preserve the original casing. + examples: + - GET + - POST + - PUT + - PATCH + - DELETE + url: + type: string + description: >- + Absolute URL of the request, without a \#fragment suffix. Only HTTP + and HTTPS schemes are supported. + format: uri + examples: + - http://example.com + - https://example.com/checkout?method=card + ipv4_address: + type: string + description: Client IPv4 address observed by your server. + format: ipv4 + examples: + - 34.162.244.71 + - 3.208.0.3 + - 173.56.0.4 + ipv6_address: + type: string + description: Client IPv6 address observed by your server. + format: ipv6 + examples: + - 2001:4860:4801:10::1 + - 2600:1f42:abcd:5678:9876:fedc:1357:2468 + - 2001:4868:85f:1a2b:3c4d:5e6f:7890:abcd + - ::ffff:22a2:f447 + - ::ffff:34.162.244.71 + linked_id: + $ref: '#/components/schemas/LinkedId' + tags: + $ref: '#/components/schemas/Tags' EventId: type: string examples: @@ -1190,19 +1416,6 @@ components: format: int64 examples: - 1708102555327 - EventSource: - type: string - description: > - Identifies how the event was generated. - - - `device` - the event was generated by the JS agent or a mobile SDK - running on an end-user device. - - - `edge` - the event was generated by the Automation Intelligence API - (`/edge` endpoint), analyzing a request intercepted at the edge. - enum: - - device - - edge Url: type: string examples: @@ -1610,6 +1823,78 @@ components: description: > `true` if the request came from a device running a VPN, `false` otherwise. + EventSource: + type: string + description: > + Identifies how the event was generated. + + - `device` - the event was generated by the JS agent or a mobile SDK + running on an end-user device. + + - `edge` - the event was generated by the Automation Intelligence API + (`/edge` endpoint), analyzing a request intercepted at the edge. + enum: + - device + - edge + EventEdge: + type: object + description: > + IP and bot analysis for an event generated by the Automation + Intelligence API (`/edge` endpoint). No client-side collection agent is + involved, so Identification (`visitor_id`) and device-telemetry-derived + Smart Signals are not available. + properties: + event_id: + $ref: '#/components/schemas/EventId' + x-platforms: + - android + - ios + - browser + timestamp: + $ref: '#/components/schemas/Timestamp' + x-platforms: + - android + - ios + - browser + linked_id: + $ref: '#/components/schemas/LinkedId' + x-platforms: + - android + - ios + - browser + tags: + $ref: '#/components/schemas/Tags' + x-platforms: + - android + - ios + - browser + url: + $ref: '#/components/schemas/Url' + bot_info: + $ref: '#/components/schemas/BotInfo' + ip_info: + $ref: '#/components/schemas/IPInfo' + proxy: + $ref: '#/components/schemas/Proxy' + proxy_confidence: + $ref: '#/components/schemas/ProxyConfidence' + proxy_details: + $ref: '#/components/schemas/ProxyDetails' + vpn: + $ref: '#/components/schemas/Vpn' + vpn_confidence: + $ref: '#/components/schemas/VpnConfidence' + vpn_methods: + $ref: '#/components/schemas/VpnMethods' + source: + allOf: + - $ref: '#/components/schemas/EventSource' + - const: edge + required: + - event_id + - timestamp + - source + - ip_info ErrorCode: type: string enum: @@ -1729,7 +2014,7 @@ components: description: >- Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event - endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event). + endpoint](https://docs.fingerprint.com/reference/server-api-update-event). Integration: type: object required: [] @@ -3098,16 +3383,18 @@ components: team](https://fingerprint.com/support/). Event: type: object - description: >- - Contains results from Fingerprint Identification and all active Smart - Signals. Some Smart Signals are only supported for certain device types, - these fields will be omitted for events not generated from the supported - devices. Consult the [Smart Signals + description: > + An identification event (`source: device`) or an Automation Intelligence + event (`source: edge`). + + + Use `source` to tell them apart. Device events include Identification + and device-derived Smart Signals. Edge events do not. + + + Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. - required: - - event_id - - timestamp properties: event_id: $ref: '#/components/schemas/EventId' @@ -3121,22 +3408,78 @@ components: - android - ios - browser - source: - $ref: '#/components/schemas/EventSource' + linked_id: + $ref: '#/components/schemas/LinkedId' x-platforms: - android - ios - browser - incremental_identification_status: - $ref: '#/components/schemas/IncrementalIdentificationStatus' + tags: + $ref: '#/components/schemas/Tags' x-platforms: + - android + - ios - browser - linked_id: - $ref: '#/components/schemas/LinkedId' + url: + $ref: '#/components/schemas/Url' + x-platforms: + - browser + bot_info: + $ref: '#/components/schemas/BotInfo' + x-platforms: + - browser + ip_info: + $ref: '#/components/schemas/IPInfo' + x-platforms: + - android + - ios + - browser + proxy: + $ref: '#/components/schemas/Proxy' x-platforms: - android - ios - browser + proxy_confidence: + $ref: '#/components/schemas/ProxyConfidence' + x-platforms: + - android + - ios + - browser + proxy_details: + $ref: '#/components/schemas/ProxyDetails' + x-platforms: + - android + - ios + - browser + vpn: + $ref: '#/components/schemas/Vpn' + x-platforms: + - android + - ios + - browser + vpn_confidence: + $ref: '#/components/schemas/VpnConfidence' + x-platforms: + - android + - ios + - browser + vpn_methods: + $ref: '#/components/schemas/VpnMethods' + x-platforms: + - android + - ios + - browser + source: + $ref: '#/components/schemas/EventSource' + x-platforms: + - android + - ios + - browser + incremental_identification_status: + $ref: '#/components/schemas/IncrementalIdentificationStatus' + x-platforms: + - browser environment_id: $ref: '#/components/schemas/EnvironmentId' x-platforms: @@ -3173,16 +3516,6 @@ components: - android - ios - browser - tags: - $ref: '#/components/schemas/Tags' - x-platforms: - - android - - ios - - browser - url: - $ref: '#/components/schemas/Url' - x-platforms: - - browser bundle_id: $ref: '#/components/schemas/BundleId' x-platforms: @@ -3248,10 +3581,6 @@ components: $ref: '#/components/schemas/BotType' x-platforms: - browser - bot_info: - $ref: '#/components/schemas/BotInfo' - x-platforms: - - browser cloned_app: $ref: '#/components/schemas/ClonedApp' x-platforms: @@ -3282,30 +3611,6 @@ components: - android - ios - browser - ip_info: - $ref: '#/components/schemas/IPInfo' - x-platforms: - - android - - ios - - browser - proxy: - $ref: '#/components/schemas/Proxy' - x-platforms: - - android - - ios - - browser - proxy_confidence: - $ref: '#/components/schemas/ProxyConfidence' - x-platforms: - - android - - ios - - browser - proxy_details: - $ref: '#/components/schemas/ProxyDetails' - x-platforms: - - android - - ios - - browser proxy_ml_score: $ref: '#/components/schemas/ProxyMLScore' x-platforms: @@ -3386,18 +3691,6 @@ components: $ref: '#/components/schemas/VirtualMachineMLScore' x-platforms: - browser - vpn: - $ref: '#/components/schemas/Vpn' - x-platforms: - - android - - ios - - browser - vpn_confidence: - $ref: '#/components/schemas/VpnConfidence' - x-platforms: - - android - - ios - - browser vpn_ml_score: $ref: '#/components/schemas/VpnMLScore' x-platforms: @@ -3413,12 +3706,6 @@ components: x-platforms: - android - ios - vpn_methods: - $ref: '#/components/schemas/VpnMethods' - x-platforms: - - android - - ios - - browser high_activity_device: $ref: '#/components/schemas/HighActivity' x-platforms: @@ -3445,6 +3732,9 @@ components: - browser - ios - android + required: + - event_id + - timestamp EventUpdate: type: object required: [] diff --git a/src/Fingerprint.ServerSdk.Test/mocks/webhook/webhook_event.json b/src/Fingerprint.ServerSdk.Test/mocks/webhook/webhook_event.json index 35567917..407a005d 100644 --- a/src/Fingerprint.ServerSdk.Test/mocks/webhook/webhook_event.json +++ b/src/Fingerprint.ServerSdk.Test/mocks/webhook/webhook_event.json @@ -1,4 +1,5 @@ { + "source": "device", "linked_id": "somelinkedId", "tags": {}, "timestamp": 1708102555327, diff --git a/src/Fingerprint.ServerSdk/Api/FingerprintApi.cs b/src/Fingerprint.ServerSdk/Api/FingerprintApi.cs index 5437cd3c..86b987c7 100644 --- a/src/Fingerprint.ServerSdk/Api/FingerprintApi.cs +++ b/src/Fingerprint.ServerSdk/Api/FingerprintApi.cs @@ -33,6 +33,29 @@ public interface IFingerprintApi : IApi /// FingerprintApiEvents Events { get; } + /// + /// Collect Automation Intelligence. + /// + /// + /// The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + /// + /// Thrown when fails to make API call + /// + /// Cancellation Token to cancel the request. + /// <> + Task AnalyzeRequestForAutomationIntelligenceAsync(EdgeRequest edgeRequest, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Collect Automation Intelligence. + /// + /// + /// The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + /// + /// + /// Cancellation Token to cancel the request. + /// <> + Task AnalyzeRequestForAutomationIntelligenceOrDefaultAsync(EdgeRequest edgeRequest, System.Threading.CancellationToken cancellationToken = default); + /// /// Delete a visitor ID /// @@ -40,7 +63,7 @@ public interface IFingerprintApi : IApi /// Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). /// /// Thrown when fails to make API call - /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. + /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. /// Cancellation Token to cancel the request. /// <> Task DeleteVisitorDataAsync(string visitorId, System.Threading.CancellationToken cancellationToken = default); @@ -51,7 +74,7 @@ public interface IFingerprintApi : IApi /// /// Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). /// - /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. + /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. /// Cancellation Token to cancel the request. /// <> Task DeleteVisitorDataOrDefaultAsync(string visitorId, System.Threading.CancellationToken cancellationToken = default); @@ -60,10 +83,10 @@ public interface IFingerprintApi : IApi /// Get an event by event ID /// /// - /// Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + /// Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Use `source` to tell identification events (`device`) from Automation Intelligence events (`edge`). /// /// Thrown when fails to make API call - /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). + /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). /// The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. (optional) /// Cancellation Token to cancel the request. /// <> @@ -73,9 +96,9 @@ public interface IFingerprintApi : IApi /// Get an event by event ID /// /// - /// Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + /// Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Use `source` to tell identification events (`device`) from Automation Intelligence events (`edge`). /// - /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). + /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). /// The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. (optional) /// Cancellation Token to cancel the request. /// <> @@ -111,7 +134,7 @@ public interface IFingerprintApi : IApi /// Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. /// /// Thrown when fails to make API call - /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). /// /// Cancellation Token to cancel the request. /// <> @@ -123,13 +146,55 @@ public interface IFingerprintApi : IApi /// /// Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. /// - /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). /// /// Cancellation Token to cancel the request. /// <> Task UpdateEventOrDefaultAsync(string eventId, EventUpdate eventUpdate, System.Threading.CancellationToken cancellationToken = default); } + /// + /// The + /// + public interface IAnalyzeRequestForAutomationIntelligenceApiResponse : Fingerprint.ServerSdk.Client.IApiResponse, IOk, IBadRequest, IForbidden, IContentTooLarge, ITooManyRequests, IInternalServerError + { + /// + /// Returns true if the response is 200 Ok + /// + /// + bool IsOk { get; } + + /// + /// Returns true if the response is 400 BadRequest + /// + /// + bool IsBadRequest { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 413 ContentTooLarge + /// + /// + bool IsContentTooLarge { get; } + + /// + /// Returns true if the response is 429 TooManyRequests + /// + /// + bool IsTooManyRequests { get; } + + /// + /// Returns true if the response is 500 InternalServerError + /// + /// + bool IsInternalServerError { get; } + } + /// /// The /// @@ -230,7 +295,7 @@ public class SearchEventsRequest public Option PaginationKey { get; set; } = default; /// - /// Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). (optional) + /// Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). (optional) /// public Option VisitorId { get; set; } = default; @@ -285,7 +350,7 @@ public class SearchEventsRequest public Option Asn { get; set; } = default; /// - /// Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) + /// Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. (optional) /// public Option LinkedId { get; set; } = default; @@ -582,7 +647,7 @@ public SearchEventsRequest WithPaginationKey(string value) /// /// Sets the visitorId parameter. /// - /// Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). + /// Unique [visitor identifier](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) issued by Fingerprint Identification and all active Smart Signals. Filter events by matching Visitor ID (`identification.visitor_id` property). /// This request instance for fluent chaining. public SearchEventsRequest WithVisitorId(string value) { @@ -703,7 +768,7 @@ public SearchEventsRequest WithAsn(string value) /// /// Sets the linkedId parameter. /// - /// Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-v4-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. + /// Filter events by your custom identifier. You can use [linked Ids](https://docs.fingerprint.com/reference/js-agent-get-function#linkedid) to associate identification requests with your own identifier, for example, session Id, purchase Id, or transaction Id. You can then use this `linked_id` parameter to retrieve all events associated with your custom identifier. /// This request instance for fluent chaining. public SearchEventsRequest WithLinkedId(string value) { @@ -1250,6 +1315,26 @@ public interface IUpdateEventApiResponse : Fingerprint.ServerSdk.Client.IApiResp /// public class FingerprintApiEvents { + /// + /// The event raised after the server response + /// + public event EventHandler OnAnalyzeRequestForAutomationIntelligence; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler OnErrorAnalyzeRequestForAutomationIntelligence; + + internal void ExecuteOnAnalyzeRequestForAutomationIntelligence(FingerprintApi.AnalyzeRequestForAutomationIntelligenceApiResponse apiResponse) + { + OnAnalyzeRequestForAutomationIntelligence?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorAnalyzeRequestForAutomationIntelligence(Exception exception) + { + OnErrorAnalyzeRequestForAutomationIntelligence?.Invoke(this, new ExceptionEventArgs(exception)); + } + /// /// The event raised after the server response /// @@ -1378,6 +1463,475 @@ public FingerprintApi(ILogger logger, ILoggerFactory loggerFacto BearerTokenProvider = bearerTokenProvider; } + partial void FormatAnalyzeRequestForAutomationIntelligence(EdgeRequest edgeRequest); + + /// + /// Validates the request parameters + /// + /// + /// + private void ValidateAnalyzeRequestForAutomationIntelligence(EdgeRequest edgeRequest) + { + if (edgeRequest == null) + throw new ArgumentNullException(nameof(edgeRequest)); + } + + /// + /// Processes the server response + /// + /// + /// + private void AfterAnalyzeRequestForAutomationIntelligenceDefaultImplementation(IAnalyzeRequestForAutomationIntelligenceApiResponse apiResponseLocalVar, EdgeRequest edgeRequest) + { + bool suppressDefaultLog = false; + AfterAnalyzeRequestForAutomationIntelligence(ref suppressDefaultLog, apiResponseLocalVar, edgeRequest); + if (!suppressDefaultLog) + Logger.LogInformation("{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + partial void AfterAnalyzeRequestForAutomationIntelligence(ref bool suppressDefaultLog, IAnalyzeRequestForAutomationIntelligenceApiResponse apiResponseLocalVar, EdgeRequest edgeRequest); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + private void OnErrorAnalyzeRequestForAutomationIntelligenceDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, EdgeRequest edgeRequest) + { + bool suppressDefaultLogLocalVar = false; + OnErrorAnalyzeRequestForAutomationIntelligence(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, edgeRequest); + if (!suppressDefaultLogLocalVar) + Logger.LogError(exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + partial void OnErrorAnalyzeRequestForAutomationIntelligence(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, EdgeRequest edgeRequest); + + /// + /// Collect Automation Intelligence. The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + /// + /// + /// Cancellation Token to cancel the request. + /// <> + public async Task AnalyzeRequestForAutomationIntelligenceOrDefaultAsync(EdgeRequest edgeRequest, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await AnalyzeRequestForAutomationIntelligenceAsync(edgeRequest, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Collect Automation Intelligence. + /// + /// + /// The Automation Intelligence API gives you the tools to determine whether traffic is legitimate and should be accepted by your application. This feature is currently in a Public Preview testing phase. All feedback is welcome! If you encounter any issues, please [contact our support team](https://fingerprint.com/support/). The API detects automation tools like AI Agents, AI Assistants, AI Browsers, and other bots. Additionally, it provides IP intelligence like geolocation, residential proxy, VPN and data center detection. Automation Intelligence is derived from HTTP request metadata that reaches your server. It does not require the use of a JavaScript client-side agent or mobile SDKs to collect device context. The API is fast, with average response times of less than 30ms, making it a great fit for edge, pre-origin or middleware contexts. The API is platform-agnostic and can be used with different CDN providers, cloud platforms, or any server backend. Because this API doesn’t require the use of a client-side device collection agent, it doesn’t support device identification via `visitor_id` and a few Smart Signals derived from deep device telemetry. ### Event Retrieval Events created by the Automation Intelligence API can be fetched via the [`/v4/events/{event_id}`](https://docs.fingerprint.com/reference/server-api-get-event) API using the `event_id` present in the API response. Fetch all Automation Intelligence API events via the [`/v4/events?source=edge`](https://docs.fingerprint.com/reference/server-api-search-events#parameter-source) API. + /// + /// Thrown when fails to make API call + /// + /// Cancellation Token to cancel the request. + /// <> + public async Task AnalyzeRequestForAutomationIntelligenceAsync(EdgeRequest edgeRequest, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateAnalyzeRequestForAutomationIntelligence(edgeRequest); + + FormatAnalyzeRequestForAutomationIntelligence(edgeRequest); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/edge" + : string.Concat(HttpClient.BaseAddress.AbsolutePath, "/edge"); + + System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty); + parseQueryStringLocalVar["ii"] = $"fingerprint-pro-server-api-dotnet-sdk/{ClientUtils.ClientVersion}"; + + uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString(); + httpRequestMessageLocalVar.Content = (edgeRequest as object) is System.IO.Stream stream + ? httpRequestMessageLocalVar.Content = new StreamContent(stream) + : httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(edgeRequest, _jsonSerializerOptions)); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + BearerToken bearerTokenLocalVar1 = await BearerTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(bearerTokenLocalVar1); + + bearerTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] contentTypes = new string[] { + "application/json" + }; + + string contentTypeLocalVar = ClientUtils.SelectHeaderContentType(contentTypes); + + if (contentTypeLocalVar != null && httpRequestMessageLocalVar.Content != null) + httpRequestMessageLocalVar.Content.Headers.ContentType = new MediaTypeHeaderValue(contentTypeLocalVar); + + string[] acceptLocalVars = new string[] { + "application/json" + }; + + string acceptLocalVar = ClientUtils.SelectHeaderAccept(acceptLocalVars); + + if (acceptLocalVar != null) + httpRequestMessageLocalVar.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(acceptLocalVar)); + httpRequestMessageLocalVar.Method = new HttpMethod("POST"); + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + ILogger apiResponseLoggerLocalVar = LoggerFactory.CreateLogger(); + AnalyzeRequestForAutomationIntelligenceApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) + { + default: + { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync().ConfigureAwait(false); + apiResponseLocalVar = new AnalyzeRequestForAutomationIntelligenceApiResponse(apiResponseLoggerLocalVar, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/edge", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterAnalyzeRequestForAutomationIntelligenceDefaultImplementation(apiResponseLocalVar, edgeRequest); + + Events.ExecuteOnAnalyzeRequestForAutomationIntelligence(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode)429) + foreach (TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch (Exception e) + { + OnErrorAnalyzeRequestForAutomationIntelligenceDefaultImplementation(e, "/edge", uriBuilderLocalVar.Path, edgeRequest); + Events.ExecuteOnErrorAnalyzeRequestForAutomationIntelligence(e); + throw; + } + } + + /// + /// The + /// + public partial class AnalyzeRequestForAutomationIntelligenceApiResponse : Fingerprint.ServerSdk.Client.ApiResponse, IAnalyzeRequestForAutomationIntelligenceApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public AnalyzeRequestForAutomationIntelligenceApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public AnalyzeRequestForAutomationIntelligenceApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 200 Ok + /// + /// + public bool IsOk => 200 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 200 Ok + /// + /// + public Fingerprint.ServerSdk.Model.EventEdge Ok() + { + // This logic may be modified with the AsModel.mustache template + return IsOk + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : default; + } + + /// + /// Returns true if the response is 200 Ok and the deserialized response is not null + /// + /// + /// + public bool TryOk(out Fingerprint.ServerSdk.Model.EventEdge result) + { + result = null; + + try + { + result = Ok(); + } + catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)200); + } + + return result != null; + } + + /// + /// Returns true if the response is 400 BadRequest + /// + /// + public bool IsBadRequest => 400 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 400 BadRequest + /// + /// + public Fingerprint.ServerSdk.Model.ErrorResponse BadRequest() + { + // This logic may be modified with the AsModel.mustache template + return IsBadRequest + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : default; + } + + /// + /// Returns true if the response is 400 BadRequest and the deserialized response is not null + /// + /// + /// + public bool TryBadRequest(out Fingerprint.ServerSdk.Model.ErrorResponse result) + { + result = null; + + try + { + result = BadRequest(); + } + catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)400); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Fingerprint.ServerSdk.Model.ErrorResponse Forbidden() + { + // This logic may be modified with the AsModel.mustache template + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : default; + } + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden(out Fingerprint.ServerSdk.Model.ErrorResponse result) + { + result = null; + + try + { + result = Forbidden(); + } + catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 413 ContentTooLarge + /// + /// + public bool IsContentTooLarge => 413 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 413 ContentTooLarge + /// + /// + public Fingerprint.ServerSdk.Model.ErrorResponse ContentTooLarge() + { + // This logic may be modified with the AsModel.mustache template + return IsContentTooLarge + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : default; + } + + /// + /// Returns true if the response is 413 ContentTooLarge and the deserialized response is not null + /// + /// + /// + public bool TryContentTooLarge(out Fingerprint.ServerSdk.Model.ErrorResponse result) + { + result = null; + + try + { + result = ContentTooLarge(); + } + catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)413); + } + + return result != null; + } + + /// + /// Returns true if the response is 429 TooManyRequests + /// + /// + public bool IsTooManyRequests => 429 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 429 TooManyRequests + /// + /// + public Fingerprint.ServerSdk.Model.ErrorResponse TooManyRequests() + { + // This logic may be modified with the AsModel.mustache template + return IsTooManyRequests + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : default; + } + + /// + /// Returns true if the response is 429 TooManyRequests and the deserialized response is not null + /// + /// + /// + public bool TryTooManyRequests(out Fingerprint.ServerSdk.Model.ErrorResponse result) + { + result = null; + + try + { + result = TooManyRequests(); + } + catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)429); + } + + return result != null; + } + + /// + /// Returns true if the response is 500 InternalServerError + /// + /// + public bool IsInternalServerError => 500 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 500 InternalServerError + /// + /// + public Fingerprint.ServerSdk.Model.ErrorResponse InternalServerError() + { + // This logic may be modified with the AsModel.mustache template + return IsInternalServerError + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : default; + } + + /// + /// Returns true if the response is 500 InternalServerError and the deserialized response is not null + /// + /// + /// + public bool TryInternalServerError(out Fingerprint.ServerSdk.Model.ErrorResponse result) + { + result = null; + + try + { + result = InternalServerError(); + } + catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)500); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + partial void FormatDeleteVisitorData(ref string visitorId); /// @@ -1440,7 +1994,7 @@ private void OnErrorDeleteVisitorDataDefaultImplementation(Exception exceptionLo /// /// Delete a visitor ID Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). /// - /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. + /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. /// Cancellation Token to cancel the request. /// <> public async Task DeleteVisitorDataOrDefaultAsync(string visitorId, System.Threading.CancellationToken cancellationToken = default) @@ -1462,7 +2016,7 @@ public async Task DeleteVisitorDataOrDefaultAsync /// Use this API to request the deletion of all data associated with a specific visitor ID. Upon a request to delete data for a visitor ID, - The data collected from the corresponding browser (or device) will be deleted asynchronously, typically within a few minutes. This data will no longer be available to identify this browser (or device). When the same browser (or device) revisits, it will receive a new visitor ID. - The identification events made from this browser (or device) in the past 10 days are typically deleted within 24 hrs. - The identification events made from this browser (or device) outside of the 10 days will be purged as per your [data retention period](https://docs.fingerprint.com/docs/regions#data-retention). The following timeline illustrates which events are deleted and which remain after a DELETE API request: ``` Day 1: First visit from browser A. (Assigned visitor ID: VID1000) Day 2: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 13: Browser A revisits. (Assigned the same visitor ID: VID1000) Day 14: Delete VID1000 Day 15: Browser A re-visits. (Assigned a different visitor ID: VID9999) Day 15: GET /events/day-13 (Returns 404. The event is within the 10 days of deleting VID1000 and will have been deleted) Day 16: GET /events/day-2 (Returns 200. The event is outside of the 10 days of deleting VID1000 and is still available) ``` ### Availability This API is available only for Enterprise plans **upon request**. If you are interested, please [contact our support team](https://fingerprint.com/support/). ### Rate limits and daily quota The rate limits and daily quota for this API **differ** from those for our other API. The maximum number of DELETE requests that can be made in an hour cannot exceed 30 RPH, and the maximum number that can be made in a day cannot exceed 500 RPD. You can request an increase to these limits by contacting [our support team](https://fingerprint.com/support/). /// /// Thrown when fails to make API call - /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-v4-get-function#visitor_id) you want to delete. + /// The [visitor ID](https://docs.fingerprint.com/reference/js-agent-get-function#visitor_id) you want to delete. /// Cancellation Token to cancel the request. /// <> public async Task DeleteVisitorDataAsync(string visitorId, System.Threading.CancellationToken cancellationToken = default) @@ -1831,9 +2385,9 @@ private void OnErrorGetEventDefaultImplementation(Exception exceptionLocalVar, s partial void OnErrorGetEvent(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string eventId, Option rulesetId); /// - /// Get an event by event ID Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + /// Get an event by event ID Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Use `source` to tell identification events (`device`) from Automation Intelligence events (`edge`). /// - /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). + /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). /// The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. (optional) /// Cancellation Token to cancel the request. /// <> @@ -1853,10 +2407,10 @@ public async Task GetEventOrDefaultAsync(string eventId, O /// Get an event by event ID /// /// - /// Get a detailed analysis of an individual identification event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. + /// Get a detailed analysis of an individual event, including Smart Signals. Use `event_id` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `event_id`. Use `source` to tell identification events (`device`) from Automation Intelligence events (`edge`). /// /// Thrown when fails to make API call - /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id) of each identification request (`requestId` can be used in its place). + /// The unique [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id) of each identification request (`requestId` can be used in its place). /// The ID of the ruleset to evaluate against the event, producing the action to take for this event. The resulting action is returned in the `rule_action` attribute of the response. (optional) /// Cancellation Token to cancel the request. /// <> @@ -3374,7 +3928,7 @@ private void OnErrorUpdateEventDefaultImplementation(Exception exceptionLocalVar /// /// Update an event Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. /// - /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). /// /// Cancellation Token to cancel the request. /// <> @@ -3397,7 +3951,7 @@ public async Task UpdateEventOrDefaultAsync(string even /// Change information in existing events specified by `event_id` or *flag suspicious events*. When an event is created, it can be assigned `linked_id` and `tags` submitted through the JS agent parameters. This information might not have been available on the client initially, so the Server API permits updating these attributes after the fact. **Warning** It's not possible to update events older than one month. **Warning** Trying to update an event immediately after creation may temporarily result in an error (HTTP 409 Conflict. The event is not mutable yet.) as the event is fully propagated across our systems. In such a case, simply retry the request. /// /// Thrown when fails to make API call - /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-v4-get-function#event_id). + /// The unique event [identifier](https://docs.fingerprint.com/reference/js-agent-get-function#event_id). /// /// Cancellation Token to cancel the request. /// <> diff --git a/src/Fingerprint.ServerSdk/Client/ApiResponse`1.cs b/src/Fingerprint.ServerSdk/Client/ApiResponse`1.cs index d53a0648..0a140e2c 100644 --- a/src/Fingerprint.ServerSdk/Client/ApiResponse`1.cs +++ b/src/Fingerprint.ServerSdk/Client/ApiResponse`1.cs @@ -295,6 +295,26 @@ public interface IForbidden : IApiResponse bool TryForbidden(out TType result); } + /// + /// An interface for responses of type + /// + /// + public interface IContentTooLarge : IApiResponse + { + /// + /// Deserializes the response if the response is ContentTooLarge + /// + /// + TType ContentTooLarge(); + + /// + /// Returns true if the response is ContentTooLarge and the deserialized response is not null + /// + /// + /// + bool TryContentTooLarge(out TType result); + } + /// /// An interface for responses of type /// diff --git a/src/Fingerprint.ServerSdk/Client/HostConfiguration.cs b/src/Fingerprint.ServerSdk/Client/HostConfiguration.cs index efb3442b..887faaef 100644 --- a/src/Fingerprint.ServerSdk/Client/HostConfiguration.cs +++ b/src/Fingerprint.ServerSdk/Client/HostConfiguration.cs @@ -77,12 +77,15 @@ public HostConfiguration(IServiceCollection services) _jsonOptions.Converters.Add(new BotResultNullableJsonConverter()); _jsonOptions.Converters.Add(new BrowserDetailsJsonConverter()); _jsonOptions.Converters.Add(new CanvasJsonConverter()); + _jsonOptions.Converters.Add(new EdgeRequestJsonConverter()); + _jsonOptions.Converters.Add(new EdgeRequestHeadersInnerJsonConverter()); _jsonOptions.Converters.Add(new EmojiJsonConverter()); _jsonOptions.Converters.Add(new ErrorJsonConverter()); _jsonOptions.Converters.Add(new ErrorCodeJsonConverter()); _jsonOptions.Converters.Add(new ErrorCodeNullableJsonConverter()); _jsonOptions.Converters.Add(new ErrorResponseJsonConverter()); _jsonOptions.Converters.Add(new EventJsonConverter()); + _jsonOptions.Converters.Add(new EventEdgeJsonConverter()); _jsonOptions.Converters.Add(new EventRuleActionJsonConverter()); _jsonOptions.Converters.Add(new EventRuleActionAllowJsonConverter()); _jsonOptions.Converters.Add(new EventRuleActionBlockJsonConverter()); diff --git a/src/Fingerprint.ServerSdk/Model/EdgeRequest.cs b/src/Fingerprint.ServerSdk/Model/EdgeRequest.cs new file mode 100644 index 00000000..27b16ada --- /dev/null +++ b/src/Fingerprint.ServerSdk/Model/EdgeRequest.cs @@ -0,0 +1,338 @@ +// +/* + * 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. + * + * The version of the OpenAPI document: 4 + * Contact: support@fingerprint.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Fingerprint.ServerSdk.Client; + +namespace Fingerprint.ServerSdk.Model +{ + /// + /// HTTP request metadata (including the HTTP method, headers and IP address) sent by you (your server) to the Fingerprint API for IP and bot analysis. To improve accuracy, retain as much of the original semantics of the HTTP request as possible. For example, preserve the order of the request headers and their capitalization. At least one of `ipv4_address` or `ipv6_address` must be provided; a request with neither is rejected with a `400` error. If both IPv4 and IPv6 are provided, IP intelligence will be provided for each address. If an IPv4-mapped IPv6 address is provided in the `ipv6_address` request property, the IP intelligence will be provided in the `ipv4_address` property of the response. + /// + public partial class EdgeRequest : IValidatableObject + { + + + /// + /// Initializes a new instance of the class. + /// + /// Ordered header entries from the request made to your server. Each entry represents one header line. If one header name appears as multiple lines, send each as a separate item in the array. Headers that contain authentication or session data must still be included, but with their value set to an empty string. This includes headers like `Authorization` and `Cookie`, but may contain more depending on your specific project, for instance `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely changes the shape of the request and can affect detection. Never forward the real secret values. Whenever possible, we recommend preserving header order and capitalization to provide the best accuracy, however it’s not a strict requirement if your runtime does not maintain http header order or canonicalizes header names. (required). + /// The original HTTP method of the request. If supported in your runtime, preserve the original casing. (required). + /// Absolute URL of the request, without a \\#fragment suffix. Only HTTP and HTTPS schemes are supported. (required). + /// Client IPv4 address observed by your server.. + /// Client IPv6 address observed by your server.. + /// A customer-provided id that was sent with the request.. + /// A customer-provided value or an object that was sent with the identification request or updated later.. + [JsonConstructor] + public EdgeRequest(List headers, string method, string url, Option ipv4Address = default, Option ipv6Address = default, Option linkedId = default, Option> tags = default) + { + Headers = headers; + Method = method; + Url = url; + Ipv4AddressOption = ipv4Address; + Ipv6AddressOption = ipv6Address; + LinkedIdOption = linkedId; + TagsOption = tags; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Ordered header entries from the request made to your server. Each entry represents one header line. If one header name appears as multiple lines, send each as a separate item in the array. Headers that contain authentication or session data must still be included, but with their value set to an empty string. This includes headers like `Authorization` and `Cookie`, but may contain more depending on your specific project, for instance `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely changes the shape of the request and can affect detection. Never forward the real secret values. Whenever possible, we recommend preserving header order and capitalization to provide the best accuracy, however it’s not a strict requirement if your runtime does not maintain http header order or canonicalizes header names. + /// + /// Ordered header entries from the request made to your server. Each entry represents one header line. If one header name appears as multiple lines, send each as a separate item in the array. Headers that contain authentication or session data must still be included, but with their value set to an empty string. This includes headers like `Authorization` and `Cookie`, but may contain more depending on your specific project, for instance `Proxy-Authenticate` or `X-Api-Key`. Omitting the headers entirely changes the shape of the request and can affect detection. Never forward the real secret values. Whenever possible, we recommend preserving header order and capitalization to provide the best accuracy, however it’s not a strict requirement if your runtime does not maintain http header order or canonicalizes header names. + [JsonPropertyName("headers")] + public List Headers { get; set; } + + /// + /// The original HTTP method of the request. If supported in your runtime, preserve the original casing. + /// + /// The original HTTP method of the request. If supported in your runtime, preserve the original casing. + [JsonPropertyName("method")] + public string Method { get; set; } + + /// + /// Absolute URL of the request, without a \\#fragment suffix. Only HTTP and HTTPS schemes are supported. + /// + /// Absolute URL of the request, without a \\#fragment suffix. Only HTTP and HTTPS schemes are supported. + [JsonPropertyName("url")] + public string Url { get; set; } + + /// + /// Used to track the state of Ipv4Address + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option Ipv4AddressOption { get; private set; } + + /// + /// Client IPv4 address observed by your server. + /// + /// Client IPv4 address observed by your server. + [JsonPropertyName("ipv4_address")] + public string Ipv4Address { get { return this.Ipv4AddressOption; } set { this.Ipv4AddressOption = new Option(value); } } + + /// + /// Used to track the state of Ipv6Address + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option Ipv6AddressOption { get; private set; } + + /// + /// Client IPv6 address observed by your server. + /// + /// Client IPv6 address observed by your server. + [JsonPropertyName("ipv6_address")] + public string Ipv6Address { get { return this.Ipv6AddressOption; } set { this.Ipv6AddressOption = new Option(value); } } + + /// + /// Used to track the state of LinkedId + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option LinkedIdOption { get; private set; } + + /// + /// A customer-provided id that was sent with the request. + /// + /// A customer-provided id that was sent with the request. + [JsonPropertyName("linked_id")] + public string LinkedId { get { return this.LinkedIdOption; } set { this.LinkedIdOption = new Option(value); } } + + /// + /// Used to track the state of Tags + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option> TagsOption { get; private set; } + + /// + /// A customer-provided value or an object that was sent with the identification request or updated later. + /// + /// A customer-provided value or an object that was sent with the identification request or updated later. + [JsonPropertyName("tags")] + public Dictionary Tags { get { return this.TagsOption; } set { this.TagsOption = new Option>(value); } } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class EdgeRequest {\n"); + sb.Append(" Headers: ").Append(Headers).Append("\n"); + sb.Append(" Method: ").Append(Method).Append("\n"); + sb.Append(" Url: ").Append(Url).Append("\n"); + sb.Append(" Ipv4Address: ").Append(Ipv4Address).Append("\n"); + sb.Append(" Ipv6Address: ").Append(Ipv6Address).Append("\n"); + sb.Append(" LinkedId: ").Append(LinkedId).Append("\n"); + sb.Append(" Tags: ").Append(Tags).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public class EdgeRequestJsonConverter : JsonConverter + { + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override EdgeRequest Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option> headers = default; + Option method = default; + Option url = default; + Option ipv4Address = default; + Option ipv6Address = default; + Option linkedId = default; + Option> tags = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "headers": + headers = new Option>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "method": + method = new Option(utf8JsonReader.GetString()); + break; + case "url": + url = new Option(utf8JsonReader.GetString()); + break; + case "ipv4_address": + ipv4Address = new Option(utf8JsonReader.GetString()); + break; + case "ipv6_address": + ipv6Address = new Option(utf8JsonReader.GetString()); + break; + case "linked_id": + linkedId = new Option(utf8JsonReader.GetString()); + break; + case "tags": + tags = new Option>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)); + break; + default: + break; + } + } + } + + if (!headers.IsSet) + throw new ArgumentException("Property is required for class EdgeRequest.", nameof(headers)); + + if (!method.IsSet) + throw new ArgumentException("Property is required for class EdgeRequest.", nameof(method)); + + if (!url.IsSet) + throw new ArgumentException("Property is required for class EdgeRequest.", nameof(url)); + + if (headers.IsSet && headers.Value == null) + throw new ArgumentNullException(nameof(headers), "Property is not nullable for class EdgeRequest."); + + if (method.IsSet && method.Value == null) + throw new ArgumentNullException(nameof(method), "Property is not nullable for class EdgeRequest."); + + if (url.IsSet && url.Value == null) + throw new ArgumentNullException(nameof(url), "Property is not nullable for class EdgeRequest."); + + if (ipv4Address.IsSet && ipv4Address.Value == null) + throw new ArgumentNullException(nameof(ipv4Address), "Property is not nullable for class EdgeRequest."); + + if (ipv6Address.IsSet && ipv6Address.Value == null) + throw new ArgumentNullException(nameof(ipv6Address), "Property is not nullable for class EdgeRequest."); + + if (linkedId.IsSet && linkedId.Value == null) + throw new ArgumentNullException(nameof(linkedId), "Property is not nullable for class EdgeRequest."); + + if (tags.IsSet && tags.Value == null) + throw new ArgumentNullException(nameof(tags), "Property is not nullable for class EdgeRequest."); + + return new EdgeRequest(headers.Value, method.Value, url.Value, ipv4Address, ipv6Address, linkedId, tags); + } + + /// + /// Serializes a + /// + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, EdgeRequest edgeRequest, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, edgeRequest, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, EdgeRequest edgeRequest, JsonSerializerOptions jsonSerializerOptions) + { + if (edgeRequest.Headers == null) + throw new ArgumentNullException(nameof(edgeRequest.Headers), "Property is required for class EdgeRequest."); + + if (edgeRequest.Method == null) + throw new ArgumentNullException(nameof(edgeRequest.Method), "Property is required for class EdgeRequest."); + + if (edgeRequest.Url == null) + throw new ArgumentNullException(nameof(edgeRequest.Url), "Property is required for class EdgeRequest."); + + if (edgeRequest.Ipv4AddressOption.IsSet && edgeRequest.Ipv4Address == null) + throw new ArgumentNullException(nameof(edgeRequest.Ipv4Address), "Property is required for class EdgeRequest."); + + if (edgeRequest.Ipv6AddressOption.IsSet && edgeRequest.Ipv6Address == null) + throw new ArgumentNullException(nameof(edgeRequest.Ipv6Address), "Property is required for class EdgeRequest."); + + if (edgeRequest.LinkedIdOption.IsSet && edgeRequest.LinkedId == null) + throw new ArgumentNullException(nameof(edgeRequest.LinkedId), "Property is required for class EdgeRequest."); + + if (edgeRequest.TagsOption.IsSet && edgeRequest.Tags == null) + throw new ArgumentNullException(nameof(edgeRequest.Tags), "Property is required for class EdgeRequest."); + + writer.WritePropertyName("headers"); + JsonSerializer.Serialize(writer, edgeRequest.Headers, jsonSerializerOptions); + writer.WriteString("method", edgeRequest.Method); + + writer.WriteString("url", edgeRequest.Url); + + if (edgeRequest.Ipv4AddressOption.IsSet) + writer.WriteString("ipv4_address", edgeRequest.Ipv4Address); + + if (edgeRequest.Ipv6AddressOption.IsSet) + writer.WriteString("ipv6_address", edgeRequest.Ipv6Address); + + if (edgeRequest.LinkedIdOption.IsSet) + writer.WriteString("linked_id", edgeRequest.LinkedId); + + if (edgeRequest.TagsOption.IsSet) + { + writer.WritePropertyName("tags"); + JsonSerializer.Serialize(writer, edgeRequest.Tags, jsonSerializerOptions); + } + } + } +} diff --git a/src/Fingerprint.ServerSdk/Model/EdgeRequestHeadersInner.cs b/src/Fingerprint.ServerSdk/Model/EdgeRequestHeadersInner.cs new file mode 100644 index 00000000..9336ab33 --- /dev/null +++ b/src/Fingerprint.ServerSdk/Model/EdgeRequestHeadersInner.cs @@ -0,0 +1,190 @@ +// +/* + * 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. + * + * The version of the OpenAPI document: 4 + * Contact: support@fingerprint.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Fingerprint.ServerSdk.Client; + +namespace Fingerprint.ServerSdk.Model +{ + /// + /// EdgeRequestHeadersInner + /// + public partial class EdgeRequestHeadersInner : IValidatableObject + { + + + /// + /// Initializes a new instance of the class. + /// + /// Header name as forwarded by your server. Headers must be valid according to RFC 7230 and will be canonicalized according to RFC 9112. (required). + /// Value of a single forwarded header entry. Be careful to preserve the original encoding and escaping. For example, do not double escape quotes. (required). + [JsonConstructor] + public EdgeRequestHeadersInner(string name, string value) + { + Name = name; + Value = value; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Header name as forwarded by your server. Headers must be valid according to RFC 7230 and will be canonicalized according to RFC 9112. + /// + /// Header name as forwarded by your server. Headers must be valid according to RFC 7230 and will be canonicalized according to RFC 9112. + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// Value of a single forwarded header entry. Be careful to preserve the original encoding and escaping. For example, do not double escape quotes. + /// + /// Value of a single forwarded header entry. Be careful to preserve the original encoding and escaping. For example, do not double escape quotes. + [JsonPropertyName("value")] + public string Value { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class EdgeRequestHeadersInner {\n"); + sb.Append(" Name: ").Append(Name).Append("\n"); + sb.Append(" Value: ").Append(Value).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public class EdgeRequestHeadersInnerJsonConverter : JsonConverter + { + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override EdgeRequestHeadersInner Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option name = default; + Option value = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "name": + name = new Option(utf8JsonReader.GetString()); + break; + case "value": + value = new Option(utf8JsonReader.GetString()); + break; + default: + break; + } + } + } + + if (!name.IsSet) + throw new ArgumentException("Property is required for class EdgeRequestHeadersInner.", nameof(name)); + + if (!value.IsSet) + throw new ArgumentException("Property is required for class EdgeRequestHeadersInner.", nameof(value)); + + if (name.IsSet && name.Value == null) + throw new ArgumentNullException(nameof(name), "Property is not nullable for class EdgeRequestHeadersInner."); + + if (value.IsSet && value.Value == null) + throw new ArgumentNullException(nameof(value), "Property is not nullable for class EdgeRequestHeadersInner."); + + return new EdgeRequestHeadersInner(name.Value, value.Value); + } + + /// + /// Serializes a + /// + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, EdgeRequestHeadersInner edgeRequestHeadersInner, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, edgeRequestHeadersInner, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, EdgeRequestHeadersInner edgeRequestHeadersInner, JsonSerializerOptions jsonSerializerOptions) + { + if (edgeRequestHeadersInner.Name == null) + throw new ArgumentNullException(nameof(edgeRequestHeadersInner.Name), "Property is required for class EdgeRequestHeadersInner."); + + if (edgeRequestHeadersInner.Value == null) + throw new ArgumentNullException(nameof(edgeRequestHeadersInner.Value), "Property is required for class EdgeRequestHeadersInner."); + + writer.WriteString("name", edgeRequestHeadersInner.Name); + + writer.WriteString("value", edgeRequestHeadersInner.Value); + } + } +} diff --git a/src/Fingerprint.ServerSdk/Model/Event.cs b/src/Fingerprint.ServerSdk/Model/Event.cs index 5214a577..724072cc 100644 --- a/src/Fingerprint.ServerSdk/Model/Event.cs +++ b/src/Fingerprint.ServerSdk/Model/Event.cs @@ -25,7 +25,7 @@ namespace Fingerprint.ServerSdk.Model { /// - /// Contains results from Fingerprint Identification and all active Smart Signals. Some Smart Signals are only supported for certain device types, these fields will be omitted for events not generated from the supported devices. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. + /// An identification event (`source: device`) or an Automation Intelligence event (`source: edge`). Use `source` to tell them apart. Device events include Identification and device-derived Smart Signals. Edge events do not. Consult the [Smart Signals reference](https://docs.fingerprint.com/docs/smart-signals-reference) for more details. /// public partial class Event : IValidatableObject { @@ -36,17 +36,25 @@ public partial class Event : IValidatableObject /// /// Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. (required). /// Timestamp of the event with millisecond precision in Unix time. (required). + /// A customer-provided id that was sent with the request.. + /// A customer-provided value or an object that was sent with the identification request or updated later.. + /// Page URL from which the request was sent.. + /// botInfo. + /// ipInfo. + /// IP address was used by a public proxy provider or belonged to a known recent residential proxy . + /// proxyConfidence. + /// proxyDetails. + /// VPN or other anonymizing service has been used when sending the request. . + /// vpnConfidence. + /// vpnMethods. /// source. /// incrementalIdentificationStatus. - /// A customer-provided id that was sent with the request.. /// Environment Id of the event.. - /// Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event).. + /// Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event).. /// sdk. /// `true` if we determined that this payload was replayed, `false` otherwise. . /// identification. /// supplementaryIdHighRecall. - /// A customer-provided value or an object that was sent with the identification request or updated later.. - /// Page URL from which the request was sent.. /// Bundle Id of the iOS application integrated with the Fingerprint SDK for the event. . /// Package name of the Android application integrated with the Fingerprint SDK for the event. . /// IP address of the requesting browser or bot.. @@ -60,17 +68,12 @@ public partial class Event : IValidatableObject /// Indicates whether the mobile device had an active call (cellular or VoIP) at the time of the request. Available from SDK 2.16.0+ on iOS and Android. . /// bot. /// Additional classification of the bot type if detected. . - /// botInfo. /// Android specific cloned application detection. There are 2 values: * `true` - Presence of app cloners work detected (e.g. fully cloned application found or launch of it inside of a not main working profile detected). * `false` - No signs of cloned application detected or the client is not Android. . /// `true` if the browser has DevTools open (Chrome, Firefox) or the Android/iOS device has Developer Tools enabled, `false` otherwise. . /// Android specific emulator detection. There are 2 values: * `true` - Emulated environment detected (e.g. launch inside of AVD). * `false` - No signs of emulated environment detected or the client is not Android. . /// The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. When a factory reset cannot be detected on the mobile device or when the request is initiated from a browser, this field will correspond to the *epoch* time (i.e 1 Jan 1970 UTC) as a value of 0. See [Factory Reset Detection](https://docs.fingerprint.com/docs/smart-signals-reference#factory-reset-detection) to learn more about this Smart Signal. . /// [Frida](https://frida.re/docs/) detection for Android and iOS devices. There are 2 values: * `true` - Frida detected * `false` - No signs of Frida or the client is not a mobile device. . /// ipBlocklist. - /// ipInfo. - /// IP address was used by a public proxy provider or belonged to a known recent residential proxy . - /// proxyConfidence. - /// proxyDetails. /// Machine learning–based proxy 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 `proxy` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). . /// `true` if we detected incognito mode used in the browser, `false` otherwise. . /// iOS specific jailbreak detection. There are 2 values: * `true` - Jailbreak detected. * `false` - No signs of jailbreak or the client is not iOS. . @@ -88,33 +91,38 @@ public partial class Event : IValidatableObject /// velocity. /// `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. . /// 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. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). . - /// VPN or other anonymizing service has been used when sending the request. . - /// vpnConfidence. /// Machine learning–based VPN 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 `vpn` detection result. This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). . /// Local timezone which is used in timezone_mismatch method. . /// Country of the request (Android SDK version >= 2.4.0, iOS SDK version >= 2.9.0, JS agent >= 3.12.9 / 4.0.2), ISO 3166 format or unknown. . - /// vpnMethods. /// Flag indicating if the request came from a high-activity visitor.. /// `true` if the device is considered rare based on its combination of hardware and software attributes. A device is classified as rare if it falls within the top 99.9 percentile (lowest-frequency segment) of observed traffic, or if its configuration has not been previously seen (`not_seen`). > This Smart Signal is currently in beta and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). . /// rareDevicePercentileBucket. /// rawDeviceAttributes. /// Each label returns a prediction (true or false) for a specific use case (label field) based on a machine learning score. The machine learning score is determined by a model trained on customer data for that use case. This field is in the beta phase and only available to select customers. If you are interested, please [contact our support team](https://fingerprint.com/support/). . [JsonConstructor] - public Event(string eventId, long timestamp, Option source = default, Option incrementalIdentificationStatus = default, Option linkedId = default, Option environmentId = default, Option suspect = default, Option sdk = default, Option replayed = default, Option identification = default, Option supplementaryIdHighRecall = default, Option> tags = default, Option url = default, Option bundleId = default, Option packageName = default, Option ipAddress = default, Option userAgent = default, Option device = default, Option os = default, Option osVersion = default, Option clientReferrer = default, Option browserDetails = default, Option proximity = default, Option activeCall = default, Option bot = default, Option botType = default, Option botInfo = default, Option clonedApp = default, Option developerTools = default, Option emulator = default, Option factoryResetTimestamp = default, Option frida = default, Option ipBlocklist = default, Option ipInfo = default, Option proxy = default, Option proxyConfidence = default, Option proxyDetails = default, Option proxyMlScore = default, Option incognito = default, Option jailbroken = default, Option locationSpoofing = default, Option mitmAttack = default, Option privacySettings = default, Option rootApps = default, Option ruleAction = default, Option simulator = default, Option suspectScore = default, Option tampering = default, Option tamperingConfidence = default, Option tamperingMlScore = default, Option tamperingDetails = default, Option velocity = default, Option virtualMachine = default, Option virtualMachineMlScore = default, Option vpn = default, Option vpnConfidence = default, Option vpnMlScore = default, Option vpnOriginTimezone = default, Option vpnOriginCountry = default, Option vpnMethods = default, Option highActivityDevice = default, Option rareDevice = default, Option rareDevicePercentileBucket = default, Option rawDeviceAttributes = default, Option> labels = default) + public Event(string eventId, long timestamp, Option linkedId = default, Option> tags = default, Option url = default, Option botInfo = default, Option ipInfo = default, Option proxy = default, Option proxyConfidence = default, Option proxyDetails = default, Option vpn = default, Option vpnConfidence = default, Option vpnMethods = default, Option source = default, Option incrementalIdentificationStatus = default, Option environmentId = default, Option suspect = default, Option sdk = default, Option replayed = default, Option identification = default, Option supplementaryIdHighRecall = default, Option bundleId = default, Option packageName = default, Option ipAddress = default, Option userAgent = default, Option device = default, Option os = default, Option osVersion = default, Option clientReferrer = default, Option browserDetails = default, Option proximity = default, Option activeCall = default, Option bot = default, Option botType = default, Option clonedApp = default, Option developerTools = default, Option emulator = default, Option factoryResetTimestamp = default, Option frida = default, Option ipBlocklist = default, Option proxyMlScore = default, Option incognito = default, Option jailbroken = default, Option locationSpoofing = default, Option mitmAttack = default, Option privacySettings = default, Option rootApps = default, Option ruleAction = default, Option simulator = default, Option suspectScore = default, Option tampering = default, Option tamperingConfidence = default, Option tamperingMlScore = default, Option tamperingDetails = default, Option velocity = default, Option virtualMachine = default, Option virtualMachineMlScore = default, Option vpnMlScore = default, Option vpnOriginTimezone = default, Option vpnOriginCountry = default, Option highActivityDevice = default, Option rareDevice = default, Option rareDevicePercentileBucket = default, Option rawDeviceAttributes = default, Option> labels = default) { EventId = eventId; Timestamp = timestamp; + LinkedIdOption = linkedId; + TagsOption = tags; + UrlOption = url; + BotInfoOption = botInfo; + IpInfoOption = ipInfo; + ProxyOption = proxy; + ProxyConfidenceOption = proxyConfidence; + ProxyDetailsOption = proxyDetails; + VpnOption = vpn; + VpnConfidenceOption = vpnConfidence; + VpnMethodsOption = vpnMethods; SourceOption = source; IncrementalIdentificationStatusOption = incrementalIdentificationStatus; - LinkedIdOption = linkedId; EnvironmentIdOption = environmentId; SuspectOption = suspect; SdkOption = sdk; ReplayedOption = replayed; IdentificationOption = identification; SupplementaryIdHighRecallOption = supplementaryIdHighRecall; - TagsOption = tags; - UrlOption = url; BundleIdOption = bundleId; PackageNameOption = packageName; IpAddressOption = ipAddress; @@ -128,17 +136,12 @@ public Event(string eventId, long timestamp, Option source = defau ActiveCallOption = activeCall; BotOption = bot; BotTypeOption = botType; - BotInfoOption = botInfo; ClonedAppOption = clonedApp; DeveloperToolsOption = developerTools; EmulatorOption = emulator; FactoryResetTimestampOption = factoryResetTimestamp; FridaOption = frida; IpBlocklistOption = ipBlocklist; - IpInfoOption = ipInfo; - ProxyOption = proxy; - ProxyConfidenceOption = proxyConfidence; - ProxyDetailsOption = proxyDetails; ProxyMlScoreOption = proxyMlScore; IncognitoOption = incognito; JailbrokenOption = jailbroken; @@ -156,12 +159,9 @@ public Event(string eventId, long timestamp, Option source = defau VelocityOption = velocity; VirtualMachineOption = virtualMachine; VirtualMachineMlScoreOption = virtualMachineMlScore; - VpnOption = vpn; - VpnConfidenceOption = vpnConfidence; VpnMlScoreOption = vpnMlScore; VpnOriginTimezoneOption = vpnOriginTimezone; VpnOriginCountryOption = vpnOriginCountry; - VpnMethodsOption = vpnMethods; HighActivityDeviceOption = highActivityDevice; RareDeviceOption = rareDevice; RareDevicePercentileBucketOption = rareDevicePercentileBucket; @@ -172,6 +172,32 @@ public Event(string eventId, long timestamp, Option source = defau partial void OnCreated(); + /// + /// Used to track the state of ProxyConfidence + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option ProxyConfidenceOption { get; private set; } + + /// + /// Gets or Sets ProxyConfidence + /// + [JsonPropertyName("proxy_confidence")] + public ProxyConfidence? ProxyConfidence { get { return this.ProxyConfidenceOption; } set { this.ProxyConfidenceOption = new Option(value); } } + + /// + /// Used to track the state of VpnConfidence + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option VpnConfidenceOption { get; private set; } + + /// + /// Gets or Sets VpnConfidence + /// + [JsonPropertyName("vpn_confidence")] + public VpnConfidence? VpnConfidence { get { return this.VpnConfidenceOption; } set { this.VpnConfidenceOption = new Option(value); } } + /// /// Used to track the state of Source /// @@ -211,19 +237,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("bot")] public BotResult? Bot { get { return this.BotOption; } set { this.BotOption = new Option(value); } } - /// - /// Used to track the state of ProxyConfidence - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option ProxyConfidenceOption { get; private set; } - - /// - /// Gets or Sets ProxyConfidence - /// - [JsonPropertyName("proxy_confidence")] - public ProxyConfidence? ProxyConfidence { get { return this.ProxyConfidenceOption; } set { this.ProxyConfidenceOption = new Option(value); } } - /// /// Used to track the state of TamperingConfidence /// @@ -237,19 +250,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("tampering_confidence")] public TamperingConfidence? TamperingConfidence { get { return this.TamperingConfidenceOption; } set { this.TamperingConfidenceOption = new Option(value); } } - /// - /// Used to track the state of VpnConfidence - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option VpnConfidenceOption { get; private set; } - - /// - /// Gets or Sets VpnConfidence - /// - [JsonPropertyName("vpn_confidence")] - public VpnConfidence? VpnConfidence { get { return this.VpnConfidenceOption; } set { this.VpnConfidenceOption = new Option(value); } } - /// /// Used to track the state of RareDevicePercentileBucket /// @@ -291,6 +291,114 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("linked_id")] public string LinkedId { get { return this.LinkedIdOption; } set { this.LinkedIdOption = new Option(value); } } + /// + /// Used to track the state of Tags + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option> TagsOption { get; private set; } + + /// + /// A customer-provided value or an object that was sent with the identification request or updated later. + /// + /// A customer-provided value or an object that was sent with the identification request or updated later. + [JsonPropertyName("tags")] + public Dictionary Tags { get { return this.TagsOption; } set { this.TagsOption = new Option>(value); } } + + /// + /// Used to track the state of Url + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option UrlOption { get; private set; } + + /// + /// Page URL from which the request was sent. + /// + /// Page URL from which the request was sent. + [JsonPropertyName("url")] + public string Url { get { return this.UrlOption; } set { this.UrlOption = new Option(value); } } + + /// + /// Used to track the state of BotInfo + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option BotInfoOption { get; private set; } + + /// + /// Gets or Sets BotInfo + /// + [JsonPropertyName("bot_info")] + public BotInfo BotInfo { get { return this.BotInfoOption; } set { this.BotInfoOption = new Option(value); } } + + /// + /// Used to track the state of IpInfo + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option IpInfoOption { get; private set; } + + /// + /// Gets or Sets IpInfo + /// + [JsonPropertyName("ip_info")] + public IPInfo IpInfo { get { return this.IpInfoOption; } set { this.IpInfoOption = new Option(value); } } + + /// + /// Used to track the state of Proxy + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option ProxyOption { get; private set; } + + /// + /// IP address was used by a public proxy provider or belonged to a known recent residential proxy + /// + /// IP address was used by a public proxy provider or belonged to a known recent residential proxy + [JsonPropertyName("proxy")] + public bool? Proxy { get { return this.ProxyOption; } set { this.ProxyOption = new Option(value); } } + + /// + /// Used to track the state of ProxyDetails + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option ProxyDetailsOption { get; private set; } + + /// + /// Gets or Sets ProxyDetails + /// + [JsonPropertyName("proxy_details")] + public ProxyDetails ProxyDetails { get { return this.ProxyDetailsOption; } set { this.ProxyDetailsOption = new Option(value); } } + + /// + /// Used to track the state of Vpn + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option VpnOption { get; private set; } + + /// + /// VPN or other anonymizing service has been used when sending the request. + /// + /// VPN or other anonymizing service has been used when sending the request. + [JsonPropertyName("vpn")] + public bool? Vpn { get { return this.VpnOption; } set { this.VpnOption = new Option(value); } } + + /// + /// Used to track the state of VpnMethods + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option VpnMethodsOption { get; private set; } + + /// + /// Gets or Sets VpnMethods + /// + [JsonPropertyName("vpn_methods")] + public VpnMethods VpnMethods { get { return this.VpnMethodsOption; } set { this.VpnMethodsOption = new Option(value); } } + /// /// Used to track the state of EnvironmentId /// @@ -313,9 +421,9 @@ public Event(string eventId, long timestamp, Option source = defau public Option SuspectOption { get; private set; } /// - /// Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event). + /// Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event). /// - /// Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-v4-update-event). + /// Field is `true` if you have previously set the `suspect` flag for this event using the [Server API Update event endpoint](https://docs.fingerprint.com/reference/server-api-update-event). [JsonPropertyName("suspect")] public bool? Suspect { get { return this.SuspectOption; } set { this.SuspectOption = new Option(value); } } @@ -372,34 +480,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("supplementary_id_high_recall")] public SupplementaryIDHighRecall SupplementaryIdHighRecall { get { return this.SupplementaryIdHighRecallOption; } set { this.SupplementaryIdHighRecallOption = new Option(value); } } - /// - /// Used to track the state of Tags - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option> TagsOption { get; private set; } - - /// - /// A customer-provided value or an object that was sent with the identification request or updated later. - /// - /// A customer-provided value or an object that was sent with the identification request or updated later. - [JsonPropertyName("tags")] - public Dictionary Tags { get { return this.TagsOption; } set { this.TagsOption = new Option>(value); } } - - /// - /// Used to track the state of Url - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option UrlOption { get; private set; } - - /// - /// Page URL from which the request was sent. - /// - /// Page URL from which the request was sent. - [JsonPropertyName("url")] - public string Url { get { return this.UrlOption; } set { this.UrlOption = new Option(value); } } - /// /// Used to track the state of BundleId /// @@ -566,19 +646,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("bot_type")] public string BotType { get { return this.BotTypeOption; } set { this.BotTypeOption = new Option(value); } } - /// - /// Used to track the state of BotInfo - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option BotInfoOption { get; private set; } - - /// - /// Gets or Sets BotInfo - /// - [JsonPropertyName("bot_info")] - public BotInfo BotInfo { get { return this.BotInfoOption; } set { this.BotInfoOption = new Option(value); } } - /// /// Used to track the state of ClonedApp /// @@ -662,46 +729,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("ip_blocklist")] public IPBlockList IpBlocklist { get { return this.IpBlocklistOption; } set { this.IpBlocklistOption = new Option(value); } } - /// - /// Used to track the state of IpInfo - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option IpInfoOption { get; private set; } - - /// - /// Gets or Sets IpInfo - /// - [JsonPropertyName("ip_info")] - public IPInfo IpInfo { get { return this.IpInfoOption; } set { this.IpInfoOption = new Option(value); } } - - /// - /// Used to track the state of Proxy - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option ProxyOption { get; private set; } - - /// - /// IP address was used by a public proxy provider or belonged to a known recent residential proxy - /// - /// IP address was used by a public proxy provider or belonged to a known recent residential proxy - [JsonPropertyName("proxy")] - public bool? Proxy { get { return this.ProxyOption; } set { this.ProxyOption = new Option(value); } } - - /// - /// Used to track the state of ProxyDetails - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option ProxyDetailsOption { get; private set; } - - /// - /// Gets or Sets ProxyDetails - /// - [JsonPropertyName("proxy_details")] - public ProxyDetails ProxyDetails { get { return this.ProxyDetailsOption; } set { this.ProxyDetailsOption = new Option(value); } } - /// /// Used to track the state of ProxyMlScore /// @@ -923,20 +950,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("virtual_machine_ml_score")] public double? VirtualMachineMlScore { get { return this.VirtualMachineMlScoreOption; } set { this.VirtualMachineMlScoreOption = new Option(value); } } - /// - /// Used to track the state of Vpn - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option VpnOption { get; private set; } - - /// - /// VPN or other anonymizing service has been used when sending the request. - /// - /// VPN or other anonymizing service has been used when sending the request. - [JsonPropertyName("vpn")] - public bool? Vpn { get { return this.VpnOption; } set { this.VpnOption = new Option(value); } } - /// /// Used to track the state of VpnMlScore /// @@ -979,19 +992,6 @@ public Event(string eventId, long timestamp, Option source = defau [JsonPropertyName("vpn_origin_country")] public string VpnOriginCountry { get { return this.VpnOriginCountryOption; } set { this.VpnOriginCountryOption = new Option(value); } } - /// - /// Used to track the state of VpnMethods - /// - [JsonIgnore] - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public Option VpnMethodsOption { get; private set; } - - /// - /// Gets or Sets VpnMethods - /// - [JsonPropertyName("vpn_methods")] - public VpnMethods VpnMethods { get { return this.VpnMethodsOption; } set { this.VpnMethodsOption = new Option(value); } } - /// /// Used to track the state of HighActivityDevice /// @@ -1057,17 +1057,25 @@ public override string ToString() sb.Append("class Event {\n"); sb.Append(" EventId: ").Append(EventId).Append("\n"); sb.Append(" Timestamp: ").Append(Timestamp).Append("\n"); + sb.Append(" LinkedId: ").Append(LinkedId).Append("\n"); + sb.Append(" Tags: ").Append(Tags).Append("\n"); + sb.Append(" Url: ").Append(Url).Append("\n"); + sb.Append(" BotInfo: ").Append(BotInfo).Append("\n"); + sb.Append(" IpInfo: ").Append(IpInfo).Append("\n"); + sb.Append(" Proxy: ").Append(Proxy).Append("\n"); + sb.Append(" ProxyConfidence: ").Append(ProxyConfidence).Append("\n"); + sb.Append(" ProxyDetails: ").Append(ProxyDetails).Append("\n"); + sb.Append(" Vpn: ").Append(Vpn).Append("\n"); + sb.Append(" VpnConfidence: ").Append(VpnConfidence).Append("\n"); + sb.Append(" VpnMethods: ").Append(VpnMethods).Append("\n"); sb.Append(" Source: ").Append(Source).Append("\n"); sb.Append(" IncrementalIdentificationStatus: ").Append(IncrementalIdentificationStatus).Append("\n"); - sb.Append(" LinkedId: ").Append(LinkedId).Append("\n"); sb.Append(" EnvironmentId: ").Append(EnvironmentId).Append("\n"); sb.Append(" Suspect: ").Append(Suspect).Append("\n"); sb.Append(" Sdk: ").Append(Sdk).Append("\n"); sb.Append(" Replayed: ").Append(Replayed).Append("\n"); sb.Append(" Identification: ").Append(Identification).Append("\n"); sb.Append(" SupplementaryIdHighRecall: ").Append(SupplementaryIdHighRecall).Append("\n"); - sb.Append(" Tags: ").Append(Tags).Append("\n"); - sb.Append(" Url: ").Append(Url).Append("\n"); sb.Append(" BundleId: ").Append(BundleId).Append("\n"); sb.Append(" PackageName: ").Append(PackageName).Append("\n"); sb.Append(" IpAddress: ").Append(IpAddress).Append("\n"); @@ -1081,17 +1089,12 @@ public override string ToString() sb.Append(" ActiveCall: ").Append(ActiveCall).Append("\n"); sb.Append(" Bot: ").Append(Bot).Append("\n"); sb.Append(" BotType: ").Append(BotType).Append("\n"); - sb.Append(" BotInfo: ").Append(BotInfo).Append("\n"); sb.Append(" ClonedApp: ").Append(ClonedApp).Append("\n"); sb.Append(" DeveloperTools: ").Append(DeveloperTools).Append("\n"); sb.Append(" Emulator: ").Append(Emulator).Append("\n"); sb.Append(" FactoryResetTimestamp: ").Append(FactoryResetTimestamp).Append("\n"); sb.Append(" Frida: ").Append(Frida).Append("\n"); sb.Append(" IpBlocklist: ").Append(IpBlocklist).Append("\n"); - sb.Append(" IpInfo: ").Append(IpInfo).Append("\n"); - sb.Append(" Proxy: ").Append(Proxy).Append("\n"); - sb.Append(" ProxyConfidence: ").Append(ProxyConfidence).Append("\n"); - sb.Append(" ProxyDetails: ").Append(ProxyDetails).Append("\n"); sb.Append(" ProxyMlScore: ").Append(ProxyMlScore).Append("\n"); sb.Append(" Incognito: ").Append(Incognito).Append("\n"); sb.Append(" Jailbroken: ").Append(Jailbroken).Append("\n"); @@ -1109,12 +1112,9 @@ public override string ToString() sb.Append(" Velocity: ").Append(Velocity).Append("\n"); sb.Append(" VirtualMachine: ").Append(VirtualMachine).Append("\n"); sb.Append(" VirtualMachineMlScore: ").Append(VirtualMachineMlScore).Append("\n"); - sb.Append(" Vpn: ").Append(Vpn).Append("\n"); - sb.Append(" VpnConfidence: ").Append(VpnConfidence).Append("\n"); sb.Append(" VpnMlScore: ").Append(VpnMlScore).Append("\n"); sb.Append(" VpnOriginTimezone: ").Append(VpnOriginTimezone).Append("\n"); sb.Append(" VpnOriginCountry: ").Append(VpnOriginCountry).Append("\n"); - sb.Append(" VpnMethods: ").Append(VpnMethods).Append("\n"); sb.Append(" HighActivityDevice: ").Append(HighActivityDevice).Append("\n"); sb.Append(" RareDevice: ").Append(RareDevice).Append("\n"); sb.Append(" RareDevicePercentileBucket: ").Append(RareDevicePercentileBucket).Append("\n"); @@ -1207,17 +1207,25 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert Option eventId = default; Option timestamp = default; + Option linkedId = default; + Option> tags = default; + Option url = default; + Option botInfo = default; + Option ipInfo = default; + Option proxy = default; + Option proxyConfidence = default; + Option proxyDetails = default; + Option vpn = default; + Option vpnConfidence = default; + Option vpnMethods = default; Option source = default; Option incrementalIdentificationStatus = default; - Option linkedId = default; Option environmentId = default; Option suspect = default; Option sdk = default; Option replayed = default; Option identification = default; Option supplementaryIdHighRecall = default; - Option> tags = default; - Option url = default; Option bundleId = default; Option packageName = default; Option ipAddress = default; @@ -1231,17 +1239,12 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert Option activeCall = default; Option bot = default; Option botType = default; - Option botInfo = default; Option clonedApp = default; Option developerTools = default; Option emulator = default; Option factoryResetTimestamp = default; Option frida = default; Option ipBlocklist = default; - Option ipInfo = default; - Option proxy = default; - Option proxyConfidence = default; - Option proxyDetails = default; Option proxyMlScore = default; Option incognito = default; Option jailbroken = default; @@ -1259,12 +1262,9 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert Option velocity = default; Option virtualMachine = default; Option virtualMachineMlScore = default; - Option vpn = default; - Option vpnConfidence = default; Option vpnMlScore = default; Option vpnOriginTimezone = default; Option vpnOriginCountry = default; - Option vpnMethods = default; Option highActivityDevice = default; Option rareDevice = default; Option rareDevicePercentileBucket = default; @@ -1289,8 +1289,45 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert case "event_id": eventId = new Option(utf8JsonReader.GetString()); break; - case "timestamp": - timestamp = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (long?)null : utf8JsonReader.GetInt64()); + case "timestamp": + timestamp = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (long?)null : utf8JsonReader.GetInt64()); + break; + case "linked_id": + linkedId = new Option(utf8JsonReader.GetString()); + break; + case "tags": + tags = new Option>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "url": + url = new Option(utf8JsonReader.GetString()); + break; + case "bot_info": + botInfo = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "ip_info": + ipInfo = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "proxy": + proxy = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); + break; + case "proxy_confidence": + string proxyConfidenceRawValue = utf8JsonReader.GetString(); + if (proxyConfidenceRawValue != null) + proxyConfidence = new Option(ProxyConfidenceValueConverter.FromStringOrDefault(proxyConfidenceRawValue)); + break; + case "proxy_details": + proxyDetails = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "vpn": + vpn = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); + break; + case "vpn_confidence": + string vpnConfidenceRawValue = utf8JsonReader.GetString(); + if (vpnConfidenceRawValue != null) + vpnConfidence = new Option(VpnConfidenceValueConverter.FromStringOrDefault(vpnConfidenceRawValue)); + break; + case "vpn_methods": + vpnMethods = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); break; case "source": string sourceRawValue = utf8JsonReader.GetString(); @@ -1302,9 +1339,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (incrementalIdentificationStatusRawValue != null) incrementalIdentificationStatus = new Option(IncrementalIdentificationStatusValueConverter.FromStringOrDefault(incrementalIdentificationStatusRawValue)); break; - case "linked_id": - linkedId = new Option(utf8JsonReader.GetString()); - break; case "environment_id": environmentId = new Option(utf8JsonReader.GetString()); break; @@ -1323,12 +1357,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert case "supplementary_id_high_recall": supplementaryIdHighRecall = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); break; - case "tags": - tags = new Option>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)); - break; - case "url": - url = new Option(utf8JsonReader.GetString()); - break; case "bundle_id": bundleId = new Option(utf8JsonReader.GetString()); break; @@ -1370,9 +1398,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert case "bot_type": botType = new Option(utf8JsonReader.GetString()); break; - case "bot_info": - botInfo = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); - break; case "cloned_app": clonedApp = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); break; @@ -1391,20 +1416,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert case "ip_blocklist": ipBlocklist = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); break; - case "ip_info": - ipInfo = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); - break; - case "proxy": - proxy = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); - break; - case "proxy_confidence": - string proxyConfidenceRawValue = utf8JsonReader.GetString(); - if (proxyConfidenceRawValue != null) - proxyConfidence = new Option(ProxyConfidenceValueConverter.FromStringOrDefault(proxyConfidenceRawValue)); - break; - case "proxy_details": - proxyDetails = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); - break; case "proxy_ml_score": proxyMlScore = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (double?)null : utf8JsonReader.GetDouble()); break; @@ -1458,14 +1469,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert case "virtual_machine_ml_score": virtualMachineMlScore = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (double?)null : utf8JsonReader.GetDouble()); break; - case "vpn": - vpn = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); - break; - case "vpn_confidence": - string vpnConfidenceRawValue = utf8JsonReader.GetString(); - if (vpnConfidenceRawValue != null) - vpnConfidence = new Option(VpnConfidenceValueConverter.FromStringOrDefault(vpnConfidenceRawValue)); - break; case "vpn_ml_score": vpnMlScore = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (double?)null : utf8JsonReader.GetDouble()); break; @@ -1475,9 +1478,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert case "vpn_origin_country": vpnOriginCountry = new Option(utf8JsonReader.GetString()); break; - case "vpn_methods": - vpnMethods = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); - break; case "high_activity_device": highActivityDevice = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); break; @@ -1513,15 +1513,45 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (timestamp.IsSet && timestamp.Value == null) throw new ArgumentNullException(nameof(timestamp), "Property is not nullable for class Event."); + if (linkedId.IsSet && linkedId.Value == null) + throw new ArgumentNullException(nameof(linkedId), "Property is not nullable for class Event."); + + if (tags.IsSet && tags.Value == null) + throw new ArgumentNullException(nameof(tags), "Property is not nullable for class Event."); + + if (url.IsSet && url.Value == null) + throw new ArgumentNullException(nameof(url), "Property is not nullable for class Event."); + + if (botInfo.IsSet && botInfo.Value == null) + throw new ArgumentNullException(nameof(botInfo), "Property is not nullable for class Event."); + + if (ipInfo.IsSet && ipInfo.Value == null) + throw new ArgumentNullException(nameof(ipInfo), "Property is not nullable for class Event."); + + if (proxy.IsSet && proxy.Value == null) + throw new ArgumentNullException(nameof(proxy), "Property is not nullable for class Event."); + + if (proxyConfidence.IsSet && proxyConfidence.Value == null) + throw new ArgumentNullException(nameof(proxyConfidence), "Property is not nullable for class Event."); + + if (proxyDetails.IsSet && proxyDetails.Value == null) + throw new ArgumentNullException(nameof(proxyDetails), "Property is not nullable for class Event."); + + if (vpn.IsSet && vpn.Value == null) + throw new ArgumentNullException(nameof(vpn), "Property is not nullable for class Event."); + + if (vpnConfidence.IsSet && vpnConfidence.Value == null) + throw new ArgumentNullException(nameof(vpnConfidence), "Property is not nullable for class Event."); + + if (vpnMethods.IsSet && vpnMethods.Value == null) + throw new ArgumentNullException(nameof(vpnMethods), "Property is not nullable for class Event."); + if (source.IsSet && source.Value == null) throw new ArgumentNullException(nameof(source), "Property is not nullable for class Event."); if (incrementalIdentificationStatus.IsSet && incrementalIdentificationStatus.Value == null) throw new ArgumentNullException(nameof(incrementalIdentificationStatus), "Property is not nullable for class Event."); - if (linkedId.IsSet && linkedId.Value == null) - throw new ArgumentNullException(nameof(linkedId), "Property is not nullable for class Event."); - if (environmentId.IsSet && environmentId.Value == null) throw new ArgumentNullException(nameof(environmentId), "Property is not nullable for class Event."); @@ -1540,12 +1570,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (supplementaryIdHighRecall.IsSet && supplementaryIdHighRecall.Value == null) throw new ArgumentNullException(nameof(supplementaryIdHighRecall), "Property is not nullable for class Event."); - if (tags.IsSet && tags.Value == null) - throw new ArgumentNullException(nameof(tags), "Property is not nullable for class Event."); - - if (url.IsSet && url.Value == null) - throw new ArgumentNullException(nameof(url), "Property is not nullable for class Event."); - if (bundleId.IsSet && bundleId.Value == null) throw new ArgumentNullException(nameof(bundleId), "Property is not nullable for class Event."); @@ -1585,9 +1609,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (botType.IsSet && botType.Value == null) throw new ArgumentNullException(nameof(botType), "Property is not nullable for class Event."); - if (botInfo.IsSet && botInfo.Value == null) - throw new ArgumentNullException(nameof(botInfo), "Property is not nullable for class Event."); - if (clonedApp.IsSet && clonedApp.Value == null) throw new ArgumentNullException(nameof(clonedApp), "Property is not nullable for class Event."); @@ -1606,18 +1627,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (ipBlocklist.IsSet && ipBlocklist.Value == null) throw new ArgumentNullException(nameof(ipBlocklist), "Property is not nullable for class Event."); - if (ipInfo.IsSet && ipInfo.Value == null) - throw new ArgumentNullException(nameof(ipInfo), "Property is not nullable for class Event."); - - if (proxy.IsSet && proxy.Value == null) - throw new ArgumentNullException(nameof(proxy), "Property is not nullable for class Event."); - - if (proxyConfidence.IsSet && proxyConfidence.Value == null) - throw new ArgumentNullException(nameof(proxyConfidence), "Property is not nullable for class Event."); - - if (proxyDetails.IsSet && proxyDetails.Value == null) - throw new ArgumentNullException(nameof(proxyDetails), "Property is not nullable for class Event."); - if (proxyMlScore.IsSet && proxyMlScore.Value == null) throw new ArgumentNullException(nameof(proxyMlScore), "Property is not nullable for class Event."); @@ -1669,12 +1678,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (virtualMachineMlScore.IsSet && virtualMachineMlScore.Value == null) throw new ArgumentNullException(nameof(virtualMachineMlScore), "Property is not nullable for class Event."); - if (vpn.IsSet && vpn.Value == null) - throw new ArgumentNullException(nameof(vpn), "Property is not nullable for class Event."); - - if (vpnConfidence.IsSet && vpnConfidence.Value == null) - throw new ArgumentNullException(nameof(vpnConfidence), "Property is not nullable for class Event."); - if (vpnMlScore.IsSet && vpnMlScore.Value == null) throw new ArgumentNullException(nameof(vpnMlScore), "Property is not nullable for class Event."); @@ -1684,9 +1687,6 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (vpnOriginCountry.IsSet && vpnOriginCountry.Value == null) throw new ArgumentNullException(nameof(vpnOriginCountry), "Property is not nullable for class Event."); - if (vpnMethods.IsSet && vpnMethods.Value == null) - throw new ArgumentNullException(nameof(vpnMethods), "Property is not nullable for class Event."); - if (highActivityDevice.IsSet && highActivityDevice.Value == null) throw new ArgumentNullException(nameof(highActivityDevice), "Property is not nullable for class Event."); @@ -1702,7 +1702,7 @@ public override Event Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert if (labels.IsSet && labels.Value == null) throw new ArgumentNullException(nameof(labels), "Property is not nullable for class Event."); - return new Event(eventId.Value, timestamp.Value.Value, source, incrementalIdentificationStatus, linkedId, environmentId, suspect, sdk, replayed, identification, supplementaryIdHighRecall, tags, url, bundleId, packageName, ipAddress, userAgent, device, os, osVersion, clientReferrer, browserDetails, proximity, activeCall, bot, botType, botInfo, clonedApp, developerTools, emulator, factoryResetTimestamp, frida, ipBlocklist, ipInfo, proxy, proxyConfidence, proxyDetails, proxyMlScore, incognito, jailbroken, locationSpoofing, mitmAttack, privacySettings, rootApps, ruleAction, simulator, suspectScore, tampering, tamperingConfidence, tamperingMlScore, tamperingDetails, velocity, virtualMachine, virtualMachineMlScore, vpn, vpnConfidence, vpnMlScore, vpnOriginTimezone, vpnOriginCountry, vpnMethods, highActivityDevice, rareDevice, rareDevicePercentileBucket, rawDeviceAttributes, labels); + return new Event(eventId.Value, timestamp.Value.Value, linkedId, tags, url, botInfo, ipInfo, proxy, proxyConfidence, proxyDetails, vpn, vpnConfidence, vpnMethods, source, incrementalIdentificationStatus, environmentId, suspect, sdk, replayed, identification, supplementaryIdHighRecall, bundleId, packageName, ipAddress, userAgent, device, os, osVersion, clientReferrer, browserDetails, proximity, activeCall, bot, botType, clonedApp, developerTools, emulator, factoryResetTimestamp, frida, ipBlocklist, proxyMlScore, incognito, jailbroken, locationSpoofing, mitmAttack, privacySettings, rootApps, ruleAction, simulator, suspectScore, tampering, tamperingConfidence, tamperingMlScore, tamperingDetails, velocity, virtualMachine, virtualMachineMlScore, vpnMlScore, vpnOriginTimezone, vpnOriginCountry, highActivityDevice, rareDevice, rareDevicePercentileBucket, rawDeviceAttributes, labels); } /// @@ -1735,6 +1735,24 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.LinkedIdOption.IsSet && varEvent.LinkedId == null) throw new ArgumentNullException(nameof(varEvent.LinkedId), "Property is required for class Event."); + if (varEvent.TagsOption.IsSet && varEvent.Tags == null) + throw new ArgumentNullException(nameof(varEvent.Tags), "Property is required for class Event."); + + if (varEvent.UrlOption.IsSet && varEvent.Url == null) + throw new ArgumentNullException(nameof(varEvent.Url), "Property is required for class Event."); + + if (varEvent.BotInfoOption.IsSet && varEvent.BotInfo == null) + throw new ArgumentNullException(nameof(varEvent.BotInfo), "Property is required for class Event."); + + if (varEvent.IpInfoOption.IsSet && varEvent.IpInfo == null) + throw new ArgumentNullException(nameof(varEvent.IpInfo), "Property is required for class Event."); + + if (varEvent.ProxyDetailsOption.IsSet && varEvent.ProxyDetails == null) + throw new ArgumentNullException(nameof(varEvent.ProxyDetails), "Property is required for class Event."); + + if (varEvent.VpnMethodsOption.IsSet && varEvent.VpnMethods == null) + throw new ArgumentNullException(nameof(varEvent.VpnMethods), "Property is required for class Event."); + if (varEvent.EnvironmentIdOption.IsSet && varEvent.EnvironmentId == null) throw new ArgumentNullException(nameof(varEvent.EnvironmentId), "Property is required for class Event."); @@ -1747,12 +1765,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.SupplementaryIdHighRecallOption.IsSet && varEvent.SupplementaryIdHighRecall == null) throw new ArgumentNullException(nameof(varEvent.SupplementaryIdHighRecall), "Property is required for class Event."); - if (varEvent.TagsOption.IsSet && varEvent.Tags == null) - throw new ArgumentNullException(nameof(varEvent.Tags), "Property is required for class Event."); - - if (varEvent.UrlOption.IsSet && varEvent.Url == null) - throw new ArgumentNullException(nameof(varEvent.Url), "Property is required for class Event."); - if (varEvent.BundleIdOption.IsSet && varEvent.BundleId == null) throw new ArgumentNullException(nameof(varEvent.BundleId), "Property is required for class Event."); @@ -1786,18 +1798,9 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.BotTypeOption.IsSet && varEvent.BotType == null) throw new ArgumentNullException(nameof(varEvent.BotType), "Property is required for class Event."); - if (varEvent.BotInfoOption.IsSet && varEvent.BotInfo == null) - throw new ArgumentNullException(nameof(varEvent.BotInfo), "Property is required for class Event."); - if (varEvent.IpBlocklistOption.IsSet && varEvent.IpBlocklist == null) throw new ArgumentNullException(nameof(varEvent.IpBlocklist), "Property is required for class Event."); - if (varEvent.IpInfoOption.IsSet && varEvent.IpInfo == null) - throw new ArgumentNullException(nameof(varEvent.IpInfo), "Property is required for class Event."); - - if (varEvent.ProxyDetailsOption.IsSet && varEvent.ProxyDetails == null) - throw new ArgumentNullException(nameof(varEvent.ProxyDetails), "Property is required for class Event."); - if (varEvent.RuleActionOption.IsSet && varEvent.RuleAction == null) throw new ArgumentNullException(nameof(varEvent.RuleAction), "Property is required for class Event."); @@ -1813,9 +1816,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.VpnOriginCountryOption.IsSet && varEvent.VpnOriginCountry == null) throw new ArgumentNullException(nameof(varEvent.VpnOriginCountry), "Property is required for class Event."); - if (varEvent.VpnMethodsOption.IsSet && varEvent.VpnMethods == null) - throw new ArgumentNullException(nameof(varEvent.VpnMethods), "Property is required for class Event."); - if (varEvent.RawDeviceAttributesOption.IsSet && varEvent.RawDeviceAttributes == null) throw new ArgumentNullException(nameof(varEvent.RawDeviceAttributes), "Property is required for class Event."); @@ -1826,6 +1826,53 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize writer.WriteNumber("timestamp", varEvent.Timestamp); + if (varEvent.LinkedIdOption.IsSet) + writer.WriteString("linked_id", varEvent.LinkedId); + + if (varEvent.TagsOption.IsSet) + { + writer.WritePropertyName("tags"); + JsonSerializer.Serialize(writer, varEvent.Tags, jsonSerializerOptions); + } + if (varEvent.UrlOption.IsSet) + writer.WriteString("url", varEvent.Url); + + if (varEvent.BotInfoOption.IsSet) + { + writer.WritePropertyName("bot_info"); + JsonSerializer.Serialize(writer, varEvent.BotInfo, jsonSerializerOptions); + } + if (varEvent.IpInfoOption.IsSet) + { + writer.WritePropertyName("ip_info"); + JsonSerializer.Serialize(writer, varEvent.IpInfo, jsonSerializerOptions); + } + if (varEvent.ProxyOption.IsSet) + writer.WriteBoolean("proxy", varEvent.ProxyOption.Value.Value); + + if (varEvent.ProxyConfidenceOption.IsSet) + { + var proxyConfidenceRawValue = ProxyConfidenceValueConverter.ToJsonValue(varEvent.ProxyConfidence.Value); + writer.WriteString("proxy_confidence", proxyConfidenceRawValue); + } + if (varEvent.ProxyDetailsOption.IsSet) + { + writer.WritePropertyName("proxy_details"); + JsonSerializer.Serialize(writer, varEvent.ProxyDetails, jsonSerializerOptions); + } + if (varEvent.VpnOption.IsSet) + writer.WriteBoolean("vpn", varEvent.VpnOption.Value.Value); + + if (varEvent.VpnConfidenceOption.IsSet) + { + var vpnConfidenceRawValue = VpnConfidenceValueConverter.ToJsonValue(varEvent.VpnConfidence.Value); + writer.WriteString("vpn_confidence", vpnConfidenceRawValue); + } + if (varEvent.VpnMethodsOption.IsSet) + { + writer.WritePropertyName("vpn_methods"); + JsonSerializer.Serialize(writer, varEvent.VpnMethods, jsonSerializerOptions); + } if (varEvent.SourceOption.IsSet) { var sourceRawValue = EventSourceValueConverter.ToJsonValue(varEvent.Source.Value); @@ -1836,9 +1883,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize var incrementalIdentificationStatusRawValue = IncrementalIdentificationStatusValueConverter.ToJsonValue(varEvent.IncrementalIdentificationStatus.Value); writer.WriteString("incremental_identification_status", incrementalIdentificationStatusRawValue); } - if (varEvent.LinkedIdOption.IsSet) - writer.WriteString("linked_id", varEvent.LinkedId); - if (varEvent.EnvironmentIdOption.IsSet) writer.WriteString("environment_id", varEvent.EnvironmentId); @@ -1863,14 +1907,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize writer.WritePropertyName("supplementary_id_high_recall"); JsonSerializer.Serialize(writer, varEvent.SupplementaryIdHighRecall, jsonSerializerOptions); } - if (varEvent.TagsOption.IsSet) - { - writer.WritePropertyName("tags"); - JsonSerializer.Serialize(writer, varEvent.Tags, jsonSerializerOptions); - } - if (varEvent.UrlOption.IsSet) - writer.WriteString("url", varEvent.Url); - if (varEvent.BundleIdOption.IsSet) writer.WriteString("bundle_id", varEvent.BundleId); @@ -1916,11 +1952,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.BotTypeOption.IsSet) writer.WriteString("bot_type", varEvent.BotType); - if (varEvent.BotInfoOption.IsSet) - { - writer.WritePropertyName("bot_info"); - JsonSerializer.Serialize(writer, varEvent.BotInfo, jsonSerializerOptions); - } if (varEvent.ClonedAppOption.IsSet) writer.WriteBoolean("cloned_app", varEvent.ClonedAppOption.Value.Value); @@ -1941,24 +1972,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize writer.WritePropertyName("ip_blocklist"); JsonSerializer.Serialize(writer, varEvent.IpBlocklist, jsonSerializerOptions); } - if (varEvent.IpInfoOption.IsSet) - { - writer.WritePropertyName("ip_info"); - JsonSerializer.Serialize(writer, varEvent.IpInfo, jsonSerializerOptions); - } - if (varEvent.ProxyOption.IsSet) - writer.WriteBoolean("proxy", varEvent.ProxyOption.Value.Value); - - if (varEvent.ProxyConfidenceOption.IsSet) - { - var proxyConfidenceRawValue = ProxyConfidenceValueConverter.ToJsonValue(varEvent.ProxyConfidence.Value); - writer.WriteString("proxy_confidence", proxyConfidenceRawValue); - } - if (varEvent.ProxyDetailsOption.IsSet) - { - writer.WritePropertyName("proxy_details"); - JsonSerializer.Serialize(writer, varEvent.ProxyDetails, jsonSerializerOptions); - } if (varEvent.ProxyMlScoreOption.IsSet) writer.WriteNumber("proxy_ml_score", varEvent.ProxyMlScoreOption.Value.Value); @@ -2018,14 +2031,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.VirtualMachineMlScoreOption.IsSet) writer.WriteNumber("virtual_machine_ml_score", varEvent.VirtualMachineMlScoreOption.Value.Value); - if (varEvent.VpnOption.IsSet) - writer.WriteBoolean("vpn", varEvent.VpnOption.Value.Value); - - if (varEvent.VpnConfidenceOption.IsSet) - { - var vpnConfidenceRawValue = VpnConfidenceValueConverter.ToJsonValue(varEvent.VpnConfidence.Value); - writer.WriteString("vpn_confidence", vpnConfidenceRawValue); - } if (varEvent.VpnMlScoreOption.IsSet) writer.WriteNumber("vpn_ml_score", varEvent.VpnMlScoreOption.Value.Value); @@ -2035,11 +2040,6 @@ public void WriteProperties(Utf8JsonWriter writer, Event varEvent, JsonSerialize if (varEvent.VpnOriginCountryOption.IsSet) writer.WriteString("vpn_origin_country", varEvent.VpnOriginCountry); - if (varEvent.VpnMethodsOption.IsSet) - { - writer.WritePropertyName("vpn_methods"); - JsonSerializer.Serialize(writer, varEvent.VpnMethods, jsonSerializerOptions); - } if (varEvent.HighActivityDeviceOption.IsSet) writer.WriteBoolean("high_activity_device", varEvent.HighActivityDeviceOption.Value.Value); diff --git a/src/Fingerprint.ServerSdk/Model/EventEdge.cs b/src/Fingerprint.ServerSdk/Model/EventEdge.cs new file mode 100644 index 00000000..b61bde45 --- /dev/null +++ b/src/Fingerprint.ServerSdk/Model/EventEdge.cs @@ -0,0 +1,535 @@ +// +/* + * 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. + * + * The version of the OpenAPI document: 4 + * Contact: support@fingerprint.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Fingerprint.ServerSdk.Client; + +namespace Fingerprint.ServerSdk.Model +{ + /// + /// IP and bot analysis for an event generated by the Automation Intelligence API (`/edge` endpoint). No client-side collection agent is involved, so Identification (`visitor_id`) and device-telemetry-derived Smart Signals are not available. + /// + public partial class EventEdge : IValidatableObject + { + + + /// + /// Initializes a new instance of the class. + /// + /// Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. (required). + /// Timestamp of the event with millisecond precision in Unix time. (required). + /// ipInfo (required). + /// source (required). + /// A customer-provided id that was sent with the request.. + /// A customer-provided value or an object that was sent with the identification request or updated later.. + /// Page URL from which the request was sent.. + /// botInfo. + /// IP address was used by a public proxy provider or belonged to a known recent residential proxy . + /// proxyConfidence. + /// proxyDetails. + /// VPN or other anonymizing service has been used when sending the request. . + /// vpnConfidence. + /// vpnMethods. + [JsonConstructor] + public EventEdge(string eventId, long timestamp, IPInfo ipInfo, EventSource source, Option linkedId = default, Option> tags = default, Option url = default, Option botInfo = default, Option proxy = default, Option proxyConfidence = default, Option proxyDetails = default, Option vpn = default, Option vpnConfidence = default, Option vpnMethods = default) + { + EventId = eventId; + Timestamp = timestamp; + IpInfo = ipInfo; + Source = source; + LinkedIdOption = linkedId; + TagsOption = tags; + UrlOption = url; + BotInfoOption = botInfo; + ProxyOption = proxy; + ProxyConfidenceOption = proxyConfidence; + ProxyDetailsOption = proxyDetails; + VpnOption = vpn; + VpnConfidenceOption = vpnConfidence; + VpnMethodsOption = vpnMethods; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Gets or Sets Source + /// + [JsonPropertyName("source")] + public EventSource Source { get; set; } + + /// + /// Used to track the state of ProxyConfidence + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option ProxyConfidenceOption { get; private set; } + + /// + /// Gets or Sets ProxyConfidence + /// + [JsonPropertyName("proxy_confidence")] + public ProxyConfidence? ProxyConfidence { get { return this.ProxyConfidenceOption; } set { this.ProxyConfidenceOption = new Option(value); } } + + /// + /// Used to track the state of VpnConfidence + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option VpnConfidenceOption { get; private set; } + + /// + /// Gets or Sets VpnConfidence + /// + [JsonPropertyName("vpn_confidence")] + public VpnConfidence? VpnConfidence { get { return this.VpnConfidenceOption; } set { this.VpnConfidenceOption = new Option(value); } } + + /// + /// Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. + /// + /// Unique identifier of the user's request. The first portion of the event_id is a unix epoch milliseconds timestamp. + [JsonPropertyName("event_id")] + public string EventId { get; set; } + + /// + /// Timestamp of the event with millisecond precision in Unix time. + /// + /// Timestamp of the event with millisecond precision in Unix time. + [JsonPropertyName("timestamp")] + public long Timestamp { get; set; } + + /// + /// Gets or Sets IpInfo + /// + [JsonPropertyName("ip_info")] + public IPInfo IpInfo { get; set; } + + /// + /// Used to track the state of LinkedId + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option LinkedIdOption { get; private set; } + + /// + /// A customer-provided id that was sent with the request. + /// + /// A customer-provided id that was sent with the request. + [JsonPropertyName("linked_id")] + public string LinkedId { get { return this.LinkedIdOption; } set { this.LinkedIdOption = new Option(value); } } + + /// + /// Used to track the state of Tags + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option> TagsOption { get; private set; } + + /// + /// A customer-provided value or an object that was sent with the identification request or updated later. + /// + /// A customer-provided value or an object that was sent with the identification request or updated later. + [JsonPropertyName("tags")] + public Dictionary Tags { get { return this.TagsOption; } set { this.TagsOption = new Option>(value); } } + + /// + /// Used to track the state of Url + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option UrlOption { get; private set; } + + /// + /// Page URL from which the request was sent. + /// + /// Page URL from which the request was sent. + [JsonPropertyName("url")] + public string Url { get { return this.UrlOption; } set { this.UrlOption = new Option(value); } } + + /// + /// Used to track the state of BotInfo + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option BotInfoOption { get; private set; } + + /// + /// Gets or Sets BotInfo + /// + [JsonPropertyName("bot_info")] + public BotInfo BotInfo { get { return this.BotInfoOption; } set { this.BotInfoOption = new Option(value); } } + + /// + /// Used to track the state of Proxy + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option ProxyOption { get; private set; } + + /// + /// IP address was used by a public proxy provider or belonged to a known recent residential proxy + /// + /// IP address was used by a public proxy provider or belonged to a known recent residential proxy + [JsonPropertyName("proxy")] + public bool? Proxy { get { return this.ProxyOption; } set { this.ProxyOption = new Option(value); } } + + /// + /// Used to track the state of ProxyDetails + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option ProxyDetailsOption { get; private set; } + + /// + /// Gets or Sets ProxyDetails + /// + [JsonPropertyName("proxy_details")] + public ProxyDetails ProxyDetails { get { return this.ProxyDetailsOption; } set { this.ProxyDetailsOption = new Option(value); } } + + /// + /// Used to track the state of Vpn + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option VpnOption { get; private set; } + + /// + /// VPN or other anonymizing service has been used when sending the request. + /// + /// VPN or other anonymizing service has been used when sending the request. + [JsonPropertyName("vpn")] + public bool? Vpn { get { return this.VpnOption; } set { this.VpnOption = new Option(value); } } + + /// + /// Used to track the state of VpnMethods + /// + [JsonIgnore] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public Option VpnMethodsOption { get; private set; } + + /// + /// Gets or Sets VpnMethods + /// + [JsonPropertyName("vpn_methods")] + public VpnMethods VpnMethods { get { return this.VpnMethodsOption; } set { this.VpnMethodsOption = new Option(value); } } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class EventEdge {\n"); + sb.Append(" EventId: ").Append(EventId).Append("\n"); + sb.Append(" Timestamp: ").Append(Timestamp).Append("\n"); + sb.Append(" IpInfo: ").Append(IpInfo).Append("\n"); + sb.Append(" Source: ").Append(Source).Append("\n"); + sb.Append(" LinkedId: ").Append(LinkedId).Append("\n"); + sb.Append(" Tags: ").Append(Tags).Append("\n"); + sb.Append(" Url: ").Append(Url).Append("\n"); + sb.Append(" BotInfo: ").Append(BotInfo).Append("\n"); + sb.Append(" Proxy: ").Append(Proxy).Append("\n"); + sb.Append(" ProxyConfidence: ").Append(ProxyConfidence).Append("\n"); + sb.Append(" ProxyDetails: ").Append(ProxyDetails).Append("\n"); + sb.Append(" Vpn: ").Append(Vpn).Append("\n"); + sb.Append(" VpnConfidence: ").Append(VpnConfidence).Append("\n"); + sb.Append(" VpnMethods: ").Append(VpnMethods).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public class EventEdgeJsonConverter : JsonConverter + { + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override EventEdge Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option eventId = default; + Option timestamp = default; + Option ipInfo = default; + Option source = default; + Option linkedId = default; + Option> tags = default; + Option url = default; + Option botInfo = default; + Option proxy = default; + Option proxyConfidence = default; + Option proxyDetails = default; + Option vpn = default; + Option vpnConfidence = default; + Option vpnMethods = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "event_id": + eventId = new Option(utf8JsonReader.GetString()); + break; + case "timestamp": + timestamp = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (long?)null : utf8JsonReader.GetInt64()); + break; + case "ip_info": + ipInfo = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "source": + string sourceRawValue = utf8JsonReader.GetString(); + if (sourceRawValue != null) + source = new Option(EventSourceValueConverter.FromStringOrDefault(sourceRawValue)); + break; + case "linked_id": + linkedId = new Option(utf8JsonReader.GetString()); + break; + case "tags": + tags = new Option>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "url": + url = new Option(utf8JsonReader.GetString()); + break; + case "bot_info": + botInfo = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "proxy": + proxy = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); + break; + case "proxy_confidence": + string proxyConfidenceRawValue = utf8JsonReader.GetString(); + if (proxyConfidenceRawValue != null) + proxyConfidence = new Option(ProxyConfidenceValueConverter.FromStringOrDefault(proxyConfidenceRawValue)); + break; + case "proxy_details": + proxyDetails = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "vpn": + vpn = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (bool?)null : utf8JsonReader.GetBoolean()); + break; + case "vpn_confidence": + string vpnConfidenceRawValue = utf8JsonReader.GetString(); + if (vpnConfidenceRawValue != null) + vpnConfidence = new Option(VpnConfidenceValueConverter.FromStringOrDefault(vpnConfidenceRawValue)); + break; + case "vpn_methods": + vpnMethods = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + default: + break; + } + } + } + + if (!eventId.IsSet) + throw new ArgumentException("Property is required for class EventEdge.", nameof(eventId)); + + if (!timestamp.IsSet) + throw new ArgumentException("Property is required for class EventEdge.", nameof(timestamp)); + + if (!ipInfo.IsSet) + throw new ArgumentException("Property is required for class EventEdge.", nameof(ipInfo)); + + if (!source.IsSet) + throw new ArgumentException("Property is required for class EventEdge.", nameof(source)); + + if (eventId.IsSet && eventId.Value == null) + throw new ArgumentNullException(nameof(eventId), "Property is not nullable for class EventEdge."); + + if (timestamp.IsSet && timestamp.Value == null) + throw new ArgumentNullException(nameof(timestamp), "Property is not nullable for class EventEdge."); + + if (ipInfo.IsSet && ipInfo.Value == null) + throw new ArgumentNullException(nameof(ipInfo), "Property is not nullable for class EventEdge."); + + if (source.IsSet && source.Value == null) + throw new ArgumentNullException(nameof(source), "Property is not nullable for class EventEdge."); + + if (linkedId.IsSet && linkedId.Value == null) + throw new ArgumentNullException(nameof(linkedId), "Property is not nullable for class EventEdge."); + + if (tags.IsSet && tags.Value == null) + throw new ArgumentNullException(nameof(tags), "Property is not nullable for class EventEdge."); + + if (url.IsSet && url.Value == null) + throw new ArgumentNullException(nameof(url), "Property is not nullable for class EventEdge."); + + if (botInfo.IsSet && botInfo.Value == null) + throw new ArgumentNullException(nameof(botInfo), "Property is not nullable for class EventEdge."); + + if (proxy.IsSet && proxy.Value == null) + throw new ArgumentNullException(nameof(proxy), "Property is not nullable for class EventEdge."); + + if (proxyConfidence.IsSet && proxyConfidence.Value == null) + throw new ArgumentNullException(nameof(proxyConfidence), "Property is not nullable for class EventEdge."); + + if (proxyDetails.IsSet && proxyDetails.Value == null) + throw new ArgumentNullException(nameof(proxyDetails), "Property is not nullable for class EventEdge."); + + if (vpn.IsSet && vpn.Value == null) + throw new ArgumentNullException(nameof(vpn), "Property is not nullable for class EventEdge."); + + if (vpnConfidence.IsSet && vpnConfidence.Value == null) + throw new ArgumentNullException(nameof(vpnConfidence), "Property is not nullable for class EventEdge."); + + if (vpnMethods.IsSet && vpnMethods.Value == null) + throw new ArgumentNullException(nameof(vpnMethods), "Property is not nullable for class EventEdge."); + + return new EventEdge(eventId.Value, timestamp.Value.Value, ipInfo.Value, source.Value.Value, linkedId, tags, url, botInfo, proxy, proxyConfidence, proxyDetails, vpn, vpnConfidence, vpnMethods); + } + + /// + /// Serializes a + /// + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, EventEdge eventEdge, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, eventEdge, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, EventEdge eventEdge, JsonSerializerOptions jsonSerializerOptions) + { + if (eventEdge.EventId == null) + throw new ArgumentNullException(nameof(eventEdge.EventId), "Property is required for class EventEdge."); + + if (eventEdge.IpInfo == null) + throw new ArgumentNullException(nameof(eventEdge.IpInfo), "Property is required for class EventEdge."); + + if (eventEdge.LinkedIdOption.IsSet && eventEdge.LinkedId == null) + throw new ArgumentNullException(nameof(eventEdge.LinkedId), "Property is required for class EventEdge."); + + if (eventEdge.TagsOption.IsSet && eventEdge.Tags == null) + throw new ArgumentNullException(nameof(eventEdge.Tags), "Property is required for class EventEdge."); + + if (eventEdge.UrlOption.IsSet && eventEdge.Url == null) + throw new ArgumentNullException(nameof(eventEdge.Url), "Property is required for class EventEdge."); + + if (eventEdge.BotInfoOption.IsSet && eventEdge.BotInfo == null) + throw new ArgumentNullException(nameof(eventEdge.BotInfo), "Property is required for class EventEdge."); + + if (eventEdge.ProxyDetailsOption.IsSet && eventEdge.ProxyDetails == null) + throw new ArgumentNullException(nameof(eventEdge.ProxyDetails), "Property is required for class EventEdge."); + + if (eventEdge.VpnMethodsOption.IsSet && eventEdge.VpnMethods == null) + throw new ArgumentNullException(nameof(eventEdge.VpnMethods), "Property is required for class EventEdge."); + + writer.WriteString("event_id", eventEdge.EventId); + + writer.WriteNumber("timestamp", eventEdge.Timestamp); + + writer.WritePropertyName("ip_info"); + JsonSerializer.Serialize(writer, eventEdge.IpInfo, jsonSerializerOptions); + var sourceRawValue = EventSourceValueConverter.ToJsonValue(eventEdge.Source); + writer.WriteString("source", sourceRawValue); + + if (eventEdge.LinkedIdOption.IsSet) + writer.WriteString("linked_id", eventEdge.LinkedId); + + if (eventEdge.TagsOption.IsSet) + { + writer.WritePropertyName("tags"); + JsonSerializer.Serialize(writer, eventEdge.Tags, jsonSerializerOptions); + } + if (eventEdge.UrlOption.IsSet) + writer.WriteString("url", eventEdge.Url); + + if (eventEdge.BotInfoOption.IsSet) + { + writer.WritePropertyName("bot_info"); + JsonSerializer.Serialize(writer, eventEdge.BotInfo, jsonSerializerOptions); + } + if (eventEdge.ProxyOption.IsSet) + writer.WriteBoolean("proxy", eventEdge.ProxyOption.Value.Value); + + if (eventEdge.ProxyConfidenceOption.IsSet) + { + var proxyConfidenceRawValue = ProxyConfidenceValueConverter.ToJsonValue(eventEdge.ProxyConfidence.Value); + writer.WriteString("proxy_confidence", proxyConfidenceRawValue); + } + if (eventEdge.ProxyDetailsOption.IsSet) + { + writer.WritePropertyName("proxy_details"); + JsonSerializer.Serialize(writer, eventEdge.ProxyDetails, jsonSerializerOptions); + } + if (eventEdge.VpnOption.IsSet) + writer.WriteBoolean("vpn", eventEdge.VpnOption.Value.Value); + + if (eventEdge.VpnConfidenceOption.IsSet) + { + var vpnConfidenceRawValue = VpnConfidenceValueConverter.ToJsonValue(eventEdge.VpnConfidence.Value); + writer.WriteString("vpn_confidence", vpnConfidenceRawValue); + } + if (eventEdge.VpnMethodsOption.IsSet) + { + writer.WritePropertyName("vpn_methods"); + JsonSerializer.Serialize(writer, eventEdge.VpnMethods, jsonSerializerOptions); + } + } + } +} diff --git a/src/Fingerprint.ServerSdk/Sealed.cs b/src/Fingerprint.ServerSdk/Sealed.cs index 8d009c98..6f13d44c 100644 --- a/src/Fingerprint.ServerSdk/Sealed.cs +++ b/src/Fingerprint.ServerSdk/Sealed.cs @@ -180,12 +180,15 @@ private static JsonSerializerOptions GetJsonSerializerOptions() jsonOptions.Converters.Add(new BotResultNullableJsonConverter()); jsonOptions.Converters.Add(new BrowserDetailsJsonConverter()); jsonOptions.Converters.Add(new CanvasJsonConverter()); + jsonOptions.Converters.Add(new EdgeRequestJsonConverter()); + jsonOptions.Converters.Add(new EdgeRequestHeadersInnerJsonConverter()); jsonOptions.Converters.Add(new EmojiJsonConverter()); jsonOptions.Converters.Add(new ErrorJsonConverter()); jsonOptions.Converters.Add(new ErrorCodeJsonConverter()); jsonOptions.Converters.Add(new ErrorCodeNullableJsonConverter()); jsonOptions.Converters.Add(new ErrorResponseJsonConverter()); jsonOptions.Converters.Add(new EventJsonConverter()); + jsonOptions.Converters.Add(new EventEdgeJsonConverter()); jsonOptions.Converters.Add(new EventRuleActionJsonConverter()); jsonOptions.Converters.Add(new EventRuleActionAllowJsonConverter()); jsonOptions.Converters.Add(new EventRuleActionBlockJsonConverter()); diff --git a/sync.sh b/sync.sh index 278a87fb..c7b44b25 100644 --- a/sync.sh +++ b/sync.sh @@ -2,7 +2,8 @@ set -euo pipefail defaultBaseUrl="https://fingerprintjs.github.io/fingerprint-pro-server-api-openapi" -schemaUrl="${1:-$defaultBaseUrl/schemas/fingerprint-server-api-v4.yaml}" +# Flattened Event (single object, source optional). start/end split into start + start_date_time. +schemaUrl="${1:-$defaultBaseUrl/schemas/fingerprint-server-api-v4-normalized.yaml}" examplesBaseUrl="${2:-$defaultBaseUrl/examples}" mkdir -p ./res