foil-server 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/spec/openapi.json CHANGED
@@ -80,6 +80,28 @@
80
80
  "type": "string",
81
81
  "example": "arm"
82
82
  }
83
+ },
84
+ {
85
+ "name": "client_user_id",
86
+ "in": "query",
87
+ "description": "Returns only sessions whose `client_user_id` is exactly this value, case-sensitive, after trimming surrounding whitespace.",
88
+ "schema": {
89
+ "type": "string",
90
+ "minLength": 1,
91
+ "maxLength": 256,
92
+ "example": "user_123"
93
+ }
94
+ },
95
+ {
96
+ "name": "client_application_id",
97
+ "in": "query",
98
+ "description": "Returns only sessions whose `client_application_id` is exactly this value, case-sensitive, after trimming surrounding whitespace.",
99
+ "schema": {
100
+ "type": "string",
101
+ "minLength": 1,
102
+ "maxLength": 256,
103
+ "example": "app_123"
104
+ }
83
105
  }
84
106
  ],
85
107
  "responses": {
@@ -96,6 +118,7 @@
96
118
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
97
119
  "created_at": "2026-03-24T20:00:00.000Z",
98
120
  "client_user_id": "user_123",
121
+ "client_application_id": "app_123",
99
122
  "latest_decision": {
100
123
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
101
124
  "verdict": "human",
@@ -273,6 +296,7 @@
273
296
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
274
297
  "created_at": "2026-03-24T20:00:00.000Z",
275
298
  "client_user_id": "user_123",
299
+ "client_application_id": "app_123",
276
300
  "decision": {
277
301
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
278
302
  "automation_status": "automated",
@@ -316,7 +340,7 @@
316
340
  "accuracy_radius_km": 10
317
341
  },
318
342
  "routing": {
319
- "asn": "64512",
343
+ "asn": "AS64512",
320
344
  "organization": "SPECTRANET LIMITED"
321
345
  },
322
346
  "anonymity": {
@@ -346,7 +370,7 @@
346
370
  "client_types": [
347
371
  "consumer"
348
372
  ],
349
- "client_count": 1
373
+ "client_count": null
350
374
  },
351
375
  "evaluated_at": "2026-03-24T20:00:05.000Z"
352
376
  },
@@ -556,7 +580,8 @@
556
580
  "lifecycle": {
557
581
  "first_seen_at": "2026-03-01T18:22:11.000Z",
558
582
  "last_seen_at": "2026-03-24T20:00:05.000Z",
559
- "seen_count": 1
583
+ "seen_count": 1,
584
+ "resolution_count": 1
560
585
  }
561
586
  },
562
587
  "connection_fingerprint": {
@@ -674,7 +699,7 @@
674
699
  "signals_fired": [
675
700
  {
676
701
  "signal": "webdriver_detected",
677
- "role": "owner",
702
+ "role": "risk",
678
703
  "category": "environment",
679
704
  "strength": "definitive",
680
705
  "signal_score": 100
@@ -711,9 +736,9 @@
711
736
  },
712
737
  "canvas": {
713
738
  "hash": 1234567890,
714
- "geometry_hash": 1234567890,
739
+ "geometry_hash": null,
715
740
  "text_hash": 1234567890,
716
- "winding": true,
741
+ "winding": null,
717
742
  "noise_detected": true,
718
743
  "offscreen_consistent": true
719
744
  },
@@ -726,6 +751,7 @@
726
751
  "parameters_hash": "01234567",
727
752
  "extensions_hash": 1234567890,
728
753
  "extension_parameters_hash": "01234567",
754
+ "webgl2_parameters_hash": "01234567",
729
755
  "shader_precision_hash": 1234567890
730
756
  },
731
757
  "webgpu": {
@@ -989,7 +1015,7 @@
989
1015
  }
990
1016
  }
991
1017
  },
992
- "description": "Set or clear the customer-supplied `client_user_id` for a session. Requires the `sessions:update` secret-key scope."
1018
+ "description": "Set or clear the customer-supplied `client_user_id`, `client_application_id`, or both for a session. At least one key is required, a key you omit keeps its current value, and `null` clears it. Requires the `sessions:update` secret-key scope."
993
1019
  }
994
1020
  },
995
1021
  "/v1/fingerprints": {
@@ -1056,23 +1082,23 @@
1056
1082
  "first_seen_at": "2026-03-01T18:22:11.000Z",
1057
1083
  "last_seen_at": "2026-03-24T20:00:05.000Z",
1058
1084
  "seen_count": 14,
1059
- "expires_at": "2026-03-24T20:00:05.000Z"
1085
+ "expires_at": "9999-12-31T00:00:00.000Z"
1060
1086
  },
1061
1087
  "latest_request": {
1062
1088
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
1063
1089
  "ip_address": "203.0.113.10"
1064
1090
  },
1065
1091
  "storage": {
1066
- "cookies": true,
1067
- "local_storage": true,
1068
- "indexed_db": true,
1069
- "service_worker": true,
1070
- "window_name": true
1092
+ "cookies": false,
1093
+ "local_storage": false,
1094
+ "indexed_db": false,
1095
+ "service_worker": false,
1096
+ "window_name": false
1071
1097
  },
1072
1098
  "anchors": {
1073
- "webgl_hash": "123456789",
1074
- "parameters_hash": "-1234567890",
1075
- "audio_hash": "1234567890"
1099
+ "webgl_hash": null,
1100
+ "parameters_hash": null,
1101
+ "audio_hash": null
1076
1102
  }
1077
1103
  }
1078
1104
  ],
@@ -1234,28 +1260,26 @@
1234
1260
  "first_seen_at": "2026-03-01T18:22:11.000Z",
1235
1261
  "last_seen_at": "2026-03-24T20:00:05.000Z",
1236
1262
  "seen_count": 14,
1237
- "expires_at": "2026-03-24T20:00:05.000Z"
1263
+ "expires_at": "9999-12-31T00:00:00.000Z"
1238
1264
  },
1239
1265
  "latest_request": {
1240
1266
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
1241
1267
  "ip_address": "203.0.113.10"
1242
1268
  },
1243
1269
  "storage": {
1244
- "cookies": true,
1245
- "local_storage": true,
1246
- "indexed_db": true,
1247
- "service_worker": true,
1248
- "window_name": true
1270
+ "cookies": false,
1271
+ "local_storage": false,
1272
+ "indexed_db": false,
1273
+ "service_worker": false,
1274
+ "window_name": false
1249
1275
  },
1250
1276
  "anchors": {
1251
- "webgl_hash": "123456789",
1252
- "parameters_hash": "-1234567890",
1253
- "audio_hash": "1234567890"
1277
+ "webgl_hash": null,
1278
+ "parameters_hash": null,
1279
+ "audio_hash": null
1254
1280
  },
1255
1281
  "components": {
1256
- "vector": [
1257
- 1.5
1258
- ]
1282
+ "vector": []
1259
1283
  },
1260
1284
  "activity": {
1261
1285
  "sessions": [
@@ -5329,11 +5353,25 @@
5329
5353
  "example": 94
5330
5354
  },
5331
5355
  "phase": {
5332
- "$ref": "#/components/schemas/Phase",
5356
+ "anyOf": [
5357
+ {
5358
+ "$ref": "#/components/schemas/Phase",
5359
+ "example": "snapshot"
5360
+ },
5361
+ {
5362
+ "type": "null",
5363
+ "example": null
5364
+ }
5365
+ ],
5366
+ "description": "Null when the decision did not record it.",
5333
5367
  "example": "snapshot"
5334
5368
  },
5335
5369
  "is_provisional": {
5336
- "type": "boolean",
5370
+ "type": [
5371
+ "boolean",
5372
+ "null"
5373
+ ],
5374
+ "description": "Null when the decision did not record it.",
5337
5375
  "example": false
5338
5376
  },
5339
5377
  "manipulation": {
@@ -5356,8 +5394,18 @@
5356
5394
  }
5357
5395
  },
5358
5396
  "evaluation_duration_ms": {
5359
- "type": "integer",
5360
- "minimum": 0,
5397
+ "anyOf": [
5398
+ {
5399
+ "type": "integer",
5400
+ "minimum": 0,
5401
+ "example": 123
5402
+ },
5403
+ {
5404
+ "type": "null",
5405
+ "example": null
5406
+ }
5407
+ ],
5408
+ "description": "Null when the decision did not record it.",
5361
5409
  "example": 123
5362
5410
  },
5363
5411
  "evaluated_at": {
@@ -5380,6 +5428,16 @@
5380
5428
  "evaluated_at": "2026-03-24T20:00:05.000Z"
5381
5429
  }
5382
5430
  },
5431
+ "DeviceClass": {
5432
+ "type": "string",
5433
+ "enum": [
5434
+ "desktop",
5435
+ "phone",
5436
+ "tablet",
5437
+ "unknown"
5438
+ ],
5439
+ "example": "desktop"
5440
+ },
5383
5441
  "Event": {
5384
5442
  "type": "object",
5385
5443
  "additionalProperties": false,
@@ -6636,6 +6694,12 @@
6636
6694
  },
6637
6695
  "engine": {
6638
6696
  "type": "string",
6697
+ "enum": [
6698
+ "blink",
6699
+ "gecko",
6700
+ "webkit",
6701
+ "unknown"
6702
+ ],
6639
6703
  "example": "blink"
6640
6704
  },
6641
6705
  "app_name": {
@@ -6707,9 +6771,9 @@
6707
6771
  "$ref": "#/components/schemas/SessionRawDeviceCanvas",
6708
6772
  "example": {
6709
6773
  "hash": 1234567890,
6710
- "geometry_hash": 1234567890,
6774
+ "geometry_hash": null,
6711
6775
  "text_hash": 1234567890,
6712
- "winding": true,
6776
+ "winding": null,
6713
6777
  "noise_detected": true,
6714
6778
  "offscreen_consistent": true
6715
6779
  }
@@ -6725,6 +6789,7 @@
6725
6789
  "parameters_hash": "01234567",
6726
6790
  "extensions_hash": 1234567890,
6727
6791
  "extension_parameters_hash": "01234567",
6792
+ "webgl2_parameters_hash": "01234567",
6728
6793
  "shader_precision_hash": 1234567890
6729
6794
  },
6730
6795
  "webgpu": {
@@ -6805,9 +6870,9 @@
6805
6870
  },
6806
6871
  "canvas": {
6807
6872
  "hash": 1234567890,
6808
- "geometry_hash": 1234567890,
6873
+ "geometry_hash": null,
6809
6874
  "text_hash": 1234567890,
6810
- "winding": true,
6875
+ "winding": null,
6811
6876
  "noise_detected": true,
6812
6877
  "offscreen_consistent": true
6813
6878
  },
@@ -6820,6 +6885,7 @@
6820
6885
  "parameters_hash": "01234567",
6821
6886
  "extensions_hash": 1234567890,
6822
6887
  "extension_parameters_hash": "01234567",
6888
+ "webgl2_parameters_hash": "01234567",
6823
6889
  "shader_precision_hash": 1234567890
6824
6890
  },
6825
6891
  "webgpu": {
@@ -6895,6 +6961,18 @@
6895
6961
  "string",
6896
6962
  "null"
6897
6963
  ],
6964
+ "enum": [
6965
+ "chrome",
6966
+ "firefox",
6967
+ "safari",
6968
+ "nodejs",
6969
+ "python",
6970
+ "go",
6971
+ "curl",
6972
+ "unknown",
6973
+ null
6974
+ ],
6975
+ "description": "Client the TLS fingerprint most resembles.",
6898
6976
  "example": "chrome"
6899
6977
  },
