diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0229abac..b8ad7827 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,7 @@ Code of demo application is in [src](src) folder. The schema is currently created separately from the API code. This is a bad practice, but we will fix it in future API versions. To validate that schema matches the actual API implementation we use a [special validation script](/bin/validateSchema.ts). -- It validates the schema against JSON examples file from [examples](/examples) folder. Note that some files in the examples folder appear unused like `get_event_extra_fields.json`, but they are downloaded and used for validation by individual SDK repositories. +- It validates the schema against JSON examples file from [examples](/schemas/paths/examples) folder. Note that some files in the examples folder appear unused like `get_event_extra_fields.json`, but they are downloaded and used for validation by individual SDK repositories. - It also generates fresh identification events using the TEST_SUBSCRIPTION [env variable](./.env.example), retrieves fresh Server API responses and validates the schema against those. - You can run `pnpm run validateSchema` to validate the schema locally. - You can create a `.env` file according to `.env.example` and set the TEST_SUBSCRIPTIONS variable to include your personal Fingerprint subscription. diff --git a/bin/validateSchema.ts b/bin/validateSchema.ts index a77a6a46..5cb3d2a3 100644 --- a/bin/validateSchema.ts +++ b/bin/validateSchema.ts @@ -33,6 +33,7 @@ type GetRelatedVisitorsArgs = { visitorId: string; subscription: TestSubscription; }; + function getRelatedVisitors({ visitorId, subscription }: GetRelatedVisitorsArgs) { const regionPrefix = subscription.region === 'us' ? '' : `${subscription.region}.`; return fetch(`https://${regionPrefix}api.fpjs.io/related-visitors?visitor_id=${visitorId}`, { @@ -99,6 +100,7 @@ type UpdateEventArgs = { subscription: TestSubscription; payload: any; }; + function updateEventRequest({ requestId, subscription, payload }: UpdateEventArgs) { const regionPrefix = subscription.region === 'us' ? '' : `${subscription.region}.`; return fetch(`https://${regionPrefix}api.fpjs.io/events/${requestId}`, { @@ -118,13 +120,13 @@ async function validateEventResponseSchema(testSubscriptions: TestSubscription[] // Validate against example files [ - './examples/get_event_200.json', - './examples/get_event_200_all_errors.json', - './examples/get_event_200_botd_failed_error.json', - './examples/get_event_200_botd_too_many_requests_error.json', - './examples/get_event_200_identification_failed_error.json', - './examples/get_event_200_identification_too_many_requests_error.json', - './examples/get_event_200_identification_too_many_requests_error_all_fields.json', + './schemas/paths/examples/get_event_200.json', + './schemas/paths/examples/get_event_200_all_errors.json', + './schemas/paths/examples/get_event_200_botd_failed_error.json', + './schemas/paths/examples/get_event_200_botd_too_many_requests_error.json', + './schemas/paths/examples/get_event_200_identification_failed_error.json', + './schemas/paths/examples/get_event_200_identification_too_many_requests_error.json', + './schemas/paths/examples/get_event_200_identification_too_many_requests_error_all_fields.json', ].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), @@ -165,7 +167,10 @@ export async function validateVisitsResponseSchema(testSubscriptions: TestSubscr const visitsResponseValidator = ajv.compile(visitsResponseSchema); // Validate against example files - ['./examples/get_visits_200_limit_1.json', './examples/get_visits_200_limit_500.json'].forEach((examplePath) => + [ + './schemas/paths/examples/get_visits_200_limit_1.json', + './schemas/paths/examples/get_visits_200_limit_500.json', + ].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -205,7 +210,7 @@ async function validateWebhookSchema() { const webhookValidator = ajv.compile(webhookSchema); // Validate against example file - ['./examples/webhook.json'].forEach((examplePath) => + ['./schemas/paths/examples/webhook.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -226,12 +231,12 @@ async function validateCommonError403Schema(testSubscriptions: TestSubscription[ // Validate against example file [ - './examples/get_event_403_error.json', - './examples/shared/403_error_feature_not_enabled.json', - './examples/shared/403_error_token_not_found.json', - './examples/shared/403_error_token_required.json', - './examples/shared/403_error_wrong_region.json', - './examples/update_event_403_error.json', + './schemas/paths/examples/get_event_403_error.json', + './schemas/paths/examples/shared/403_error_feature_not_enabled.json', + './schemas/paths/examples/shared/403_error_token_not_found.json', + './schemas/paths/examples/shared/403_error_token_required.json', + './schemas/paths/examples/shared/403_error_wrong_region.json', + './schemas/paths/examples/update_event_403_error.json', ].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), @@ -321,13 +326,14 @@ async function validateEventError404Schema(testSubscriptions: TestSubscription[] const eventError404Validator = ajv.compile(eventError404Schema); // Validate against example file - ['./examples/get_event_404_error.json', './examples/update_event_404_error.json'].forEach((examplePath) => - validateJson({ - json: JSON.parse(fs.readFileSync(examplePath).toString()), - jsonName: examplePath, - validator: eventError404Validator, - schemaName: 'EventError404Schema', - }) + ['./schemas/paths/examples/get_event_404_error.json', './schemas/paths/examples/update_event_404_error.json'].forEach( + (examplePath) => + validateJson({ + json: JSON.parse(fs.readFileSync(examplePath).toString()), + jsonName: examplePath, + validator: eventError404Validator, + schemaName: 'EventError404Schema', + }) ); const nonExistentRequestId = 'non-existent-request-id'; @@ -385,7 +391,7 @@ async function validateGetVisitsError403Schema(testSubscriptions: TestSubscripti const visitsError403Validator = ajv.compile(visitsError403Schema); // Validate against example file - ['./examples/get_visits_403_error.json'].forEach((examplePath) => + ['./schemas/paths/examples/get_visits_403_error.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -427,7 +433,7 @@ async function validateGetVisitsError429Schema() { const visitsError429Validator = ajv.compile(visitsError429Schema); // Validate against example file - ['./examples/get_visits_429_too_many_requests_error.json'].forEach((examplePath) => + ['./schemas/paths/examples/get_visits_429_too_many_requests_error.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -449,7 +455,7 @@ async function validateErrorCommon429Response() { const errorCommon429ResponseValidator = ajv.compile(errorCommon429ResponseSchema); // Validate against example file - ['./examples/shared/429_error_too_many_requests.json'].forEach((examplePath) => + ['./schemas/paths/examples/shared/429_error_too_many_requests.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -470,8 +476,8 @@ async function validateErrorVisitor400Response(testSubscriptions: TestSubscripti // Validate against example file [ - './examples/shared/400_error_incorrect_visitor_id.json', - './examples/shared/400_error_empty_visitor_id.json', + './schemas/paths/examples/shared/400_error_incorrect_visitor_id.json', + './schemas/paths/examples/shared/400_error_empty_visitor_id.json', ].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), @@ -525,7 +531,7 @@ async function validateErrorVisitor404Response(testSubscriptions: TestSubscripti const visitorError404Validator = ajv.compile(visitorError404Schema); // Validate against example file - ['./examples/shared/404_error_visitor_not_found.json'].forEach((examplePath) => + ['./schemas/paths/examples/shared/404_error_visitor_not_found.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -579,8 +585,8 @@ async function validateRelatedVisitorsResponseSchema(testSubscriptions: TestSubs // Validate against example file [ - './examples/related-visitors/get_related_visitors_200_empty.json', - './examples/related-visitors/get_related_visitors_200.json', + './schemas/paths/examples/related-visitors/get_related_visitors_200_empty.json', + './schemas/paths/examples/related-visitors/get_related_visitors_200.json', ].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), @@ -612,7 +618,7 @@ async function validateUpdateEventError400Schema(testSubscriptions: TestSubscrip const updateEvent400ErrorValidator = ajv.compile(updateEvent400ErrorSchema); // Validate against example file - ['./examples/update_event_400_error.json'].forEach((examplePath) => + ['./schemas/paths/examples/update_event_400_error.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, @@ -659,7 +665,7 @@ async function validateUpdateEventError409Schema(testSubscriptions: TestSubscrip const updateEvent409ErrorValidator = ajv.compile(updateEvent409ErrorSchema); // Validate against example file - ['./examples/update_event_409_error.json'].forEach((examplePath) => + ['./schemas/paths/examples/update_event_409_error.json'].forEach((examplePath) => validateJson({ json: JSON.parse(fs.readFileSync(examplePath).toString()), jsonName: examplePath, diff --git a/schemas/components/schemas/ASN.yaml b/schemas/components/schemas/ASN.yaml new file mode 100644 index 00000000..d32639c0 --- /dev/null +++ b/schemas/components/schemas/ASN.yaml @@ -0,0 +1,16 @@ +type: object +additionalProperties: false +properties: + asn: + type: string + example: '7922' + network: + type: string + example: 73.136.0.0/13 + name: + type: string + example: COMCAST-7922 +required: + - asn + - network +title: ASN diff --git a/schemas/components/schemas/BotdDetectionResult.yaml b/schemas/components/schemas/BotdDetectionResult.yaml new file mode 100644 index 00000000..8bdaa9c1 --- /dev/null +++ b/schemas/components/schemas/BotdDetectionResult.yaml @@ -0,0 +1,21 @@ +type: object +additionalProperties: false +description: Stores bot detection result +properties: + result: + type: string + description: | + Bot detection result: + * `notDetected` - the visitor is not a bot + * `good` - good bot detected, such as Google bot, Baidu Spider, AlexaBot and so on + * `bad` - bad bot detected, such as Selenium, Puppeteer, Playwright, headless browsers, and so on + enum: + - notDetected + - good + - bad + example: bad + type: + type: string + example: selenium +required: + - result diff --git a/schemas/components/schemas/BotdResult.yaml b/schemas/components/schemas/BotdResult.yaml new file mode 100644 index 00000000..2f2a0d20 --- /dev/null +++ b/schemas/components/schemas/BotdResult.yaml @@ -0,0 +1,42 @@ +type: object +additionalProperties: false +description: Contains all the information from Bot Detection product +properties: + ip: + type: string + format: ipv4 + example: 8.8.8.8 + description: IP address of the requesting browser or bot. + time: + title: Time + description: >- + Time in UTC when the request from the JS agent was made. We recommend to + treat requests that are older than 2 minutes as malicious. Otherwise, + request replay attacks are possible + type: string + format: date-time + example: '2022-06-09T22:58:36Z' + url: + description: Page URL from which identification request was sent. + type: string + example: https://example.com/login + userAgent: + type: string + example: >- + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, + like Gecko) Chrome/111.0.0.0 Safari/537.36 + requestId: + type: string + example: 1681392853693.lRiBBD + linkedId: + type: string + example: Automatic tests bot + bot: + $ref: BotdDetectionResult.yaml +required: + - bot + - url + - ip + - time + - userAgent + - requestId diff --git a/schemas/components/schemas/BrowserDetails.yaml b/schemas/components/schemas/BrowserDetails.yaml new file mode 100644 index 00000000..dab4f83e --- /dev/null +++ b/schemas/components/schemas/BrowserDetails.yaml @@ -0,0 +1,37 @@ +type: object +additionalProperties: false +properties: + browserName: + type: string + example: Chrome + browserMajorVersion: + type: string + example: '101' + browserFullVersion: + type: string + example: 101.0.4951 + os: + type: string + example: Windows + osVersion: + type: string + example: '10' + device: + type: string + example: Other + userAgent: + type: string + example: >- + Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like + Gecko) Chrome/101.0.4951.41 Safari/537.36 + botProbability: + type: integer +required: + - browserFullVersion + - browserMajorVersion + - browserName + - device + - os + - osVersion + - userAgent +title: BrowserDetails diff --git a/schemas/components/schemas/ClonedAppResult.yaml b/schemas/components/schemas/ClonedAppResult.yaml new file mode 100644 index 00000000..a80f7474 --- /dev/null +++ b/schemas/components/schemas/ClonedAppResult.yaml @@ -0,0 +1,14 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + 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. + example: false +required: + - result diff --git a/schemas/components/schemas/Confidence.yaml b/schemas/components/schemas/Confidence.yaml new file mode 100644 index 00000000..80e46e03 --- /dev/null +++ b/schemas/components/schemas/Confidence.yaml @@ -0,0 +1,20 @@ +type: object +additionalProperties: false +properties: + score: + description: >- + The confidence score is a floating-point number between 0 and 1 that + represents the probability of accurate identification. + type: number + format: float + minimum: 0 + maximum: 1 + revision: + description: >- + The revision name of the method used to calculate the Confidence score. + This field is only present for customers who opted in to an alternative + calculation method. + type: string +required: + - score +title: Confidence diff --git a/schemas/components/schemas/DataCenter.yaml b/schemas/components/schemas/DataCenter.yaml new file mode 100644 index 00000000..cd6da904 --- /dev/null +++ b/schemas/components/schemas/DataCenter.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + name: + type: string + example: DediPath +required: + - result +title: DataCenter diff --git a/schemas/components/schemas/DeveloperToolsResult.yaml b/schemas/components/schemas/DeveloperToolsResult.yaml new file mode 100644 index 00000000..a28baaed --- /dev/null +++ b/schemas/components/schemas/DeveloperToolsResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if the browser is Chrome with DevTools open or Firefox with + Developer Tools open, `false` otherwise. + example: false +required: + - result diff --git a/schemas/components/schemas/EmulatorResult.yaml b/schemas/components/schemas/EmulatorResult.yaml new file mode 100644 index 00000000..fd0646ff --- /dev/null +++ b/schemas/components/schemas/EmulatorResult.yaml @@ -0,0 +1,12 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + 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. + example: false +required: + - result diff --git a/schemas/components/schemas/ErrorCommon403Response.yaml b/schemas/components/schemas/ErrorCommon403Response.yaml new file mode 100644 index 00000000..8be2bbff --- /dev/null +++ b/schemas/components/schemas/ErrorCommon403Response.yaml @@ -0,0 +1,30 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + title: Common403ErrorResponse + properties: + code: + type: string + description: | + Error code: + * `TokenRequired` - `Auth-API-Key` header is missing or empty + * `TokenNotFound` - No Fingerprint application found for specified secret key + * `SubscriptionNotActive` - Fingerprint application is not active + * `WrongRegion` - server and application region differ + * `FeatureNotEnabled` - this feature (for example, Delete API) is not enabled for your application + enum: + - TokenRequired + - TokenNotFound + - SubscriptionNotActive + - WrongRegion + - FeatureNotEnabled + example: TokenRequired + message: + type: string + example: secret key is required + required: + - code + - message diff --git a/schemas/components/schemas/ErrorCommon429Response.yaml b/schemas/components/schemas/ErrorCommon429Response.yaml new file mode 100644 index 00000000..15fd912f --- /dev/null +++ b/schemas/components/schemas/ErrorCommon429Response.yaml @@ -0,0 +1,20 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + properties: + code: + type: string + description: | + Error code: * `TooManyRequests` - The request is throttled. + enum: + - TooManyRequests + example: TooManyRequests + message: + type: string + example: request throttled + required: + - code + - message diff --git a/schemas/components/schemas/ErrorEvent404Response.yaml b/schemas/components/schemas/ErrorEvent404Response.yaml new file mode 100644 index 00000000..a15f2c69 --- /dev/null +++ b/schemas/components/schemas/ErrorEvent404Response.yaml @@ -0,0 +1,22 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + title: ErrorEvent404ResponseError + properties: + code: + type: string + description: | + Error code: + * `RequestNotFound` - The specified request ID was not found. It never existed, expired, or it has been deleted. + enum: + - RequestNotFound + example: RequestNotFound + message: + type: string + example: request id is not found + required: + - code + - message diff --git a/schemas/components/schemas/ErrorUpdateEvent400Response.yaml b/schemas/components/schemas/ErrorUpdateEvent400Response.yaml new file mode 100644 index 00000000..45ed3812 --- /dev/null +++ b/schemas/components/schemas/ErrorUpdateEvent400Response.yaml @@ -0,0 +1,26 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + title: ErrorUpdateEvent400ResponseError + properties: + code: + type: string + description: > + Error code: * `RequestCannotBeParsed` - the JSON content of the + request contains some errors that prevented us from parsing it (wrong + type/surpassed limits) * `Failed` - the event is more than 10 days old + and cannot be updated + enum: + - RequestCannotBeParsed + - Failed + example: RequestCannotBeParsed + message: + type: string + description: Details about the underlying issue with the input payload + example: suspect flag must be a boolean + required: + - code + - message diff --git a/schemas/components/schemas/ErrorUpdateEvent409Response.yaml b/schemas/components/schemas/ErrorUpdateEvent409Response.yaml new file mode 100644 index 00000000..01c6e875 --- /dev/null +++ b/schemas/components/schemas/ErrorUpdateEvent409Response.yaml @@ -0,0 +1,26 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + title: ErrorUpdateEvent409ResponseError + properties: + code: + type: string + description: > + Error code: * `StateNotReady` - The event specified with request id is + not ready for updates yet. Try again. + + This error happens in rare cases when update API is called immediately + after receiving the request id on the client. In case you need to send + information right away, we recommend using the JS agent API instead. + enum: + - StateNotReady + example: StateNotReady + message: + type: string + example: resource is not mutable yet, try again + required: + - code + - message diff --git a/schemas/components/schemas/ErrorVisitor400Response.yaml b/schemas/components/schemas/ErrorVisitor400Response.yaml new file mode 100644 index 00000000..6ce7173f --- /dev/null +++ b/schemas/components/schemas/ErrorVisitor400Response.yaml @@ -0,0 +1,21 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + properties: + code: + type: string + description: > + Error code: * `RequestCannotBeParsed` - The visitor ID parameter is + missing or in the wrong format. + enum: + - RequestCannotBeParsed + example: RequestCannotBeParsed + message: + type: string + example: invalid visitor id + required: + - code + - message diff --git a/schemas/components/schemas/ErrorVisitor404Response.yaml b/schemas/components/schemas/ErrorVisitor404Response.yaml new file mode 100644 index 00000000..2b3d6944 --- /dev/null +++ b/schemas/components/schemas/ErrorVisitor404Response.yaml @@ -0,0 +1,22 @@ +type: object +additionalProperties: false +properties: + error: + type: object + additionalProperties: false + title: ErrorVisitor404ResponseError + properties: + code: + type: string + description: > + Error code: * `VisitorNotFound` - The specified visitor ID was not + found. It never existed or it may have already been deleted. + enum: + - VisitorNotFound + example: VisitorNotFound + message: + type: string + example: visitor not found + required: + - code + - message diff --git a/schemas/components/schemas/ErrorVisits403.yaml b/schemas/components/schemas/ErrorVisits403.yaml new file mode 100644 index 00000000..d67f7b3c --- /dev/null +++ b/schemas/components/schemas/ErrorVisits403.yaml @@ -0,0 +1,9 @@ +type: object +additionalProperties: false +properties: + error: + type: string + description: Error text. + example: Forbidden (HTTP 403) +required: + - error diff --git a/schemas/components/schemas/EventResponse.yaml b/schemas/components/schemas/EventResponse.yaml new file mode 100644 index 00000000..41f739a9 --- /dev/null +++ b/schemas/components/schemas/EventResponse.yaml @@ -0,0 +1,12 @@ +description: >- + Contains results from all activated products - Fingerprint Pro, Bot Detection, + and others. +type: object +additionalProperties: false +properties: + products: + $ref: ProductsResponse.yaml + error: + $ref: ProductError.yaml +required: + - products diff --git a/schemas/components/schemas/EventUpdateRequest.yaml b/schemas/components/schemas/EventUpdateRequest.yaml new file mode 100644 index 00000000..9b6376ba --- /dev/null +++ b/schemas/components/schemas/EventUpdateRequest.yaml @@ -0,0 +1,13 @@ +type: object +properties: + linkedId: + type: string + description: LinkedID value to assign to the existing event + tag: + type: object + description: >- + Full `tag` value to be set to the existing event. Replaces any existing + `tag` payload completely. + suspect: + type: boolean + description: Suspect flag indicating observed suspicious or fraudulent event diff --git a/schemas/components/schemas/FactoryResetResult.yaml b/schemas/components/schemas/FactoryResetResult.yaml new file mode 100644 index 00000000..8008c5f2 --- /dev/null +++ b/schemas/components/schemas/FactoryResetResult.yaml @@ -0,0 +1,31 @@ +type: object +additionalProperties: false +properties: + time: + description: > + Indicates the time (in UTC) of the most recent factory reset that happened + on the **mobile device**. + + 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). + + See [Factory Reset + Detection](https://dev.fingerprint.com/docs/smart-signals-overview#factory-reset-detection) + to learn more about this Smart Signal. + type: string + format: date-time + example: '2022-06-09T22:58:36Z' + timestamp: + description: > + This field is just another representation of the value in the `time` + field. + + The time of the most recent factory reset that happened on the **mobile + device** is expressed as Unix epoch time. + type: integer + format: int64 + example: 1654815517198 +required: + - time + - timestamp diff --git a/schemas/components/schemas/FridaResult.yaml b/schemas/components/schemas/FridaResult.yaml new file mode 100644 index 00000000..3ab46940 --- /dev/null +++ b/schemas/components/schemas/FridaResult.yaml @@ -0,0 +1,12 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + [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. + example: false +required: + - result diff --git a/schemas/components/schemas/HighActivityResult.yaml b/schemas/components/schemas/HighActivityResult.yaml new file mode 100644 index 00000000..2ade5f70 --- /dev/null +++ b/schemas/components/schemas/HighActivityResult.yaml @@ -0,0 +1,14 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: Flag indicating whether the request came from a high activity visitor. + example: false + dailyRequests: + type: number + description: Number of requests from the same visitor in the previous day. + example: 10 + minimum: 1 +required: + - result diff --git a/schemas/components/schemas/IPLocation.yaml b/schemas/components/schemas/IPLocation.yaml new file mode 100644 index 00000000..1619fddf --- /dev/null +++ b/schemas/components/schemas/IPLocation.yaml @@ -0,0 +1,46 @@ +type: object +additionalProperties: false +properties: + accuracyRadius: + description: >- + The IP address is likely to be within this radius (in km) of the specified + location. + type: integer + minimum: 0 + example: 1000 + latitude: + type: number + format: double + minimum: -90 + maximum: 90 + example: 37.75 + longitude: + type: number + format: double + minimum: -180 + maximum: 180 + example: -97.82 + postalCode: + type: string + example: 130 00 + timezone: + type: string + format: timezone + example: America/Chicago + city: + type: object + additionalProperties: false + title: IPLocationCity + properties: + name: + type: string + example: Prague + country: + $ref: Location.yaml + continent: + $ref: Location.yaml + subdivisions: + type: array + items: + $ref: Subdivision.yaml +title: IPLocation diff --git a/schemas/components/schemas/IdentificationError.yaml b/schemas/components/schemas/IdentificationError.yaml new file mode 100644 index 00000000..ce805769 --- /dev/null +++ b/schemas/components/schemas/IdentificationError.yaml @@ -0,0 +1,19 @@ +type: object +additionalProperties: false +properties: + code: + type: string + description: | + Error code: + * `429 Too Many Requests` - the limit on secret API key requests per second has been exceeded + * `Failed` - internal server error + enum: + - 429 Too Many Requests + - Failed + example: 429 Too Many Requests + message: + type: string + example: too many requests +required: + - code + - message diff --git a/schemas/components/schemas/IncognitoResult.yaml b/schemas/components/schemas/IncognitoResult.yaml new file mode 100644 index 00000000..e3190526 --- /dev/null +++ b/schemas/components/schemas/IncognitoResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if we detected incognito mode used in the browser, `false` + otherwise. + example: false +required: + - result diff --git a/schemas/components/schemas/IpBlockListResult.yaml b/schemas/components/schemas/IpBlockListResult.yaml new file mode 100644 index 00000000..5244ebc1 --- /dev/null +++ b/schemas/components/schemas/IpBlockListResult.yaml @@ -0,0 +1,27 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if request IP address is part of any database that we use to search + for known malicious actors, `false` otherwise. + example: false + details: + type: object + additionalProperties: false + properties: + emailSpam: + type: boolean + description: IP address was part of a known email spam attack (SMTP). + example: false + attackSource: + type: boolean + description: IP address was part of a known network attack (SSH/HTTPS). + example: false + required: + - emailSpam + - attackSource +required: + - result + - details diff --git a/schemas/components/schemas/IpInfoResult.yaml b/schemas/components/schemas/IpInfoResult.yaml new file mode 100644 index 00000000..45d8001b --- /dev/null +++ b/schemas/components/schemas/IpInfoResult.yaml @@ -0,0 +1,40 @@ +type: object +description: >- + Details about the request IP address. Has separate fields for v4 and v6 IP + address versions. +additionalProperties: false +properties: + v4: + type: object + additionalProperties: false + properties: + address: + type: string + format: ipv4 + example: 94.142.239.124 + geolocation: + $ref: IPLocation.yaml + asn: + $ref: ASN.yaml + datacenter: + $ref: DataCenter.yaml + required: + - address + - geolocation + v6: + type: object + additionalProperties: false + properties: + address: + type: string + format: ipv6 + example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 + geolocation: + $ref: IPLocation.yaml + asn: + $ref: ASN.yaml + datacenter: + $ref: DataCenter.yaml + required: + - address + - geolocation diff --git a/schemas/components/schemas/JailbrokenResult.yaml b/schemas/components/schemas/JailbrokenResult.yaml new file mode 100644 index 00000000..1ec98e9c --- /dev/null +++ b/schemas/components/schemas/JailbrokenResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + iOS specific jailbreak detection. There are 2 values: • `true` - Jailbreak + detected • `false` - No signs of jailbreak or the client is not iOS. + example: false +required: + - result diff --git a/schemas/components/schemas/Location.yaml b/schemas/components/schemas/Location.yaml new file mode 100644 index 00000000..2f2a183c --- /dev/null +++ b/schemas/components/schemas/Location.yaml @@ -0,0 +1,15 @@ +type: object +additionalProperties: false +properties: + code: + type: string + minLength: 2 + maxLength: 2 + example: US + name: + type: string + example: United States +required: + - code + - name +title: Location diff --git a/schemas/components/schemas/LocationSpoofingResult.yaml b/schemas/components/schemas/LocationSpoofingResult.yaml new file mode 100644 index 00000000..22cce714 --- /dev/null +++ b/schemas/components/schemas/LocationSpoofingResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: >- + Flag indicating whether the request came from a mobile device with + location spoofing enabled. + example: false +required: + - result diff --git a/schemas/components/schemas/PrivacySettingsResult.yaml b/schemas/components/schemas/PrivacySettingsResult.yaml new file mode 100644 index 00000000..a4330f6c --- /dev/null +++ b/schemas/components/schemas/PrivacySettingsResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if the request is from a privacy aware browser (e.g. Tor) or from a + browser in which fingerprinting is blocked. Otherwise `false`. + example: false +required: + - result diff --git a/schemas/components/schemas/ProductError.yaml b/schemas/components/schemas/ProductError.yaml new file mode 100644 index 00000000..f2f12baf --- /dev/null +++ b/schemas/components/schemas/ProductError.yaml @@ -0,0 +1,19 @@ +type: object +additionalProperties: false +properties: + code: + type: string + description: | + Error code: + * `TooManyRequests` - the limit on secret API key requests per second has been exceeded + * `Failed` - internal server error + enum: + - TooManyRequests + - Failed + example: TooManyRequests + message: + type: string + example: too many requests +required: + - code + - message diff --git a/schemas/components/schemas/ProductsResponse.yaml b/schemas/components/schemas/ProductsResponse.yaml new file mode 100644 index 00000000..faef19f3 --- /dev/null +++ b/schemas/components/schemas/ProductsResponse.yaml @@ -0,0 +1,238 @@ +type: object +description: >- + Contains all information about the request identified by `requestId`, + depending on the pricing plan (Pro, Pro Plus, Enterprise) +additionalProperties: false +properties: + identification: + type: object + additionalProperties: false + title: ProductsResponseIdentification + properties: + data: + title: ProductsResponseIdentificationData + allOf: + - $ref: Visit.yaml + - type: object + additionalProperties: false + properties: + visitorId: + type: string + description: > + String of 20 characters that uniquely identifies the visitor's + browser. + example: + - Ibk1527CUFmcnjLwIs4A + required: + - visitorId + - required: + - tag + error: + $ref: IdentificationError.yaml + botd: + title: ProductsResponseBotd + type: object + additionalProperties: false + properties: + data: + $ref: BotdResult.yaml + error: + $ref: ProductError.yaml + ipInfo: + title: SignalResponseIpInfo + type: object + additionalProperties: false + properties: + data: + $ref: IpInfoResult.yaml + error: + $ref: ProductError.yaml + incognito: + title: SignalResponseIncognito + type: object + additionalProperties: false + properties: + data: + $ref: IncognitoResult.yaml + error: + $ref: IdentificationError.yaml + rootApps: + title: SignalResponseRootApps + type: object + additionalProperties: false + properties: + data: + $ref: RootAppsResult.yaml + error: + $ref: ProductError.yaml + emulator: + title: SignalResponseEmulator + type: object + additionalProperties: false + properties: + data: + $ref: EmulatorResult.yaml + error: + $ref: ProductError.yaml + clonedApp: + title: SignalResponseClonedApp + type: object + additionalProperties: false + properties: + data: + $ref: ClonedAppResult.yaml + error: + $ref: ProductError.yaml + factoryReset: + title: SignalResponseFactoryReset + type: object + additionalProperties: false + properties: + data: + $ref: FactoryResetResult.yaml + error: + $ref: ProductError.yaml + jailbroken: + title: SignalResponseJailbroken + type: object + additionalProperties: false + properties: + data: + $ref: JailbrokenResult.yaml + error: + $ref: ProductError.yaml + frida: + title: SignalResponseFrida + type: object + additionalProperties: false + properties: + data: + $ref: FridaResult.yaml + error: + $ref: ProductError.yaml + ipBlocklist: + title: SignalResponseIpBlocklist + type: object + additionalProperties: false + properties: + data: + $ref: IpBlockListResult.yaml + error: + $ref: ProductError.yaml + tor: + title: SignalResponseTor + type: object + additionalProperties: false + properties: + data: + $ref: TorResult.yaml + error: + $ref: ProductError.yaml + privacySettings: + title: SignalResponsePrivacySettings + type: object + additionalProperties: false + properties: + data: + $ref: PrivacySettingsResult.yaml + error: + $ref: ProductError.yaml + virtualMachine: + title: SignalResponseVirtualMachine + type: object + additionalProperties: false + properties: + data: + $ref: VirtualMachineResult.yaml + error: + $ref: ProductError.yaml + vpn: + title: SignalResponseVpn + type: object + additionalProperties: false + properties: + data: + $ref: VpnResult.yaml + error: + $ref: ProductError.yaml + proxy: + title: SignalResponseProxy + type: object + additionalProperties: false + properties: + data: + $ref: ProxyResult.yaml + error: + $ref: ProductError.yaml + tampering: + title: SignalResponseTampering + type: object + additionalProperties: false + properties: + data: + $ref: TamperingResult.yaml + error: + $ref: IdentificationError.yaml + highActivity: + title: SignalResponseHighActivity + type: object + additionalProperties: false + properties: + data: + $ref: HighActivityResult.yaml + error: + $ref: ProductError.yaml + locationSpoofing: + title: SignalResponseLocationSpoofing + type: object + additionalProperties: false + properties: + data: + $ref: LocationSpoofingResult.yaml + error: + $ref: ProductError.yaml + suspectScore: + title: SignalResponseSuspectScore + type: object + additionalProperties: false + properties: + data: + $ref: SuspectScoreResult.yaml + error: + $ref: ProductError.yaml + rawDeviceAttributes: + title: SignalResponseRawDeviceAttributes + type: object + additionalProperties: false + properties: + data: + $ref: RawDeviceAttributesResult.yaml + error: + $ref: IdentificationError.yaml + remoteControl: + title: SignalResponseRemoteControl + type: object + additionalProperties: false + properties: + data: + $ref: RemoteControlResult.yaml + error: + $ref: ProductError.yaml + velocity: + title: SignalResponseVelocity + type: object + additionalProperties: false + properties: + data: + $ref: VelocityResult.yaml + error: + $ref: ProductError.yaml + developerTools: + title: SignalResponseDeveloperTools + type: object + additionalProperties: false + properties: + data: + $ref: DeveloperToolsResult.yaml + error: + $ref: ProductError.yaml diff --git a/schemas/components/schemas/ProxyResult.yaml b/schemas/components/schemas/ProxyResult.yaml new file mode 100644 index 00000000..2fd4a912 --- /dev/null +++ b/schemas/components/schemas/ProxyResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if the request IP address is used by a public proxy provider, + `false` otherwise. + example: false +required: + - result diff --git a/schemas/components/schemas/RawDeviceAttributesResult.yaml b/schemas/components/schemas/RawDeviceAttributesResult.yaml new file mode 100644 index 00000000..e9ddf058 --- /dev/null +++ b/schemas/components/schemas/RawDeviceAttributesResult.yaml @@ -0,0 +1,31 @@ +type: object +description: > + It includes 35+ raw browser identification attributes to provide Fingerprint + users with even more information than our standard visitor ID provides. This + enables Fingerprint users to not have to run our open-source product in + conjunction with Fingerprint Pro Plus and Enterprise to get those additional + attributes. + + Warning: The raw signals data can change at any moment as we improve the + product. We cannot guarantee the internal shape of raw device attributes to be + stable, so typical semantic versioning rules do not apply here. Use this data + with caution without assuming a specific structure beyond the generic type + provided here. +additionalProperties: + type: object + properties: + error: + properties: + name: + title: error.name + type: string + message: + title: error.message + type: string + required: + - name + - message + title: error + type: object + value: + title: value diff --git a/schemas/components/schemas/RelatedVisitor.yaml b/schemas/components/schemas/RelatedVisitor.yaml new file mode 100644 index 00000000..5d700221 --- /dev/null +++ b/schemas/components/schemas/RelatedVisitor.yaml @@ -0,0 +1,9 @@ +type: object +additionalProperties: false +properties: + visitorId: + description: Visitor ID of a browser that originates from the same mobile device as the input visitor ID. + type: string + example: 'Ibk1527CUFmcnjLwIs4A' +required: + - visitorId diff --git a/schemas/components/schemas/RelatedVisitorsResponse.yaml b/schemas/components/schemas/RelatedVisitorsResponse.yaml new file mode 100644 index 00000000..ee42b0aa --- /dev/null +++ b/schemas/components/schemas/RelatedVisitorsResponse.yaml @@ -0,0 +1,9 @@ +type: object +additionalProperties: false +properties: + relatedVisitors: + type: array + items: + $ref: 'RelatedVisitor.yaml' +required: + - relatedVisitors diff --git a/schemas/components/schemas/RemoteControlResult.yaml b/schemas/components/schemas/RemoteControlResult.yaml new file mode 100644 index 00000000..59e0c7a5 --- /dev/null +++ b/schemas/components/schemas/RemoteControlResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if the request came from a machine being remotely controlled (e.g. + TeamViewer), `false` otherwise. + example: false +required: + - result diff --git a/schemas/components/schemas/Response.yaml b/schemas/components/schemas/Response.yaml new file mode 100644 index 00000000..764fce69 --- /dev/null +++ b/schemas/components/schemas/Response.yaml @@ -0,0 +1,34 @@ +type: object +additionalProperties: false +properties: + visitorId: + type: string + visits: + type: array + items: + title: ResponseVisits + allOf: + - $ref: Visit.yaml + - required: + - tag + lastTimestamp: + description: > + ⚠️ Deprecated paging attribute, please use `paginationKey` instead. + Timestamp of the last visit in the current page of results. + type: integer + format: int64 + example: 1654815517198 + paginationKey: + description: >- + Request ID of the last visit in the current page of results. Use this + value in the following request as the `paginationKey` parameter to get the + next page of results. + type: string + example: 1654815517198.azN4IZ +required: + - visitorId + - visits +title: PaginatedResponse +description: >- + Fields `lastTimestamp` and `paginationKey` added when `limit` or `before` + parameter provided and there is more data to show diff --git a/schemas/components/schemas/RootAppsResult.yaml b/schemas/components/schemas/RootAppsResult.yaml new file mode 100644 index 00000000..58bf2837 --- /dev/null +++ b/schemas/components/schemas/RootAppsResult.yaml @@ -0,0 +1,12 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + Android specific root management apps detection. There are 2 values: • + `true` - Root Management Apps detected (e.g. Magisk) • `false` - No Root + Management Apps detected or the client isn't Android. + example: false +required: + - result diff --git a/schemas/components/schemas/SeenAt.yaml b/schemas/components/schemas/SeenAt.yaml new file mode 100644 index 00000000..2a128658 --- /dev/null +++ b/schemas/components/schemas/SeenAt.yaml @@ -0,0 +1,20 @@ +type: object +additionalProperties: false +properties: + global: + type: string + nullable: true + format: date-time + example: '2022-05-05T18:28:54.535Z' + subscription: + type: string + nullable: true + format: date-time + example: '2022-06-09T22:58:05.576Z' +required: + - global + - subscription +title: SeenAt +example: + global: '2022-05-05T18:28:54.535Z' + subscription: null diff --git a/schemas/components/schemas/Subdivision.yaml b/schemas/components/schemas/Subdivision.yaml new file mode 100644 index 00000000..e8722798 --- /dev/null +++ b/schemas/components/schemas/Subdivision.yaml @@ -0,0 +1,9 @@ +type: object +additionalProperties: false +properties: + isoCode: + type: string + example: '10' + name: + type: string + example: Hlavni mesto Praha diff --git a/schemas/components/schemas/SuspectScoreResult.yaml b/schemas/components/schemas/SuspectScoreResult.yaml new file mode 100644 index 00000000..e14e8fcf --- /dev/null +++ b/schemas/components/schemas/SuspectScoreResult.yaml @@ -0,0 +1,14 @@ +type: object +additionalProperties: false +properties: + result: + type: integer + description: > + Suspect Score is an easy way to integrate Smart Signals into your fraud + protection work flow. It is a weighted representation of all Smart + Signals present in the payload that helps identify suspicious activity. + The value range is [0; S] where S is sum of all Smart Signals weights. + See more details here: https://dev.fingerprint.com/docs/suspect-score + example: 0 +required: + - result diff --git a/schemas/components/schemas/TamperingResult.yaml b/schemas/components/schemas/TamperingResult.yaml new file mode 100644 index 00000000..88bed366 --- /dev/null +++ b/schemas/components/schemas/TamperingResult.yaml @@ -0,0 +1,21 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: >- + Flag indicating whether browser tampering was detected according to our + internal thresholds. + example: false + anomalyScore: + type: number + description: >- + Confidence score (`0.0 - 1.0`) for the tampering detection. Values above + `0.5` suggest that we're reasonably sure there was a tampering attempt. + Values below `0.5` are genuine browsers. + example: 0 + minimum: 0 + maximum: 1 +required: + - result + - anomalyScore diff --git a/schemas/components/schemas/TooManyRequestsResponse.yaml b/schemas/components/schemas/TooManyRequestsResponse.yaml new file mode 100644 index 00000000..1fdbbb5f --- /dev/null +++ b/schemas/components/schemas/TooManyRequestsResponse.yaml @@ -0,0 +1,9 @@ +type: object +additionalProperties: false +properties: + error: + type: string + description: Error text. + example: request throttled +required: + - error diff --git a/schemas/components/schemas/TorResult.yaml b/schemas/components/schemas/TorResult.yaml new file mode 100644 index 00000000..26b6ea66 --- /dev/null +++ b/schemas/components/schemas/TorResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if the request IP address is a known tor exit node, `false` + otherwise. + example: false +required: + - result diff --git a/schemas/components/schemas/VelocityIntervalResult.yaml b/schemas/components/schemas/VelocityIntervalResult.yaml new file mode 100644 index 00000000..3b7be1b0 --- /dev/null +++ b/schemas/components/schemas/VelocityIntervalResult.yaml @@ -0,0 +1,22 @@ +type: object +description: | + Is absent if the velocity data could not be generated for the visitor ID. +additionalProperties: false +properties: + 5m: + type: integer + example: 1 + 1h: + type: integer + example: 1 + 24h: + type: integer + description: > + The `24h` interval of `distinctIp`, `distinctLinkedId`, and + `distinctCountry` will be omitted if the number of `events`` for the + visitor ID in the last 24 hours (`events.intervals.['24h']`) is higher + than 20.000. + example: 1 +required: + - 5m + - 1h diff --git a/schemas/components/schemas/VelocityIntervals.yaml b/schemas/components/schemas/VelocityIntervals.yaml new file mode 100644 index 00000000..fe2fac43 --- /dev/null +++ b/schemas/components/schemas/VelocityIntervals.yaml @@ -0,0 +1,5 @@ +type: object +additionalProperties: false +properties: + intervals: + $ref: VelocityIntervalResult.yaml diff --git a/schemas/components/schemas/VelocityResult.yaml b/schemas/components/schemas/VelocityResult.yaml new file mode 100644 index 00000000..b3005647 --- /dev/null +++ b/schemas/components/schemas/VelocityResult.yaml @@ -0,0 +1,28 @@ +type: object +description: > + Sums key data points for a specific `visitorId` at three distinct time + intervals: 5 minutes, 1 hour, and 24 hours as follows: + + - Number of identification events attributed to the visitor ID - Number of + distinct IP addresses associated to the visitor ID. - Number of distinct + countries associated with the visitor ID. - Number of distinct `linkedId`s + associated with the visitor ID. + + The `24h` interval of `distinctIp`, `distinctLinkedId`, and `distinctCountry` + will be omitted if the number of `events` for the visitor ID in the last 24 + hours (`events.intervals.['24h']`) is higher than 20.000. +additionalProperties: false +properties: + distinctIp: + $ref: VelocityIntervals.yaml + distinctLinkedId: + $ref: VelocityIntervals.yaml + distinctCountry: + $ref: VelocityIntervals.yaml + events: + $ref: VelocityIntervals.yaml +required: + - distinctIp + - distinctLinkedId + - distinctCountry + - events diff --git a/schemas/components/schemas/VirtualMachineResult.yaml b/schemas/components/schemas/VirtualMachineResult.yaml new file mode 100644 index 00000000..51eb61de --- /dev/null +++ b/schemas/components/schemas/VirtualMachineResult.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: > + `true` if the request came from a browser running inside a virtual machine + (e.g. VMWare), `false` otherwise. + example: false +required: + - result diff --git a/schemas/components/schemas/Visit.yaml b/schemas/components/schemas/Visit.yaml new file mode 100644 index 00000000..1eb968a1 --- /dev/null +++ b/schemas/components/schemas/Visit.yaml @@ -0,0 +1,110 @@ +type: object +additionalProperties: false +properties: + requestId: + description: Unique identifier of the user's identification request. + type: string + example: 1654815516083.OX6kx8 + browserDetails: + $ref: BrowserDetails.yaml + incognito: + description: Flag if user used incognito session. + type: boolean + ip: + type: string + format: ipv4 + example: 8.8.8.8 + ipLocation: + type: object + additionalProperties: false + deprecated: true + description: >- + This field is **deprecated** and will not return a result for + **applications created after January 23rd, 2024**. Please use the [IP + Geolocation Smart + signal](https://dev.fingerprint.com/docs/smart-signals-overview#ip-geolocation) + for geolocation information. + properties: + accuracyRadius: + description: >- + The IP address is likely to be within this radius (in km) of the + specified location. + type: integer + minimum: 0 + latitude: + type: number + format: double + minimum: -90 + maximum: 90 + longitude: + type: number + format: double + minimum: -180 + maximum: 180 + postalCode: + type: string + timezone: + type: string + format: timezone + city: + type: object + additionalProperties: false + title: DeprecatedIPLocationCity + properties: + name: + type: string + country: + $ref: Location.yaml + continent: + $ref: Location.yaml + subdivisions: + type: array + items: + $ref: Subdivision.yaml + title: DeprecatedIPLocation + timestamp: + description: Timestamp of the event with millisecond precision in Unix time. + type: integer + format: int64 + example: 1654815516086 + time: + title: Time + description: Time expressed according to ISO 8601 in UTC format. + type: string + format: date-time + example: '2022-06-09T22:58:36Z' + url: + description: Page URL from which the identification request was sent. + type: string + example: https://some.website/path?query=params + tag: + description: >- + A customer-provided value or an object that was sent with identification + request. + type: object + additionalProperties: true + linkedId: + description: A customer-provided id that was sent with identification request. + type: string + example: someID + confidence: + $ref: Confidence.yaml + visitorFound: + description: Attribute represents if a visitor had been identified before. + type: boolean + firstSeenAt: + $ref: SeenAt.yaml + lastSeenAt: + $ref: SeenAt.yaml +required: + - browserDetails + - firstSeenAt + - incognito + - ip + - lastSeenAt + - requestId + - time + - timestamp + - url + - visitorFound +title: Visit diff --git a/schemas/components/schemas/VpnResult.yaml b/schemas/components/schemas/VpnResult.yaml new file mode 100644 index 00000000..b56a5855 --- /dev/null +++ b/schemas/components/schemas/VpnResult.yaml @@ -0,0 +1,52 @@ +type: object +additionalProperties: false +properties: + result: + type: boolean + description: VPN or other anonymizing service has been used when sending the request. + example: false + originTimezone: + type: string + description: Local timezone which is used in timezoneMismatch method. + example: Europe/Berlin + originCountry: + type: string + description: >- + Country of the request (only for Android SDK version >= 2.4.0, ISO 3166 + format or unknown). + example: unknown + methods: + type: object + additionalProperties: false + properties: + timezoneMismatch: + type: boolean + description: >- + The browser timezone doesn't match the timezone inferred from the + request IP address. + example: false + publicVPN: + type: boolean + description: Request IP address is owned and used by a public VPN service provider. + example: false + auxiliaryMobile: + type: boolean + description: >- + This method applies to mobile devices only. Indicates the result of + additional methods used to detect a VPN in mobile devices. + example: false + osMismatch: + type: boolean + description: >- + The browser runs on a different operating system than the operating + system inferred from the request network signature. + example: false + required: + - timezoneMismatch + - publicVPN + - auxiliaryMobile + - osMismatch +required: + - result + - originTimezone + - methods diff --git a/schemas/components/schemas/WebhookVisit.yaml b/schemas/components/schemas/WebhookVisit.yaml new file mode 100644 index 00000000..aa854c77 --- /dev/null +++ b/schemas/components/schemas/WebhookVisit.yaml @@ -0,0 +1,64 @@ +allOf: + - type: object + additionalProperties: false + properties: + visitorId: + type: string + example: 3HNey93AkBW6CRbxV6xP + clientReferrer: + type: string + example: https://google.com?search=banking+services + userAgent: + type: string + example: >- + Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 + (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 + bot: + $ref: BotdDetectionResult.yaml + ipInfo: + $ref: IpInfoResult.yaml + incognito: + $ref: IncognitoResult.yaml + rootApps: + $ref: RootAppsResult.yaml + emulator: + $ref: EmulatorResult.yaml + clonedApp: + $ref: ClonedAppResult.yaml + factoryReset: + $ref: FactoryResetResult.yaml + jailbroken: + $ref: JailbrokenResult.yaml + frida: + $ref: FridaResult.yaml + ipBlocklist: + $ref: IpBlockListResult.yaml + tor: + $ref: TorResult.yaml + privacySettings: + $ref: PrivacySettingsResult.yaml + virtualMachine: + $ref: VirtualMachineResult.yaml + vpn: + $ref: VpnResult.yaml + proxy: + $ref: ProxyResult.yaml + tampering: + $ref: TamperingResult.yaml + rawDeviceAttributes: + $ref: RawDeviceAttributesResult.yaml + highActivity: + $ref: HighActivityResult.yaml + locationSpoofing: + $ref: LocationSpoofingResult.yaml + suspectScore: + $ref: SuspectScoreResult.yaml + remoteControl: + $ref: RemoteControlResult.yaml + velocity: + $ref: VelocityResult.yaml + developerTools: + $ref: DeveloperToolsResult.yaml + required: + - visitorId + - $ref: Visit.yaml diff --git a/schemas/fingerprint-related-visitors-api.yaml b/schemas/fingerprint-related-visitors-api.yaml index a19841fe..29fb10f9 100644 --- a/schemas/fingerprint-related-visitors-api.yaml +++ b/schemas/fingerprint-related-visitors-api.yaml @@ -2,7 +2,7 @@ openapi: 3.0.3 info: title: Related Visitors API description: | - Use this API to unify and personalize the experience for your anonymous users who visit your website from regular and in-app browsers. + Use this API to unify and personalize the experience for your anonymous users who visit your website from regular and in-app browsers. version: '1.0' contact: name: Fingerprint Support @@ -23,88 +23,7 @@ security: - ApiKeyQuery: [] paths: /related-visitors: - get: - tags: - - Related Visitors - operationId: 'getRelatedVisitors' - summary: Get Related Visitors - description: | - This API will enable you to find if one or more web and in-app browser sessions originated from the same mobile device. - When requested, this API will search identification events within the past 6 months to find the visitor IDs that belong to the same mobile device as the given visitor ID. - Please visit the [Overview](https://dev.fingerprint.com/reference/related-visitors-api) page to learn more about this API. - parameters: - - name: visitor_id - description: The [visitor ID](https://dev.fingerprint.com/docs/js-agent#visitorid) for which you want to find the other visitor IDs that originated from the same mobile device. - in: query - required: true - schema: - type: string - responses: - '200': - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/RelatedVisitorsResponse' - examples: - 200-success-empty-response: - summary: Success, empty response - externalValue: '/examples/related-visitors/get_related_visitors_200_empty.json' - 200-success-response: - summary: Success response - externalValue: '/examples/related-visitors/get_related_visitors_200.json' - '400': - description: Bad request. The visitor ID parameter is missing or in the wrong format. - content: - application/json: - schema: - $ref: 'fingerprint-server-api.yaml#/components/schemas/ErrorVisitor400Response' - examples: - 400-empty-visitor-id: - summary: Error response when the request does not include a visitor ID - externalValue: '/examples/shared/400_error_empty_visitor_id.json' - 400-invalid-visitor-id: - summary: Error response when the visitor ID is incorrectly formatted - externalValue: '/examples/shared/400_error_incorrect_visitor_id.json' - '403': - description: Forbidden. Access to this API is denied. - content: - application/json: - schema: - $ref: 'fingerprint-server-api.yaml#/components/schemas/ErrorCommon403Response' - examples: - 403-feature-not-enabled: - summary: Error response when this feature is not enabled for a subscription. - externalValue: '/examples/shared/403_error_feature_not_enabled.json' - 403-token-not-found: - summary: Error response when the provided secret API key does not exist. - externalValue: '/examples/shared/403_error_token_not_found.json' - 403-token-required: - summary: Error response when the secret API key was not provided. - externalValue: '/examples/shared/403_error_token_required.json' - 403-wrong-region: - summary: Error response when the API region is different from the region, the calling application is configured with. - externalValue: '/examples/shared/403_error_wrong_region.json' - '404': - description: Not found. The visitor ID cannot be found in this application's data. - content: - application/json: - schema: - $ref: 'fingerprint-server-api.yaml#/components/schemas/ErrorVisitor404Response' - examples: - 404-visitor-not-found: - summary: Error response when the visitor ID cannot be found in this application's data. - externalValue: '/examples/shared/404_error_visitor_not_found.json' - '429': - description: Too Many Requests. The request is throttled. - content: - application/json: - schema: - $ref: 'fingerprint-server-api.yaml#/components/schemas/ErrorCommon429Response' - examples: - example: - summary: Too Many Requests - externalValue: '/examples/shared/429_error_too_many_requests.json' + $ref: './paths/related-visitors.yaml' components: securitySchemes: ApiKeyHeader: @@ -115,25 +34,3 @@ components: type: apiKey in: query # can be "header", "query" or "cookie" name: api_key # name of the header, query parameter or cookie - schemas: - RelatedVisitorsResponse: - type: object - additionalProperties: false - properties: - relatedVisitors: - type: array - items: - $ref: '#/components/schemas/RelatedVisitor' - required: - - relatedVisitors - RelatedVisitor: - type: object - additionalProperties: false - properties: - visitorId: - description: Visitor ID of a browser that originates from the same mobile device as the input visitor ID. - type: string - example: 'Ibk1527CUFmcnjLwIs4A' - required: - - visitorId - diff --git a/schemas/fingerprint-server-api.yaml b/schemas/fingerprint-server-api.yaml index d520c668..99fb3912 100644 --- a/schemas/fingerprint-server-api.yaml +++ b/schemas/fingerprint-server-api.yaml @@ -36,669 +36,11 @@ x-readme: - go paths: /events/{request_id}: - get: - tags: - - Events - operationId: 'getEvent' - summary: Get event by request ID - description: | - Get a detailed analysis of an individual identification event, including Smart Signals. - Please note that the response includes mobile signals (e.g. `rootApps`) even if the request originated from a non-mobile platform. - It is highly recommended that you **ignore** the mobile signals for such requests. - - Use `requestId` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `requestId`. - parameters: - - name: request_id - in: path - description: The unique [identifier](https://dev.fingerprint.com/docs/js-agent#requestid) of each identification request. - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/EventResponse' - examples: - fullResponse: - summary: Example response - externalValue: '/examples/get_event_200.json' - allErrorsResponse: - summary: All failed signals - externalValue: '/examples/get_event_200_all_errors.json' - withBotdError: - summary: BotD error - externalValue: '/examples/get_event_200_botd_failed_error.json' - withBotdTooManyRequestsError: - summary: BotD too many requests error - externalValue: '/examples/get_event_200_botd_too_many_requests_error.json' - withIdentificationError: - summary: Identification error - externalValue: '/examples/get_event_200_identification_failed_error.json' - withIdentificationTooManyRequestsError: - summary: Identification too many requests error - externalValue: '/examples/get_event_200_identification_too_many_requests_error.json' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorCommon403Response' - examples: - example: - summary: Forbidden - externalValue: '/examples/get_event_403_error.json' - '404': - description: Not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorEvent404Response' - examples: - example: - summary: Not found - externalValue: '/examples/get_event_404_error.json' - x-readme: - code-samples: - - language: node - name: Node SDK - install: npm install @fingerprintjs/fingerprintjs-pro-server-api - code: | - import { - FingerprintJsServerApiClient, - Region, - } from '@fingerprintjs/fingerprintjs-pro-server-api' - - const client = new FingerprintJsServerApiClient({ - apiKey: 'SERVER_API_KEY', // Replace with your key - region: Region.Global, // Replace with your region - }) - - // Get a specific fingerprinting event - client.getEvent('REQUEST_ID').then((event) => { - console.log(event) - }) - - language: php - name: PHP SDK - install: composer require fingerprint/fingerprint-pro-server-api-sdk - code: | - getEvent("REQUEST_ID"); - echo "
" . $response->__toString() . ""; - } catch (Exception $e) { - echo $e->getMessage(), PHP_EOL; - } - - language: python - name: Python SDK - install: pip install fingerprint_pro_server_api_sdk - code: | - import fingerprint_pro_server_api_sdk - from fingerprint_pro_server_api_sdk import EventResponse - from fingerprint_pro_server_api_sdk import Response - from fingerprint_pro_server_api_sdk.rest import ApiException - - configuration = fingerprint_pro_server_api_sdk.Configuration( - api_key="SERVER_API_KEY", // Replace with your key - region="us" // Replace with your region - ) - api_instance = fingerprint_pro_server_api_sdk.FingerprintApi(configuration) - - # Get a specific fingerprinting event - try: - event: EventResponse = api_instance.get_event("REQUEST_ID") - print(event) - except ApiException as e: - print("Exception when getting an event: %s\n" % e) - - language: golang - name: Go SDK - install: go get github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk - code: | - package main - - import ( - "context" - "fmt" - "github.com/antihax/optional" - "github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk/v3/sdk" - "log" - ) - - func main() { - cfg := sdk.NewConfiguration() - client := sdk.NewAPIClient(cfg) - - auth := context.WithValue( - context.Background(), - sdk.ContextAPIKey, - sdk.APIKey{Key: "SERVER_API_KEY"}, // Replace with your key - ) - cfg.ChangeRegion(sdk.RegionUS) // Replace with your region - - // Get a specific fingerprinting event - event, eventHttpRes, eventErr := - client.FingerprintApi.GetEvent(auth, "REQUEST_ID") - if eventErr != nil { - log.Fatal(eventErr) - } - fmt.Printf("Event: %s", event) - } - - language: java - name: Java SDK - code: | - import com.fingerprint.api.FingerprintApi; - import com.fingerprint.models.EventResponse; - import com.fingerprint.models.Response; - import com.fingerprint.sdk.ApiClient; - import com.fingerprint.sdk.ApiException; - import com.fingerprint.sdk.Configuration; - import com.fingerprint.sdk.Region; - - public class FingerprintApiExample { - public static void main(String... args) { - ApiClient client = Configuration.getDefaultApiClient( - "SERVER_API_KEY", // Replace with your key - Region.GLOBAL // Replace with your region - ); - FingerprintApi api = new FingerprintApi(client); - - // Get a specific fingerprinting event - try { - EventResponse response = api.getEvent("REQUEST_ID"); - System.out.println(response.getProducts().toString()); - } catch (ApiException e) { - System.err.println(e.getMessage()); - } - } - } - - language: csharp - name: C# SDK - install: dotnet add package FingerprintPro.ServerSdk - code: | - using FingerprintPro.ServerSdk.Api; - using FingerprintPro.ServerSdk.Client; - - var configuration = new Configuration("SERVER_API_KEY"); // Replace with your key - configuration.Region = Region.Us; // Replace with your region - - var api = new FingerprintApi( - configuration - ); - - // Get a specific fingerprinting event - var events = api.GetEvent("REQUEST_ID"); - Console.WriteLine(events); - put: - tags: - - Events - operationId: 'updateEvent' - summary: Update an event with a given request ID - description: | - Change information in existing events specified by `requestId` or *flag suspicious events*. - - When an event is created, it is assigned `linkedId` and `tag` submitted through the JS agent parameters. This information might not be available on the client so the Server API allows for updating the attributes after the fact. - - **Warning** It's not possible to update events older than 10 days. - parameters: - - name: request_id - in: path - description: The unique event [identifier](https://dev.fingerprint.com/docs/js-agent#requestid). - required: true - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/EventUpdateRequest' - responses: - '200': - description: OK - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorUpdateEvent400Response' - examples: - example: - summary: Example response - externalValue: '/examples/update_event_400_error.json' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorCommon403Response' - examples: - example: - summary: Example response - externalValue: '/examples/update_event_403_error.json' - '404': - description: Not found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorEvent404Response' - examples: - example: - summary: Example response - externalValue: '/examples/get_event_404_error.json' - '409': - description: Conflict - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorUpdateEvent409Response' - examples: - example: - summary: Example response - externalValue: '/examples/update_event_409_error.json' + $ref: 'paths/events.yaml' /visitors/{visitor_id}: - get: - tags: - - Visitors - operationId: 'getVisits' - summary: Get visits by visitor ID - description: | - Get a history of visits (identification events) for a specific `visitorId`. Use the `visitorId` as a URL path parameter. - Only information from the _Identification_ product is returned. - - #### Headers - - * `Retry-After` — Present in case of `429 Too many requests`. Indicates how long you should wait before making a follow-up request. The value is non-negative decimal integer indicating the seconds to delay after the response is received. - parameters: - - name: visitor_id - description: Unique [visitor identifier](https://dev.fingerprint.com/docs/js-agent#visitorid) issued by Fingerprint Pro. - in: path - required: true - schema: - type: string - example: uYIm7Ksp5rf00SllPhFp - - name: request_id - description: | - Filter visits by `requestId`. - - Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/docs/js-agent#requestid). When you filter visits by `requestId`, only one visit will be returned. - in: query - schema: - type: string - # example: 1654815516083.OX6kx8 - - name: linked_id - description: | - Filter visits by your custom identifier. - - You can use [`linkedId`](https://dev.fingerprint.com/docs/js-agent#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. - in: query - schema: - type: string - required: - false - # example: some_id - - name: limit - description: | - Limit scanned results. - - For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). - By default, the most recent 100 visits are scanned, the maximum is 500. - in: query - schema: - type: integer - format: int32 - minimum: 0 - # default: 0 - # example: 10 - - name: paginationKey - description: | - Use `paginationKey` to get the next page of results. - - When more results are available (e.g., you requested 200 results using `limit` parameter, but a total of 600 results are available), the `paginationKey` top-level attribute is added to the response. The key corresponds to the `requestId` of the last returned event. In the following request, use that value in the `paginationKey` parameter to get the next page of results: - - 1. First request, returning most recent 200 events: `GET api-base-url/visitors/:visitorId?limit=200` - 2. Use `response.paginationKey` to get the next page of results: `GET api-base-url/visitors/:visitorId?limit=200&paginationKey=1683900801733.Ogvu1j` - - Pagination happens during scanning and before filtering, so you can get less visits than the `limit` you specified with more available on the next page. When there are no more results available for scanning, the `paginationKey` attribute is not returned. - in: query - schema: - type: string - required: - false - # example: 1683900801733.Ogvu1j - - name: before - description: | - ⚠️ Deprecated pagination method, please use `paginationKey` instead. Timestamp (in milliseconds since epoch) used to paginate results. - in: query - schema: - type: integer - format: int64 - minimum: 0 - # default: 0 - # example: 1654815517198 - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Response' - examples: - limit1: - summary: Example response with limit=1 - externalValue: '/examples/get_visits_200_limit_1.json' - limit500: - summary: Example response with limit=500 - externalValue: '/examples/get_visits_200_limit_500.json' - '403': - description: Forbidden. The API Key is probably missing or incorrect. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorVisits403' - examples: - example: - summary: Forbidden - externalValue: '/examples/get_visits_403_error.json' - '429': - description: Too Many Requests - headers: - Retry-After: - description: Indicates how many seconds you should wait before attempting the next request. - schema: - type: integer - format: int32 - minimum: 0 - content: - application/json: - schema: - $ref: '#/components/schemas/TooManyRequestsResponse' - examples: - example: - summary: Too Many Requests - externalValue: '/examples/get_visits_429_too_many_requests_error.json' - x-readme: - code-samples: - - language: node - name: Node SDK - install: npm install @fingerprintjs/fingerprintjs-pro-server-api - code: | - import { - FingerprintJsServerApiClient, - Region, - } from '@fingerprintjs/fingerprintjs-pro-server-api' - - const client = new FingerprintJsServerApiClient({ - apiKey: 'SERVER_API_KEY', // Replace with your key - region: Region.Global, // Replace with your region - }) - - // Get visit history of a specific visitor - client.getVisitorHistory('VISITOR_ID').then((visitorHistory) => { - console.log(visitorHistory) - }) - - language: php - name: PHP SDK - install: composer require fingerprint/fingerprint-pro-server-api-sdk - code: | - getVisits("VISITOR_ID"); - echo "
" . $response->__toString() . ""; - } catch (Exception $e) { - echo $e->getMessage(), PHP_EOL; - } - - language: python - name: Python SDK - install: pip install fingerprint_pro_server_api_sdk - code: | - import fingerprint_pro_server_api_sdk - from fingerprint_pro_server_api_sdk import EventResponse - from fingerprint_pro_server_api_sdk import Response - from fingerprint_pro_server_api_sdk.rest import ApiException - - configuration = fingerprint_pro_server_api_sdk.Configuration( - api_key="SERVER_API_KEY", // Replace with your key - region="us" // Replace with your region - ) - api_instance = fingerprint_pro_server_api_sdk.FingerprintApi(configuration) - - # Get visit history of a specific visitor - try: - visits: Response = api_instance.get_visits("VISITOR_ID", limit=10) - print(visits) - except ApiException as e: - print("Exception when getting visits: %s\n" % e) - - language: golang - name: Go SDK - install: go get github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk - code: | - package main - - import ( - "context" - "fmt" - "github.com/antihax/optional" - "github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk/v3/sdk" - "log" - ) - - func main() { - cfg := sdk.NewConfiguration() - client := sdk.NewAPIClient(cfg) - - auth := context.WithValue( - context.Background(), - sdk.ContextAPIKey, - sdk.APIKey{Key: "SERVER_API_KEY"}, // Replace with your key - ) - cfg.ChangeRegion(sdk.RegionUS) // Replace with your region - - // Get visit history of a specific visitor - getVisitsOpts := sdk.FingerprintApiGetVisitsOpts{ - Limit: optional.NewInt32(10), - } - history, historyHttpRes, historyErr := - client.FingerprintApi.GetVisits(auth, "VISITOR_ID", &getVisitsOpts) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Visitor history: %s", history) - } - - language: java - name: Java SDK - code: | - import com.fingerprint.api.FingerprintApi; - import com.fingerprint.models.EventResponse; - import com.fingerprint.models.Response; - import com.fingerprint.sdk.ApiClient; - import com.fingerprint.sdk.ApiException; - import com.fingerprint.sdk.Configuration; - import com.fingerprint.sdk.Region; - - public class FingerprintApiExample { - public static void main(String... args) { - ApiClient client = Configuration.getDefaultApiClient( - "SERVER_API_KEY", // Replace with your key - Region.GLOBAL // Replace with your region - ); - FingerprintApi api = new FingerprintApi(client); - - // Get visit history of a specific visitor - try { - Response response = api.getVisits("VISITOR_ID"); - System.out.println(response.getVisits().toString()); - } catch (ApiException e) { - System.err.println(e.getMessage()); - } - } - } - - language: csharp - name: C# SDK - install: dotnet add package FingerprintPro.ServerSdk - code: | - using FingerprintPro.ServerSdk.Api; - using FingerprintPro.ServerSdk.Client; - - var configuration = new Configuration("SERVER_API_KEY"); // Replace with your key - configuration.Region = Region.Us; // Replace with your region - - var api = new FingerprintApi( - configuration - ); - - // Get visit history of a specific visitor - var visits = api.GetVisits("VISITOR_ID"); - Console.WriteLine(visits); - delete: - tags: - - Visitors - operationId: 'deleteVisitorData' - summary: Delete data by visitor ID - description: | - Request deleting all data associated with the specified visitor ID. This API is useful for compliance with privacy regulations. - - ### Which data is deleted? - - Browser (or device) properties - - Identification requests made from this browser (or device) - - #### Browser (or device) properties - - Represents the data that Fingerprint collected from this specific browser (or device) and everything inferred and derived from it. - - Upon request to delete, this data is deleted asynchronously (typically within a few minutes) and it will no longer be used to identify this browser (or device) for your [Fingerprint Application](https://dev.fingerprint.com/docs/glossary#fingerprint-application). - - #### Identification requests made from this browser (or device) - - Fingerprint stores the identification requests made from a browser (or device) for up to 30 (or 90) days depending on your plan. To learn more, see [Data Retention](https://dev.fingerprint.com/docs/regions#data-retention). - - Upon request to delete, the identification requests that were made by this browser - - Within the past 10 days are deleted within 24 hrs. - - Outside of 10 days are allowed to purge as per your data retention period. - - ### Corollary - After requesting to delete a visitor ID, - - If the same browser (or device) requests to identify, it will receive a different visitor ID. - - If you request [`/events` API](https://dev.fingerprint.com/reference/getevent) with a `request_id` that was made outside of the 10 days, you will still receive a valid response. - - If you request [`/visitors` API](https://dev.fingerprint.com/reference/getvisits) for the deleted visitor ID, the response will include identification requests that were made outside of those 10 days. - - ### Interested? - Please [contact our support team](https://fingerprint.com/support/) to enable it for you. Otherwise, you will receive a 403. - parameters: - - name: visitor_id - in: path - description: The [visitor ID](https://dev.fingerprint.com/docs/js-agent#visitorid) you want to delete. - required: true - schema: - type: string - responses: - '200': - description: OK. The visitor ID is scheduled for deletion. - '400': - description: Bad request. The visitor ID parameter is missing or in the wrong format. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorVisitor400Response' - examples: - 400-empty-visitor-id: - summary: Error response when the request does not include a visitor ID - externalValue: '/examples/shared/400_error_empty_visitor_id.json' - 400-invalid-visitor-id: - summary: Error response when the visitor ID is incorrectly formatted - externalValue: '/examples/shared/400_error_incorrect_visitor_id.json' - '403': - description: Forbidden. Access to this API is denied. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorCommon403Response' - examples: - 403-feature-not-enabled: - summary: Error response when this feature is not enabled for a subscription. - externalValue: '/examples/shared/403_error_feature_not_enabled.json' - 403-token-not-found: - summary: Error response when the provided secret API key does not exist. - externalValue: '/examples/shared/403_error_token_not_found.json' - 403-token-required: - summary: Error response when the secret API key was not provided. - externalValue: '/examples/shared/403_error_token_required.json' - 403-wrong-region: - summary: Error response when the API region is different from the region, the calling application is configured with. - externalValue: '/examples/shared/403_error_wrong_region.json' - - '404': - description: Not found. The visitor ID cannot be found in this application's data. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorVisitor404Response' - examples: - example: - summary: Not found - externalValue: '/examples/shared/404_error_visitor_not_found.json' - '429': - description: Too Many Requests. The request is throttled. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorCommon429Response' - examples: - example: - summary: Too Many Requests - externalValue: '/examples/shared/429_error_too_many_requests.json' + $ref: 'paths/visitors.yaml' /webhook: - trace: - tags: - - Fingerprint - description: Fake path to describe webhook format. More information about webhooks can be found in the [documentation](https://dev.fingerprint.com/docs/webhooks) - responses: - default: - description: Dummy for the schema - callbacks: - webhook: - webhook: - post: - description: You can use HTTP basic authentication and set up credentials in your [Fingerprint account](https://dashboard.fingerprint.com/login) - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/WebhookVisit' - example: - externalValue: '/examples/webhook.json' - responses: - default: - description: The server doesn't validate the answer. + $ref: 'paths/webhook.yaml' components: securitySchemes: ApiKeyHeader: @@ -709,1333 +51,3 @@ components: type: apiKey in: query # can be "header", "query" or "cookie" name: api_key # name of the header, query parameter or cookie - schemas: - Response: - type: object - additionalProperties: false - properties: - visitorId: - type: string - visits: - type: array - items: - title: ResponseVisits - allOf: - - $ref: '#/components/schemas/Visit' - - required: - - tag - lastTimestamp: - description: | - ⚠️ Deprecated paging attribute, please use `paginationKey` instead. Timestamp of the last visit in the current page of results. - type: integer - format: int64 - example: 1654815517198 - paginationKey: - description: Request ID of the last visit in the current page of results. Use this value in the following request as the `paginationKey` parameter to get the next page of results. - type: string - example: '1654815517198.azN4IZ' - required: - - visitorId - - visits - title: PaginatedResponse - description: Fields `lastTimestamp` and `paginationKey` added when `limit` or `before` parameter provided and there is more data to show - ErrorCommon403Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - title: Common403ErrorResponse - properties: - code: - type: string - description: > - Error code: - * `TokenRequired` - `Auth-API-Key` header is missing or empty - * `TokenNotFound` - No Fingerprint application found for specified secret key - * `SubscriptionNotActive` - Fingerprint application is not active - * `WrongRegion` - server and application region differ - * `FeatureNotEnabled` - this feature (for example, Delete API) is not enabled for your application - enum: - - TokenRequired - - TokenNotFound - - SubscriptionNotActive - - WrongRegion - - FeatureNotEnabled - example: 'TokenRequired' - message: - type: string - example: 'secret key is required' - required: - - code - - message - ErrorCommon429Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - properties: - code: - type: string - description: > - Error code: - * `TooManyRequests` - The request is throttled. - enum: - - TooManyRequests - example: 'TooManyRequests' - message: - type: string - example: 'request throttled' - required: - - code - - message - ErrorEvent404Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - title: ErrorEvent404ResponseError - properties: - code: - type: string - description: > - Error code: - * `RequestNotFound` - The specified request ID was not found. It never existed, expired, or it has been deleted. - enum: - - RequestNotFound - example: 'RequestNotFound' - message: - type: string - example: 'request id is not found' - required: - - code - - message - ErrorVisits403: - type: object - additionalProperties: false - properties: - error: - type: string - description: Error text. - example: 'Forbidden (HTTP 403)' - required: - - error - TooManyRequestsResponse: - type: object - additionalProperties: false - properties: - error: - type: string - description: Error text. - example: 'request throttled' - required: - - error - ErrorVisitor404Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - title: ErrorVisitor404ResponseError - properties: - code: - type: string - description: > - Error code: - * `VisitorNotFound` - The specified visitor ID was not found. It never existed or it may have already been deleted. - enum: - - VisitorNotFound - example: 'VisitorNotFound' - message: - type: string - example: 'visitor not found' - required: - - code - - message - ErrorVisitor400Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - properties: - code: - type: string - description: > - Error code: - * `RequestCannotBeParsed` - The visitor ID parameter is missing or in the wrong format. - enum: - - RequestCannotBeParsed - example: 'RequestCannotBeParsed' - message: - type: string - example: 'invalid visitor id' - required: - - code - - message - WebhookVisit: - allOf: - - type: object - additionalProperties: false - properties: - visitorId: - type: string - example: '3HNey93AkBW6CRbxV6xP' - clientReferrer: - type: string - example: 'https://google.com?search=banking+services' - userAgent: - type: string - example: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36' - bot: - $ref: '#/components/schemas/BotdDetectionResult' - ipInfo: - $ref: '#/components/schemas/IpInfoResult' - incognito: - $ref: '#/components/schemas/IncognitoResult' - rootApps: - $ref: '#/components/schemas/RootAppsResult' - emulator: - $ref: '#/components/schemas/EmulatorResult' - clonedApp: - $ref: '#/components/schemas/ClonedAppResult' - factoryReset: - $ref: '#/components/schemas/FactoryResetResult' - jailbroken: - $ref: '#/components/schemas/JailbrokenResult' - frida: - $ref: '#/components/schemas/FridaResult' - ipBlocklist: - $ref: '#/components/schemas/IpBlockListResult' - tor: - $ref: '#/components/schemas/TorResult' - privacySettings: - $ref: '#/components/schemas/PrivacySettingsResult' - virtualMachine: - $ref: '#/components/schemas/VirtualMachineResult' - vpn: - $ref: '#/components/schemas/VpnResult' - proxy: - $ref: '#/components/schemas/ProxyResult' - tampering: - $ref: '#/components/schemas/TamperingResult' - rawDeviceAttributes: - $ref: '#/components/schemas/RawDeviceAttributesResult' - highActivity: - $ref: '#/components/schemas/HighActivityResult' - locationSpoofing: - $ref: '#/components/schemas/LocationSpoofingResult' - suspectScore: - $ref: '#/components/schemas/SuspectScoreResult' - remoteControl: - $ref: '#/components/schemas/RemoteControlResult' - velocity: - $ref: '#/components/schemas/VelocityResult' - developerTools: - $ref: '#/components/schemas/DeveloperToolsResult' - required: - - visitorId - - $ref: '#/components/schemas/Visit' - Visit: - type: object - additionalProperties: false - properties: - requestId: - description: Unique identifier of the user's identification request. - type: string - example: '1654815516083.OX6kx8' - browserDetails: - $ref: '#/components/schemas/BrowserDetails' - incognito: - description: Flag if user used incognito session. - type: boolean - ip: - type: string - format: ipv4 - example: '8.8.8.8' - ipLocation: - type: object - additionalProperties: false - deprecated: true - description: This field is **deprecated** and will not return a result for **applications created after January 23rd, 2024**. Please use the [IP Geolocation Smart signal](https://dev.fingerprint.com/docs/smart-signals-overview#ip-geolocation) for geolocation information. - properties: - accuracyRadius: - description: The IP address is likely to be within this radius (in km) of the specified location. - type: integer - minimum: 0 - latitude: - type: number - format: double - minimum: -90 - maximum: 90 - longitude: - type: number - format: double - minimum: -180 - maximum: 180 - postalCode: - type: string - timezone: - type: string - format: timezone - city: - type: object - additionalProperties: false - title: DeprecatedIPLocationCity - properties: - name: - type: string - country: - $ref: '#/components/schemas/Location' - continent: - $ref: '#/components/schemas/Location' - subdivisions: - type: array - items: - $ref: '#/components/schemas/Subdivision' - title: DeprecatedIPLocation - timestamp: - description: Timestamp of the event with millisecond precision in Unix time. - type: integer - format: int64 - example: 1654815516086 - time: - title: Time - description: Time expressed according to ISO 8601 in UTC format. - type: string - format: date-time - example: '2022-06-09T22:58:36Z' - url: - description: Page URL from which the identification request was sent. - type: string - example: 'https://some.website/path?query=params' - tag: - description: A customer-provided value or an object that was sent with identification request. - type: object - additionalProperties: true - linkedId: - description: A customer-provided id that was sent with identification request. - type: string - example: 'someID' - confidence: - $ref: '#/components/schemas/Confidence' - visitorFound: - description: Attribute represents if a visitor had been identified before. - type: boolean - firstSeenAt: - $ref: '#/components/schemas/SeenAt' - lastSeenAt: - $ref: '#/components/schemas/SeenAt' - required: - - browserDetails - - firstSeenAt - - incognito - - ip - - lastSeenAt - - requestId - - time - - timestamp - - url - - visitorFound - title: Visit - BrowserDetails: - type: object - additionalProperties: false - properties: - browserName: - type: string - example: 'Chrome' - browserMajorVersion: - type: string - example: '101' - browserFullVersion: - type: string - example: '101.0.4951' - os: - type: string - example: 'Windows' - osVersion: - type: string - example: '10' - device: - type: string - example: 'Other' - userAgent: - type: string - example: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36' - botProbability: - type: integer - required: - - browserFullVersion - - browserMajorVersion - - browserName - - device - - os - - osVersion - - userAgent - title: BrowserDetails - Confidence: - type: object - additionalProperties: false - properties: - score: - description: The confidence score is a floating-point number between 0 and 1 that represents the probability of accurate identification. - type: number - format: float - minimum: 0 - maximum: 1 - revision: - description: The revision name of the method used to calculate the Confidence score. This field is only present for customers who opted in to an alternative calculation method. - type: string - required: - - score - title: Confidence - SeenAt: - type: object - additionalProperties: false - properties: - global: - type: string - nullable: true - format: date-time - example: '2022-05-05T18:28:54.535Z' - subscription: - type: string - nullable: true - format: date-time - example: '2022-06-09T22:58:05.576Z' - required: - - global - - subscription - title: SeenAt - example: - global: '2022-05-05T18:28:54.535Z' - subscription: null - ASN: - type: object - additionalProperties: false - properties: - asn: - type: string - example: '7922' - network: - type: string - example: '73.136.0.0/13' - name: - type: string - example: 'COMCAST-7922' - required: - - asn - - network - title: ASN - DataCenter: - type: object - additionalProperties: false - properties: - result: - type: boolean - name: - type: string - example: 'DediPath' - required: - - result - title: DataCenter - IPLocation: - type: object - additionalProperties: false - properties: - accuracyRadius: - description: The IP address is likely to be within this radius (in km) of the specified location. - type: integer - minimum: 0 - example: 1000 - latitude: - type: number - format: double - minimum: -90 - maximum: 90 - example: 37.75 - longitude: - type: number - format: double - minimum: -180 - maximum: 180 - example: -97.82 - postalCode: - type: string - example: '130 00' - timezone: - type: string - format: timezone - example: 'America/Chicago' - city: - type: object - additionalProperties: false - title: IPLocationCity - properties: - name: - type: string - example: 'Prague' - country: - $ref: '#/components/schemas/Location' - continent: - $ref: '#/components/schemas/Location' - subdivisions: - type: array - items: - $ref: '#/components/schemas/Subdivision' - title: IPLocation - Location: - type: object - additionalProperties: false - properties: - code: - type: string - minLength: 2 - maxLength: 2 - example: 'US' - name: - type: string - example: 'United States' - required: - - code - - name - title: Location - Subdivision: - type: object - additionalProperties: false - properties: - isoCode: - type: string - example: '10' - name: - type: string - example: 'Hlavni mesto Praha' - ProductsResponse: - type: object - description: Contains all information about the request identified by `requestId`, depending on the pricing plan (Pro, Pro Plus, Enterprise) - additionalProperties: false - properties: - identification: - type: object - additionalProperties: false - title: ProductsResponseIdentification - properties: - data: - title: ProductsResponseIdentificationData - allOf: - - $ref: '#/components/schemas/Visit' - - type: object - additionalProperties: false - properties: - visitorId: - type: string - description: | - String of 20 characters that uniquely identifies the visitor's browser. - - example: - - Ibk1527CUFmcnjLwIs4A - required: - - visitorId - - required: - - tag - error: - $ref: '#/components/schemas/IdentificationError' - botd: - title: ProductsResponseBotd - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/BotdResult' - error: - $ref: '#/components/schemas/ProductError' - ipInfo: - title: SignalResponseIpInfo - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/IpInfoResult' - error: - $ref: '#/components/schemas/ProductError' - incognito: - title: SignalResponseIncognito - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/IncognitoResult' - error: - $ref: '#/components/schemas/IdentificationError' - rootApps: - title: SignalResponseRootApps - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/RootAppsResult' - error: - $ref: '#/components/schemas/ProductError' - emulator: - title: SignalResponseEmulator - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/EmulatorResult' - error: - $ref: '#/components/schemas/ProductError' - clonedApp: - title: SignalResponseClonedApp - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/ClonedAppResult' - error: - $ref: '#/components/schemas/ProductError' - factoryReset: - title: SignalResponseFactoryReset - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/FactoryResetResult' - error: - $ref: '#/components/schemas/ProductError' - jailbroken: - title: SignalResponseJailbroken - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/JailbrokenResult' - error: - $ref: '#/components/schemas/ProductError' - frida: - title: SignalResponseFrida - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/FridaResult' - error: - $ref: '#/components/schemas/ProductError' - ipBlocklist: - title: SignalResponseIpBlocklist - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/IpBlockListResult' - error: - $ref: '#/components/schemas/ProductError' - tor: - title: SignalResponseTor - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/TorResult' - error: - $ref: '#/components/schemas/ProductError' - privacySettings: - title: SignalResponsePrivacySettings - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/PrivacySettingsResult' - error: - $ref: '#/components/schemas/ProductError' - virtualMachine: - title: SignalResponseVirtualMachine - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/VirtualMachineResult' - error: - $ref: '#/components/schemas/ProductError' - vpn: - title: SignalResponseVpn - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/VpnResult' - error: - $ref: '#/components/schemas/ProductError' - proxy: - title: SignalResponseProxy - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/ProxyResult' - error: - $ref: '#/components/schemas/ProductError' - tampering: - title: SignalResponseTampering - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/TamperingResult' - error: - $ref: '#/components/schemas/IdentificationError' - highActivity: - title: SignalResponseHighActivity - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/HighActivityResult' - error: - $ref: '#/components/schemas/ProductError' - locationSpoofing: - title: SignalResponseLocationSpoofing - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/LocationSpoofingResult' - error: - $ref: '#/components/schemas/ProductError' - suspectScore: - title: SignalResponseSuspectScore - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/SuspectScoreResult' - error: - $ref: '#/components/schemas/ProductError' - rawDeviceAttributes: - title: SignalResponseRawDeviceAttributes - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/RawDeviceAttributesResult' - error: - $ref: '#/components/schemas/IdentificationError' - remoteControl: - title: SignalResponseRemoteControl - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/RemoteControlResult' - error: - $ref: '#/components/schemas/ProductError' - velocity: - title: SignalResponseVelocity - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/VelocityResult' - error: - $ref: '#/components/schemas/ProductError' - developerTools: - title: SignalResponseDeveloperTools - type: object - additionalProperties: false - properties: - data: - $ref: '#/components/schemas/DeveloperToolsResult' - error: - $ref: '#/components/schemas/ProductError' - EventResponse: - description: Contains results from all activated products - Fingerprint Pro, Bot Detection, and others. - type: object - additionalProperties: false - properties: - products: - $ref: '#/components/schemas/ProductsResponse' - error: - $ref: '#/components/schemas/ProductError' - required: - - products - IdentificationError: - type: object - additionalProperties: false - properties: - code: - type: string - description: > - Error code: - * `429 Too Many Requests` - the limit on secret API key requests per second has been exceeded - * `Failed` - internal server error - enum: - - '429 Too Many Requests' - - Failed - example: '429 Too Many Requests' - message: - type: string - example: 'too many requests' - required: - - code - - message - BotdResult: - type: object - additionalProperties: false - description: Contains all the information from Bot Detection product - properties: - ip: - type: string - format: ipv4 - example: '8.8.8.8' - description: IP address of the requesting browser or bot. - time: - title: Time - description: Time in UTC when the request from the JS agent was made. We recommend to treat requests that are older than 2 minutes as malicious. Otherwise, request replay attacks are possible - type: string - format: date-time - example: '2022-06-09T22:58:36Z' - url: - description: Page URL from which identification request was sent. - type: string - example: 'https://example.com/login' - userAgent: - type: string - example: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36' - requestId: - type: string - example: '1681392853693.lRiBBD' - linkedId: - type: string - example: 'Automatic tests bot' - bot: - $ref: '#/components/schemas/BotdDetectionResult' - required: - - bot - - url - - ip - - time - - userAgent - - requestId - BotdDetectionResult: - type: object - additionalProperties: false - description: Stores bot detection result - properties: - result: - type: string - description: > - Bot detection result: - * `notDetected` - the visitor is not a bot - * `good` - good bot detected, such as Google bot, Baidu Spider, AlexaBot and so on - * `bad` - bad bot detected, such as Selenium, Puppeteer, Playwright, headless browsers, and so on - enum: - - notDetected - - good - - bad - example: 'bad' - type: - type: string - example: 'selenium' - required: - - result - IpInfoResult: - type: object - description: Details about the request IP address. Has separate fields for v4 and v6 IP address versions. - additionalProperties: false - properties: - v4: - type: object - additionalProperties: false - properties: - address: - type: string - format: ipv4 - example: '94.142.239.124' - geolocation: - $ref: '#/components/schemas/IPLocation' - asn: - $ref: '#/components/schemas/ASN' - datacenter: - $ref: '#/components/schemas/DataCenter' - required: - - address - - geolocation - v6: - type: object - additionalProperties: false - properties: - address: - type: string - format: ipv6 - example: '2001:0db8:85a3:0000:0000:8a2e:0370:7334' - geolocation: - $ref: '#/components/schemas/IPLocation' - asn: - $ref: '#/components/schemas/ASN' - datacenter: - $ref: '#/components/schemas/DataCenter' - required: - - address - - geolocation - IpBlockListResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if request IP address is part of any database that we use to search for known malicious actors, `false` otherwise. - example: false - details: - type: object - additionalProperties: false - properties: - emailSpam: - type: boolean - description: IP address was part of a known email spam attack (SMTP). - example: false - attackSource: - type: boolean - description: IP address was part of a known network attack (SSH/HTTPS). - example: false - required: - - emailSpam - - attackSource - required: - - result - - details - VpnResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: VPN or other anonymizing service has been used when sending the request. - example: false - originTimezone: - type: string - description: Local timezone which is used in timezoneMismatch method. - example: 'Europe/Berlin' - originCountry: - type: string - description: Country of the request (only for Android SDK version >= 2.4.0, ISO 3166 format or unknown). - example: 'unknown' - methods: - type: object - additionalProperties: false - properties: - timezoneMismatch: - type: boolean - description: The browser timezone doesn't match the timezone inferred from the request IP address. - example: false - publicVPN: - type: boolean - description: Request IP address is owned and used by a public VPN service provider. - example: false - auxiliaryMobile: - type: boolean - description: This method applies to mobile devices only. Indicates the result of additional methods used to detect a VPN in mobile devices. - example: false - osMismatch: - type: boolean - description: The browser runs on a different operating system than the operating system inferred from the request network signature. - example: false - required: - - timezoneMismatch - - publicVPN - - auxiliaryMobile - - osMismatch - required: - - result - - originTimezone - - methods - TamperingResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: Flag indicating whether browser tampering was detected according to our internal thresholds. - example: false - anomalyScore: - type: number - description: Confidence score (`0.0 - 1.0`) for the tampering detection. Values above `0.5` suggest that we're reasonably sure there was a tampering attempt. Values below `0.5` are genuine browsers. - example: 0 - minimum: 0 - maximum: 1 - required: - - result - - anomalyScore - HighActivityResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: Flag indicating whether the request came from a high activity visitor. - example: false - dailyRequests: - type: number - description: Number of requests from the same visitor in the previous day. - example: 10 - minimum: 1 - required: - - result - LocationSpoofingResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: Flag indicating whether the request came from a mobile device with location spoofing enabled. - example: false - required: - - result - SuspectScoreResult: - type: object - additionalProperties: false - properties: - result: - type: integer - description: > - Suspect Score is an easy way to integrate Smart Signals into your fraud protection work flow. - It is a weighted representation of all Smart Signals present in the payload that helps identify suspicious activity. - The value range is [0; S] where S is sum of all Smart Signals weights. - See more details here: https://dev.fingerprint.com/docs/suspect-score - example: 0 - required: - - result - VelocityResult: - type: object - description: > - Sums key data points for a specific `visitorId` at three distinct time intervals: 5 minutes, 1 hour, and 24 hours as follows: - - - Number of identification events attributed to the visitor ID - - Number of distinct IP addresses associated to the visitor ID. - - Number of distinct countries associated with the visitor ID. - - Number of distinct `linkedId`s associated with the visitor ID. - - The `24h` interval of `distinctIp`, `distinctLinkedId`, and `distinctCountry` will be omitted if the number of `events` for the visitor ID in the last 24 hours (`events.intervals.['24h']`) is higher than 20.000. - - additionalProperties: false - properties: - distinctIp: - $ref: '#/components/schemas/VelocityIntervals' - distinctLinkedId: - $ref: '#/components/schemas/VelocityIntervals' - distinctCountry: - $ref: '#/components/schemas/VelocityIntervals' - events: - $ref: '#/components/schemas/VelocityIntervals' - required: - - distinctIp - - distinctLinkedId - - distinctCountry - - events - RawDeviceAttributesResult: - type: object - description: > - It includes 35+ raw browser identification attributes to provide Fingerprint users with even more information than our standard visitor ID provides. - This enables Fingerprint users to not have to run our open-source product in conjunction with Fingerprint Pro Plus and Enterprise to get those additional attributes. - - Warning: The raw signals data can change at any moment as we improve the product. We cannot guarantee the internal shape of raw device attributes to be stable, so typical semantic versioning rules do not apply here. Use this data with caution without assuming a specific structure beyond the generic type provided here. - additionalProperties: - type: object - properties: - error: - properties: - name: - title: error.name - type: string - message: - title: error.message - type: string - required: - - name - - message - title: error - type: object - value: - title: value - FactoryResetResult: - type: object - additionalProperties: false - properties: - time: - description: | - Indicates the time (in UTC) of the most recent factory reset that happened on the **mobile device**. - 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). - See [Factory Reset Detection](https://dev.fingerprint.com/docs/smart-signals-overview#factory-reset-detection) to learn more about this Smart Signal. - type: string - format: date-time - example: '2022-06-09T22:58:36Z' - timestamp: - description: | - This field is just another representation of the value in the `time` field. - The time of the most recent factory reset that happened on the **mobile device** is expressed as Unix epoch time. - type: integer - format: int64 - example: 1654815517198 - required: - - time - - timestamp - ClonedAppResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - 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. - example: false - required: - - result - EmulatorResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - 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. - example: false - required: - - result - RootAppsResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - Android specific root management apps detection. There are 2 values: - • `true` - Root Management Apps detected (e.g. Magisk) - • `false` - No Root Management Apps detected or the client isn't Android. - example: false - required: - - result - IncognitoResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if we detected incognito mode used in the browser, `false` otherwise. - example: false - required: - - result - JailbrokenResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - iOS specific jailbreak detection. There are 2 values: - • `true` - Jailbreak detected - • `false` - No signs of jailbreak or the client is not iOS. - example: false - required: - - result - FridaResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - [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. - example: false - required: - - result - TorResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if the request IP address is a known tor exit node, `false` otherwise. - example: false - required: - - result - PrivacySettingsResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if the request is from a privacy aware browser (e.g. Tor) or from a browser in which fingerprinting is blocked. Otherwise `false`. - example: false - required: - - result - VirtualMachineResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if the request came from a browser running inside a virtual machine (e.g. VMWare), `false` otherwise. - example: false - required: - - result - ProxyResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if the request IP address is used by a public proxy provider, `false` otherwise. - example: false - required: - - result - ProductError: - type: object - additionalProperties: false - properties: - code: - type: string - description: > - Error code: - * `TooManyRequests` - the limit on secret API key requests per second has been exceeded - * `Failed` - internal server error - enum: - - TooManyRequests - - Failed - example: 'TooManyRequests' - message: - type: string - example: 'too many requests' - required: - - code - - message - RemoteControlResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if the request came from a machine being remotely controlled (e.g. TeamViewer), `false` otherwise. - example: false - required: - - result - DeveloperToolsResult: - type: object - additionalProperties: false - properties: - result: - type: boolean - description: > - `true` if the browser is Chrome with DevTools open or Firefox with Developer Tools open, `false` otherwise. - example: false - required: - - result - EventUpdateRequest: - type: object - properties: - linkedId: - type: string - description: LinkedID value to assign to the existing event - tag: - type: object - description: Full `tag` value to be set to the existing event. Replaces any existing `tag` payload completely. - suspect: - type: boolean - description: Suspect flag indicating observed suspicious or fraudulent event - ErrorUpdateEvent400Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - title: ErrorUpdateEvent400ResponseError - properties: - code: - type: string - description: > - Error code: - * `RequestCannotBeParsed` - the JSON content of the request contains some errors that prevented us from parsing it (wrong type/surpassed limits) - * `Failed` - the event is more than 10 days old and cannot be updated - enum: - - RequestCannotBeParsed - - Failed - example: 'RequestCannotBeParsed' - message: - type: string - description: Details about the underlying issue with the input payload - example: 'suspect flag must be a boolean' - required: - - code - - message - ErrorUpdateEvent409Response: - type: object - additionalProperties: false - properties: - error: - type: 'object' - additionalProperties: false - title: ErrorUpdateEvent409ResponseError - properties: - code: - type: string - description: > - Error code: - * `StateNotReady` - The event specified with request id is not ready for updates yet. Try again. - - This error happens in rare cases when update API is called immediately after receiving the request id on the client. In case you need to send information right away, we recommend using the JS agent API instead. - enum: - - StateNotReady - example: 'StateNotReady' - message: - type: string - example: 'resource is not mutable yet, try again' - required: - - code - - message - VelocityIntervals: - type: object - additionalProperties: false - properties: - 'intervals': - $ref: '#/components/schemas/VelocityIntervalResult' - VelocityIntervalResult: - type: object - description: > - Is absent if the velocity data could not be generated for the visitor ID. - additionalProperties: false - properties: - '5m': - type: integer - example: 1 - '1h': - type: integer - example: 1 - '24h': - type: integer - description: > - The `24h` interval of `distinctIp`, `distinctLinkedId`, and `distinctCountry` will be omitted if the number of `events`` for the visitor ID in the last 24 hours (`events.intervals.['24h']`) is higher than 20.000. - example: 1 - required: - - 5m - - 1h - diff --git a/schemas/paths/events.yaml b/schemas/paths/events.yaml new file mode 100644 index 00000000..85dbeac3 --- /dev/null +++ b/schemas/paths/events.yaml @@ -0,0 +1,131 @@ +get: + tags: + - Events + operationId: 'getEvent' + summary: Get event by request ID + description: | + Get a detailed analysis of an individual identification event, including Smart Signals. + Please note that the response includes mobile signals (e.g. `rootApps`) even if the request originated from a non-mobile platform. + It is highly recommended that you **ignore** the mobile signals for such requests. + + Use `requestId` as the URL path parameter. This API method is scoped to a request, i.e. all returned information is by `requestId`. + parameters: + - name: request_id + in: path + description: The unique [identifier](https://dev.fingerprint.com/docs/js-agent#requestid) of each identification request. + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../components/schemas/EventResponse.yaml' + examples: + fullResponse: + summary: Example response + externalValue: 'examples/get_event_200.json' + allErrorsResponse: + summary: All failed signals + externalValue: 'examples/get_event_200_all_errors.json' + withBotdError: + summary: BotD error + externalValue: 'examples/get_event_200_botd_failed_error.json' + withBotdTooManyRequestsError: + summary: BotD too many requests error + externalValue: 'examples/get_event_200_botd_too_many_requests_error.json' + withIdentificationError: + summary: Identification error + externalValue: 'examples/get_event_200_identification_failed_error.json' + withIdentificationTooManyRequestsError: + summary: Identification too many requests error + externalValue: 'examples/get_event_200_identification_too_many_requests_error.json' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '../components/schemas/ErrorCommon403Response.yaml' + examples: + example: + summary: Forbidden + externalValue: 'examples/get_event_403_error.json' + '404': + description: Not found + content: + application/json: + schema: + $ref: '../components/schemas/ErrorEvent404Response.yaml' + examples: + example: + summary: Not found + externalValue: 'examples/get_event_404_error.json' +put: + tags: + - Events + operationId: 'updateEvent' + summary: Update an event with a given request ID + description: | + Change information in existing events specified by `requestId` or *flag suspicious events*. + + When an event is created, it is assigned `linkedId` and `tag` submitted through the JS agent parameters. This information might not be available on the client so the Server API allows for updating the attributes after the fact. + + **Warning** It's not possible to update events older than 10 days. + parameters: + - name: request_id + in: path + description: The unique event [identifier](https://dev.fingerprint.com/docs/js-agent#requestid). + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '../components/schemas/EventUpdateRequest.yaml' + responses: + '200': + description: OK + '400': + description: Bad request + content: + application/json: + schema: + $ref: '../components/schemas/ErrorUpdateEvent400Response.yaml' + examples: + example: + summary: Example response + externalValue: 'examples/update_event_400_error.json' + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '../components/schemas/ErrorCommon403Response.yaml' + examples: + example: + summary: Example response + externalValue: 'examples/update_event_403_error.json' + '404': + description: Not found + content: + application/json: + schema: + $ref: '../components/schemas/ErrorEvent404Response.yaml' + examples: + example: + summary: Example response + externalValue: 'examples/get_event_404_error.json' + '409': + description: Conflict + content: + application/json: + schema: + $ref: '../components/schemas/ErrorUpdateEvent409Response.yaml' + examples: + example: + summary: Example response + externalValue: 'examples/update_event_409_error.json' diff --git a/examples/get_event_200.json b/schemas/paths/examples/get_event_200.json similarity index 100% rename from examples/get_event_200.json rename to schemas/paths/examples/get_event_200.json diff --git a/examples/get_event_200_all_errors.json b/schemas/paths/examples/get_event_200_all_errors.json similarity index 100% rename from examples/get_event_200_all_errors.json rename to schemas/paths/examples/get_event_200_all_errors.json diff --git a/examples/get_event_200_botd_failed_error.json b/schemas/paths/examples/get_event_200_botd_failed_error.json similarity index 100% rename from examples/get_event_200_botd_failed_error.json rename to schemas/paths/examples/get_event_200_botd_failed_error.json diff --git a/examples/get_event_200_botd_too_many_requests_error.json b/schemas/paths/examples/get_event_200_botd_too_many_requests_error.json similarity index 100% rename from examples/get_event_200_botd_too_many_requests_error.json rename to schemas/paths/examples/get_event_200_botd_too_many_requests_error.json diff --git a/examples/get_event_200_extra_fields.json b/schemas/paths/examples/get_event_200_extra_fields.json similarity index 100% rename from examples/get_event_200_extra_fields.json rename to schemas/paths/examples/get_event_200_extra_fields.json diff --git a/examples/get_event_200_identification_failed_error.json b/schemas/paths/examples/get_event_200_identification_failed_error.json similarity index 100% rename from examples/get_event_200_identification_failed_error.json rename to schemas/paths/examples/get_event_200_identification_failed_error.json diff --git a/examples/get_event_200_identification_too_many_requests_error.json b/schemas/paths/examples/get_event_200_identification_too_many_requests_error.json similarity index 100% rename from examples/get_event_200_identification_too_many_requests_error.json rename to schemas/paths/examples/get_event_200_identification_too_many_requests_error.json diff --git a/examples/get_event_200_identification_too_many_requests_error_all_fields.json b/schemas/paths/examples/get_event_200_identification_too_many_requests_error_all_fields.json similarity index 100% rename from examples/get_event_200_identification_too_many_requests_error_all_fields.json rename to schemas/paths/examples/get_event_200_identification_too_many_requests_error_all_fields.json diff --git a/examples/get_event_403_error.json b/schemas/paths/examples/get_event_403_error.json similarity index 100% rename from examples/get_event_403_error.json rename to schemas/paths/examples/get_event_403_error.json diff --git a/examples/get_event_404_error.json b/schemas/paths/examples/get_event_404_error.json similarity index 100% rename from examples/get_event_404_error.json rename to schemas/paths/examples/get_event_404_error.json diff --git a/examples/get_visits_200_limit_1.json b/schemas/paths/examples/get_visits_200_limit_1.json similarity index 100% rename from examples/get_visits_200_limit_1.json rename to schemas/paths/examples/get_visits_200_limit_1.json diff --git a/examples/get_visits_200_limit_500.json b/schemas/paths/examples/get_visits_200_limit_500.json similarity index 100% rename from examples/get_visits_200_limit_500.json rename to schemas/paths/examples/get_visits_200_limit_500.json diff --git a/examples/get_visits_403_error.json b/schemas/paths/examples/get_visits_403_error.json similarity index 100% rename from examples/get_visits_403_error.json rename to schemas/paths/examples/get_visits_403_error.json diff --git a/examples/get_visits_429_too_many_requests_error.json b/schemas/paths/examples/get_visits_429_too_many_requests_error.json similarity index 100% rename from examples/get_visits_429_too_many_requests_error.json rename to schemas/paths/examples/get_visits_429_too_many_requests_error.json diff --git a/examples/related-visitors/get_related_visitors_200.json b/schemas/paths/examples/related-visitors/get_related_visitors_200.json similarity index 100% rename from examples/related-visitors/get_related_visitors_200.json rename to schemas/paths/examples/related-visitors/get_related_visitors_200.json diff --git a/examples/related-visitors/get_related_visitors_200_empty.json b/schemas/paths/examples/related-visitors/get_related_visitors_200_empty.json similarity index 100% rename from examples/related-visitors/get_related_visitors_200_empty.json rename to schemas/paths/examples/related-visitors/get_related_visitors_200_empty.json diff --git a/examples/shared/400_error_empty_visitor_id.json b/schemas/paths/examples/shared/400_error_empty_visitor_id.json similarity index 100% rename from examples/shared/400_error_empty_visitor_id.json rename to schemas/paths/examples/shared/400_error_empty_visitor_id.json diff --git a/examples/shared/400_error_incorrect_visitor_id.json b/schemas/paths/examples/shared/400_error_incorrect_visitor_id.json similarity index 100% rename from examples/shared/400_error_incorrect_visitor_id.json rename to schemas/paths/examples/shared/400_error_incorrect_visitor_id.json diff --git a/examples/shared/403_error_feature_not_enabled.json b/schemas/paths/examples/shared/403_error_feature_not_enabled.json similarity index 100% rename from examples/shared/403_error_feature_not_enabled.json rename to schemas/paths/examples/shared/403_error_feature_not_enabled.json diff --git a/examples/shared/403_error_token_not_found.json b/schemas/paths/examples/shared/403_error_token_not_found.json similarity index 100% rename from examples/shared/403_error_token_not_found.json rename to schemas/paths/examples/shared/403_error_token_not_found.json diff --git a/examples/shared/403_error_token_required.json b/schemas/paths/examples/shared/403_error_token_required.json similarity index 100% rename from examples/shared/403_error_token_required.json rename to schemas/paths/examples/shared/403_error_token_required.json diff --git a/examples/shared/403_error_wrong_region.json b/schemas/paths/examples/shared/403_error_wrong_region.json similarity index 100% rename from examples/shared/403_error_wrong_region.json rename to schemas/paths/examples/shared/403_error_wrong_region.json diff --git a/examples/shared/404_error_visitor_not_found.json b/schemas/paths/examples/shared/404_error_visitor_not_found.json similarity index 100% rename from examples/shared/404_error_visitor_not_found.json rename to schemas/paths/examples/shared/404_error_visitor_not_found.json diff --git a/examples/shared/429_error_too_many_requests.json b/schemas/paths/examples/shared/429_error_too_many_requests.json similarity index 100% rename from examples/shared/429_error_too_many_requests.json rename to schemas/paths/examples/shared/429_error_too_many_requests.json diff --git a/examples/update_event_400_error.json b/schemas/paths/examples/update_event_400_error.json similarity index 100% rename from examples/update_event_400_error.json rename to schemas/paths/examples/update_event_400_error.json diff --git a/examples/update_event_403_error.json b/schemas/paths/examples/update_event_403_error.json similarity index 100% rename from examples/update_event_403_error.json rename to schemas/paths/examples/update_event_403_error.json diff --git a/examples/update_event_404_error.json b/schemas/paths/examples/update_event_404_error.json similarity index 100% rename from examples/update_event_404_error.json rename to schemas/paths/examples/update_event_404_error.json diff --git a/examples/update_event_409_error.json b/schemas/paths/examples/update_event_409_error.json similarity index 100% rename from examples/update_event_409_error.json rename to schemas/paths/examples/update_event_409_error.json diff --git a/examples/update_event_multiple_fields_request.json b/schemas/paths/examples/update_event_multiple_fields_request.json similarity index 100% rename from examples/update_event_multiple_fields_request.json rename to schemas/paths/examples/update_event_multiple_fields_request.json diff --git a/examples/update_event_one_field_request.json b/schemas/paths/examples/update_event_one_field_request.json similarity index 100% rename from examples/update_event_one_field_request.json rename to schemas/paths/examples/update_event_one_field_request.json diff --git a/examples/webhook.json b/schemas/paths/examples/webhook.json similarity index 100% rename from examples/webhook.json rename to schemas/paths/examples/webhook.json diff --git a/schemas/paths/related-visitors.yaml b/schemas/paths/related-visitors.yaml new file mode 100644 index 00000000..053a05bd --- /dev/null +++ b/schemas/paths/related-visitors.yaml @@ -0,0 +1,82 @@ +get: + tags: + - Related Visitors + operationId: 'getRelatedVisitors' + summary: Get Related Visitors + description: | + This API will enable you to find if one or more web and in-app browser sessions originated from the same mobile device. + When requested, this API will search identification events within the past 6 months to find the visitor IDs that belong to the same mobile device as the given visitor ID. + Please visit the [Overview](https://dev.fingerprint.com/reference/related-visitors-api) page to learn more about this API. + parameters: + - name: visitor_id + description: The [visitor ID](https://dev.fingerprint.com/docs/js-agent#visitorid) for which you want to find the other visitor IDs that originated from the same mobile device. + in: query + required: true + schema: + type: string + responses: + '200': + description: OK. + content: + application/json: + schema: + $ref: '../components/schemas/RelatedVisitorsResponse.yaml' + examples: + 200-success-empty-response: + summary: Success, empty response + externalValue: 'examples/related-visitors/get_related_visitors_200_empty.json' + 200-success-response: + summary: Success response + externalValue: 'examples/related-visitors/get_related_visitors_200.json' + '400': + description: Bad request. The visitor ID parameter is missing or in the wrong format. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorVisitor400Response.yaml' + examples: + 400-empty-visitor-id: + summary: Error response when the request does not include a visitor ID + externalValue: 'examples/shared/400_error_empty_visitor_id.json' + 400-invalid-visitor-id: + summary: Error response when the visitor ID is incorrectly formatted + externalValue: 'examples/shared/400_error_incorrect_visitor_id.json' + '403': + description: Forbidden. Access to this API is denied. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorCommon403Response.yaml' + examples: + 403-feature-not-enabled: + summary: Error response when this feature is not enabled for a subscription. + externalValue: 'examples/shared/403_error_feature_not_enabled.json' + 403-token-not-found: + summary: Error response when the provided secret API key does not exist. + externalValue: 'examples/shared/403_error_token_not_found.json' + 403-token-required: + summary: Error response when the secret API key was not provided. + externalValue: 'examples/shared/403_error_token_required.json' + 403-wrong-region: + summary: Error response when the API region is different from the region, the calling application is configured with. + externalValue: 'examples/shared/403_error_wrong_region.json' + '404': + description: Not found. The visitor ID cannot be found in this application's data. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorVisitor404Response.yaml' + examples: + 404-visitor-not-found: + summary: Error response when the visitor ID cannot be found in this application's data. + externalValue: 'examples/shared/404_error_visitor_not_found.json' + '429': + description: Too Many Requests. The request is throttled. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorCommon429Response.yaml' + examples: + example: + summary: Too Many Requests + externalValue: 'examples/shared/429_error_too_many_requests.json' diff --git a/schemas/paths/visitors.yaml b/schemas/paths/visitors.yaml new file mode 100644 index 00000000..783a6d82 --- /dev/null +++ b/schemas/paths/visitors.yaml @@ -0,0 +1,212 @@ +get: + tags: + - Visitors + operationId: 'getVisits' + summary: Get visits by visitor ID + description: | + Get a history of visits (identification events) for a specific `visitorId`. Use the `visitorId` as a URL path parameter. + Only information from the _Identification_ product is returned. + + #### Headers + + * `Retry-After` — Present in case of `429 Too many requests`. Indicates how long you should wait before making a follow-up request. The value is non-negative decimal integer indicating the seconds to delay after the response is received. + parameters: + - name: visitor_id + description: Unique [visitor identifier](https://dev.fingerprint.com/docs/js-agent#visitorid) issued by Fingerprint Pro. + in: path + required: true + schema: + type: string + example: uYIm7Ksp5rf00SllPhFp + - name: request_id + description: | + Filter visits by `requestId`. + + Every identification request has a unique identifier associated with it called `requestId`. This identifier is returned to the client in the identification [result](https://dev.fingerprint.com/docs/js-agent#requestid). When you filter visits by `requestId`, only one visit will be returned. + in: query + schema: + type: string + # example: 1654815516083.OX6kx8 + - name: linked_id + description: | + Filter visits by your custom identifier. + + You can use [`linkedId`](https://dev.fingerprint.com/docs/js-agent#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. + in: query + schema: + type: string + required: + false + # example: some_id + - name: limit + description: | + Limit scanned results. + + For performance reasons, the API first scans some number of events before filtering them. Use `limit` to specify how many events are scanned before they are filtered by `requestId` or `linkedId`. Results are always returned sorted by the timestamp (most recent first). + By default, the most recent 100 visits are scanned, the maximum is 500. + in: query + schema: + type: integer + format: int32 + minimum: 0 + # default: 0 + # example: 10 + - name: paginationKey + description: | + Use `paginationKey` to get the next page of results. + + When more results are available (e.g., you requested 200 results using `limit` parameter, but a total of 600 results are available), the `paginationKey` top-level attribute is added to the response. The key corresponds to the `requestId` of the last returned event. In the following request, use that value in the `paginationKey` parameter to get the next page of results: + + 1. First request, returning most recent 200 events: `GET api-base-url/visitors/:visitorId?limit=200` + 2. Use `response.paginationKey` to get the next page of results: `GET api-base-url/visitors/:visitorId?limit=200&paginationKey=1683900801733.Ogvu1j` + + Pagination happens during scanning and before filtering, so you can get less visits than the `limit` you specified with more available on the next page. When there are no more results available for scanning, the `paginationKey` attribute is not returned. + in: query + schema: + type: string + required: + false + # example: 1683900801733.Ogvu1j + - name: before + description: | + ⚠️ Deprecated pagination method, please use `paginationKey` instead. Timestamp (in milliseconds since epoch) used to paginate results. + in: query + schema: + type: integer + format: int64 + minimum: 0 + # default: 0 + # example: 1654815517198 + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../components/schemas/Response.yaml' + examples: + limit1: + summary: Example response with limit=1 + externalValue: '/examples/get_visits_200_limit_1.json' + limit500: + summary: Example response with limit=500 + externalValue: '/examples/get_visits_200_limit_500.json' + '403': + description: Forbidden. The API Key is probably missing or incorrect. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorVisits403.yaml' + examples: + example: + summary: Forbidden + externalValue: 'examples/get_visits_403_error.json' + '429': + description: Too Many Requests + headers: + Retry-After: + description: Indicates how many seconds you should wait before attempting the next request. + schema: + type: integer + format: int32 + minimum: 0 + content: + application/json: + schema: + $ref: '../components/schemas/TooManyRequestsResponse.yaml' + examples: + example: + summary: Too Many Requests + externalValue: 'examples/get_visits_429_too_many_requests_error.json' +delete: + tags: + - Visitors + operationId: 'deleteVisitorData' + summary: Delete data by visitor ID + description: | + Request deleting all data associated with the specified visitor ID. This API is useful for compliance with privacy regulations. + ### Which data is deleted? + - Browser (or device) properties + - Identification requests made from this browser (or device) + + #### Browser (or device) properties + - Represents the data that Fingerprint collected from this specific browser (or device) and everything inferred and derived from it. + - Upon request to delete, this data is deleted asynchronously (typically within a few minutes) and it will no longer be used to identify this browser (or device) for your [Fingerprint Application](https://dev.fingerprint.com/docs/glossary#fingerprint-application). + + #### Identification requests made from this browser (or device) + - Fingerprint stores the identification requests made from a browser (or device) for up to 30 (or 90) days depending on your plan. To learn more, see [Data Retention](https://dev.fingerprint.com/docs/regions#data-retention). + - Upon request to delete, the identification requests that were made by this browser + - Within the past 10 days are deleted within 24 hrs. + - Outside of 10 days are allowed to purge as per your data retention period. + + ### Corollary + After requesting to delete a visitor ID, + - If the same browser (or device) requests to identify, it will receive a different visitor ID. + - If you request [`/events` API](https://dev.fingerprint.com/reference/getevent) with a `request_id` that was made outside of the 10 days, you will still receive a valid response. + - If you request [`/visitors` API](https://dev.fingerprint.com/reference/getvisits) for the deleted visitor ID, the response will include identification requests that were made outside of those 10 days. + + ### Interested? + Please [contact our support team](https://fingerprint.com/support/) to enable it for you. Otherwise, you will receive a 403. + parameters: + - name: visitor_id + in: path + description: The [visitor ID](https://dev.fingerprint.com/docs/js-agent#visitorid) you want to delete. + required: true + schema: + type: string + responses: + '200': + description: OK. The visitor ID is scheduled for deletion. + '400': + description: Bad request. The visitor ID parameter is missing or in the wrong format. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorVisitor400Response.yaml' + examples: + 400-empty-visitor-id: + summary: Error response when the request does not include a visitor ID + externalValue: 'examples/shared/400_error_empty_visitor_id.json' + 400-invalid-visitor-id: + summary: Error response when the visitor ID is incorrectly formatted + externalValue: 'examples/shared/400_error_incorrect_visitor_id.json' + '403': + description: Forbidden. Access to this API is denied. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorCommon403Response.yaml' + examples: + 403-feature-not-enabled: + summary: Error response when this feature is not enabled for a subscription. + externalValue: 'examples/shared/403_error_feature_not_enabled.json' + 403-token-not-found: + summary: Error response when the provided secret API key does not exist. + externalValue: 'examples/shared/403_error_token_not_found.json' + 403-token-required: + summary: Error response when the secret API key was not provided. + externalValue: 'examples/shared/403_error_token_required.json' + 403-wrong-region: + summary: Error response when the API region is different from the region, the calling application is configured with. + externalValue: 'examples/shared/403_error_wrong_region.json' + + '404': + description: Not found. The visitor ID cannot be found in this application's data. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorVisitor404Response.yaml' + examples: + example: + summary: Not found + externalValue: 'examples/shared/404_error_visitor_not_found.json' + '429': + description: Too Many Requests. The request is throttled. + content: + application/json: + schema: + $ref: '../components/schemas/ErrorCommon429Response.yaml' + examples: + example: + summary: Too Many Requests + externalValue: 'examples/shared/429_error_too_many_requests.json' diff --git a/schemas/paths/webhook.yaml b/schemas/paths/webhook.yaml new file mode 100644 index 00000000..e9787f93 --- /dev/null +++ b/schemas/paths/webhook.yaml @@ -0,0 +1,22 @@ +trace: + tags: + - Fingerprint + description: Fake path to describe webhook format. More information about webhooks can be found in the [documentation](https://dev.fingerprint.com/docs/webhooks) + responses: + default: + description: Dummy for the schema + callbacks: + webhook: + webhook: + post: + description: You can use HTTP basic authentication and set up credentials in your [Fingerprint account](https://dashboard.fingerprint.com/login) + requestBody: + content: + application/json: + schema: + $ref: '../components/schemas/WebhookVisit.yaml' + example: + externalValue: 'examples/webhook.json' + responses: + default: + description: The server doesn't validate the answer. diff --git a/utils/mocks/components/Error.yaml b/utils/mocks/components/Error.yaml new file mode 100644 index 00000000..e83cb3fc --- /dev/null +++ b/utils/mocks/components/Error.yaml @@ -0,0 +1,25 @@ +type: object +additionalProperties: false +properties: + error: + type: 'object' + additionalProperties: false + title: ErrorUpdateEvent400ResponseError + properties: + code: + type: string + description: > + Error code: + * `RequestCannotBeParsed` - the JSON content of the request contains some errors that prevented us from parsing it (wrong type/surpassed limits) + * `Failed` - the event is more than 10 days old and cannot be updated + enum: + - RequestCannotBeParsed + - Failed + example: 'RequestCannotBeParsed' + message: + type: string + description: Details about the underlying issue with the input payload + example: 'suspect flag must be a boolean' + required: + - code + - message diff --git a/utils/mocks/components/Response.yaml b/utils/mocks/components/Response.yaml new file mode 100644 index 00000000..e542d690 --- /dev/null +++ b/utils/mocks/components/Response.yaml @@ -0,0 +1,9 @@ +type: object +additionalProperties: false +properties: + visitorId: + type: string +required: + - visitorId + - visits +title: Response diff --git a/utils/mocks/oneDependency.yaml b/utils/mocks/oneDependency.yaml index d44ab995..505f47b6 100644 --- a/utils/mocks/oneDependency.yaml +++ b/utils/mocks/oneDependency.yaml @@ -22,7 +22,7 @@ paths: examples: exampleA: summary: Example A - externalValue: '/utils/mocks/exampleA.json' + externalValue: 'exampleA.json' components: schemas: Response: diff --git a/utils/mocks/paths/visitors.yml b/utils/mocks/paths/visitors.yml new file mode 100644 index 00000000..431cdcd9 --- /dev/null +++ b/utils/mocks/paths/visitors.yml @@ -0,0 +1,21 @@ +get: + parameters: + - name: visitor_id + in: path + required: true + schema: + type: string + example: mcEozNgqhKgmfXx7ZaMW + responses: + '200': + description: Auto generated using Swagger Inspector + content: + application/json: + schema: + $ref: '../components/Response.yaml' + '500': + description: Internal errror + content: + application/json: + schema: + $ref: '../components/Error.yaml' diff --git a/utils/mocks/schemaWithExternalRef.yaml b/utils/mocks/schemaWithExternalRef.yaml new file mode 100644 index 00000000..57b4da50 --- /dev/null +++ b/utils/mocks/schemaWithExternalRef.yaml @@ -0,0 +1,7 @@ +openapi: 3.0.3 +info: + title: Fingerprint server API + version: '0.1' +paths: + /visitors/{visitor_id}: + $ref: paths/visitors.yml diff --git a/utils/mocks/schemaWithExternalRefBundled.yaml b/utils/mocks/schemaWithExternalRefBundled.yaml new file mode 100644 index 00000000..0b12a945 --- /dev/null +++ b/utils/mocks/schemaWithExternalRefBundled.yaml @@ -0,0 +1,66 @@ +openapi: 3.0.3 +info: + title: Fingerprint server API + version: '0.1' +paths: + /visitors/{visitor_id}: + get: + parameters: + - name: visitor_id + in: path + required: true + schema: + type: string + example: mcEozNgqhKgmfXx7ZaMW + responses: + '200': + description: Auto generated using Swagger Inspector + content: + application/json: + schema: + $ref: '#/components/schemas/Response' + '500': + description: Internal errror + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + Response: + type: object + additionalProperties: false + properties: + visitorId: + type: string + required: + - visitorId + - visits + title: Response + Error: + type: object + additionalProperties: false + properties: + error: + type: object + additionalProperties: false + title: ErrorUpdateEvent400ResponseError + properties: + code: + type: string + description: > + Error code: * `RequestCannotBeParsed` - the JSON content of the + request contains some errors that prevented us from parsing it + (wrong type/surpassed limits) * `Failed` - the event is more + than 10 days old and cannot be updated + enum: + - RequestCannotBeParsed + - Failed + example: RequestCannotBeParsed + message: + type: string + description: Details about the underlying issue with the input payload + example: suspect flag must be a boolean + required: + - code + - message diff --git a/utils/mocks/simpleWithXReadme.yaml b/utils/mocks/simpleWithXReadme.yaml new file mode 100644 index 00000000..44036dda --- /dev/null +++ b/utils/mocks/simpleWithXReadme.yaml @@ -0,0 +1,58 @@ +openapi: 3.0.3 +info: + title: Fingerprint server API + description: defaultDescription + version: '0.1' +servers: + - url: https://api.fpjs.io + description: Global +paths: + /visitors/{visitor_id}: + get: + parameters: + - name: visitor_id + in: path + required: true + schema: + type: string + example: mcEozNgqhKgmfXx7ZaMW + responses: + '200': + description: Auto generated using Swagger Inspector + content: + application/json: + schema: + $ref: '#/components/schemas/Response' + x-readme: + code-samples: + - language: node + name: Node SDK + install: npm install @fingerprintjs/fingerprintjs-pro-server-api + code: | + import { + FingerprintJsServerApiClient, + Region, + } from '@fingerprintjs/fingerprintjs-pro-server-api' + + const client = new FingerprintJsServerApiClient({ + apiKey: 'SERVER_API_KEY', // Replace with your key + region: Region.Global, // Replace with your region + }) + + // Get visit history of a specific visitor + client.getVisitorHistory('VISITOR_ID').then((visitorHistory) => { + console.log(visitorHistory) + }) +components: + schemas: + Response: + type: object + additionalProperties: false + properties: + visitorId: + type: string + example: null + required: + - visitorId + - visits + title: Response diff --git a/utils/mocks/twoDependency.yaml b/utils/mocks/twoDependency.yaml index 4e43f372..c2b7bf30 100644 --- a/utils/mocks/twoDependency.yaml +++ b/utils/mocks/twoDependency.yaml @@ -22,10 +22,10 @@ paths: examples: exampleA: summary: Example A - externalValue: '/utils/mocks/exampleA.json' + externalValue: 'exampleA.json' exampleB: summary: Example B - externalValue: '/utils/mocks/exampleB.json' + externalValue: 'exampleB.json' components: schemas: Response: diff --git a/utils/mocks/x-readme/oneMethod.yaml b/utils/mocks/x-readme/oneMethod.yaml new file mode 100644 index 00000000..d9c26c5e --- /dev/null +++ b/utils/mocks/x-readme/oneMethod.yaml @@ -0,0 +1,22 @@ +/visitors/{visitor_id}: + get: + x-readme: + code-samples: + - language: node + name: Node SDK + install: npm install @fingerprintjs/fingerprintjs-pro-server-api + code: | + import { + FingerprintJsServerApiClient, + Region, + } from '@fingerprintjs/fingerprintjs-pro-server-api' + + const client = new FingerprintJsServerApiClient({ + apiKey: 'SERVER_API_KEY', // Replace with your key + region: Region.Global, // Replace with your region + }) + + // Get visit history of a specific visitor + client.getVisitorHistory('VISITOR_ID').then((visitorHistory) => { + console.log(visitorHistory) + }) diff --git a/utils/transformers/addXReadmeTransformer.js b/utils/transformers/addXReadmeTransformer.js new file mode 100644 index 00000000..fb4acafc --- /dev/null +++ b/utils/transformers/addXReadmeTransformer.js @@ -0,0 +1,42 @@ +import yaml from 'js-yaml'; +import { readFileSync } from 'fs'; + +function loadYaml(path) { + return yaml.load(readFileSync(path, 'utf8')); +} + +/** + * + * @param {string[]} xReadmeSources + * @returns {Set