diff --git a/.changeset/deprecate-504-events-search.md b/.changeset/deprecate-504-events-search.md new file mode 100644 index 00000000..0ca3d88e --- /dev/null +++ b/.changeset/deprecate-504-events-search.md @@ -0,0 +1,5 @@ +--- +'@fingerprint/node-sdk': minor +--- + +**events-search**: The `504` response for the Events Search endpoint is deprecated and will no longer be generated by the Server API. diff --git a/.changeset/deprecate-504-events.md b/.changeset/deprecate-504-events.md new file mode 100644 index 00000000..17d6584f --- /dev/null +++ b/.changeset/deprecate-504-events.md @@ -0,0 +1,5 @@ +--- +'@fingerprint/node-sdk': minor +--- + +**events**: The `504` response for the Get Event endpoint is deprecated and will no longer be generated by the Server API. diff --git a/.changeset/error-response-503-events-search.md b/.changeset/error-response-503-events-search.md new file mode 100644 index 00000000..c2903390 --- /dev/null +++ b/.changeset/error-response-503-events-search.md @@ -0,0 +1,5 @@ +--- +'@fingerprint/node-sdk': minor +--- + +**events-search**: Add `503` Service Temporarily Unavailable response to the Events Search endpoint diff --git a/.changeset/error-response-503-events.md b/.changeset/error-response-503-events.md new file mode 100644 index 00000000..95b38007 --- /dev/null +++ b/.changeset/error-response-503-events.md @@ -0,0 +1,5 @@ +--- +'@fingerprint/node-sdk': minor +--- + +**events**: Add `503` Service Temporarily Unavailable response to the Get Event endpoint diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000..cb2ac6c1 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,10 @@ +{ + "mode": "pre", + "tag": "test", + "initialVersions": { + "@fingerprint/node-sdk": "7.8.0", + "node-sdk-example": "1.0.0", + "node-sdk-functional-tests": "2.0.0" + }, + "changesets": [] +} diff --git a/.schema-version b/.schema-version index ea535dc5..65aee83a 100644 --- a/.schema-version +++ b/.schema-version @@ -1 +1 @@ -v3.8.0 \ No newline at end of file +v3.9.0 \ No newline at end of file diff --git a/resources/fingerprint-server-api.yaml b/resources/fingerprint-server-api.yaml index 2784ca09..6b178b67 100644 --- a/resources/fingerprint-server-api.yaml +++ b/resources/fingerprint-server-api.yaml @@ -17,8 +17,7 @@ info: email: support@fingerprint.com license: name: MIT - url: >- - https://github.com/fingerprintjs/fingerprint-pro-server-api-openapi/blob/main/LICENSE + url: https://github.com/fingerprintjs/openapi/blob/main/LICENSE tags: - name: Fingerprint description: >- @@ -104,12 +103,8 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' '429': - description: > + description: | Too Many Requests. The request is throttled. - - To protect service stability during rare periods of extreme load, we - may return HTTP 429 responses with message `too many search - requests` even if you are within your assigned rate limits. content: application/json: schema: @@ -120,10 +115,15 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service Temporarily Unavailable. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '504': - description: >- - Gateway Timeout. Search execution exceeded the allowed timeout - window. + description: Gateway Timeout. + x-deprecated-response: true content: application/json: schema: @@ -1005,12 +1005,8 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' '429': - description: > + description: | Too Many Requests. The request is throttled. - - To protect service stability during rare periods of extreme load, we - may return HTTP 429 responses with message `too many search - requests` even if you are within your assigned rate limits. content: application/json: schema: @@ -1021,10 +1017,15 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service Temporarily Unavailable. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' '504': - description: >- - Gateway Timeout. Search execution exceeded the allowed timeout - window. + description: Gateway Timeout. + x-deprecated-response: true content: application/json: schema: @@ -2088,8 +2089,11 @@ components: type: string examples: - SM-G991U - - iPhone14,5 - description: Raw device model identifier, as reported by the mobile OS. + - D84AP + description: >- + Raw device model identifier, as reported by the mobile OS. On + Android, this is the vendor-defined model string (e.g., `SM-G991U`). + On iOS, this is an Apple board code (e.g., `D84AP`). os_version: type: string examples: diff --git a/src/generatedApiTypes.ts b/src/generatedApiTypes.ts index 8cda28ae..af03669a 100644 --- a/src/generatedApiTypes.ts +++ b/src/generatedApiTypes.ts @@ -730,9 +730,9 @@ export interface components { */ device_manufacturer?: string /** - * @description Raw device model identifier, as reported by the mobile OS. + * @description Raw device model identifier, as reported by the mobile OS. On Android, this is the vendor-defined model string (e.g., `SM-G991U`). On iOS, this is an Apple board code (e.g., `D84AP`). * @example SM-G991U - * @example iPhone14,5 + * @example D84AP */ device_model?: string /** @@ -1770,10 +1770,7 @@ export interface operations { 'application/json': components['schemas']['ErrorResponse'] } } - /** - * @description Too Many Requests. The request is throttled. - * To protect service stability during rare periods of extreme load, we may return HTTP 429 responses with message `too many search requests` even if you are within your assigned rate limits. - */ + /** @description Too Many Requests. The request is throttled. */ 429: { headers: { [name: string]: unknown @@ -1791,7 +1788,16 @@ export interface operations { 'application/json': components['schemas']['ErrorResponse'] } } - /** @description Gateway Timeout. Search execution exceeded the allowed timeout window. */ + /** @description Service Temporarily Unavailable. */ + 503: { + headers: { + [name: string]: unknown + } + content: { + 'application/json': components['schemas']['ErrorResponse'] + } + } + /** @description Gateway Timeout. */ 504: { headers: { [name: string]: unknown @@ -2216,10 +2222,7 @@ export interface operations { 'application/json': components['schemas']['ErrorResponse'] } } - /** - * @description Too Many Requests. The request is throttled. - * To protect service stability during rare periods of extreme load, we may return HTTP 429 responses with message `too many search requests` even if you are within your assigned rate limits. - */ + /** @description Too Many Requests. The request is throttled. */ 429: { headers: { [name: string]: unknown @@ -2237,7 +2240,16 @@ export interface operations { 'application/json': components['schemas']['ErrorResponse'] } } - /** @description Gateway Timeout. Search execution exceeded the allowed timeout window. */ + /** @description Service Temporarily Unavailable. */ + 503: { + headers: { + [name: string]: unknown + } + content: { + 'application/json': components['schemas']['ErrorResponse'] + } + } + /** @description Gateway Timeout. */ 504: { headers: { [name: string]: unknown diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_bot_type_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_bot_type_invalid.json deleted file mode 100644 index caa21bf4..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_bot_type_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid bot type" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_edge_ip_required.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_edge_ip_required.json deleted file mode 100644 index 8f055f8f..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_edge_ip_required.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "at least one of ipv4_address or ipv6_address is required" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_edge_unknown_field.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_edge_unknown_field.json deleted file mode 100644 index c0a153ef..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_edge_unknown_field.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "request body contains an unknown field \"unknown\"" - } -} \ No newline at end of file diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_end_time_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_end_time_invalid.json deleted file mode 100644 index 7b4eb466..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_end_time_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid end time" - } -} \ No newline at end of file diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_event_id_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_event_id_invalid.json deleted file mode 100644 index 5c43577e..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_event_id_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid event_id" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_ip_address_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_ip_address_invalid.json deleted file mode 100644 index 8f6ab37d..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_ip_address_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid ip address" - } -} \ No newline at end of file diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_limit_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_limit_invalid.json deleted file mode 100644 index 9cd005e8..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_limit_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid limit" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_linked_id_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_linked_id_invalid.json deleted file mode 100644 index d573919d..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_linked_id_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "linked_id can't be greater than 256 characters long" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_pagination_key_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_pagination_key_invalid.json deleted file mode 100644 index e7597f91..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_pagination_key_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid pagination key" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_request_read_timeout.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_request_read_timeout.json deleted file mode 100644 index 89daaca8..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_request_read_timeout.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_read_timeout", - "message": "request read timeout" - } -} \ No newline at end of file diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_reverse_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_reverse_invalid.json deleted file mode 100644 index da696b5b..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_reverse_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid reverse param" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_ruleset_not_found.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_ruleset_not_found.json deleted file mode 100644 index 1e4ac5dd..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_ruleset_not_found.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "ruleset_not_found", - "message": "ruleset not found" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_start_time_invalid.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_start_time_invalid.json deleted file mode 100644 index d564703d..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_start_time_invalid.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "invalid start time" - } -} \ No newline at end of file diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/400_visitor_id_required.json b/tests/mocked-responses-tests/mocked-responses-data/errors/400_visitor_id_required.json deleted file mode 100644 index e144a892..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/400_visitor_id_required.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "request_cannot_be_parsed", - "message": "visitor id is required" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/403_secret_api_key_not_found.json b/tests/mocked-responses-tests/mocked-responses-data/errors/403_secret_api_key_not_found.json deleted file mode 100644 index 7cf7953b..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/403_secret_api_key_not_found.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "secret_api_key_not_found", - "message": "no fingerprint workspace found for specified secret API key" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/403_secret_api_key_required.json b/tests/mocked-responses-tests/mocked-responses-data/errors/403_secret_api_key_required.json deleted file mode 100644 index 9ed2f958..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/403_secret_api_key_required.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "secret_api_key_required", - "message": "secret API key in header is missing or empty" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/403_subscription_not_active.json b/tests/mocked-responses-tests/mocked-responses-data/errors/403_subscription_not_active.json deleted file mode 100644 index 761bbfed..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/403_subscription_not_active.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "subscription_not_active", - "message": "forbidden" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/403_wrong_region.json b/tests/mocked-responses-tests/mocked-responses-data/errors/403_wrong_region.json deleted file mode 100644 index 3c5fe748..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/403_wrong_region.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "wrong_region", - "message": "wrong region" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/413_payload_too_large.json b/tests/mocked-responses-tests/mocked-responses-data/errors/413_payload_too_large.json deleted file mode 100644 index 00a1c6f9..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/413_payload_too_large.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "payload_too_large", - "message": "payload too large" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/429_too_many_search_requests.json b/tests/mocked-responses-tests/mocked-responses-data/errors/429_too_many_search_requests.json deleted file mode 100644 index bc42b32a..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/429_too_many_search_requests.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "too_many_requests", - "message": "too many search requests" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/500_internal_server_error.json b/tests/mocked-responses-tests/mocked-responses-data/errors/500_internal_server_error.json deleted file mode 100644 index 5a8bc8af..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/500_internal_server_error.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "failed", - "message": "internal server error" - } -} \ No newline at end of file diff --git a/tests/mocked-responses-tests/mocked-responses-data/errors/504_search_timeout_exceeded.json b/tests/mocked-responses-tests/mocked-responses-data/errors/504_search_timeout_exceeded.json deleted file mode 100644 index cc5fcbd7..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/errors/504_search_timeout_exceeded.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "error": { - "code": "failed", - "message": "gateway timeout" - } -} diff --git a/tests/mocked-responses-tests/mocked-responses-data/events/get_event_200_with_unknown_field.json b/tests/mocked-responses-tests/mocked-responses-data/events/get_event_200_with_unknown_field.json deleted file mode 100644 index 39bc6324..00000000 --- a/tests/mocked-responses-tests/mocked-responses-data/events/get_event_200_with_unknown_field.json +++ /dev/null @@ -1,325 +0,0 @@ -{ - "linked_id": "somelinkedId", - "tags": {}, - "timestamp": 1708102555327, - "event_id": "1708102555327.NLOjmg", - "source": "device", - "incremental_identification_status": "completed", - "url": "https://www.example.com/login?hope{this{works[!", - "ip_address": "61.127.217.15", - "user_agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) ....", - "device": "Other", - "os": "Windows", - "os_version": "7", - "client_referrer": "https://example.com/blog/my-article", - "browser_details": { - "browser_name": "Chrome", - "browser_major_version": "74", - "browser_full_version": "74.0.3729", - "os": "Windows", - "os_version": "7", - "device": "Other", - "unknown_sub_field": "unknown_sub_field_value" - }, - "identification": { - "visitor_id": "Ibk1527CUFmcnjLwIs4A9", - "confidence": { - "score": 0.97, - "version": "1.1" - }, - "visitor_found": false, - "first_seen_at": 1708102555327, - "last_seen_at": 1708102555327 - }, - "supplementary_id_high_recall": { - "visitor_id": "0jnGMkPYXX37DqVa4ZIO3f_hr", - "visitor_found": true, - "confidence": { - "score": 0, - "version": "Not Supported" - }, - "first_seen_at": 1778086556130, - "last_seen_at": 1778604975494 - }, - "proximity": { - "id": "w1aTfd4MCvl", - "precision_radius": 10, - "confidence": 0.95 - }, - "bot": "not_detected", - "root_apps": false, - "emulator": false, - "ip_info": { - "v4": { - "address": "94.142.239.124", - "geolocation": { - "accuracy_radius": 20, - "latitude": 50.05, - "longitude": 14.4, - "postal_code": "150 00", - "timezone": "Europe/Prague", - "city_name": "Prague", - "country_code": "CZ", - "country_name": "Czechia", - "continent_code": "EU", - "continent_name": "Europe", - "subdivisions": [ - { - "iso_code": "10", - "name": "Hlavni mesto Praha" - } - ] - }, - "asn": "7922", - "asn_name": "COMCAST-7922", - "asn_network": "73.136.0.0/13", - "asn_type": "isp", - "datacenter_result": true, - "datacenter_name": "DediPath" - }, - "v6": { - "address": "2001:db8:3333:4444:5555:6666:7777:8888", - "geolocation": { - "accuracy_radius": 5, - "latitude": 49.982, - "longitude": 36.2566, - "postal_code": "10112", - "timezone": "Europe/Berlin", - "city_name": "Berlin", - "country_code": "DE", - "country_name": "Germany", - "continent_code": "EU", - "continent_name": "Europe", - "subdivisions": [ - { - "iso_code": "BE", - "name": "Land Berlin" - } - ] - }, - "asn": "6805", - "asn_name": "Telefonica Germany", - "asn_network": "2a02:3100::/24", - "asn_type": "isp", - "datacenter_result": false, - "datacenter_name": "" - } - }, - "ip_blocklist": { - "email_spam": false, - "attack_source": false, - "tor_node": false - }, - "proxy": true, - "proxy_confidence": "low", - "proxy_details": { - "proxy_type": "residential", - "last_seen_at": 1708102555327, - "provider": "Massive" - }, - "proxy_ml_score": 0.2, - "vpn": false, - "vpn_confidence": "high", - "vpn_ml_score": 0.2, - "vpn_origin_timezone": "Europe/Berlin", - "vpn_origin_country": "unknown", - "vpn_methods": { - "timezone_mismatch": false, - "public_vpn": false, - "auxiliary_mobile": false, - "os_mismatch": false, - "relay": false, - "ml_prediction": false - }, - "incognito": false, - "tampering": false, - "tampering_confidence": "high", - "tampering_ml_score": 0.3231, - "tampering_details": { - "anomaly_score": 0.1955, - "anti_detect_browser": false - }, - "cloned_app": false, - "factory_reset_timestamp": 0, - "jailbroken": false, - "simulator": false, - "frida": false, - "privacy_settings": false, - "virtual_machine": false, - "virtual_machine_ml_score": 0.2, - "location_spoofing": false, - "velocity": { - "distinct_ip": { - "5_minutes": 1, - "1_hour": 1, - "24_hours": 1 - }, - "distinct_linked_id": { - "5_minutes": 1, - "1_hour": 5, - "24_hours": 5 - }, - "distinct_country": { - "5_minutes": 1, - "1_hour": 2, - "24_hours": 2 - }, - "events": { - "5_minutes": 1, - "1_hour": 5, - "24_hours": 5 - }, - "ip_events": { - "5_minutes": 1, - "1_hour": 5, - "24_hours": 5 - }, - "distinct_ip_by_linked_id": { - "5_minutes": 1, - "1_hour": 5, - "24_hours": 5 - }, - "distinct_visitor_id_by_linked_id": { - "5_minutes": 1, - "1_hour": 5, - "24_hours": 5 - } - }, - "developer_tools": false, - "device_details": { - "device_manufacturer": "samsung", - "device_model": "SM-G991U", - "os_version": "13" - }, - "mitm_attack": false, - "sdk": { - "platform": "js", - "version": "3.11.10", - "integrations": [ - { - "name": "fingerprint-pro-react", - "version": "3.11.10", - "subintegration": { - "name": "preact", - "version": "10.21.0" - } - } - ] - }, - "replayed": false, - "high_activity_device": false, - "raw_device_attributes": { - "math": "5f030fa7d2e5f9f757bfaf81642eb1a6", - "vendor": "Google Inc.", - "plugins": [ - { - "description": "Portable Document Format", - "mimeTypes": [ - { - "suffixes": "pdf", - "type": "application/pdf" - }, - { - "suffixes": "pdf", - "type": "text/pdf" - } - ], - "name": "PDF Viewer" - } - ], - "webgl_extensions": { - "context_attributes": "6b1ed336830d2bc96442a9d76373252a", - "extension_parameters": "86a8abb36f0cb30b5946dec0c761d042", - "extensions": "57233d7b10f89fcd1ff95e3837ccd72d", - "parameters": "ea118c48e308bc4b0677118bbb3019ec", - "shader_precisions": "f223dfbcd580cf142da156d93790eb83", - "unsupported_extensions": [] - }, - "cookies_enabled": true, - "webgl_basics": { - "renderer": "WebKit WebGL", - "renderer_unmasked": "ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)", - "shading_language_version": "WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)", - "vendor": "WebKit", - "vendor_unmasked": "Google Inc. (Apple)", - "version": "WebGL 1.0 (OpenGL ES 2.0 Chromium)" - }, - "canvas": { - "geometry": "db3c1462576a399a03ae93d0ab9eb5c4", - "text": "70c3d3f7eb4408dc37a6bf8af1c51029", - "winding": true - }, - "hardware_concurrency": 10, - "languages": [ - [ - "en-US" - ] - ], - "color_depth": 24, - "fonts": [ - "Arial Unicode MS", - "Gill Sans", - "Helvetica Neue", - "Menlo" - ], - "indexed_db": true, - "touch_support": { - "max_touch_points": 0, - "touch_event": false, - "touch_start": false - }, - "device_memory": 8, - "oscpu": "Windows NT 6.1; Win64; x64", - "architecture": 127, - "screen_resolution": [ - 1920, - 1080 - ], - "timezone": "America/Sao_Paulo", - "emoji": { - "bottom": 32, - "font": "Times", - "height": 18, - "left": 8, - "right": 1608, - "top": 14, - "width": 1600, - "x": 8, - "y": 14 - }, - "font_preferences": { - "apple": 147.5625, - "default": 147.5625, - "min": 9.234375, - "mono": 133.0625, - "sans": 144.015625, - "serif": 147.5625, - "system": 146.09375 - }, - "platform": "MacIntel", - "local_storage": true, - "session_storage": true, - "date_time_locale": "en-US", - "audio": 124.04347745512496, - "keyboard_layout_hash": "691e3845c85c202a1514b6fd7ef17065", - "keyboard_layout_name": "en-US", - "battery_charging": true, - "battery_level": 80, - "battery_low_power_mode": true, - "timezone_offset": "-03:00", - "font_hash": "bb4d842593877975d45017c603ff5994", - "device_manufacturer": "samsung", - "device_model": "SM-S921U" - }, - "rare_device": false, - "rare_device_percentile_bucket": "