6900
6978
  "family": {
@@ -6902,6 +6980,19 @@
6902
6980
  "string",
6903
6981
  "null"
6904
6982
  ],
6983
+ "enum": [
6984
+ "chromium",
6985
+ "firefox",
6986
+ "webkit",
6987
+ "nodejs",
6988
+ "python",
6989
+ "go",
6990
+ "curl",
6991
+ "middlebox",
6992
+ "unknown",
6993
+ null
6994
+ ],
6995
+ "description": "TLS stack family the JA4 fingerprint matches. `middlebox` means a TLS-intercepting proxy or security appliance.",
6905
6996
  "example": "chromium"
6906
6997
  },
6907
6998
  "product": {
@@ -6916,6 +7007,14 @@
6916
7007
  "string",
6917
7008
  "null"
6918
7009
  ],
7010
+ "enum": [
7011
+ "exact",
7012
+ "strong",
7013
+ "heuristic",
7014
+ "unknown",
7015
+ null
7016
+ ],
7017
+ "description": "How closely the JA4 fingerprint matched a known client.",
6919
7018
  "example": "exact"
6920
7019
  },
6921
7020
  "match_source": {
@@ -6923,6 +7022,15 @@
6923
7022
  "string",
6924
7023
  "null"
6925
7024
  ],
7025
+ "enum": [
7026
+ "full_ja4",
7027
+ "bc_hash",
7028
+ "cipher_hash",
7029
+ "prefix",
7030
+ "unknown",
7031
+ null
7032
+ ],
7033
+ "description": "Which part of the JA4 fingerprint produced the match: the full fingerprint, the cipher and extension hashes, the cipher hash alone, or the prefix.",
6926
7034
  "example": "full_ja4"
6927
7035
  },
6928
7036
  "deterministic": {
@@ -6956,6 +7064,10 @@
6956
7064
  },
6957
7065
  "source": {
6958
7066
  "type": "string",
7067
+ "enum": [
7068
+ "master_db",
7069
+ "heuristic"
7070
+ ],
6959
7071
  "example": "master_db"
6960
7072
  },
6961
7073
  "protocol": {
@@ -7019,7 +7131,11 @@
7019
7131
  }
7020
7132
  },
7021
7133
  "sample_size": {
7022
- "type": "integer",
7134
+ "type": [
7135
+ "integer",
7136
+ "null"
7137
+ ],
7138
+ "description": "Number of observations behind the reference. Null when the source does not report one.",
7023
7139
  "example": 63
7024
7140
  },
7025
7141
  "verified": {
@@ -7122,6 +7238,19 @@
7122
7238
  "string",
7123
7239
  "null"
7124
7240
  ],
7241
+ "enum": [
7242
+ "chrome",
7243
+ "firefox",
7244
+ "safari",
7245
+ "edge",
7246
+ "nodejs",
7247
+ "python",
7248
+ "go",
7249
+ "curl",
7250
+ "unknown",
7251
+ null
7252
+ ],
7253
+ "description": "Client the HTTP/2 fingerprint most resembles.",
7125
7254
  "example": "chrome"
7126
7255
  }
7127
7256
  },
@@ -7213,6 +7342,7 @@
7213
7342
  "signals_fired",
7214
7343
  "client_telemetry",
7215
7344
  "client_user_id",
7345
+ "client_application_id",
7216
7346
  "behavior"
7217
7347
  ],
7218
7348
  "properties": {
@@ -7241,6 +7371,15 @@
7241
7371
  "description": "Customer-supplied identifier for the end user associated with this Foil session. Set with PATCH /v1/sessions/{sessionId}.",
7242
7372
  "example": "user_123"
7243
7373
  },
7374
+ "client_application_id": {
7375
+ "type": [
7376
+ "string",
7377
+ "null"
7378
+ ],
7379
+ "maxLength": 256,
7380
+ "description": "Customer-supplied identifier for the application or organization on your platform that this Foil session belongs to. Set with PATCH /v1/sessions/{sessionId}.",
7381
+ "example": "app_123"
7382
+ },
7244
7383
  "decision": {
7245
7384
  "$ref": "#/components/schemas/SessionDetailDecision",
7246
7385
  "example": {
@@ -7322,7 +7461,7 @@
7322
7461
  "accuracy_radius_km": 10
7323
7462
  },
7324
7463
  "routing": {
7325
- "asn": "64512",
7464
+ "asn": "AS64512",
7326
7465
  "organization": "SPECTRANET LIMITED"
7327
7466
  },
7328
7467
  "anonymity": {
@@ -7352,7 +7491,7 @@
7352
7491
  "client_types": [
7353
7492
  "consumer"
7354
7493
  ],
7355
- "client_count": 1
7494
+ "client_count": null
7356
7495
  },
7357
7496
  "evaluated_at": "2026-03-24T20:00:05.000Z"
7358
7497
  }
@@ -7814,7 +7953,8 @@
7814
7953
  "lifecycle": {
7815
7954
  "first_seen_at": "2026-03-01T18:22:11.000Z",
7816
7955
  "last_seen_at": "2026-03-24T20:00:05.000Z",
7817
- "seen_count": 1
7956
+ "seen_count": 1,
7957
+ "resolution_count": 1
7818
7958
  }
7819
7959
  }
7820
7960
  },
@@ -7835,7 +7975,8 @@
7835
7975
  "lifecycle": {
7836
7976
  "first_seen_at": "2026-03-01T18:22:11.000Z",
7837
7977
  "last_seen_at": "2026-03-24T20:00:05.000Z",
7838
- "seen_count": 1
7978
+ "seen_count": 1,
7979
+ "resolution_count": 1
7839
7980
  }
7840
7981
  }
7841
7982
  },
@@ -7986,7 +8127,7 @@
7986
8127
  "$ref": "#/components/schemas/SessionSignalFired",
7987
8128
  "example": {
7988
8129
  "signal": "webdriver_detected",
7989
- "role": "owner",
8130
+ "role": "risk",
7990
8131
  "category": "environment",
7991
8132
  "strength": "definitive",
7992
8133
  "signal_score": 100
@@ -7995,7 +8136,7 @@
7995
8136
  "example": [
7996
8137
  {
7997
8138
  "signal": "webdriver_detected",
7998
- "role": "owner",
8139
+ "role": "risk",
7999
8140
  "category": "environment",
8000
8141
  "strength": "definitive",
8001
8142
  "signal_score": 100
@@ -8035,9 +8176,9 @@
8035
8176
  },
8036
8177
  "canvas": {
8037
8178
  "hash": 1234567890,
8038
- "geometry_hash": 1234567890,
8179
+ "geometry_hash": null,
8039
8180
  "text_hash": 1234567890,
8040
- "winding": true,
8181
+ "winding": null,
8041
8182
  "noise_detected": true,
8042
8183
  "offscreen_consistent": true
8043
8184
  },
@@ -8050,6 +8191,7 @@
8050
8191
  "parameters_hash": "01234567",
8051
8192
  "extensions_hash": 1234567890,
8052
8193
  "extension_parameters_hash": "01234567",
8194
+ "webgl2_parameters_hash": "01234567",
8053
8195
  "shader_precision_hash": 1234567890
8054
8196
  },
8055
8197
  "webgpu": {
@@ -8168,6 +8310,7 @@
8168
8310
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
8169
8311
  "created_at": "2026-03-24T20:00:00.000Z",
8170
8312
  "client_user_id": "user_123",
8313
+ "client_application_id": "app_123",
8171
8314
  "decision": {
8172
8315
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
8173
8316
  "automation_status": "automated",
@@ -8211,7 +8354,7 @@
8211
8354
  "accuracy_radius_km": 10
8212
8355
  },
8213
8356
  "routing": {
8214
- "asn": "64512",
8357
+ "asn": "AS64512",
8215
8358
  "organization": "SPECTRANET LIMITED"
8216
8359
  },
8217
8360
  "anonymity": {
@@ -8241,7 +8384,7 @@
8241
8384
  "client_types": [
8242
8385
  "consumer"
8243
8386
  ],
8244
- "client_count": 1
8387
+ "client_count": null
8245
8388
  },
8246
8389
  "evaluated_at": "2026-03-24T20:00:05.000Z"
8247
8390
  },
@@ -8451,7 +8594,8 @@
8451
8594
  "lifecycle": {
8452
8595
  "first_seen_at": "2026-03-01T18:22:11.000Z",
8453
8596
  "last_seen_at": "2026-03-24T20:00:05.000Z",
8454
- "seen_count": 1
8597
+ "seen_count": 1,
8598
+ "resolution_count": 1
8455
8599
  }
8456
8600
  },
8457
8601
  "connection_fingerprint": {
@@ -8569,7 +8713,7 @@
8569
8713
  "signals_fired": [
8570
8714
  {
8571
8715
  "signal": "webdriver_detected",
8572
- "role": "owner",
8716
+ "role": "risk",
8573
8717
  "category": "environment",
8574
8718
  "strength": "definitive",
8575
8719
  "signal_score": 100
@@ -8606,9 +8750,9 @@
8606
8750
  },
8607
8751
  "canvas": {
8608
8752
  "hash": 1234567890,
8609
- "geometry_hash": 1234567890,
8753
+ "geometry_hash": null,
8610
8754
  "text_hash": 1234567890,
8611
- "winding": true,
8755
+ "winding": null,
8612
8756
  "noise_detected": true,
8613
8757
  "offscreen_consistent": true
8614
8758
  },
@@ -8621,6 +8765,7 @@
8621
8765
  "parameters_hash": "01234567",
8622
8766
  "extensions_hash": 1234567890,
8623
8767
  "extension_parameters_hash": "01234567",
8768
+ "webgl2_parameters_hash": "01234567",
8624
8769
  "shader_precision_hash": 1234567890
8625
8770
  },
8626
8771
  "webgpu": {
@@ -8866,6 +9011,7 @@
8866
9011
  "machine_speed",
8867
9012
  "scripted_cadence",
8868
9013
  "filled_instantly",
9014
+ "burst_fill",
8869
9015
  "changed",
8870
9016
  "visited_no_entry",
8871
9017
  "unknown"
@@ -9180,6 +9326,7 @@
9180
9326
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
9181
9327
  "created_at": "2026-03-24T20:00:00.000Z",
9182
9328
  "client_user_id": "user_123",
9329
+ "client_application_id": "app_123",
9183
9330
  "decision": {
9184
9331
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
9185
9332
  "automation_status": "automated",
@@ -9223,7 +9370,7 @@
9223
9370
  "accuracy_radius_km": 10
9224
9371
  },
9225
9372
  "routing": {
9226
- "asn": "64512",
9373
+ "asn": "AS64512",
9227
9374
  "organization": "SPECTRANET LIMITED"
9228
9375
  },
9229
9376
  "anonymity": {
@@ -9253,7 +9400,7 @@
9253
9400
  "client_types": [
9254
9401
  "consumer"
9255
9402
  ],
9256
- "client_count": 1
9403
+ "client_count": null
9257
9404
  },
9258
9405
  "evaluated_at": "2026-03-24T20:00:05.000Z"
9259
9406
  },
@@ -9463,7 +9610,8 @@
9463
9610
  "lifecycle": {
9464
9611
  "first_seen_at": "2026-03-01T18:22:11.000Z",
9465
9612
  "last_seen_at": "2026-03-24T20:00:05.000Z",
9466
- "seen_count": 1
9613
+ "seen_count": 1,
9614
+ "resolution_count": 1
9467
9615
  }
9468
9616
  },
9469
9617
  "connection_fingerprint": {
@@ -9581,7 +9729,7 @@
9581
9729
  "signals_fired": [
9582
9730
  {
9583
9731
  "signal": "webdriver_detected",
9584
- "role": "owner",
9732
+ "role": "risk",
9585
9733
  "category": "environment",
9586
9734
  "strength": "definitive",
9587
9735
  "signal_score": 100
@@ -9618,9 +9766,9 @@
9618
9766
  },
9619
9767
  "canvas": {
9620
9768
  "hash": 1234567890,
9621
- "geometry_hash": 1234567890,
9769
+ "geometry_hash": null,
9622
9770
  "text_hash": 1234567890,
9623
- "winding": true,
9771
+ "winding": null,
9624
9772
  "noise_detected": true,
9625
9773
  "offscreen_consistent": true
9626
9774
  },
@@ -9633,6 +9781,7 @@
9633
9781
  "parameters_hash": "01234567",
9634
9782
  "extensions_hash": 1234567890,
9635
9783
  "extension_parameters_hash": "01234567",
9784
+ "webgl2_parameters_hash": "01234567",
9636
9785
  "shader_precision_hash": 1234567890
9637
9786
  },
9638
9787
  "webgpu": {
@@ -9712,6 +9861,7 @@
9712
9861
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
9713
9862
  "created_at": "2026-03-24T20:00:00.000Z",
9714
9863
  "client_user_id": "user_123",
9864
+ "client_application_id": "app_123",
9715
9865
  "decision": {
9716
9866
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
9717
9867
  "automation_status": "automated",
@@ -9755,7 +9905,7 @@
9755
9905
  "accuracy_radius_km": 10
9756
9906
  },
9757
9907
  "routing": {
9758
- "asn": "64512",
9908
+ "asn": "AS64512",
9759
9909
  "organization": "SPECTRANET LIMITED"
9760
9910
  },
9761
9911
  "anonymity": {
@@ -9785,7 +9935,7 @@
9785
9935
  "client_types": [
9786
9936
  "consumer"
9787
9937
  ],
9788
- "client_count": 1
9938
+ "client_count": null
9789
9939
  },
9790
9940
  "evaluated_at": "2026-03-24T20:00:05.000Z"
9791
9941
  },
@@ -9995,7 +10145,8 @@
9995
10145
  "lifecycle": {
9996
10146
  "first_seen_at": "2026-03-01T18:22:11.000Z",
9997
10147
  "last_seen_at": "2026-03-24T20:00:05.000Z",
9998
- "seen_count": 1
10148
+ "seen_count": 1,
10149
+ "resolution_count": 1
9999
10150
  }
10000
10151
  },
10001
10152
  "connection_fingerprint": {
@@ -10113,7 +10264,7 @@
10113
10264
  "signals_fired": [
10114
10265
  {
10115
10266
  "signal": "webdriver_detected",
10116
- "role": "owner",
10267
+ "role": "risk",
10117
10268
  "category": "environment",
10118
10269
  "strength": "definitive",
10119
10270
  "signal_score": 100
@@ -10150,9 +10301,9 @@
10150
10301
  },
10151
10302
  "canvas": {
10152
10303
  "hash": 1234567890,
10153
- "geometry_hash": 1234567890,
10304
+ "geometry_hash": null,
10154
10305
  "text_hash": 1234567890,
10155
- "winding": true,
10306
+ "winding": null,
10156
10307
  "noise_detected": true,
10157
10308
  "offscreen_consistent": true
10158
10309
  },
@@ -10165,6 +10316,7 @@
10165
10316
  "parameters_hash": "01234567",
10166
10317
  "extensions_hash": 1234567890,
10167
10318
  "extension_parameters_hash": "01234567",
10319
+ "webgl2_parameters_hash": "01234567",
10168
10320
  "shader_precision_hash": 1234567890
10169
10321
  },
10170
10322
  "webgpu": {
@@ -10295,15 +10447,12 @@
10295
10447
  "enum": [
10296
10448
  "continuity",
10297
10449
  "fingerprint",
10298
- "fingerprint_evolution",
10299
10450
  "new",
10300
10451
  "native_persistent",
10301
10452
  "native_new",
10302
- "existing",
10303
- "unknown",
10304
10453
  null
10305
10454
  ],
10306
- "description": "The evidence that resolved this session to the visitor ID. Null when the session predates resolution tracking.",
10455
+ "description": "The evidence that resolved this session to the visitor ID: `continuity` for an identifier saved in an earlier session, `fingerprint` for a fingerprint match, `new` for a first sighting, and `native_persistent` or `native_new` for iOS and Android SDK sessions. Null when the session predates resolution tracking.",
10307
10456
  "example": "continuity"
10308
10457
  },
10309
10458
  "basis": {
@@ -10330,7 +10479,8 @@
10330
10479
  "example": {
10331
10480
  "first_seen_at": "2026-03-01T18:22:11.000Z",
10332
10481
  "last_seen_at": "2026-03-24T20:00:05.000Z",
10333
- "seen_count": 1
10482
+ "seen_count": 1,
10483
+ "resolution_count": 1
10334
10484
  }
10335
10485
  }
10336
10486
  },
@@ -10346,7 +10496,8 @@
10346
10496
  "lifecycle": {
10347
10497
  "first_seen_at": "2026-03-01T18:22:11.000Z",
10348
10498
  "last_seen_at": "2026-03-24T20:00:05.000Z",
10349
- "seen_count": 1
10499
+ "seen_count": 1,
10500
+ "resolution_count": 1
10350
10501
  }
10351
10502
  }
10352
10503
  },
@@ -10356,7 +10507,8 @@
10356
10507
  "required": [
10357
10508
  "first_seen_at",
10358
10509
  "last_seen_at",
10359
- "seen_count"
10510
+ "seen_count",
10511
+ "resolution_count"
10360
10512
  ],
10361
10513
  "properties": {
10362
10514
  "first_seen_at": {
@@ -10387,14 +10539,33 @@
10387
10539
  "example": null
10388
10540
  }
10389
10541
  ],
10542
+ "deprecated": true,
10543
+ "description": "Deprecated. Same value as `resolution_count`. It does not match `seen_count` from `GET /v1/fingerprints/{visitorId}`, which counts sessions.",
10390
10544
  "example": 1
10545
+ },
10546
+ "resolution_count": {
10547
+ "anyOf": [
10548
+ {
10549
+ "type": "integer",
10550
+ "minimum": 0,
10551
+ "example": 14
10552
+ },
10553
+ {
10554
+ "type": "null",
10555
+ "example": null
10556
+ }
10557
+ ],
10558
+ "description": "Number of times Foil resolved a page load or app launch to this visitor ID across the organization, including both environments. One session can count more than once.",
10559
+ "example": 14
10391
10560
  }
10392
10561
  },
10393
10562
  "example": {
10394
10563
  "first_seen_at": "2026-03-01T18:22:11.000Z",
10395
10564
  "last_seen_at": "2026-03-24T20:00:05.000Z",
10396
- "seen_count": 1
10397
- }
10565
+ "seen_count": 1,
10566
+ "resolution_count": 1
10567
+ },
10568
+ "description": "Lifecycle of the visitor ID across the organization, including both environments."
10398
10569
  },
10399
10570
  "SessionDevice": {
10400
10571
  "type": "object",
@@ -10409,7 +10580,7 @@
10409
10580
  ],
10410
10581
  "properties": {
10411
10582
  "form_factor": {
10412
- "type": "string",
10583
+ "$ref": "#/components/schemas/DeviceClass",
10413
10584
  "example": "desktop"
10414
10585
  },
10415
10586
  "operating_system": {
@@ -10928,6 +11099,7 @@
10928
11099
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
10929
11100
  "created_at": "2026-03-24T20:00:00.000Z",
10930
11101
  "client_user_id": "user_123",
11102
+ "client_application_id": "app_123",
10931
11103
  "latest_decision": {
10932
11104
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
10933
11105
  "verdict": "human",
@@ -10955,6 +11127,7 @@
10955
11127
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
10956
11128
  "created_at": "2026-03-24T20:00:00.000Z",
10957
11129
  "client_user_id": "user_123",
11130
+ "client_application_id": "app_123",
10958
11131
  "latest_decision": {
10959
11132
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
10960
11133
  "verdict": "human",
@@ -10999,6 +11172,7 @@
10999
11172
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
11000
11173
  "created_at": "2026-03-24T20:00:00.000Z",
11001
11174
  "client_user_id": "user_123",
11175
+ "client_application_id": "app_123",
11002
11176
  "latest_decision": {
11003
11177
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
11004
11178
  "verdict": "human",
@@ -12144,6 +12318,7 @@
12144
12318
  "string",
12145
12319
  "null"
12146
12320
  ],
12321
+ "description": "Client IP address. Null when Foil did not capture one.",
12147
12322
  "example": "203.0.113.10"
12148
12323
  },
12149
12324
  "ip_version": {
@@ -12201,6 +12376,7 @@
12201
12376
  "example": null
12202
12377
  }
12203
12378
  ],
12379
+ "description": "Location of the IP address. Null when the lookup found none.",
12204
12380
  "example": {
12205
12381
  "city": "San Francisco",
12206
12382
  "region": "California",
@@ -12226,7 +12402,8 @@
12226
12402
  "string",
12227
12403
  "null"
12228
12404
  ],
12229
- "example": "64512"
12405
+ "description": "Autonomous system number with an `AS` prefix.",
12406
+ "example": "AS64512"
12230
12407
  },
12231
12408
  "organization": {
12232
12409
  "type": [
@@ -12237,7 +12414,7 @@
12237
12414
  }
12238
12415
  },
12239
12416
  "example": {
12240
- "asn": "64512",
12417
+ "asn": "AS64512",
12241
12418
  "organization": "SPECTRANET LIMITED"
12242
12419
  }
12243
12420
  },
@@ -12281,6 +12458,8 @@
12281
12458
  },
12282
12459
  "callback_proxy": {
12283
12460
  "type": "boolean",
12461
+ "deprecated": true,
12462
+ "description": "Always `false` for sessions evaluated since July 30, 2026. The current IP intelligence source has no callback-proxy classification.",
12284
12463
  "example": false
12285
12464
  },
12286
12465
  "provider": {
@@ -12327,6 +12506,8 @@
12327
12506
  },
12328
12507
  "suspicious_network": {
12329
12508
  "type": "boolean",
12509
+ "deprecated": true,
12510
+ "description": "Always `false` for sessions evaluated since July 30, 2026. The current IP intelligence source has no suspicious-network classification.",
12330
12511
  "example": false
12331
12512
  }
12332
12513
  },
@@ -12390,7 +12571,9 @@
12390
12571
  "example": null
12391
12572
  }
12392
12573
  ],
12393
- "example": 1
12574
+ "deprecated": true,
12575
+ "description": "Always `null` for sessions evaluated since July 30, 2026. The current IP intelligence source does not count clients behind an address.",
12576
+ "example": null
12394
12577
  }
12395
12578
  },
12396
12579
  "example": {
@@ -12403,7 +12586,7 @@
12403
12586
  "client_types": [
12404
12587
  "consumer"
12405
12588
  ],
12406
- "client_count": 1
12589
+ "client_count": null
12407
12590
  }
12408
12591
  },
12409
12592
  "evaluated_at": {
@@ -12432,7 +12615,7 @@
12432
12615
  "accuracy_radius_km": 10
12433
12616
  },
12434
12617
  "routing": {
12435
- "asn": "64512",
12618
+ "asn": "AS64512",
12436
12619
  "organization": "SPECTRANET LIMITED"
12437
12620
  },
12438
12621
  "anonymity": {
@@ -12462,7 +12645,7 @@
12462
12645
  "client_types": [
12463
12646
  "consumer"
12464
12647
  ],
12465
- "client_count": 1
12648
+ "client_count": null
12466
12649
  },
12467
12650
  "evaluated_at": "2026-03-24T20:00:05.000Z"
12468
12651
  }
@@ -12609,7 +12792,8 @@
12609
12792
  "null"
12610
12793
  ],
12611
12794
  "minimum": 0,
12612
- "example": 3
12795
+ "description": "The `maxChannelCount` of the audio output. Null when the browser did not report it.",
12796
+ "example": 2
12613
12797
  },
12614
12798
  "voice_count": {
12615
12799
  "type": [
@@ -12670,7 +12854,9 @@
12670
12854
  },
12671
12855
  "geometry_hash": {
12672
12856
  "$ref": "#/components/schemas/ObservationHash",
12673
- "example": 1234567890
12857
+ "deprecated": true,
12858
+ "description": "Always null. Foil stopped measuring canvas geometry in July 2026.",
12859
+ "example": null
12674
12860
  },
12675
12861
  "text_hash": {
12676
12862
  "$ref": "#/components/schemas/ObservationHash",
@@ -12681,7 +12867,9 @@
12681
12867
  "boolean",
12682
12868
  "null"
12683
12869
  ],
12684
- "example": true
12870
+ "deprecated": true,
12871
+ "description": "Always null. No Foil probe measures canvas winding.",
12872
+ "example": null
12685
12873
  },
12686
12874
  "noise_detected": {
12687
12875
  "type": [
@@ -12700,9 +12888,9 @@
12700
12888
  },
12701
12889
  "example": {
12702
12890
  "hash": 1234567890,
12703
- "geometry_hash": 1234567890,
12891
+ "geometry_hash": null,
12704
12892
  "text_hash": 1234567890,
12705
- "winding": true,
12893
+ "winding": null,
12706
12894
  "noise_detected": true,
12707
12895
  "offscreen_consistent": true
12708
12896
  }
@@ -12725,6 +12913,7 @@
12725
12913
  "null"
12726
12914
  ],
12727
12915
  "minimum": 0,
12916
+ "description": "Number of tested fonts that are installed.",
12728
12917
  "example": 3
12729
12918
  },
12730
12919
  "tested_count": {
@@ -12733,7 +12922,8 @@
12733
12922
  "null"
12734
12923
  ],
12735
12924
  "minimum": 0,
12736
- "example": 3
12925
+ "description": "Number of fonts in the panel Foil tested. Null when the font probe returned no usable measurement.",
12926
+ "example": 41
12737
12927
  },
12738
12928
  "enumeration_hash": {
12739
12929
  "$ref": "#/components/schemas/ObservationHash",
@@ -12749,7 +12939,8 @@
12749
12939
  },
12750
12940
  "emoji_hash": {
12751
12941
  "$ref": "#/components/schemas/ObservationHash",
12752
- "example": 1234567890
12942
+ "description": "Hash of the rendered dimensions of a fixed set of emoji. Null when the browser could not measure them.",
12943
+ "example": "5f0e2a71"
12753
12944
  }
12754
12945
  },
12755
12946
  "example": {
@@ -12779,6 +12970,7 @@
12779
12970
  "parameters_hash": "01234567",
12780
12971
  "extensions_hash": 1234567890,
12781
12972
  "extension_parameters_hash": "01234567",
12973
+ "webgl2_parameters_hash": "01234567",
12782
12974
  "shader_precision_hash": 1234567890
12783
12975
  }
12784
12976
  },
@@ -12803,6 +12995,7 @@
12803
12995
  "parameters_hash": "01234567",
12804
12996
  "extensions_hash": 1234567890,
12805
12997
  "extension_parameters_hash": "01234567",
12998
+ "webgl2_parameters_hash": "01234567",
12806
12999
  "shader_precision_hash": 1234567890
12807
13000
  },
12808
13001
  "webgpu": {
@@ -12826,6 +13019,7 @@
12826
13019
  "parameters_hash",
12827
13020
  "extensions_hash",
12828
13021
  "extension_parameters_hash",
13022
+ "webgl2_parameters_hash",
12829
13023
  "shader_precision_hash"
12830
13024
  ],
12831
13025
  "properties": {
@@ -12867,6 +13061,13 @@
12867
13061
  },
12868
13062
  "extension_parameters_hash": {
12869
13063
  "$ref": "#/components/schemas/ObservationHash",
13064
+ "deprecated": true,
13065
+ "description": "Deprecated misnomer for `webgl2_parameters_hash`, which carries the same value. This field never described extension parameters.",
13066
+ "example": "01234567"
13067
+ },
13068
+ "webgl2_parameters_hash": {
13069
+ "$ref": "#/components/schemas/ObservationHash",
13070
+ "description": "Hash of the WebGL2 context parameters. Null when WebGL2 is unavailable.",
12870
13071
  "example": "01234567"
12871
13072
  },
12872
13073
  "shader_precision_hash": {
@@ -12882,6 +13083,7 @@
12882
13083
  "parameters_hash": "01234567",
12883
13084
  "extensions_hash": 1234567890,
12884
13085
  "extension_parameters_hash": "01234567",
13086
+ "webgl2_parameters_hash": "01234567",
12885
13087
  "shader_precision_hash": 1234567890
12886
13088
  }
12887
13089
  },
@@ -13145,6 +13347,7 @@
13145
13347
  "SessionRawDeviceStorage": {
13146
13348
  "type": "object",
13147
13349
  "additionalProperties": false,
13350
+ "description": "Whether each storage API is available to the page. A field is `true` when a probe found the API or Foil read its own identifier back from that store, `false` only when a probe found the API missing, and `null` when nothing measured it. A missing identifier is not evidence that the store is unavailable.",
13148
13351
  "required": [
13149
13352
  "cookies",
13150
13353
  "local_storage",
@@ -13159,6 +13362,7 @@
13159
13362
  "boolean",
13160
13363
  "null"
13161
13364
  ],
13365
+ "description": "From `navigator.cookieEnabled`. Otherwise `true` when Foil read its cookie back, and `null`.",
13162
13366
  "example": true
13163
13367
  },
13164
13368
  "local_storage": {
@@ -13166,6 +13370,7 @@
13166
13370
  "boolean",
13167
13371
  "null"
13168
13372
  ],
13373
+ "description": "Whether `window.localStorage` is reachable. Otherwise `true` when Foil read its identifier back, and `null`.",
13169
13374
  "example": true
13170
13375
  },
13171
13376
  "session_storage": {
@@ -13173,6 +13378,7 @@
13173
13378
  "boolean",
13174
13379
  "null"
13175
13380
  ],
13381
+ "description": "Whether `window.sessionStorage` is reachable. Otherwise `true` when Foil read its identifier back, and `null`.",
13176
13382
  "example": true
13177
13383
  },
13178
13384
  "indexed_db": {
@@ -13180,6 +13386,7 @@
13180
13386
  "boolean",
13181
13387
  "null"
13182
13388
  ],
13389
+ "description": "`true` when Foil read its identifier back from IndexedDB, otherwise `null`. No probe tests IndexedDB directly, so this field is never `false`.",
13183
13390
  "example": true
13184
13391
  },
13185
13392
  "service_worker": {
@@ -13187,6 +13394,7 @@
13187
13394
  "boolean",
13188
13395
  "null"
13189
13396
  ],
13397
+ "description": "Whether `navigator.serviceWorker` exists. Null when the probe did not run.",
13190
13398
  "example": true
13191
13399
  },
13192
13400
  "window_name": {
@@ -13194,6 +13402,7 @@
13194
13402
  "boolean",
13195
13403
  "null"
13196
13404
  ],
13405
+ "description": "`true` when Foil read its identifier back from `window.name`, otherwise `null`. This field is never `false`.",
13197
13406
  "example": true
13198
13407
  }
13199
13408
  },
@@ -13215,6 +13424,7 @@
13215
13424
  "event",
13216
13425
  "decision",
13217
13426
  "visitor_fingerprint",
13427
+ "device_cluster",
13218
13428
  "request",
13219
13429
  "score_breakdown",
13220
13430
  "signals",
@@ -13259,14 +13469,24 @@
13259
13469
  },
13260
13470
  "scoring_event_id": {
13261
13471
  "type": "string",
13262
- "example": "scoring_event_id"
13472
+ "example": "1842"
13263
13473
  },
13264
13474
  "phase": {
13265
- "type": [
13266
- "string",
13267
- "null"
13475
+ "anyOf": [
13476
+ {
13477
+ "type": "string",
13478
+ "enum": [
13479
+ "snapshot",
13480
+ "behavioral"
13481
+ ],
13482
+ "example": "behavioral"
13483
+ },
13484
+ {
13485
+ "type": "null",
13486
+ "example": null
13487
+ }
13268
13488
  ],
13269
- "example": "phase"
13489
+ "example": "behavioral"
13270
13490
  },
13271
13491
  "is_provisional": {
13272
13492
  "type": [
@@ -13283,8 +13503,8 @@
13283
13503
  },
13284
13504
  "example": {
13285
13505
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
13286
- "scoring_event_id": "scoring_event_id",
13287
- "phase": "phase",
13506
+ "scoring_event_id": "1842",
13507
+ "phase": "behavioral",
13288
13508
  "is_provisional": false,
13289
13509
  "persisted_at": "2026-03-24T20:00:05.000Z"
13290
13510
  }
@@ -13301,27 +13521,29 @@
13301
13521
  "properties": {
13302
13522
  "verdict": {
13303
13523
  "$ref": "#/components/schemas/Verdict",
13304
- "example": "human"
13524
+ "example": "bot"
13305
13525
  },
13306
13526
  "risk_score": {
13307
13527
  "type": "integer",
13308
13528
  "minimum": 0,
13309
13529
  "maximum": 100,
13310
- "example": 94
13530
+ "example": 94,
13531
+ "description": "The risk score as an integer from 0 to 100."
13311
13532
  },
13312
13533
  "score": {
13313
13534
  "type": "number",
13314
13535
  "minimum": 0,
13315
13536
  "maximum": 1,
13316
- "example": 0.08
13537
+ "example": 0.94,
13538
+ "description": "The same risk score as a number from 0 to 1."
13317
13539
  },
13318
13540
  "manipulation": {
13319
13541
  "anyOf": [
13320
13542
  {
13321
13543
  "$ref": "#/components/schemas/ManipulationSummary",
13322
13544
  "example": {
13323
- "score": 1,
13324
- "verdict": "none"
13545
+ "score": 18,
13546
+ "verdict": "low"
13325
13547
  }
13326
13548
  },
13327
13549
  {
@@ -13330,18 +13552,18 @@
13330
13552
  }
13331
13553
  ],
13332
13554
  "example": {
13333
- "score": 1,
13334
- "verdict": "none"
13555
+ "score": 18,
13556
+ "verdict": "low"
13335
13557
  }
13336
13558
  }
13337
13559
  },
13338
13560
  "example": {
13339
- "verdict": "human",
13561
+ "verdict": "bot",
13340
13562
  "risk_score": 94,
13341
- "score": 0.08,
13563
+ "score": 0.94,
13342
13564
  "manipulation": {
13343
- "score": 1,
13344
- "verdict": "none"
13565
+ "score": 18,
13566
+ "verdict": "low"
13345
13567
  }
13346
13568
  }
13347
13569
  },
@@ -13372,6 +13594,81 @@
13372
13594
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
13373
13595
  }
13374
13596
  },
13597
+ "device_cluster": {
13598
+ "description": "The device cluster Foil linked the visitor to, or null when device-cluster results are not enabled.",
13599
+ "anyOf": [
13600
+ {
13601
+ "type": "object",
13602
+ "additionalProperties": false,
13603
+ "required": [
13604
+ "object",
13605
+ "id",
13606
+ "confidence",
13607
+ "matched_by"
13608
+ ],
13609
+ "properties": {
13610
+ "object": {
13611
+ "type": "string",
13612
+ "const": "device_cluster",
13613
+ "example": "device_cluster"
13614
+ },
13615
+ "id": {
13616
+ "type": "string",
13617
+ "example": "dcl_3k9vb7xq2m8n4c6p1r5t0wyzhe"
13618
+ },
13619
+ "confidence": {
13620
+ "anyOf": [
13621
+ {
13622
+ "type": "integer",
13623
+ "minimum": 0,
13624
+ "maximum": 100,
13625
+ "example": 88
13626
+ },
13627
+ {
13628
+ "type": "null",
13629
+ "example": null
13630
+ }
13631
+ ],
13632
+ "example": 88
13633
+ },
13634
+ "matched_by": {
13635
+ "anyOf": [
13636
+ {
13637
+ "type": "string",
13638
+ "enum": [
13639
+ "visitor_membership",
13640
+ "fingerprint",
13641
+ "new"
13642
+ ],
13643
+ "example": "fingerprint"
13644
+ },
13645
+ {
13646
+ "type": "null",
13647
+ "example": null
13648
+ }
13649
+ ],
13650
+ "example": "fingerprint"
13651
+ }
13652
+ },
13653
+ "example": {
13654
+ "object": "device_cluster",
13655
+ "id": "dcl_3k9vb7xq2m8n4c6p1r5t0wyzhe",
13656
+ "confidence": 88,
13657
+ "matched_by": "fingerprint"
13658
+ }
13659
+ },
13660
+ {
13661
+ "type": "null",
13662
+ "example": null
13663
+ }
13664
+ ],
13665
+ "example": {
13666
+ "object": "device_cluster",
13667
+ "id": "dcl_3k9vb7xq2m8n4c6p1r5t0wyzhe",
13668
+ "confidence": 88,
13669
+ "matched_by": "fingerprint"
13670
+ }
13671
+ },
13375
13672
  "request": {
13376
13673
  "$ref": "#/components/schemas/WebhookRequestSummary",
13377
13674
  "example": {
@@ -13379,42 +13676,61 @@
13379
13676
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
13380
13677
  "ip_address": "203.0.113.10",
13381
13678
  "screen_size": "1440x900",
13382
- "is_touch_capable": true,
13679
+ "is_touch_capable": false,
13383
13680
  "platform": "macOS",
13384
- "first_seen": "2026-03-01T18:22:11.000Z",
13681
+ "first_seen": "2026-03-24T19:59:58.000Z",
13385
13682
  "risk_time": "2026-03-24T20:00:05.000Z"
13386
13683
  }
13387
13684
  },
13388
13685
  "score_breakdown": {
13389
13686
  "type": "object",
13390
- "additionalProperties": true,
13687
+ "additionalProperties": false,
13391
13688
  "required": [
13392
13689
  "categories"
13393
13690
  ],
13394
13691
  "properties": {
13395
13692
  "categories": {
13396
13693
  "type": "object",
13397
- "additionalProperties": true,
13694
+ "description": "Each scoring category mapped to its score, an integer from 0 to 100.",
13695
+ "additionalProperties": {
13696
+ "type": "integer",
13697
+ "minimum": 0,
13698
+ "maximum": 100,
13699
+ "example": 60
13700
+ },
13398
13701
  "example": {
13399
- "source": "signup_form"
13702
+ "environment": 60,
13703
+ "fingerprint": 30,
13704
+ "keyboard": 10
13400
13705
  }
13401
13706
  }
13402
13707
  },
13403
13708
  "example": {
13404
13709
  "categories": {
13405
- "source": "signup_form"
13710
+ "environment": 60,
13711
+ "fingerprint": 30,
13712
+ "keyboard": 10
13406
13713
  }
13407
13714
  }
13408
13715
  },
13409
13716
  "signals": {
13410
13717
  "type": "array",
13718
+ "description": "The risk signals that fired for the decision. Shadow and telemetry-only signals are never included. Empty unless the organization's plan includes raw signals.",
13411
13719
  "items": {
13412
13720
  "type": "object",
13413
- "additionalProperties": true,
13721
+ "additionalProperties": false,
13722
+ "required": [
13723
+ "id",
13724
+ "category",
13725
+ "confidence",
13726
+ "score",
13727
+ "role"
13728
+ ],
13414
13729
  "properties": {
13415
13730
  "id": {
13416
13731
  "type": "string",
13417
- "example": "sid_87wfetm98myh9awj0dpt28a3kc"
13732
+ "description": "An opaque signal identifier.",
13733
+ "example": "E1"
13418
13734
  },
13419
13735
  "category": {
13420
13736
  "type": "string",
@@ -13425,50 +13741,88 @@
13425
13741
  "example": "exact"
13426
13742
  },
13427
13743
  "score": {
13428
- "type": "number",
13429
- "example": 0.08
13744
+ "type": "integer",
13745
+ "minimum": 0,
13746
+ "maximum": 100,
13747
+ "description": "The signal's contribution as an integer from 0 to 100.",
13748
+ "example": 60
13430
13749
  },
13431
13750
  "role": {
13432
13751
  "type": "string",
13433
- "example": "owner"
13752
+ "const": "risk",
13753
+ "example": "risk"
13434
13754
  }
13435
13755
  },
13436
13756
  "example": {
13437
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
13757
+ "id": "E1",
13438
13758
  "category": "environment",
13439
13759
  "confidence": "exact",
13440
- "score": 0.08,
13441
- "role": "owner"
13760
+ "score": 60,
13761
+ "role": "risk"
13442
13762
  }
13443
13763
  },
13444
13764
  "example": [
13445
13765
  {
13446
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
13766
+ "id": "E1",
13447
13767
  "category": "environment",
13448
13768
  "confidence": "exact",
13449
- "score": 0.08,
13450
- "role": "owner"
13769
+ "score": 60,
13770
+ "role": "risk"
13451
13771
  }
13452
13772
  ]
13453
13773
  },
13454
13774
  "attribution": {
13455
13775
  "type": "object",
13456
- "additionalProperties": true,
13776
+ "additionalProperties": false,
13777
+ "required": [
13778
+ "bot"
13779
+ ],
13457
13780
  "properties": {
13458
13781
  "bot": {
13459
- "type": [
13460
- "object",
13461
- "null"
13782
+ "anyOf": [
13783
+ {
13784
+ "$ref": "#/components/schemas/SessionAttribution",
13785
+ "example": {
13786
+ "labels": [
13787
+ {
13788
+ "kind": "actor",
13789
+ "value": "automation",
13790
+ "label": "Automation",
13791
+ "confidence": 97
13792
+ }
13793
+ ],
13794
+ "behaviors": []
13795
+ }
13796
+ },
13797
+ {
13798
+ "type": "null",
13799
+ "example": null
13800
+ }
13462
13801
  ],
13463
- "additionalProperties": true,
13464
13802
  "example": {
13465
- "source": "signup_form"
13803
+ "labels": [
13804
+ {
13805
+ "kind": "actor",
13806
+ "value": "automation",
13807
+ "label": "Automation",
13808
+ "confidence": 97
13809
+ }
13810
+ ],
13811
+ "behaviors": []
13466
13812
  }
13467
13813
  }
13468
13814
  },
13469
13815
  "example": {
13470
13816
  "bot": {
13471
- "source": "signup_form"
13817
+ "labels": [
13818
+ {
13819
+ "kind": "actor",
13820
+ "value": "automation",
13821
+ "label": "Automation",
13822
+ "confidence": 97
13823
+ }
13824
+ ],
13825
+ "behaviors": []
13472
13826
  }
13473
13827
  }
13474
13828
  }
@@ -13480,50 +13834,61 @@
13480
13834
  },
13481
13835
  "event": {
13482
13836
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
13483
- "scoring_event_id": "scoring_event_id",
13484
- "phase": "phase",
13837
+ "scoring_event_id": "1842",
13838
+ "phase": "behavioral",
13485
13839
  "is_provisional": false,
13486
13840
  "persisted_at": "2026-03-24T20:00:05.000Z"
13487
13841
  },
13488
13842
  "decision": {
13489
- "verdict": "human",
13843
+ "verdict": "bot",
13490
13844
  "risk_score": 94,
13491
- "score": 0.08,
13845
+ "score": 0.94,
13492
13846
  "manipulation": {
13493
- "score": 1,
13494
- "verdict": "none"
13847
+ "score": 18,
13848
+ "verdict": "low"
13495
13849
  }
13496
13850
  },
13497
13851
  "visitor_fingerprint": {
13498
13852
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
13499
13853
  },
13854
+ "device_cluster": null,
13500
13855
  "request": {
13501
13856
  "url": "https://app.acme.co/signup",
13502
13857
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
13503
13858
  "ip_address": "203.0.113.10",
13504
13859
  "screen_size": "1440x900",
13505
- "is_touch_capable": true,
13860
+ "is_touch_capable": false,
13506
13861
  "platform": "macOS",
13507
- "first_seen": "2026-03-01T18:22:11.000Z",
13862
+ "first_seen": "2026-03-24T19:59:58.000Z",
13508
13863
  "risk_time": "2026-03-24T20:00:05.000Z"
13509
13864
  },
13510
13865
  "score_breakdown": {
13511
13866
  "categories": {
13512
- "source": "signup_form"
13867
+ "environment": 60,
13868
+ "fingerprint": 30,
13869
+ "keyboard": 10
13513
13870
  }
13514
13871
  },
13515
13872
  "signals": [
13516
13873
  {
13517
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
13874
+ "id": "E1",
13518
13875
  "category": "environment",
13519
13876
  "confidence": "exact",
13520
- "score": 0.08,
13521
- "role": "owner"
13877
+ "score": 60,
13878
+ "role": "risk"
13522
13879
  }
13523
13880
  ],
13524
13881
  "attribution": {
13525
13882
  "bot": {
13526
- "source": "signup_form"
13883
+ "labels": [
13884
+ {
13885
+ "kind": "actor",
13886
+ "value": "automation",
13887
+ "label": "Automation",
13888
+ "confidence": 97
13889
+ }
13890
+ ],
13891
+ "behaviors": []
13527
13892
  }
13528
13893
  }
13529
13894
  }
@@ -13544,50 +13909,61 @@
13544
13909
  },
13545
13910
  "event": {
13546
13911
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
13547
- "scoring_event_id": "scoring_event_id",
13548
- "phase": "phase",
13912
+ "scoring_event_id": "1842",
13913
+ "phase": "behavioral",
13549
13914
  "is_provisional": false,
13550
13915
  "persisted_at": "2026-03-24T20:00:05.000Z"
13551
13916
  },
13552
13917
  "decision": {
13553
- "verdict": "human",
13918
+ "verdict": "bot",
13554
13919
  "risk_score": 94,
13555
- "score": 0.08,
13920
+ "score": 0.94,
13556
13921
  "manipulation": {
13557
- "score": 1,
13558
- "verdict": "none"
13922
+ "score": 18,
13923
+ "verdict": "low"
13559
13924
  }
13560
13925
  },
13561
13926
  "visitor_fingerprint": {
13562
13927
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
13563
13928
  },
13929
+ "device_cluster": null,
13564
13930
  "request": {
13565
13931
  "url": "https://app.acme.co/signup",
13566
13932
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
13567
13933
  "ip_address": "203.0.113.10",
13568
13934
  "screen_size": "1440x900",
13569
- "is_touch_capable": true,
13935
+ "is_touch_capable": false,
13570
13936
  "platform": "macOS",
13571
- "first_seen": "2026-03-01T18:22:11.000Z",
13937
+ "first_seen": "2026-03-24T19:59:58.000Z",
13572
13938
  "risk_time": "2026-03-24T20:00:05.000Z"
13573
13939
  },
13574
13940
  "score_breakdown": {
13575
13941
  "categories": {
13576
- "source": "signup_form"
13942
+ "environment": 60,
13943
+ "fingerprint": 30,
13944
+ "keyboard": 10
13577
13945
  }
13578
13946
  },
13579
13947
  "signals": [
13580
13948
  {
13581
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
13949
+ "id": "E1",
13582
13950
  "category": "environment",
13583
13951
  "confidence": "exact",
13584
- "score": 0.08,
13585
- "role": "owner"
13952
+ "score": 60,
13953
+ "role": "risk"
13586
13954
  }
13587
13955
  ],
13588
13956
  "attribution": {
13589
13957
  "bot": {
13590
- "source": "signup_form"
13958
+ "labels": [
13959
+ {
13960
+ "kind": "actor",
13961
+ "value": "automation",
13962
+ "label": "Automation",
13963
+ "confidence": 97
13964
+ }
13965
+ ],
13966
+ "behaviors": []
13591
13967
  }
13592
13968
  }
13593
13969
  }
@@ -13610,50 +13986,61 @@
13610
13986
  },
13611
13987
  "event": {
13612
13988
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
13613
- "scoring_event_id": "scoring_event_id",
13614
- "phase": "phase",
13989
+ "scoring_event_id": "1842",
13990
+ "phase": "behavioral",
13615
13991
  "is_provisional": false,
13616
13992
  "persisted_at": "2026-03-24T20:00:05.000Z"
13617
13993
  },
13618
13994
  "decision": {
13619
- "verdict": "human",
13995
+ "verdict": "bot",
13620
13996
  "risk_score": 94,
13621
- "score": 0.08,
13997
+ "score": 0.94,
13622
13998
  "manipulation": {
13623
- "score": 1,
13624
- "verdict": "none"
13999
+ "score": 18,
14000
+ "verdict": "low"
13625
14001
  }
13626
14002
  },
13627
14003
  "visitor_fingerprint": {
13628
14004
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
13629
14005
  },
14006
+ "device_cluster": null,
13630
14007
  "request": {
13631
14008
  "url": "https://app.acme.co/signup",
13632
14009
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
13633
14010
  "ip_address": "203.0.113.10",
13634
14011
  "screen_size": "1440x900",
13635
- "is_touch_capable": true,
14012
+ "is_touch_capable": false,
13636
14013
  "platform": "macOS",
13637
- "first_seen": "2026-03-01T18:22:11.000Z",
14014
+ "first_seen": "2026-03-24T19:59:58.000Z",
13638
14015
  "risk_time": "2026-03-24T20:00:05.000Z"
13639
14016
  },
13640
14017
  "score_breakdown": {
13641
14018
  "categories": {
13642
- "source": "signup_form"
14019
+ "environment": 60,
14020
+ "fingerprint": 30,
14021
+ "keyboard": 10
13643
14022
  }
13644
14023
  },
13645
14024
  "signals": [
13646
14025
  {
13647
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
14026
+ "id": "E1",
13648
14027
  "category": "environment",
13649
14028
  "confidence": "exact",
13650
- "score": 0.08,
13651
- "role": "owner"
14029
+ "score": 60,
14030
+ "role": "risk"
13652
14031
  }
13653
14032
  ],
13654
14033
  "attribution": {
13655
14034
  "bot": {
13656
- "source": "signup_form"
14035
+ "labels": [
14036
+ {
14037
+ "kind": "actor",
14038
+ "value": "automation",
14039
+ "label": "Automation",
14040
+ "confidence": 97
14041
+ }
14042
+ ],
14043
+ "behaviors": []
13657
14044
  }
13658
14045
  }
13659
14046
  }
@@ -13671,50 +14058,61 @@
13671
14058
  },
13672
14059
  "event": {
13673
14060
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
13674
- "scoring_event_id": "scoring_event_id",
13675
- "phase": "phase",
14061
+ "scoring_event_id": "1842",
14062
+ "phase": "behavioral",
13676
14063
  "is_provisional": false,
13677
14064
  "persisted_at": "2026-03-24T20:00:05.000Z"
13678
14065
  },
13679
14066
  "decision": {
13680
- "verdict": "human",
14067
+ "verdict": "bot",
13681
14068
  "risk_score": 94,
13682
- "score": 0.08,
14069
+ "score": 0.94,
13683
14070
  "manipulation": {
13684
- "score": 1,
13685
- "verdict": "none"
14071
+ "score": 18,
14072
+ "verdict": "low"
13686
14073
  }
13687
14074
  },
13688
14075
  "visitor_fingerprint": {
13689
14076
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
13690
14077
  },
14078
+ "device_cluster": null,
13691
14079
  "request": {
13692
14080
  "url": "https://app.acme.co/signup",
13693
14081
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
13694
14082
  "ip_address": "203.0.113.10",
13695
14083
  "screen_size": "1440x900",
13696
- "is_touch_capable": true,
14084
+ "is_touch_capable": false,
13697
14085
  "platform": "macOS",
13698
- "first_seen": "2026-03-01T18:22:11.000Z",
14086
+ "first_seen": "2026-03-24T19:59:58.000Z",
13699
14087
  "risk_time": "2026-03-24T20:00:05.000Z"
13700
14088
  },
13701
14089
  "score_breakdown": {
13702
14090
  "categories": {
13703
- "source": "signup_form"
14091
+ "environment": 60,
14092
+ "fingerprint": 30,
14093
+ "keyboard": 10
13704
14094
  }
13705
14095
  },
13706
14096
  "signals": [
13707
14097
  {
13708
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
14098
+ "id": "E1",
13709
14099
  "category": "environment",
13710
14100
  "confidence": "exact",
13711
- "score": 0.08,
13712
- "role": "owner"
14101
+ "score": 60,
14102
+ "role": "risk"
13713
14103
  }
13714
14104
  ],
13715
14105
  "attribution": {
13716
14106
  "bot": {
13717
- "source": "signup_form"
14107
+ "labels": [
14108
+ {
14109
+ "kind": "actor",
14110
+ "value": "automation",
14111
+ "label": "Automation",
14112
+ "confidence": 97
14113
+ }
14114
+ ],
14115
+ "behaviors": []
13718
14116
  }
13719
14117
  }
13720
14118
  }
@@ -13845,14 +14243,33 @@
13845
14243
  },
13846
14244
  "role": {
13847
14245
  "type": "string",
13848
- "example": "owner"
14246
+ "enum": [
14247
+ "risk"
14248
+ ],
14249
+ "description": "Always `risk`: only signals that counted toward the risk score are listed.",
14250
+ "example": "risk"
13849
14251
  },
13850
14252
  "category": {
13851
14253
  "type": "string",
14254
+ "enum": [
14255
+ "environment",
14256
+ "eventTrust",
14257
+ "fingerprint",
14258
+ "mouse",
14259
+ "keyboard",
14260
+ "timing",
14261
+ "touch"
14262
+ ],
13852
14263
  "example": "environment"
13853
14264
  },
13854
14265
  "strength": {
13855
14266
  "type": "string",
14267
+ "enum": [
14268
+ "definitive",
14269
+ "strong",
14270
+ "behavioral",
14271
+ "weak"
14272
+ ],
13856
14273
  "example": "definitive"
13857
14274
  },
13858
14275
  "signal_score": {
@@ -13864,7 +14281,7 @@
13864
14281
  },
13865
14282
  "example": {
13866
14283
  "signal": "webdriver_detected",
13867
- "role": "owner",
14284
+ "role": "risk",
13868
14285
  "category": "environment",
13869
14286
  "strength": "definitive",
13870
14287
  "signal_score": 100
@@ -13879,7 +14296,8 @@
13879
14296
  "created_at",
13880
14297
  "latest_decision",
13881
14298
  "visitor_fingerprint",
13882
- "client_user_id"
14299
+ "client_user_id",
14300
+ "client_application_id"
13883
14301
  ],
13884
14302
  "properties": {
13885
14303
  "object": {
@@ -13907,6 +14325,15 @@
13907
14325
  "description": "Customer-supplied identifier for the end user associated with this Foil session. Set with PATCH /v1/sessions/{sessionId}.",
13908
14326
  "example": "user_123"
13909
14327
  },
14328
+ "client_application_id": {
14329
+ "type": [
14330
+ "string",
14331
+ "null"
14332
+ ],
14333
+ "maxLength": 256,
14334
+ "description": "Customer-supplied identifier for the application or organization on your platform that this Foil session belongs to. Set with PATCH /v1/sessions/{sessionId}.",
14335
+ "example": "app_123"
14336
+ },
13910
14337
  "latest_decision": {
13911
14338
  "$ref": "#/components/schemas/Decision",
13912
14339
  "example": {
@@ -13952,6 +14379,7 @@
13952
14379
  "id": "sid_87wfetm98myh9awj0dpt28a3kc",
13953
14380
  "created_at": "2026-03-24T20:00:00.000Z",
13954
14381
  "client_user_id": "user_123",
14382
+ "client_application_id": "app_123",
13955
14383
  "latest_decision": {
13956
14384
  "event_id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
13957
14385
  "verdict": "human",
@@ -13986,6 +14414,14 @@
13986
14414
  "string",
13987
14415
  "null"
13988
14416
  ],
14417
+ "enum": [
14418
+ "verified",
14419
+ "invalid",
14420
+ "error",
14421
+ "absent",
14422
+ null
14423
+ ],
14424
+ "description": "Result of checking the request's Web Bot Auth signature. `absent` means the request carried no signature.",
13989
14425
  "example": "verified"
13990
14426
  },
13991
14427
  "domain": {
@@ -14087,9 +14523,8 @@
14087
14523
  "UpdateSessionRequest": {
14088
14524
  "type": "object",
14089
14525
  "additionalProperties": false,
14090
- "required": [
14091
- "client_user_id"
14092
- ],
14526
+ "minProperties": 1,
14527
+ "description": "Send `client_user_id`, `client_application_id`, or both. At least one is required. A key you omit keeps its current value, and `null` clears it.",
14093
14528
  "properties": {
14094
14529
  "client_user_id": {
14095
14530
  "type": [
@@ -14099,10 +14534,20 @@
14099
14534
  "maxLength": 256,
14100
14535
  "description": "Customer-supplied identifier for the end user associated with this Foil session. Set with PATCH /v1/sessions/{sessionId}.",
14101
14536
  "example": "user_123"
14537
+ },
14538
+ "client_application_id": {
14539
+ "type": [
14540
+ "string",
14541
+ "null"
14542
+ ],
14543
+ "maxLength": 256,
14544
+ "description": "Customer-supplied identifier for the application or organization on your platform that this Foil session belongs to. Set with PATCH /v1/sessions/{sessionId}.",
14545
+ "example": "app_123"
14102
14546
  }
14103
14547
  },
14104
14548
  "example": {
14105
- "client_user_id": "user_123"
14549
+ "client_user_id": "user_123",
14550
+ "client_application_id": "app_123"
14106
14551
  }
14107
14552
  },
14108
14553
  "UpdateWebhookEndpointRequest": {
@@ -14340,6 +14785,8 @@
14340
14785
  "VisitorFingerprintAnchors": {
14341
14786
  "type": "object",
14342
14787
  "additionalProperties": false,
14788
+ "deprecated": true,
14789
+ "description": "Always `null` from `/v1/fingerprints`. The identity record behind this field spans both environments, so `/v1/fingerprints` cannot attribute it to your key's environment.",
14343
14790
  "required": [
14344
14791
  "webgl_hash",
14345
14792
  "parameters_hash",
@@ -14369,9 +14816,9 @@
14369
14816
  }
14370
14817
  },
14371
14818
  "example": {
14372
- "webgl_hash": "123456789",
14373
- "parameters_hash": "-1234567890",
14374
- "audio_hash": "1234567890"
14819
+ "webgl_hash": null,
14820
+ "parameters_hash": null,
14821
+ "audio_hash": null
14375
14822
  }
14376
14823
  },
14377
14824
  "VisitorFingerprintComponents": {
@@ -14387,15 +14834,13 @@
14387
14834
  "type": "number",
14388
14835
  "example": 1.5
14389
14836
  },
14390
- "example": [
14391
- 1.5
14392
- ]
14837
+ "deprecated": true,
14838
+ "description": "Always empty from `/v1/fingerprints`. The identity record behind this field spans both environments, so `/v1/fingerprints` cannot attribute it to your key's environment.",
14839
+ "example": []
14393
14840
  }
14394
14841
  },
14395
14842
  "example": {
14396
- "vector": [
14397
- 1.5
14398
- ]
14843
+ "vector": []
14399
14844
  }
14400
14845
  },
14401
14846
  "VisitorFingerprintDetail": {
@@ -14426,7 +14871,7 @@
14426
14871
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14427
14872
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14428
14873
  "seen_count": 14,
14429
- "expires_at": "2026-03-24T20:00:05.000Z"
14874
+ "expires_at": "9999-12-31T00:00:00.000Z"
14430
14875
  }
14431
14876
  },
14432
14877
  "latest_request": {
@@ -14449,17 +14894,15 @@
14449
14894
  "anchors": {
14450
14895
  "$ref": "#/components/schemas/VisitorFingerprintAnchors",
14451
14896
  "example": {
14452
- "webgl_hash": "123456789",
14453
- "parameters_hash": "-1234567890",
14454
- "audio_hash": "1234567890"
14897
+ "webgl_hash": null,
14898
+ "parameters_hash": null,
14899
+ "audio_hash": null
14455
14900
  }
14456
14901
  },
14457
14902
  "components": {
14458
14903
  "$ref": "#/components/schemas/VisitorFingerprintComponents",
14459
14904
  "example": {
14460
- "vector": [
14461
- 1.5
14462
- ]
14905
+ "vector": []
14463
14906
  }
14464
14907
  },
14465
14908
  "activity": {
@@ -14505,28 +14948,26 @@
14505
14948
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14506
14949
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14507
14950
  "seen_count": 14,
14508
- "expires_at": "2026-03-24T20:00:05.000Z"
14951
+ "expires_at": "9999-12-31T00:00:00.000Z"
14509
14952
  },
14510
14953
  "latest_request": {
14511
14954
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
14512
14955
  "ip_address": "203.0.113.10"
14513
14956
  },
14514
14957
  "storage": {
14515
- "cookies": true,
14516
- "local_storage": true,
14517
- "indexed_db": true,
14518
- "service_worker": true,
14519
- "window_name": true
14958
+ "cookies": false,
14959
+ "local_storage": false,
14960
+ "indexed_db": false,
14961
+ "service_worker": false,
14962
+ "window_name": false
14520
14963
  },
14521
14964
  "anchors": {
14522
- "webgl_hash": "123456789",
14523
- "parameters_hash": "-1234567890",
14524
- "audio_hash": "1234567890"
14965
+ "webgl_hash": null,
14966
+ "parameters_hash": null,
14967
+ "audio_hash": null
14525
14968
  },
14526
14969
  "components": {
14527
- "vector": [
14528
- 1.5
14529
- ]
14970
+ "vector": []
14530
14971
  },
14531
14972
  "activity": {
14532
14973
  "sessions": [
@@ -14579,28 +15020,26 @@
14579
15020
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14580
15021
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14581
15022
  "seen_count": 14,
14582
- "expires_at": "2026-03-24T20:00:05.000Z"
15023
+ "expires_at": "9999-12-31T00:00:00.000Z"
14583
15024
  },
14584
15025
  "latest_request": {
14585
15026
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
14586
15027
  "ip_address": "203.0.113.10"
14587
15028
  },
14588
15029
  "storage": {
14589
- "cookies": true,
14590
- "local_storage": true,
14591
- "indexed_db": true,
14592
- "service_worker": true,
14593
- "window_name": true
15030
+ "cookies": false,
15031
+ "local_storage": false,
15032
+ "indexed_db": false,
15033
+ "service_worker": false,
15034
+ "window_name": false
14594
15035
  },
14595
15036
  "anchors": {
14596
- "webgl_hash": "123456789",
14597
- "parameters_hash": "-1234567890",
14598
- "audio_hash": "1234567890"
15037
+ "webgl_hash": null,
15038
+ "parameters_hash": null,
15039
+ "audio_hash": null
14599
15040
  },
14600
15041
  "components": {
14601
- "vector": [
14602
- 1.5
14603
- ]
15042
+ "vector": []
14604
15043
  },
14605
15044
  "activity": {
14606
15045
  "sessions": [
@@ -14651,28 +15090,26 @@
14651
15090
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14652
15091
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14653
15092
  "seen_count": 14,
14654
- "expires_at": "2026-03-24T20:00:05.000Z"
15093
+ "expires_at": "9999-12-31T00:00:00.000Z"
14655
15094
  },
14656
15095
  "latest_request": {
14657
15096
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
14658
15097
  "ip_address": "203.0.113.10"
14659
15098
  },
14660
15099
  "storage": {
14661
- "cookies": true,
14662
- "local_storage": true,
14663
- "indexed_db": true,
14664
- "service_worker": true,
14665
- "window_name": true
15100
+ "cookies": false,
15101
+ "local_storage": false,
15102
+ "indexed_db": false,
15103
+ "service_worker": false,
15104
+ "window_name": false
14666
15105
  },
14667
15106
  "anchors": {
14668
- "webgl_hash": "123456789",
14669
- "parameters_hash": "-1234567890",
14670
- "audio_hash": "1234567890"
15107
+ "webgl_hash": null,
15108
+ "parameters_hash": null,
15109
+ "audio_hash": null
14671
15110
  },
14672
15111
  "components": {
14673
- "vector": [
14674
- 1.5
14675
- ]
15112
+ "vector": []
14676
15113
  },
14677
15114
  "activity": {
14678
15115
  "sessions": [
@@ -14757,19 +15194,22 @@
14757
15194
  "seen_count": {
14758
15195
  "type": "integer",
14759
15196
  "minimum": 0,
15197
+ "description": "Number of sessions linked to this visitor ID in your key's environment.",
14760
15198
  "example": 14
14761
15199
  },
14762
15200
  "expires_at": {
14763
15201
  "type": "string",
14764
15202
  "format": "date-time",
14765
- "example": "2026-03-24T20:00:05.000Z"
15203
+ "deprecated": true,
15204
+ "description": "Always `9999-12-31T00:00:00.000Z`. Visitor IDs do not expire.",
15205
+ "example": "9999-12-31T00:00:00.000Z"
14766
15206
  }
14767
15207
  },
14768
15208
  "example": {
14769
15209
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14770
15210
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14771
15211
  "seen_count": 14,
14772
- "expires_at": "2026-03-24T20:00:05.000Z"
15212
+ "expires_at": "9999-12-31T00:00:00.000Z"
14773
15213
  }
14774
15214
  },
14775
15215
  "VisitorFingerprintLink": {
@@ -14841,23 +15281,23 @@
14841
15281
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14842
15282
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14843
15283
  "seen_count": 14,
14844
- "expires_at": "2026-03-24T20:00:05.000Z"
15284
+ "expires_at": "9999-12-31T00:00:00.000Z"
14845
15285
  },
14846
15286
  "latest_request": {
14847
15287
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
14848
15288
  "ip_address": "203.0.113.10"
14849
15289
  },
14850
15290
  "storage": {
14851
- "cookies": true,
14852
- "local_storage": true,
14853
- "indexed_db": true,
14854
- "service_worker": true,
14855
- "window_name": true
15291
+ "cookies": false,
15292
+ "local_storage": false,
15293
+ "indexed_db": false,
15294
+ "service_worker": false,
15295
+ "window_name": false
14856
15296
  },
14857
15297
  "anchors": {
14858
- "webgl_hash": "123456789",
14859
- "parameters_hash": "-1234567890",
14860
- "audio_hash": "1234567890"
15298
+ "webgl_hash": null,
15299
+ "parameters_hash": null,
15300
+ "audio_hash": null
14861
15301
  }
14862
15302
  }
14863
15303
  },
@@ -14869,23 +15309,23 @@
14869
15309
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14870
15310
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14871
15311
  "seen_count": 14,
14872
- "expires_at": "2026-03-24T20:00:05.000Z"
15312
+ "expires_at": "9999-12-31T00:00:00.000Z"
14873
15313
  },
14874
15314
  "latest_request": {
14875
15315
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
14876
15316
  "ip_address": "203.0.113.10"
14877
15317
  },
14878
15318
  "storage": {
14879
- "cookies": true,
14880
- "local_storage": true,
14881
- "indexed_db": true,
14882
- "service_worker": true,
14883
- "window_name": true
15319
+ "cookies": false,
15320
+ "local_storage": false,
15321
+ "indexed_db": false,
15322
+ "service_worker": false,
15323
+ "window_name": false
14884
15324
  },
14885
15325
  "anchors": {
14886
- "webgl_hash": "123456789",
14887
- "parameters_hash": "-1234567890",
14888
- "audio_hash": "1234567890"
15326
+ "webgl_hash": null,
15327
+ "parameters_hash": null,
15328
+ "audio_hash": null
14889
15329
  }
14890
15330
  }
14891
15331
  ]
@@ -14914,23 +15354,23 @@
14914
15354
  "first_seen_at": "2026-03-01T18:22:11.000Z",
14915
15355
  "last_seen_at": "2026-03-24T20:00:05.000Z",
14916
15356
  "seen_count": 14,
14917
- "expires_at": "2026-03-24T20:00:05.000Z"
15357
+ "expires_at": "9999-12-31T00:00:00.000Z"
14918
15358
  },
14919
15359
  "latest_request": {
14920
15360
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
14921
15361
  "ip_address": "203.0.113.10"
14922
15362
  },
14923
15363
  "storage": {
14924
- "cookies": true,
14925
- "local_storage": true,
14926
- "indexed_db": true,
14927
- "service_worker": true,
14928
- "window_name": true
15364
+ "cookies": false,
15365
+ "local_storage": false,
15366
+ "indexed_db": false,
15367
+ "service_worker": false,
15368
+ "window_name": false
14929
15369
  },
14930
15370
  "anchors": {
14931
- "webgl_hash": "123456789",
14932
- "parameters_hash": "-1234567890",
14933
- "audio_hash": "1234567890"
15371
+ "webgl_hash": null,
15372
+ "parameters_hash": null,
15373
+ "audio_hash": null
14934
15374
  }
14935
15375
  }
14936
15376
  ],
@@ -14947,6 +15387,8 @@
14947
15387
  "VisitorFingerprintStorage": {
14948
15388
  "type": "object",
14949
15389
  "additionalProperties": false,
15390
+ "deprecated": true,
15391
+ "description": "Always `false` from `/v1/fingerprints`. The identity record behind this field spans both environments, so `/v1/fingerprints` cannot attribute it to your key's environment. Treat the flags as unavailable, not as evidence that a store was absent.",
14950
15392
  "required": [
14951
15393
  "cookies",
14952
15394
  "local_storage",
@@ -15010,7 +15452,7 @@
15010
15452
  "first_seen_at": "2026-03-01T18:22:11.000Z",
15011
15453
  "last_seen_at": "2026-03-24T20:00:05.000Z",
15012
15454
  "seen_count": 14,
15013
- "expires_at": "2026-03-24T20:00:05.000Z"
15455
+ "expires_at": "9999-12-31T00:00:00.000Z"
15014
15456
  }
15015
15457
  },
15016
15458
  "latest_request": {
@@ -15033,9 +15475,9 @@
15033
15475
  "anchors": {
15034
15476
  "$ref": "#/components/schemas/VisitorFingerprintAnchors",
15035
15477
  "example": {
15036
- "webgl_hash": "123456789",
15037
- "parameters_hash": "-1234567890",
15038
- "audio_hash": "1234567890"
15478
+ "webgl_hash": null,
15479
+ "parameters_hash": null,
15480
+ "audio_hash": null
15039
15481
  }
15040
15482
  }
15041
15483
  },
@@ -15046,23 +15488,23 @@
15046
15488
  "first_seen_at": "2026-03-01T18:22:11.000Z",
15047
15489
  "last_seen_at": "2026-03-24T20:00:05.000Z",
15048
15490
  "seen_count": 14,
15049
- "expires_at": "2026-03-24T20:00:05.000Z"
15491
+ "expires_at": "9999-12-31T00:00:00.000Z"
15050
15492
  },
15051
15493
  "latest_request": {
15052
15494
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
15053
15495
  "ip_address": "203.0.113.10"
15054
15496
  },
15055
15497
  "storage": {
15056
- "cookies": true,
15057
- "local_storage": true,
15058
- "indexed_db": true,
15059
- "service_worker": true,
15060
- "window_name": true
15498
+ "cookies": false,
15499
+ "local_storage": false,
15500
+ "indexed_db": false,
15501
+ "service_worker": false,
15502
+ "window_name": false
15061
15503
  },
15062
15504
  "anchors": {
15063
- "webgl_hash": "123456789",
15064
- "parameters_hash": "-1234567890",
15065
- "audio_hash": "1234567890"
15505
+ "webgl_hash": null,
15506
+ "parameters_hash": null,
15507
+ "audio_hash": null
15066
15508
  }
15067
15509
  }
15068
15510
  },
@@ -15448,50 +15890,61 @@
15448
15890
  },
15449
15891
  "event": {
15450
15892
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
15451
- "scoring_event_id": "scoring_event_id",
15452
- "phase": "phase",
15893
+ "scoring_event_id": "1842",
15894
+ "phase": "behavioral",
15453
15895
  "is_provisional": false,
15454
15896
  "persisted_at": "2026-03-24T20:00:05.000Z"
15455
15897
  },
15456
15898
  "decision": {
15457
- "verdict": "human",
15899
+ "verdict": "bot",
15458
15900
  "risk_score": 94,
15459
- "score": 0.08,
15901
+ "score": 0.94,
15460
15902
  "manipulation": {
15461
- "score": 1,
15462
- "verdict": "none"
15903
+ "score": 18,
15904
+ "verdict": "low"
15463
15905
  }
15464
15906
  },
15465
15907
  "visitor_fingerprint": {
15466
15908
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
15467
15909
  },
15910
+ "device_cluster": null,
15468
15911
  "request": {
15469
15912
  "url": "https://app.acme.co/signup",
15470
15913
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
15471
15914
  "ip_address": "203.0.113.10",
15472
15915
  "screen_size": "1440x900",
15473
- "is_touch_capable": true,
15916
+ "is_touch_capable": false,
15474
15917
  "platform": "macOS",
15475
- "first_seen": "2026-03-01T18:22:11.000Z",
15918
+ "first_seen": "2026-03-24T19:59:58.000Z",
15476
15919
  "risk_time": "2026-03-24T20:00:05.000Z"
15477
15920
  },
15478
15921
  "score_breakdown": {
15479
15922
  "categories": {
15480
- "source": "signup_form"
15923
+ "environment": 60,
15924
+ "fingerprint": 30,
15925
+ "keyboard": 10
15481
15926
  }
15482
15927
  },
15483
15928
  "signals": [
15484
15929
  {
15485
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
15930
+ "id": "E1",
15486
15931
  "category": "environment",
15487
15932
  "confidence": "exact",
15488
- "score": 0.08,
15489
- "role": "owner"
15933
+ "score": 60,
15934
+ "role": "risk"
15490
15935
  }
15491
15936
  ],
15492
15937
  "attribution": {
15493
15938
  "bot": {
15494
- "source": "signup_form"
15939
+ "labels": [
15940
+ {
15941
+ "kind": "actor",
15942
+ "value": "automation",
15943
+ "label": "Automation",
15944
+ "confidence": 97
15945
+ }
15946
+ ],
15947
+ "behaviors": []
15495
15948
  }
15496
15949
  }
15497
15950
  }
@@ -15502,7 +15955,8 @@
15502
15955
  "object": "webhook_test",
15503
15956
  "endpoint": {
15504
15957
  "id": "we_0123456789abcdef0123456789abcdef"
15505
- }
15958
+ },
15959
+ "message": "This is a Foil webhook test event."
15506
15960
  }
15507
15961
  }
15508
15962
  ],
@@ -15513,50 +15967,61 @@
15513
15967
  },
15514
15968
  "event": {
15515
15969
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
15516
- "scoring_event_id": "scoring_event_id",
15517
- "phase": "phase",
15970
+ "scoring_event_id": "1842",
15971
+ "phase": "behavioral",
15518
15972
  "is_provisional": false,
15519
15973
  "persisted_at": "2026-03-24T20:00:05.000Z"
15520
15974
  },
15521
15975
  "decision": {
15522
- "verdict": "human",
15976
+ "verdict": "bot",
15523
15977
  "risk_score": 94,
15524
- "score": 0.08,
15978
+ "score": 0.94,
15525
15979
  "manipulation": {
15526
- "score": 1,
15527
- "verdict": "none"
15980
+ "score": 18,
15981
+ "verdict": "low"
15528
15982
  }
15529
15983
  },
15530
15984
  "visitor_fingerprint": {
15531
15985
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
15532
15986
  },
15987
+ "device_cluster": null,
15533
15988
  "request": {
15534
15989
  "url": "https://app.acme.co/signup",
15535
15990
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
15536
15991
  "ip_address": "203.0.113.10",
15537
15992
  "screen_size": "1440x900",
15538
- "is_touch_capable": true,
15993
+ "is_touch_capable": false,
15539
15994
  "platform": "macOS",
15540
- "first_seen": "2026-03-01T18:22:11.000Z",
15995
+ "first_seen": "2026-03-24T19:59:58.000Z",
15541
15996
  "risk_time": "2026-03-24T20:00:05.000Z"
15542
15997
  },
15543
15998
  "score_breakdown": {
15544
15999
  "categories": {
15545
- "source": "signup_form"
16000
+ "environment": 60,
16001
+ "fingerprint": 30,
16002
+ "keyboard": 10
15546
16003
  }
15547
16004
  },
15548
16005
  "signals": [
15549
16006
  {
15550
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
16007
+ "id": "E1",
15551
16008
  "category": "environment",
15552
16009
  "confidence": "exact",
15553
- "score": 0.08,
15554
- "role": "owner"
16010
+ "score": 60,
16011
+ "role": "risk"
15555
16012
  }
15556
16013
  ],
15557
16014
  "attribution": {
15558
16015
  "bot": {
15559
- "source": "signup_form"
16016
+ "labels": [
16017
+ {
16018
+ "kind": "actor",
16019
+ "value": "automation",
16020
+ "label": "Automation",
16021
+ "confidence": 97
16022
+ }
16023
+ ],
16024
+ "behaviors": []
15560
16025
  }
15561
16026
  }
15562
16027
  }
@@ -15574,50 +16039,61 @@
15574
16039
  },
15575
16040
  "event": {
15576
16041
  "id": "evt_srwqc0yqhz4bxvtrdtf69q7vkr",
15577
- "scoring_event_id": "scoring_event_id",
15578
- "phase": "phase",
16042
+ "scoring_event_id": "1842",
16043
+ "phase": "behavioral",
15579
16044
  "is_provisional": false,
15580
16045
  "persisted_at": "2026-03-24T20:00:05.000Z"
15581
16046
  },
15582
16047
  "decision": {
15583
- "verdict": "human",
16048
+ "verdict": "bot",
15584
16049
  "risk_score": 94,
15585
- "score": 0.08,
16050
+ "score": 0.94,
15586
16051
  "manipulation": {
15587
- "score": 1,
15588
- "verdict": "none"
16052
+ "score": 18,
16053
+ "verdict": "low"
15589
16054
  }
15590
16055
  },
15591
16056
  "visitor_fingerprint": {
15592
16057
  "id": "vid_7cyvmdfjs3rzznf8m65v3bv51m"
15593
16058
  },
16059
+ "device_cluster": null,
15594
16060
  "request": {
15595
16061
  "url": "https://app.acme.co/signup",
15596
16062
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
15597
16063
  "ip_address": "203.0.113.10",
15598
16064
  "screen_size": "1440x900",
15599
- "is_touch_capable": true,
16065
+ "is_touch_capable": false,
15600
16066
  "platform": "macOS",
15601
- "first_seen": "2026-03-01T18:22:11.000Z",
16067
+ "first_seen": "2026-03-24T19:59:58.000Z",
15602
16068
  "risk_time": "2026-03-24T20:00:05.000Z"
15603
16069
  },
15604
16070
  "score_breakdown": {
15605
16071
  "categories": {
15606
- "source": "signup_form"
16072
+ "environment": 60,
16073
+ "fingerprint": 30,
16074
+ "keyboard": 10
15607
16075
  }
15608
16076
  },
15609
16077
  "signals": [
15610
16078
  {
15611
- "id": "sid_87wfetm98myh9awj0dpt28a3kc",
16079
+ "id": "E1",
15612
16080
  "category": "environment",
15613
16081
  "confidence": "exact",
15614
- "score": 0.08,
15615
- "role": "owner"
16082
+ "score": 60,
16083
+ "role": "risk"
15616
16084
  }
15617
16085
  ],
15618
16086
  "attribution": {
15619
16087
  "bot": {
15620
- "source": "signup_form"
16088
+ "labels": [
16089
+ {
16090
+ "kind": "actor",
16091
+ "value": "automation",
16092
+ "label": "Automation",
16093
+ "confidence": 97
16094
+ }
16095
+ ],
16096
+ "behaviors": []
15621
16097
  }
15622
16098
  }
15623
16099
  }
@@ -15800,10 +16276,11 @@
15800
16276
  },
15801
16277
  "WebhookTestEventPayload": {
15802
16278
  "type": "object",
15803
- "additionalProperties": true,
16279
+ "additionalProperties": false,
15804
16280
  "required": [
15805
16281
  "object",
15806
- "endpoint"
16282
+ "endpoint",
16283
+ "message"
15807
16284
  ],
15808
16285
  "properties": {
15809
16286
  "object": {
@@ -15826,13 +16303,18 @@
15826
16303
  "example": {
15827
16304
  "id": "we_0123456789abcdef0123456789abcdef"
15828
16305
  }
16306
+ },
16307
+ "message": {
16308
+ "type": "string",
16309
+ "example": "This is a Foil webhook test event."
15829
16310
  }
15830
16311
  },
15831
16312
  "example": {
15832
16313
  "object": "webhook_test",
15833
16314
  "endpoint": {
15834
16315
  "id": "we_0123456789abcdef0123456789abcdef"
15835
- }
16316
+ },
16317
+ "message": "This is a Foil webhook test event."
15836
16318
  }
15837
16319
  },
15838
16320
  "WebhookTestResponse": {