didit-sdk 1.0.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.
Files changed (234) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +25 -0
  3. data/LICENSE +21 -0
  4. data/README.md +277 -0
  5. data/lib/didit/authentication/base64_url.rb +34 -0
  6. data/lib/didit/authentication/cache.rb +201 -0
  7. data/lib/didit/authentication/http.rb +150 -0
  8. data/lib/didit/authentication/issuer.rb +115 -0
  9. data/lib/didit/authentication/jws.rb +231 -0
  10. data/lib/didit/authentication/key_set.rb +89 -0
  11. data/lib/didit/authentication/pkce.rb +64 -0
  12. data/lib/didit/authentication/types.rb +175 -0
  13. data/lib/didit/authentication.rb +546 -0
  14. data/lib/didit/client.rb +211 -0
  15. data/lib/didit/errors.rb +153 -0
  16. data/lib/didit/file_part.rb +85 -0
  17. data/lib/didit/internal/config.rb +94 -0
  18. data/lib/didit/internal/errors.rb +83 -0
  19. data/lib/didit/internal/log.rb +41 -0
  20. data/lib/didit/internal/multipart.rb +60 -0
  21. data/lib/didit/internal/request.rb +322 -0
  22. data/lib/didit/internal/transport.rb +198 -0
  23. data/lib/didit/internal/util.rb +76 -0
  24. data/lib/didit/internal.rb +15 -0
  25. data/lib/didit/model.rb +199 -0
  26. data/lib/didit/page.rb +130 -0
  27. data/lib/didit/raw_response.rb +57 -0
  28. data/lib/didit/resource.rb +15 -0
  29. data/lib/didit/resources/account.rb +309 -0
  30. data/lib/didit/resources/address_validation.rb +73 -0
  31. data/lib/didit/resources/age_estimation.rb +110 -0
  32. data/lib/didit/resources/aml.rb +166 -0
  33. data/lib/didit/resources/aml_monitoring.rb +30 -0
  34. data/lib/didit/resources/analytics.rb +87 -0
  35. data/lib/didit/resources/bank.rb +65 -0
  36. data/lib/didit/resources/billing.rb +61 -0
  37. data/lib/didit/resources/biometric_templates.rb +234 -0
  38. data/lib/didit/resources/blocklist.rb +130 -0
  39. data/lib/didit/resources/business_sessions.rb +29 -0
  40. data/lib/didit/resources/businesses.rb +471 -0
  41. data/lib/didit/resources/cases.rb +2116 -0
  42. data/lib/didit/resources/customization.rb +153 -0
  43. data/lib/didit/resources/database_validation.rb +327 -0
  44. data/lib/didit/resources/document_ai.rb +145 -0
  45. data/lib/didit/resources/email.rb +254 -0
  46. data/lib/didit/resources/face_match.rb +103 -0
  47. data/lib/didit/resources/face_search.rb +103 -0
  48. data/lib/didit/resources/fraud_checks.rb +130 -0
  49. data/lib/didit/resources/id_verification.rb +163 -0
  50. data/lib/didit/resources/id_wallets.rb +1468 -0
  51. data/lib/didit/resources/investigator.rb +419 -0
  52. data/lib/didit/resources/ip.rb +68 -0
  53. data/lib/didit/resources/kyb.rb +256 -0
  54. data/lib/didit/resources/lists.rb +332 -0
  55. data/lib/didit/resources/monitoring_events.rb +466 -0
  56. data/lib/didit/resources/networks.rb +427 -0
  57. data/lib/didit/resources/passive_liveness.rb +103 -0
  58. data/lib/didit/resources/phone.rb +271 -0
  59. data/lib/didit/resources/pricing.rb +40 -0
  60. data/lib/didit/resources/proof_of_address.rb +167 -0
  61. data/lib/didit/resources/questionnaires.rb +170 -0
  62. data/lib/didit/resources/regulatory_reports.rb +314 -0
  63. data/lib/didit/resources/report_templates.rb +146 -0
  64. data/lib/didit/resources/sessions.rb +2820 -0
  65. data/lib/didit/resources/transactions.rb +981 -0
  66. data/lib/didit/resources/travel_rule.rb +1202 -0
  67. data/lib/didit/resources/users.rb +521 -0
  68. data/lib/didit/resources/wallet_screening.rb +190 -0
  69. data/lib/didit/resources/webhooks.rb +396 -0
  70. data/lib/didit/resources/workflows.rb +214 -0
  71. data/lib/didit/resources.rb +263 -0
  72. data/lib/didit/types/account.rb +11 -0
  73. data/lib/didit/types/account_components.rb +105 -0
  74. data/lib/didit/types/address_validation.rb +8 -0
  75. data/lib/didit/types/age_estimation.rb +89 -0
  76. data/lib/didit/types/aml.rb +193 -0
  77. data/lib/didit/types/aml_monitoring.rb +73 -0
  78. data/lib/didit/types/analytics.rb +62 -0
  79. data/lib/didit/types/bank.rb +8 -0
  80. data/lib/didit/types/billing.rb +18 -0
  81. data/lib/didit/types/biometric_templates.rb +292 -0
  82. data/lib/didit/types/blocklist.rb +31 -0
  83. data/lib/didit/types/businesses.rb +45 -0
  84. data/lib/didit/types/cases.rb +368 -0
  85. data/lib/didit/types/components.rb +12206 -0
  86. data/lib/didit/types/customization.rb +8 -0
  87. data/lib/didit/types/database_validation.rb +177 -0
  88. data/lib/didit/types/document_ai.rb +135 -0
  89. data/lib/didit/types/email.rb +116 -0
  90. data/lib/didit/types/face_match.rb +93 -0
  91. data/lib/didit/types/face_search.rb +129 -0
  92. data/lib/didit/types/fraud_checks.rb +8 -0
  93. data/lib/didit/types/id_verification.rb +231 -0
  94. data/lib/didit/types/id_wallets.rb +8 -0
  95. data/lib/didit/types/investigator.rb +221 -0
  96. data/lib/didit/types/ip.rb +8 -0
  97. data/lib/didit/types/kyb.rb +1391 -0
  98. data/lib/didit/types/lists.rb +111 -0
  99. data/lib/didit/types/monitoring_events.rb +235 -0
  100. data/lib/didit/types/networks.rb +120 -0
  101. data/lib/didit/types/passive_liveness.rb +95 -0
  102. data/lib/didit/types/phone.rb +69 -0
  103. data/lib/didit/types/proof_of_address.rb +166 -0
  104. data/lib/didit/types/questionnaires.rb +29 -0
  105. data/lib/didit/types/regulatory_reports.rb +100 -0
  106. data/lib/didit/types/report_templates.rb +41 -0
  107. data/lib/didit/types/sessions.rb +1441 -0
  108. data/lib/didit/types/transactions.rb +245 -0
  109. data/lib/didit/types/travel_rule.rb +168 -0
  110. data/lib/didit/types/users.rb +180 -0
  111. data/lib/didit/types/wallet_screening.rb +49 -0
  112. data/lib/didit/types/webhooks.rb +355 -0
  113. data/lib/didit/types/workflows.rb +32 -0
  114. data/lib/didit/types.rb +1681 -0
  115. data/lib/didit/version.rb +5 -0
  116. data/lib/didit/webhooks/canonical_json.rb +187 -0
  117. data/lib/didit/webhooks/client_methods.rb +23 -0
  118. data/lib/didit/webhooks/events.rb +221 -0
  119. data/lib/didit/webhooks/headers.rb +83 -0
  120. data/lib/didit/webhooks/verifier.rb +260 -0
  121. data/lib/didit/webhooks.rb +99 -0
  122. data/lib/didit-sdk.rb +4 -0
  123. data/lib/didit.rb +31 -0
  124. data/sig/didit/authentication/base64_url.rbs +10 -0
  125. data/sig/didit/authentication/cache.rbs +60 -0
  126. data/sig/didit/authentication/http.rbs +37 -0
  127. data/sig/didit/authentication/issuer.rbs +17 -0
  128. data/sig/didit/authentication/jws.rbs +41 -0
  129. data/sig/didit/authentication/jwt.rbs +14 -0
  130. data/sig/didit/authentication/key_set.rbs +25 -0
  131. data/sig/didit/authentication/pkce.rbs +20 -0
  132. data/sig/didit/authentication/types.rbs +114 -0
  133. data/sig/didit/authentication.rbs +81 -0
  134. data/sig/didit/client.rbs +61 -0
  135. data/sig/didit/errors.rbs +80 -0
  136. data/sig/didit/file_part.rbs +19 -0
  137. data/sig/didit/internal.rbs +199 -0
  138. data/sig/didit/model.rbs +42 -0
  139. data/sig/didit/page.rbs +34 -0
  140. data/sig/didit/raw_response.rbs +20 -0
  141. data/sig/didit/resource.rbs +8 -0
  142. data/sig/didit/resources/account.rbs +23 -0
  143. data/sig/didit/resources/address_validation.rbs +9 -0
  144. data/sig/didit/resources/age_estimation.rbs +9 -0
  145. data/sig/didit/resources/aml.rbs +10 -0
  146. data/sig/didit/resources/aml_monitoring.rbs +9 -0
  147. data/sig/didit/resources/analytics.rbs +9 -0
  148. data/sig/didit/resources/bank.rbs +9 -0
  149. data/sig/didit/resources/billing.rbs +10 -0
  150. data/sig/didit/resources/biometric_templates.rbs +13 -0
  151. data/sig/didit/resources/blocklist.rbs +11 -0
  152. data/sig/didit/resources/business_sessions.rbs +9 -0
  153. data/sig/didit/resources/businesses.rbs +22 -0
  154. data/sig/didit/resources/cases.rbs +103 -0
  155. data/sig/didit/resources/customization.rbs +10 -0
  156. data/sig/didit/resources/database_validation.rbs +9 -0
  157. data/sig/didit/resources/document_ai.rbs +9 -0
  158. data/sig/didit/resources/email.rbs +11 -0
  159. data/sig/didit/resources/face_match.rbs +9 -0
  160. data/sig/didit/resources/face_search.rbs +9 -0
  161. data/sig/didit/resources/fraud_checks.rbs +11 -0
  162. data/sig/didit/resources/id_verification.rbs +9 -0
  163. data/sig/didit/resources/id_wallets.rbs +37 -0
  164. data/sig/didit/resources/investigator.rbs +23 -0
  165. data/sig/didit/resources/ip.rbs +9 -0
  166. data/sig/didit/resources/kyb.rbs +12 -0
  167. data/sig/didit/resources/lists.rbs +20 -0
  168. data/sig/didit/resources/monitoring_events.rbs +16 -0
  169. data/sig/didit/resources/networks.rbs +25 -0
  170. data/sig/didit/resources/passive_liveness.rbs +9 -0
  171. data/sig/didit/resources/phone.rbs +11 -0
  172. data/sig/didit/resources/pricing.rbs +9 -0
  173. data/sig/didit/resources/proof_of_address.rbs +9 -0
  174. data/sig/didit/resources/questionnaires.rbs +13 -0
  175. data/sig/didit/resources/regulatory_reports.rbs +16 -0
  176. data/sig/didit/resources/report_templates.rbs +13 -0
  177. data/sig/didit/resources/sessions.rbs +78 -0
  178. data/sig/didit/resources/transactions.rbs +43 -0
  179. data/sig/didit/resources/travel_rule.rbs +62 -0
  180. data/sig/didit/resources/users.rbs +21 -0
  181. data/sig/didit/resources/wallet_screening.rbs +11 -0
  182. data/sig/didit/resources/webhooks.rbs +23 -0
  183. data/sig/didit/resources/workflows.rbs +13 -0
  184. data/sig/didit/resources.rbs +50 -0
  185. data/sig/didit/types/account.rbs +22 -0
  186. data/sig/didit/types/account_components.rbs +94 -0
  187. data/sig/didit/types/address_validation.rbs +7 -0
  188. data/sig/didit/types/age_estimation.rbs +80 -0
  189. data/sig/didit/types/aml.rbs +174 -0
  190. data/sig/didit/types/aml_monitoring.rbs +67 -0
  191. data/sig/didit/types/analytics.rbs +57 -0
  192. data/sig/didit/types/bank.rbs +9 -0
  193. data/sig/didit/types/billing.rbs +19 -0
  194. data/sig/didit/types/biometric_templates.rbs +268 -0
  195. data/sig/didit/types/blocklist.rbs +33 -0
  196. data/sig/didit/types/businesses.rbs +54 -0
  197. data/sig/didit/types/cases.rbs +414 -0
  198. data/sig/didit/types/components.rbs +10920 -0
  199. data/sig/didit/types/customization.rbs +7 -0
  200. data/sig/didit/types/database_validation.rbs +152 -0
  201. data/sig/didit/types/document_ai.rbs +123 -0
  202. data/sig/didit/types/email.rbs +112 -0
  203. data/sig/didit/types/face_match.rbs +86 -0
  204. data/sig/didit/types/face_search.rbs +112 -0
  205. data/sig/didit/types/fraud_checks.rbs +9 -0
  206. data/sig/didit/types/id_verification.rbs +196 -0
  207. data/sig/didit/types/id_wallets.rbs +55 -0
  208. data/sig/didit/types/investigator.rbs +212 -0
  209. data/sig/didit/types/ip.rbs +7 -0
  210. data/sig/didit/types/kyb.rbs +1254 -0
  211. data/sig/didit/types/lists.rbs +106 -0
  212. data/sig/didit/types/monitoring_events.rbs +234 -0
  213. data/sig/didit/types/networks.rbs +113 -0
  214. data/sig/didit/types/passive_liveness.rbs +87 -0
  215. data/sig/didit/types/phone.rbs +65 -0
  216. data/sig/didit/types/proof_of_address.rbs +144 -0
  217. data/sig/didit/types/questionnaires.rbs +30 -0
  218. data/sig/didit/types/regulatory_reports.rbs +101 -0
  219. data/sig/didit/types/report_templates.rbs +42 -0
  220. data/sig/didit/types/sessions.rbs +1349 -0
  221. data/sig/didit/types/transactions.rbs +273 -0
  222. data/sig/didit/types/travel_rule.rbs +188 -0
  223. data/sig/didit/types/users.rbs +181 -0
  224. data/sig/didit/types/wallet_screening.rbs +40 -0
  225. data/sig/didit/types/webhooks.rbs +311 -0
  226. data/sig/didit/types/workflows.rbs +30 -0
  227. data/sig/didit/webhooks/canonical_json.rbs +25 -0
  228. data/sig/didit/webhooks/client_methods.rbs +11 -0
  229. data/sig/didit/webhooks/events.rbs +125 -0
  230. data/sig/didit/webhooks/headers.rbs +22 -0
  231. data/sig/didit/webhooks/verifier.rbs +54 -0
  232. data/sig/didit/webhooks.rbs +37 -0
  233. data/sig/didit.rbs +20 -0
  234. metadata +300 -0
@@ -0,0 +1,2820 @@
1
+ # Code generated by codegen from openapi/*.json. DO NOT EDIT.
2
+ # frozen_string_literal: true
3
+
4
+ module Didit
5
+ module Resources
6
+ # The +sessions+ resource.
7
+ class Sessions < Didit::Resource
8
+ # @return [Didit::Resources::Sessions::Imports]
9
+ def imports
10
+ @imports ||= Imports.new(@client)
11
+ end
12
+
13
+ # @return [Didit::Resources::Sessions::Reviews]
14
+ def reviews
15
+ @reviews ||= Reviews.new(@client)
16
+ end
17
+
18
+ # @return [Didit::Resources::Sessions::Signatures]
19
+ def signatures
20
+ @signatures ||= Signatures.new(@client)
21
+ end
22
+
23
+ # @return [Didit::Resources::Sessions::Webhooks]
24
+ def webhooks
25
+ @webhooks ||= Webhooks.new(@client)
26
+ end
27
+
28
+ # Add an image to a session
29
+ #
30
+ # Attach one extra image or PDF to the ID verification (`model_type=kyc`) or Proof of Address (`model_type=poa`)
31
+ # result of a finished User Verification (KYC) session, for example evidence collected outside the flow. The
32
+ # session must be `Approved`, `Declined`, `In Review` or `Kyc Expired` and carry the result named by
33
+ # `model_type`; Business Verification (KYB) sessions are not supported. Each call appends one file (to the most
34
+ # recent result when the step ran more than once), keeps the existing files and records a `FILE_ADDED` entry in
35
+ # the session activity log; the upload sends no webhook and does not change the session status. The file is
36
+ # compressed on upload and is returned in `extra_files` of the session decision. This endpoint is limited to 10
37
+ # requests per minute per API key. A scoped API key needs `sessions: write`, and without `media: read` it
38
+ # receives the `extra_files` links as `null`.
39
+ #
40
+ # +PATCH /v3/session/{sessionId}/add-images/+
41
+ #
42
+ # @param session_id [String] UUID of the User Verification (KYC) session to add the file to (the `session_id`
43
+ # returned by `POST /v3/session/`). A Business Verification (KYB) session ID returns `404`.
44
+ # @param file [Pathname, IO, String, Didit::FilePart] The image or PDF. Allowed extensions: `jpg`, `jpeg`,
45
+ # `png`, `webp`, `tiff`, `pdf`. At most 15 MB as uploaded; the file is then compressed and rejected with `400`
46
+ # if it is still larger than 2 MB (2,097,152 bytes). Empty files are rejected.
47
+ # @param model_type [String] `kyc` adds the file to the ID verification result, `poa` to the Proof of Address
48
+ # result.
49
+ # @param file_password [String] Password of an encrypted PDF. Without it, or with a wrong one, an encrypted PDF
50
+ # returns `400`.
51
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
52
+ # @return [Didit::Types::SessionsAddImagesResponse]
53
+ def add_images(session_id, file:, model_type:, file_password: OMIT, request_options: nil)
54
+ @client.request(
55
+ :patch,
56
+ "/v3/session/{sessionId}/add-images/",
57
+ path_params: { "sessionId" => session_id },
58
+ body: {
59
+ "file" => file,
60
+ "model_type" => model_type,
61
+ "file_password" => file_password
62
+ },
63
+ encoding: :multipart,
64
+ file_fields: %w[file],
65
+ response: Types::SessionsAddImagesResponse,
66
+ request_options: request_options
67
+ )
68
+ end
69
+
70
+ # Bulk delete KYC sessions by session_number
71
+ #
72
+ # Bulk delete User Verification (KYC) sessions by their numeric `session_number`, or every KYC session in your
73
+ # application with `delete_all: true`.
74
+ #
75
+ # `session_number` is the human-friendly incrementing counter shown in the Console session list and returned as
76
+ # `session_number` by the create-session and decision endpoints; it is **not** the `session_id` UUID. To delete
77
+ # a session by UUID, or to delete a Business Verification (KYB) session, which this endpoint never touches, use
78
+ # `DELETE /v3/session/{sessionId}/delete/` instead.
79
+ #
80
+ # **Up to 20 sessions are deleted in the request, more run as a job.** The number of matching sessions decides,
81
+ # whether they are selected by `session_numbers` or with `delete_all`:
82
+ # - Up to 20 matching sessions: they are deleted before the response, which is `200` with one entry per session
83
+ # in `results[]`.
84
+ # - More than 20: the response is `202` with a deletion job, and the sessions are deleted in the background.
85
+ # Poll `GET /v3/sessions/delete/{job_id}/` until `status` is `COMPLETED` or `FAILED`. A job reports counts per
86
+ # outcome, never which sessions it deleted. A `delete_all` job deletes only the sessions created before the
87
+ # request; sessions started while it runs are not deleted.
88
+ #
89
+ # Each deleted session gets exactly the same treatment as the single-session delete endpoint: the session, every
90
+ # verification attempt it holds, its decision and extracted data, its related feature records (ID verification,
91
+ # face, liveness, face match, and so on) and all of its stored files are deleted, it disappears from every read
92
+ # endpoint, and previously issued media URLs stop resolving. Webhook deliveries still queued for a deleted
93
+ # session, and their retries, are dropped; webhooks already delivered are not affected. Blocklist entries are
94
+ # **not** removed, credits already consumed are **not** refunded, and the parent User entities are **not**
95
+ # deleted (use `POST /v3/users/delete/` for those); no webhook is emitted for the deletion. Deletion is
96
+ # permanent and irreversible.
97
+ #
98
+ # **Selection semantics:**
99
+ # - With `delete_all: true` you can narrow the selection with the filters of `GET /v3/sessions/`, each prefixed
100
+ # with `filter_` (for example `filter_status`, `filter_workflow_id`, `filter_date_from`). Filters that take
101
+ # several values in List Sessions (`status`, `workflow_id`, `country`, `region`, `document_type`,
102
+ # `document_name`, `session_type`, `warning`, `organization_name`) accept a comma-separated string or an
103
+ # array; the others take one value. An empty value is ignored. Filters apply only together with `delete_all`,
104
+ # and a deletion job applies the same filters.
105
+ # - An unknown `filter_*` key, or a filter value that cannot be read, rejects the whole request with `400`
106
+ # before anything is deleted, so a mistyped filter never widens the deletion to every session.
107
+ # - Entries in `session_numbers` that do not match a live KYC session in your application (unknown numbers,
108
+ # already-deleted sessions, or sessions owned by another application) are **silently skipped**: they do not
109
+ # appear in `results` and are not counted in a job's `total`.
110
+ # - Validation failures (a non-numeric entry, an empty list, neither `session_numbers` nor `delete_all`
111
+ # provided, or a template retention the application cannot honour) reject the **whole request** with `400` and
112
+ # delete nothing.
113
+ # - Sessions are deleted in groups. If a group cannot be deleted (for example because a storage service is
114
+ # unavailable), every session in that group is reported as `face_retention_outcome: failed_retryable` and
115
+ # stays in place; the other groups are unaffected. Repeat the request for those sessions. A job retries such a
116
+ # group by itself.
117
+ # - There is no documented cap on the list length; the shared write rate limit (below) is the practical bound.
118
+ #
119
+ # **Face biometric data:** the optional `retain_face_embeddings`, `face_retention_days`,
120
+ # `face_retention_deadline`, `deletion_instruction`, and `instruction_id` fields have the same meaning as on
121
+ # `DELETE /v3/session/{sessionId}/delete/` and apply to every matched session. Each result reports its own
122
+ # `face_retention_outcome`.
123
+ #
124
+ # **Response:** `200 OK` with `results[]` for up to 20 matching sessions, or `202 Accepted` with a deletion job
125
+ # for more. Every result confirms deletion except `face_retention_outcome: failed_retryable`, which reports a
126
+ # session that was NOT deleted and should be retried. Earlier versions of this endpoint returned `204 No
127
+ # Content`; update clients that assert on `204`.
128
+ #
129
+ # **Idempotency:** repeating the same request deletes nothing more: numbers that no longer match a session are
130
+ # skipped.
131
+ #
132
+ # **`delete_all: true` (destructive):** deletes **every** remaining KYC session in the application;
133
+ # `session_numbers` is ignored when set. There is no confirmation step and no undo.
134
+ #
135
+ # **Authentication:** API key in the `x-api-key` header. Missing or invalid credentials return `403`
136
+ # (`{"detail": "You do not have permission to perform this action."}`); this API never returns `401`.
137
+ #
138
+ # **Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints;
139
+ # exceeding it returns `429`.
140
+ #
141
+ # This endpoint accepts API keys only. Business Console user Bearer tokens are rejected with `403` (unlike the
142
+ # single-session delete, which accepts both).
143
+ #
144
+ # **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is
145
+ # refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with
146
+ # `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request.
147
+ #
148
+ # +POST /v3/sessions/delete/+
149
+ #
150
+ # @param session_numbers [Array<String>] Numeric `session_number` values of the KYC sessions to delete, as
151
+ # digit-only strings (JSON numbers are also accepted and coerced). Required unless `delete_all` is `true`; an
152
+ # empty list returns `400`. Any non-digit entry rejects the whole request with `400` (unless `delete_all` is
153
+ # `true`, in which case validation is skipped and the entries are ignored). Numbers that do not match a live
154
+ # session in...
155
+ # @param delete_all [Boolean] When `true`, every remaining KYC session in the calling application is deleted and
156
+ # `session_numbers` is ignored, unless you narrow the selection with `filter_*` keys. More than 20 matching
157
+ # sessions run as a deletion job (`202`) that covers only the sessions created before the request. Defaults to
158
+ # `false`. Irreversible; there is no confirmation step.
159
+ # @param retain_face_embeddings [Boolean, nil] Override the application's `face_retention_policy` for this
160
+ # deletion. `true` keeps one image-free face biometric template anchored to the session's User after the session
161
+ # is deleted; `false` deletes the face embedding with the session; omit or `null` to follow the application
162
+ # policy. Ignored for KYB sessions and for sessions without a face embedding.
163
+ # @param face_retention_days [Integer] Finite retention duration, in days, for a retained template. Required
164
+ # when a template is retained unless the application already sets `face_retention_days`. The template's
165
+ # `expires_at` is the earliest of this duration, the application's general data-retention window, and
166
+ # `face_retention_deadline`.
167
+ # @param face_retention_deadline [Time, String] Optional hard expiry for a retained template. Must be in the
168
+ # future.
169
+ # @param deletion_instruction [String] The class of instruction you are giving. `operational_session_delete`
170
+ # deletes the session and retains a template only when the policy or `retain_face_embeddings` says so.
171
+ # `privacy_erasure` purges every retained biometric template anchored to the session's User before deleting the
172
+ # session, cannot be overridden by the application policy, and cannot be combined with `retain_face_embeddings:
173
+ # true` (`...
174
+ # @param instruction_id [String] Your durable reference for this deletion instruction (for example an
175
+ # erasure-ticket id). Recorded on the audit trail and on any retained template. Generated by Didit when omitted.
176
+ # @param filter_status [String, Array<String>] Narrows a `delete_all` to the sessions that match the `status`
177
+ # filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an
178
+ # array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
179
+ # @param filter_vendor_data [String] Narrows a `delete_all` to the sessions that match the `vendor_data` filter
180
+ # of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is
181
+ # joined into one comma-separated text, so several values are not matched as alternatives. Ignored without
182
+ # `delete_all`. An empty value is ignored and does not narrow the selection.
183
+ # @param filter_search [String] Narrows a `delete_all` to the sessions that match the `search` filter of [List
184
+ # Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into
185
+ # one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An
186
+ # empty value is ignored and does not narrow the selection.
187
+ # @param filter_workflow_id [String, Array<String>] Narrows a `delete_all` to the sessions that match the
188
+ # `workflow_id` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated
189
+ # string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
190
+ # @param filter_date_from [Date, String] Narrows a `delete_all` to the sessions that match the `date_from`
191
+ # filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array
192
+ # is joined into one comma-separated value, so several values are refused with `400`. Ignored without
193
+ # `delete_all`. An empty value is ignored and does not narrow the selection.
194
+ # @param filter_date_to [Date, String] Narrows a `delete_all` to the sessions that match the `date_to` filter of
195
+ # [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined
196
+ # into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An
197
+ # empty value is ignored and does not narrow the selection.
198
+ # @param filter_country [String, Array<String>] Narrows a `delete_all` to the sessions that match the `country`
199
+ # filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an
200
+ # array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
201
+ # @param filter_document_type [String, Array<String>] Narrows a `delete_all` to the sessions that match the
202
+ # `document_type` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A
203
+ # comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not
204
+ # narrow the selection.
205
+ # @param filter_document_name [String, Array<String>] Narrows a `delete_all` to the sessions that match the
206
+ # `document_name` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A
207
+ # comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not
208
+ # narrow the selection.
209
+ # @param filter_region [String, Array<String>] Narrows a `delete_all` to the sessions that match the `region`
210
+ # filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an
211
+ # array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
212
+ # @param filter_didit_internal_id [String] Narrows a `delete_all` to the sessions that match the
213
+ # `didit_internal_id` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value,
214
+ # not a list: an array is joined into one comma-separated value, so several values are refused with `400`.
215
+ # Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
216
+ # @param filter_session_type [String, Array<String>] Narrows a `delete_all` to the sessions that match the
217
+ # `session_type` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated
218
+ # string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
219
+ # @param filter_api_service [String] Narrows a `delete_all` to the sessions that match the `api_service` filter
220
+ # of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is
221
+ # joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`.
222
+ # An empty value is ignored and does not narrow the selection.
223
+ # @param filter_screened_full_name [String] Narrows a `delete_all` to the sessions that match the
224
+ # `screened_full_name` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value,
225
+ # not a list: an array is joined into one comma-separated text, so several values are not matched as
226
+ # alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
227
+ # @param filter_warning [String, Array<String>] Narrows a `delete_all` to the sessions that match the `warning`
228
+ # filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an
229
+ # array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
230
+ # @param filter_status_initialized_as_in_review [Boolean] Narrows a `delete_all` to the sessions that match the
231
+ # `status_initialized_as_in_review` filter of [List Sessions](/sessions-api/list-sessions), with the same
232
+ # values. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection.
233
+ # @param filter_is_kyc_to_be_reviewed [Boolean] Narrows a `delete_all` to the sessions that match the
234
+ # `is_kyc_to_be_reviewed` filter of [List Sessions](/sessions-api/list-sessions), with the same values. Ignored
235
+ # without `delete_all`. An empty value is ignored and does not narrow the selection.
236
+ # @param filter_euuid [String] Narrows a `delete_all` to the sessions that match the `euuid` filter of [List
237
+ # Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into
238
+ # one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty
239
+ # value is ignored and does not narrow the selection.
240
+ # @param filter_organization_name [String, Array<String>] Narrows a `delete_all` to the sessions that match the
241
+ # `organization_name` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A
242
+ # comma-separated string or an array. With an API key it can only match your own organization's name, so it
243
+ # selects all of your sessions or none. Ignored without `delete_all`. An empty value is ignored and does not
244
+ # narrow the selection.
245
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
246
+ # @return [Didit::Types::SessionsBatchDeleteResponse, Didit::Types::SessionDeletionJob]
247
+ def batch_delete(
248
+ session_numbers: OMIT,
249
+ delete_all: OMIT,
250
+ retain_face_embeddings: OMIT,
251
+ face_retention_days: OMIT,
252
+ face_retention_deadline: OMIT,
253
+ deletion_instruction: OMIT,
254
+ instruction_id: OMIT,
255
+ filter_status: OMIT,
256
+ filter_vendor_data: OMIT,
257
+ filter_search: OMIT,
258
+ filter_workflow_id: OMIT,
259
+ filter_date_from: OMIT,
260
+ filter_date_to: OMIT,
261
+ filter_country: OMIT,
262
+ filter_document_type: OMIT,
263
+ filter_document_name: OMIT,
264
+ filter_region: OMIT,
265
+ filter_didit_internal_id: OMIT,
266
+ filter_session_type: OMIT,
267
+ filter_api_service: OMIT,
268
+ filter_screened_full_name: OMIT,
269
+ filter_warning: OMIT,
270
+ filter_status_initialized_as_in_review: OMIT,
271
+ filter_is_kyc_to_be_reviewed: OMIT,
272
+ filter_euuid: OMIT,
273
+ filter_organization_name: OMIT,
274
+ request_options: nil
275
+ )
276
+ @client.request(
277
+ :post,
278
+ "/v3/sessions/delete/",
279
+ body: {
280
+ "session_numbers" => session_numbers,
281
+ "delete_all" => delete_all,
282
+ "retain_face_embeddings" => retain_face_embeddings,
283
+ "face_retention_days" => face_retention_days,
284
+ "face_retention_deadline" => face_retention_deadline,
285
+ "deletion_instruction" => deletion_instruction,
286
+ "instruction_id" => instruction_id,
287
+ "filter_status" => filter_status,
288
+ "filter_vendor_data" => filter_vendor_data,
289
+ "filter_search" => filter_search,
290
+ "filter_workflow_id" => filter_workflow_id,
291
+ "filter_date_from" => filter_date_from,
292
+ "filter_date_to" => filter_date_to,
293
+ "filter_country" => filter_country,
294
+ "filter_document_type" => filter_document_type,
295
+ "filter_document_name" => filter_document_name,
296
+ "filter_region" => filter_region,
297
+ "filter_didit_internal_id" => filter_didit_internal_id,
298
+ "filter_session_type" => filter_session_type,
299
+ "filter_api_service" => filter_api_service,
300
+ "filter_screened_full_name" => filter_screened_full_name,
301
+ "filter_warning" => filter_warning,
302
+ "filter_status_initialized_as_in_review" => filter_status_initialized_as_in_review,
303
+ "filter_is_kyc_to_be_reviewed" => filter_is_kyc_to_be_reviewed,
304
+ "filter_euuid" => filter_euuid,
305
+ "filter_organization_name" => filter_organization_name
306
+ },
307
+ response: { 200 => Types::SessionsBatchDeleteResponse, 202 => Types::SessionDeletionJob },
308
+ request_options: request_options
309
+ )
310
+ end
311
+
312
+ # Bulk update AML hit review statuses
313
+ #
314
+ # Update the review status of **multiple AML hits** in one call. Provide `hit_updates`, a list of `{ hit_id,
315
+ # review_status }` pairs. `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or
316
+ # `Inconclusive`.
317
+ #
318
+ # The update is all-or-nothing: if any `hit_id` is not found in the AML check, the request returns `404` and no
319
+ # hit is changed. A successful call fires a single `data.updated` webhook and records one activity entry
320
+ # covering all changes. For graph workflows with multiple AML checks, pass `node_id` to target a specific check.
321
+ #
322
+ # Authenticate with your API key (`x-api-key`) or a user authorization header - either must carry the
323
+ # `write:sessions` privilege.
324
+ #
325
+ # +PATCH /v3/session/{sessionId}/bulk-update-aml-hit-status/+
326
+ #
327
+ # @param session_id [String] UUID of the verification session. Accepts both user (KYC) and business (KYB)
328
+ # session IDs - the service resolves the ID across both session types.
329
+ # @param hit_updates [Array<Hash>] Non-empty list of hit updates.
330
+ # @param node_id [String] Optional graph node ID. Use it (here or as a query parameter) when the session has
331
+ # multiple AML checks.
332
+ # @param node_id_query [String] Workflow graph node ID. Required only when the session has multiple AML checks
333
+ # (one per node); omit it for single-AML sessions.
334
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
335
+ # @return [Didit::Types::SessionsBulkUpdateAmlHitStatusResponse]
336
+ def bulk_update_aml_hit_status(session_id, hit_updates:, node_id: OMIT, node_id_query: OMIT, request_options: nil)
337
+ @client.request(
338
+ :patch,
339
+ "/v3/session/{sessionId}/bulk-update-aml-hit-status/",
340
+ path_params: { "sessionId" => session_id },
341
+ query: {
342
+ "node_id" => node_id_query
343
+ },
344
+ body: {
345
+ "hit_updates" => hit_updates,
346
+ "node_id" => node_id
347
+ },
348
+ response: Types::SessionsBulkUpdateAmlHitStatusResponse,
349
+ request_options: request_options
350
+ )
351
+ end
352
+
353
+ # Cancel a check override that waits for the flow to finish
354
+ #
355
+ # Cancel an override of a feature (step) status that is still `pending_until_flow_finishes`, so it never
356
+ # applies. The check keeps its status, the cancellation is recorded in the session's activity as
357
+ # `FEATURE_OVERRIDE_CANCELLED`, and no webhook is sent. The response is the override with `state: cancelled` and
358
+ # `cancel_reason: cancelled_by_reviewer`.
359
+ #
360
+ # An override that already applied or was cancelled returns `409` with the code `feature_override_not_pending`.
361
+ # Find override IDs with `GET /v3/session/{sessionId}/features/overrides/` or in the `override` returned by the
362
+ # feature status update.
363
+ #
364
+ # Requires the `write:sessions` privilege; a scoped API key needs write access to decisions.
365
+ #
366
+ # +POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/+
367
+ #
368
+ # @param session_id [String] UUID of the verification session. Accepts both user (KYC) and business (KYB)
369
+ # session IDs.
370
+ # @param override_id [String] The `id` of the override to cancel.
371
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
372
+ # @return [Didit::Types::FeatureStatusOverride]
373
+ def cancel_feature_override(session_id, override_id, request_options: nil)
374
+ @client.request(
375
+ :post,
376
+ "/v3/session/{sessionId}/features/overrides/{overrideId}/cancel/",
377
+ path_params: { "sessionId" => session_id, "overrideId" => override_id },
378
+ response: Types::FeatureStatusOverride,
379
+ request_options: request_options
380
+ )
381
+ end
382
+
383
+ # Create a verification session
384
+ #
385
+ # Create a User Verification (KYC) or Business Verification (KYB) session and receive a hosted verification
386
+ # `url` plus a `session_token` to redirect or embed for your end user. The `workflow_id` selects which
387
+ # verification steps run and whether the session is KYC or KYB.
388
+ #
389
+ # Call this from your backend (never the browser - the API key is a secret) whenever a user or business needs to
390
+ # be verified: at signup, before a sensitive action, or when re-verification is required. Prerequisites: a
391
+ # published workflow (created in the Console [Workflows](https://docs.didit.me/console/workflows) page) and an
392
+ # application API key with available credits. Sandbox applications bypass the credit check.
393
+ #
394
+ # **Idempotency:** when `vendor_data` is provided and an unfinished session (`Not Started`, `In Progress`,
395
+ # `Resubmitted`, or `Awaiting User`) with the same `vendor_data` already exists on the workflow's **current
396
+ # latest published version** (and that session already has a hosted verification URL), the existing session is
397
+ # returned (still `201`) instead of creating a duplicate - with its `callback` and `metadata` updated to the
398
+ # newly provided values. An unfinished session created on an older version of the workflow (one that has since
399
+ # been republished) is **not** reused; a new session pinned to the latest published version is created instead.
400
+ # Sessions in `Approved`, `Declined`, `In Review`, `Expired`, `Abandoned`, or `Kyc Expired` are never reused.
401
+ #
402
+ # **Side effects:** the hosted verification URL is generated and stored; if
403
+ # `contact_details.send_notification_emails` is `true` and an email is provided, a verification invite email is
404
+ # sent. The session expires after the workflow's configured session expiration time. For KYB workflows,
405
+ # `contact_details.phone` and `expected_details` are ignored.
406
+ #
407
+ # +POST /v3/session/+
408
+ #
409
+ # @param workflow_id [String] Stable identifier of the workflow that defines which verification steps the
410
+ # session will run. Workflows are created and managed in the [Workflows](/console/workflows) page of the
411
+ # Console. The `workflow_id` also implicitly selects whether the session is KYC or KYB.
412
+ # @param vendor_data [String] A unique identifier for the user being verified, such as a UUID, email, or
413
+ # internal user ID. This field is used for: (1) **User grouping** - sessions with the same vendor_data are
414
+ # linked to the same user profile in the Users tab. (2) **Cross-session duplicate detection** - when checking
415
+ # for duplicated faces, documents, phone numbers, emails, IP addresses, or device fingerprints, sessions with
416
+ # the...
417
+ # @param callback [String] URL to redirect the user to after verification completes. Didit automatically appends
418
+ # `verificationSessionId` and `status` (Approved, Declined, In Review) as query parameters. Custom URL schemes
419
+ # (e.g. `myapp://`) are supported for mobile callbacks. If omitted, the workflow's default `callback_url` is
420
+ # used. When the application has allowed domains (`allowed_domains` on `PATCH /v3/webhook/`), an `h...
421
+ # @param callback_method [String] Determines which device should handle the redirect to the provided callback
422
+ # URL. Use `initiator` to redirect only the device that started the flow, `completer` for the device that
423
+ # finishes it, or `both` to allow either device to trigger the callback. If you ever notice the callback not
424
+ # triggering reliably, we recommend setting this value to `both`.
425
+ # @param metadata [Object] Arbitrary JSON stored with the session and echoed back in the response and webhooks.
426
+ # Any JSON value is accepted (object, string, number, array), but a JSON object of key/value pairs is
427
+ # recommended. Not shown to the end user. Use it to pass your own correlation ids, A/B variants, or business
428
+ # context.
429
+ # @param tags [Array<String>] Tags added to the session when it is created, by name. Up to 10, each up to 50
430
+ # characters. Names are case-insensitive and stored in upper case. A name that does not exist yet in the
431
+ # application is created as a new tag. The tags show on the session in the console, where you can filter by
432
+ # them.
433
+ # @param language [String] Language code (ISO 639-1) for the verification process interface. Controls the
434
+ # language displayed to the end user during verification. If not provided, the browser's language will be
435
+ # automatically detected and used. Check all the supported languages [here](/integration/supported-languages).
436
+ # @param contact_details [Hash] User contact information that can be used for notifications, prefilling
437
+ # verification forms, and phone verification. This includes email address, preferred language for
438
+ # communications, and phone number.
439
+ # @param expected_details [Hash] Expected user details used to cross-validate against the data extracted from
440
+ # the user's ID document, Proof of Address, and other verification steps. Mismatches are surfaced as warnings on
441
+ # the decision; some fields (e.g. `id_country`, `expected_document_types`) also alter the user-facing flow. For
442
+ # Business Verification (KYB) workflows only the business fields (`company_name`, `registry_country`, `...
443
+ # @param portrait_image [String] Base64-encoded portrait image of the end user's face (max 2MB; JPEG, PNG, WebP,
444
+ # or TIFF). Used as the reference image to match against the liveness capture when the workflow is a `Biometric
445
+ # Authentication` workflow with Face Match enabled, or any graph workflow where Face Match runs before ID
446
+ # Verification (OCR). Optional when the `vendor_data` user already has a stored face image: Didit reuses it...
447
+ # @param sandbox_scenario [String] Sandbox-only scenario slug. Only accepted when the API key belongs to a
448
+ # sandbox-mode application; rejected on live applications. When set, the create flow expands the scenario's
449
+ # bundled magic values onto the session's input fields (contact_details, expected_details) so the mocked
450
+ # providers reproduce the scenario's outcome through the real workflow pipeline. See the scenario catalog at GET
451
+ # /v1/san...
452
+ # @param sign [Hash] Electronic Signature input for this session. `documents` are the documents to sign, for a
453
+ # workflow whose Electronic Signature step takes documents from the session (`signature_documents_source`
454
+ # `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill`
455
+ # is `api.<key>`, on workflow and session documents alike. Creating a session again for the same `...
456
+ # @param user_state [String] Where the person lives, when you know it: an ISO 3166-2 subdivision code (`US-IL`,
457
+ # `ES-M`) or a US state code or name (`IL`, `Illinois`). A state whose law requires explicit biometric consent
458
+ # (Illinois, Texas, Colorado) makes the verification flow ask for it before capturing a face, with trigger
459
+ # `declared_state`. An unrecognized value returns `400`. See [Biometric consent](/getting-started/biomet...
460
+ # @param biometric_consent [Hash] Explicit biometric consent you already collected from the person. It satisfies
461
+ # the requirement, so the verification flow does not ask again, and the decision records it as `status: "given"`
462
+ # with trigger `customer_collected`. An answer the person already gave in the flow is never replaced. See
463
+ # [Biometric consent](/getting-started/biometric-consent).
464
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
465
+ # @return [Didit::Types::SessionsCreateResponse]
466
+ def create(
467
+ workflow_id:,
468
+ vendor_data: OMIT,
469
+ callback: OMIT,
470
+ callback_method: OMIT,
471
+ metadata: OMIT,
472
+ tags: OMIT,
473
+ language: OMIT,
474
+ contact_details: OMIT,
475
+ expected_details: OMIT,
476
+ portrait_image: OMIT,
477
+ sandbox_scenario: OMIT,
478
+ sign: OMIT,
479
+ user_state: OMIT,
480
+ biometric_consent: OMIT,
481
+ request_options: nil
482
+ )
483
+ @client.request(
484
+ :post,
485
+ "/v3/session/",
486
+ body: {
487
+ "workflow_id" => workflow_id,
488
+ "vendor_data" => vendor_data,
489
+ "callback" => callback,
490
+ "callback_method" => callback_method,
491
+ "metadata" => metadata,
492
+ "tags" => tags,
493
+ "language" => language,
494
+ "contact_details" => contact_details,
495
+ "expected_details" => expected_details,
496
+ "portrait_image" => portrait_image,
497
+ "sandbox_scenario" => sandbox_scenario,
498
+ "sign" => sign,
499
+ "user_state" => user_state,
500
+ "biometric_consent" => biometric_consent
501
+ },
502
+ response: Types::SessionsCreateResponse,
503
+ request_options: request_options
504
+ )
505
+ end
506
+
507
+ # Delete a verification session (KYC or KYB)
508
+ #
509
+ # Delete a single verification session, User Verification (KYC) or Business Verification (KYB), by its
510
+ # `session_id`. The id is resolved against KYC sessions first, then KYB sessions, so both kinds are deleted
511
+ # through this one URL.
512
+ #
513
+ # **What is deleted:**
514
+ # - The session and every verification attempt it holds, including results that a resubmission replaced: the
515
+ # decision, extracted data, all related feature records (ID verification, face, liveness, face match, AML,
516
+ # registry checks, IP analysis, and so on), its reviews and its activity log.
517
+ # - All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred
518
+ # variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference
519
+ # images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded
520
+ # files (KYC); uploaded company documents and extra files (KYB). Electronic Signature documents, signed PDFs,
521
+ # evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media
522
+ # URLs (`https://<media-host>/...`) stop resolving.
523
+ # - The session's face data. Its face embedding is deleted too, unless you choose to keep an image-free template
524
+ # (see **Face biometric data**).
525
+ # - Webhook deliveries still queued for the session, and their retries. Webhooks already delivered are not
526
+ # affected.
527
+ # - For a Business Verification (KYB) session: the verifications it created for its key people (KYC) and its
528
+ # corporate owners (KYB), recursively, reported as `deleted_child_verifications`. A verification it only links
529
+ # to, such as an existing approved KYC it reused, is not deleted.
530
+ #
531
+ # The session disappears from every read endpoint immediately: `GET /v3/session/{sessionId}/decision/` returns
532
+ # `404` and `GET /v3/sessions/` stops listing it. Ongoing AML monitoring and KYB registry monitoring started by
533
+ # the deleted verifications stop.
534
+ #
535
+ # **What is not affected:** blocklist entries created from this session (face or document) are **not** removed;
536
+ # manage those with the blocklist endpoints. Share tokens issued for the session are not revoked, but there is
537
+ # nothing left for them to import: an import with one returns `400` with `{"share_token": ["Original session
538
+ # does not exist."]}`. Credits already consumed are **not** refunded. The parent User or Business entity is
539
+ # **not** deleted; use `POST /v3/users/delete/` or `POST /v3/businesses/delete/` for those. If the User's
540
+ # profile portrait came from this session, the portrait is removed with it.
541
+ #
542
+ # **Face biometric data:** by default the session's face embedding is deleted with the session
543
+ # (`face_retention_outcome: deleted`). An application that opted in to biometric-template retention
544
+ # (`face_retention_policy: retain_until_user_deleted` on `PATCH /v3/webhook/`), or a request with
545
+ # `retain_face_embeddings: true`, keeps one separately managed, image-free face biometric template anchored to
546
+ # the session's User (`retained_with_user`) so that duplicate detection, Face Search, and biometric
547
+ # authentication keep working. The template never contains the face image, media, identity fields, the decision,
548
+ # or the deleted session's id; it is biometric data deleted at `biometric_template_expires_at`, or earlier on
549
+ # User deletion, privacy erasure, or an explicit purge through `/v3/biometric-templates/`. A session without a
550
+ # linked User cannot retain a template (`ineligible_no_vendor_user`). Send `deletion_instruction:
551
+ # privacy_erasure` for data-subject requests: it purges every retained template for that User and never retains
552
+ # a new one.
553
+ #
554
+ # **Irreversible:** deletion is permanent and there is no restore endpoint. Export anything you need (for
555
+ # example a decision PDF) before you call it.
556
+ #
557
+ # **Side effects:** no webhook is emitted for deletions.
558
+ #
559
+ # **Response:** `200 OK` once the deletion has completed, with a JSON body reporting the
560
+ # `face_retention_outcome`, the retained template's expiry and, for a KYB session,
561
+ # `deleted_child_verifications`. Earlier versions of this endpoint returned `204 No Content`; update clients
562
+ # that assert on `204`. Keep your `instruction_id` in your own erasure log.
563
+ #
564
+ # **Idempotency:** not idempotent at the HTTP level: the first call returns `200`; repeating it returns `404`
565
+ # because the session no longer resolves. After a `503` the session is still in place; repeat the same request
566
+ # to finish deleting it.
567
+ #
568
+ # **Authentication:** send your application's API key in the `x-api-key` header; the session must belong to that
569
+ # application. Console user access tokens (`Authorization: Bearer ...`) may also call this endpoint when they
570
+ # carry the `delete:sessions` permission. Authentication and permission failures both return `403`; this API
571
+ # never returns `401`.
572
+ #
573
+ # **Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints;
574
+ # exceeding it returns `429`.
575
+ #
576
+ # To bulk-delete KYC sessions by their numeric `session_number`, use `POST /v3/sessions/delete/` instead.
577
+ #
578
+ # **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is
579
+ # refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with
580
+ # `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request.
581
+ #
582
+ # +DELETE /v3/session/{sessionId}/delete/+
583
+ #
584
+ # @param session_id [String] UUID (`session_id`) of the User Verification (KYC) or Business Verification (KYB)
585
+ # session to delete, as returned when the session was created. Must be a canonical hyphenated UUID - a non-UUID
586
+ # value does not match the route and returns `404`.
587
+ # @param retain_face_embeddings [Boolean, nil] Override the application's `face_retention_policy` for this
588
+ # deletion. `true` keeps one image-free face biometric template anchored to the session's User after the session
589
+ # is deleted; `false` deletes the face embedding with the session; omit or `null` to follow the application
590
+ # policy. Ignored for KYB sessions and for sessions without a face embedding.
591
+ # @param face_retention_days [Integer] Finite retention duration, in days, for a retained template. Required
592
+ # when a template is retained unless the application already sets `face_retention_days`. The template's
593
+ # `expires_at` is the earliest of this duration, the application's general data-retention window, and
594
+ # `face_retention_deadline`.
595
+ # @param face_retention_deadline [Time, String] Optional hard expiry for a retained template. Must be in the
596
+ # future.
597
+ # @param deletion_instruction [String] The class of instruction you are giving. `operational_session_delete`
598
+ # deletes the session and retains a template only when the policy or `retain_face_embeddings` says so.
599
+ # `privacy_erasure` purges every retained biometric template anchored to the session's User before deleting the
600
+ # session, cannot be overridden by the application policy, and cannot be combined with `retain_face_embeddings:
601
+ # true` (`...
602
+ # @param instruction_id [String] Your durable reference for this deletion instruction (for example an
603
+ # erasure-ticket id). Recorded on the audit trail and on any retained template. Generated by Didit when omitted.
604
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
605
+ # @return [Didit::Types::SessionsDeleteResponse]
606
+ def delete(
607
+ session_id,
608
+ retain_face_embeddings: OMIT,
609
+ face_retention_days: OMIT,
610
+ face_retention_deadline: OMIT,
611
+ deletion_instruction: OMIT,
612
+ instruction_id: OMIT,
613
+ request_options: nil
614
+ )
615
+ @client.request(
616
+ :delete,
617
+ "/v3/session/{sessionId}/delete/",
618
+ path_params: { "sessionId" => session_id },
619
+ body: {
620
+ "retain_face_embeddings" => retain_face_embeddings,
621
+ "face_retention_days" => face_retention_days,
622
+ "face_retention_deadline" => face_retention_deadline,
623
+ "deletion_instruction" => deletion_instruction,
624
+ "instruction_id" => instruction_id
625
+ },
626
+ response: Types::SessionsDeleteResponse,
627
+ request_options: request_options
628
+ )
629
+ end
630
+
631
+ # Export AML screening history as CSV
632
+ #
633
+ # Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV
634
+ # file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole
635
+ # (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated,
636
+ # and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB
637
+ # session IDs; pass `node_id` when the session ran more than one AML step. Errors are returned as JSON, not CSV.
638
+ # A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media:
639
+ # read` gets `403`.
640
+ #
641
+ # +GET /v3/session/{sessionId}/aml-screening-history/export/+
642
+ #
643
+ # @param session_id [String] UUID of the verification session (the `session_id` returned by `POST
644
+ # /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server
645
+ # resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the
646
+ # route and returns an HTML `404`.
647
+ # @param node_id [String] Workflow graph node ID of the AML check. Needed only when the session ran more than
648
+ # one AML step; without it the most recent AML check is used. An unknown node returns `404`.
649
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
650
+ # @return [String, nil] the body bytes, or nil when a block receives the chunks
651
+ def export_aml_screening_history(session_id, node_id: OMIT, request_options: nil, &block)
652
+ @client.request(
653
+ :get,
654
+ "/v3/session/{sessionId}/aml-screening-history/export/",
655
+ path_params: { "sessionId" => session_id },
656
+ query: {
657
+ "node_id" => node_id
658
+ },
659
+ response: :binary,
660
+ accept: "text/csv, application/json",
661
+ request_options: request_options, &block
662
+ )
663
+ end
664
+
665
+ # Download a PDF report for a verification session
666
+ #
667
+ # Render and download a compliance-ready PDF report for a finished verification session. The same path serves
668
+ # both User Verification (KYC) and Business Verification (KYB) sessions - the server resolves the `sessionId`
669
+ # against both session types and picks the matching report template.
670
+ #
671
+ # **Eligible statuses.** The session must already carry a final or reviewable status:
672
+ #
673
+ # - KYC sessions: `Approved`, `Declined`, `In Review`, or `Kyc Expired`.
674
+ # - KYB sessions: `Approved`, `Declined`, or `In Review`.
675
+ #
676
+ # Any other status (`Not Started`, `In Progress`, `Expired`, `Abandoned`, …) returns `403` with an explanatory
677
+ # `detail` string - see the `403` response below.
678
+ #
679
+ # **What the report contains.** The PDF mirrors the console session view at the moment of the request:
680
+ #
681
+ # - **KYC** - rolled-up session status, the warnings list, and one section per executed feature: ID Verification
682
+ # (document images plus extracted fields), NFC, Liveness, Face Match, Email Verification, Phone Verification,
683
+ # Proof of Address, Questionnaire answers, Database Validation, AML Screening, and IP Analysis - followed by
684
+ # session tags, console review activity (comments and status changes), and the session event timeline.
685
+ # - **KYB** - registry checks (company data), AML screenings, business document verifications, key-people
686
+ # checks, questionnaire responses, phone/email verifications, IP analyses, and the session event timeline,
687
+ # followed by tags and review activity.
688
+ #
689
+ # **Branding.** If your application has white-label customization, the report is rendered with your logo and
690
+ # links to your privacy-policy URL; otherwise it carries Didit branding. Reports are rendered in English - there
691
+ # is no language parameter.
692
+ #
693
+ # **No caching.** Every call re-renders the PDF from the current session data, so a report generated after a
694
+ # manual review reflects the reviewer’s decision. Two calls for the same session can produce byte-different
695
+ # files - archive the downloaded file if you need an immutable copy.
696
+ #
697
+ # **Latency.** Rendering downloads every stored image (document sides, selfies, extra files) before composing
698
+ # the PDF, so media-heavy sessions can take several seconds. Use a generous client read timeout (60 s
699
+ # recommended) and stream the body to disk.
700
+ #
701
+ # **Trailing slash.** The canonical route ends with a trailing slash (`…/generate-pdf/`). A request without it
702
+ # is served directly with the same response - there is no `301` redirect, so no client has to follow redirects
703
+ # and `curl` does not need `-L`. Use the slashed URL as in the samples.
704
+ #
705
+ # If you need the underlying data as JSON instead of a rendered report, use `GET
706
+ # /v3/session/{sessionId}/decision/`. For every reportable session of one user in a single document, use `GET
707
+ # /v3/users/{vendor_data}/generate-pdf/`.
708
+ #
709
+ # +GET /v3/session/{sessionId}/generate-pdf/+
710
+ #
711
+ # @param session_id [String] UUID of the User Verification (KYC) or Business Verification (KYB) session to
712
+ # render - the `session_id` returned by `POST /v3/session/`. The same path works for both session kinds; use the
713
+ # `Content-Disposition` filename on the response to tell which report type you received. **Must be a
714
+ # well-formed, lowercase UUID.** The route only matches valid UUIDs, so a malformed value is rejected by the
715
+ # URL...
716
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
717
+ # @return [String, nil] the body bytes, or nil when a block receives the chunks
718
+ def generate_pdf(session_id, request_options: nil, &block)
719
+ @client.request(
720
+ :get,
721
+ "/v3/session/{sessionId}/generate-pdf/",
722
+ path_params: { "sessionId" => session_id },
723
+ response: :binary,
724
+ accept: "application/pdf, application/json",
725
+ request_options: request_options, &block
726
+ )
727
+ end
728
+
729
+ # Redeem a share token to clone a verification session into your application
730
+ #
731
+ # Redeem a share token to clone a KYC or KYB session into the calling application with a fresh `session_id`. Not
732
+ # idempotent - a token redeems once per receiver.
733
+ #
734
+ # +POST /v3/session/import-shared/+
735
+ #
736
+ # @param share_token [String] JWT share token issued by [`POST
737
+ # /v3/session/{sessionId}/share/`](/sessions-api/share-session).
738
+ # @param trust_review [Boolean] If `true`, the cloned session keeps the source's final `status`. If `false`, it
739
+ # is forced into `In Review`.
740
+ # @param workflow_id [String] UUID of a workflow in the calling application. Cross-application IDs are rejected
741
+ # with `404`.
742
+ # @param vendor_data [String, nil] Optional override for the cloned session's `vendor_data`.
743
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
744
+ # @return [Didit::Types::SessionDecision]
745
+ def import_shared(share_token:, trust_review:, workflow_id:, vendor_data: OMIT, request_options: nil)
746
+ @client.request(
747
+ :post,
748
+ "/v3/session/import-shared/",
749
+ body: {
750
+ "share_token" => share_token,
751
+ "trust_review" => trust_review,
752
+ "workflow_id" => workflow_id,
753
+ "vendor_data" => vendor_data
754
+ },
755
+ response: Types::SessionDecision,
756
+ request_options: request_options
757
+ )
758
+ end
759
+
760
+ # List verification sessions (KYC and/or KYB) with filters and pagination
761
+ #
762
+ # Returns a paginated list of verification sessions for the application identified by your API key, newest first
763
+ # (descending `session_number`).
764
+ #
765
+ # **Canonical URL:** the route is `/v3/sessions/` (trailing slash). Requests to `/v3/sessions` without the slash
766
+ # receive a `301` redirect to the slashed URL with the query string preserved; most HTTP clients follow it
767
+ # transparently on GET.
768
+ #
769
+ # **When to use this endpoint vs webhooks.** Use this endpoint for dashboards, back-office search,
770
+ # reconciliation, and batch exports. Do not poll it to track the progress of individual verifications -
771
+ # configure [webhooks](/integration/webhooks) instead, which push `status.updated` events the moment a session
772
+ # changes. For one session's full result, call `GET /v3/session/{sessionId}/decision/`.
773
+ #
774
+ # **KYC and KYB sessions.** `session_kind` selects which kinds are listed:
775
+ # - `user` (default) - User Verification (KYC) sessions only. Backward-compatible behavior.
776
+ # - `business` - Business Verification (KYB) sessions only. Rows have a different, smaller shape (see the
777
+ # response schema).
778
+ # - `all` - both kinds in one response: the KYC page and the KYB page for the same `limit`/`offset` are
779
+ # concatenated in `results` (KYC rows first), so a page can contain up to `2 x limit` rows. `count` is the sum
780
+ # of both kinds and `next`/`previous` reflect the KYC-side pagination. For strict pagination of mixed data,
781
+ # call `user` and `business` separately.
782
+ #
783
+ # Every row carries a `session_kind` discriminator (`"user"` or `"business"`).
784
+ #
785
+ # **Pagination.** Standard limit/offset: `limit` (default 50) and `offset` (default 0), with `next`/`previous`
786
+ # ready-made page URLs. For KYC rows `count` is exact. For KYB rows `count` is computed with a bounded scan and
787
+ # is capped at 100 - when there are more than 100 matches it stays at 100, so iterate using `next` (or by
788
+ # checking whether a full page came back) rather than computing total pages from `count`.
789
+ #
790
+ # **Filter semantics.** All filters combine with AND and apply to KYC rows. When `session_kind` is `business` or
791
+ # `all`, the KYB side honors the shared parameters `vendor_data`, `status`, `workflow_id`, `country`
792
+ # (registry-company country code), `date_from`, `date_to`, `search` (company name, registration number - type
793
+ # registration numbers without separators, e.g. `DPC001` not `DPC-001` - vendor_data, session number, or session
794
+ # UUID), `warning`, and `organization_name`; the remaining KYC-only filters are ignored for KYB rows.
795
+ # Comma-separated parameters (`status`, `country`, `document_type`, `region`, `workflow_id`, `document_name`,
796
+ # `warning`, `organization_name`, `session_type`) match any of the listed values (OR within the parameter).
797
+ # `vendor_data` is an exact match - use `search` for partial matching. Unknown values in list filters simply
798
+ # return no rows (no error); malformed typed values (`date_from`, `date_to`, `didit_internal_id`, `api_service`,
799
+ # `session_kind`) return `400` with a per-field error object.
800
+ #
801
+ # **Search.** `search` adapts to the input: a full UUID looks up `session_id`; digits (with optional `+ - .
802
+ # space`) match session-number prefix, document/personal numbers, phone-number prefix, or `vendor_data`; values
803
+ # containing `@` match email prefixes; any other text matches names (accent-insensitive) and `vendor_data`.
804
+ #
805
+ # No fixed per-endpoint rate limit is enforced, but keep list polling infrequent and rely on webhooks for
806
+ # real-time updates.
807
+ #
808
+ # +GET /v3/sessions/+
809
+ #
810
+ # @param session_kind [String] Which kind of sessions to list: `user` (KYC only, default), `business` (KYB
811
+ # only), or `all` (both, concatenated - see the description for merged-pagination semantics). Matching is
812
+ # case-insensitive (`BUSINESS` works); any value other than a case variant of `user`/`business`/`all` returns
813
+ # `400`.
814
+ # @param limit [Integer] Maximum number of rows per page (per kind when `session_kind=all`). Defaults to 50.
815
+ # @param offset [Integer] Number of rows to skip before the first returned row. Defaults to 0. Prefer following
816
+ # the `next`/`previous` URLs from the response.
817
+ # @param status [String] Comma-separated list of session statuses to include, e.g. `Approved,In Review`. Values
818
+ # are case-sensitive; see [Verification Statuses](/integration/verification-statuses). Unknown values match
819
+ # nothing.
820
+ # @param vendor_data [String] Exact-match filter on the `vendor_data` you sent at session creation (your own
821
+ # user/business identifier). For partial matches use `search` instead.
822
+ # @param search [String] A complete displayed reference such as `S-0001` (user) or `B-0001` (business) matches
823
+ # only that session number and kind; leading zeros and letter case do not affect matching. Smart free-text
824
+ # search. A full UUID matches `session_id`; numeric input matches session-number prefix, document/personal
825
+ # numbers, phone prefix, or `vendor_data`; input containing `@` matches email prefixes; other text matche...
826
+ # @param workflow_id [String] Comma-separated workflow UUIDs (find them on the Workflows page in the Console).
827
+ # Malformed UUIDs in the list are ignored; if none are valid the result is empty.
828
+ # @param date_from [Date, String] Only sessions created on or after this date (UTC), format `YYYY-MM-DD`.
829
+ # Malformed dates return `400`.
830
+ # @param date_to [Date, String] Only sessions created up to this date (UTC), format `YYYY-MM-DD`. For KYC rows
831
+ # the entire day is included; for KYB rows the comparison is `created_at <= date_to` (midnight), so use the next
832
+ # day's date to include a full day of KYB sessions.
833
+ # @param country [String] Comma-separated country filter. For KYC rows: ISO 3166-1 alpha-3 codes of the ID
834
+ # document's issuing state (e.g. `ESP,USA`), which may differ from nationality. For KYB rows: the registry
835
+ # company's country code.
836
+ # @param document_type [String] Comma-separated ID-document type codes verified in the session (KYC rows only):
837
+ # `P` (Passport), `ID` (Identity Card), `DL` (Driver's License), `RP` (Residence Permit), `SSC` (Social Security
838
+ # Card), `HIC` (Health Insurance Card), `WP` (Work Permit), `TC` (Tax Card), `VISA`, `PSC` (Public Service
839
+ # Card), `BC` (Birth Certificate), `OTHER`. Note the response field `document_type` contains the display...
840
+ # @param document_name [String] Exact document names; multiple names can be passed comma-separated, but the
841
+ # value is only split on commas when it contains more than one ` - ` separator (a lone name with an embedded
842
+ # comma is matched whole). Names are as recognized by document verification (front or back side), e.g. `Spain -
843
+ # Id Card (2021)`. KYC rows only.
844
+ # @param region [String] Comma-separated document region/state values (for documents issued per region, such as
845
+ # US driver's licenses). KYC rows only.
846
+ # @param didit_internal_id [String] Filter by Didit's internal user identifier (the `didit_internal_id` response
847
+ # field) to list all sessions of one verified user. Must be a valid UUID; malformed values return `400`. KYC
848
+ # rows only.
849
+ # @param session_type [String] Comma-separated session creation channels: `API`, `HOSTED`, `MIGRATED`. The
850
+ # special value `ALL` (or omitting the parameter) disables the filter. KYC rows only.
851
+ # @param api_service [String] Filter standalone API sessions by service. Invalid values return `400`. KYC rows
852
+ # only.
853
+ # @param screened_full_name [String] Accent-insensitive name search inside AML and database-validation screened
854
+ # data. When combined with `api_service=AML` or `api_service=DATABASE_VALIDATION`, the search is restricted to
855
+ # that feature's screened data. KYC rows only.
856
+ # @param warning [String] Comma-separated warning risk codes; returns sessions that raised any of them (e.g.
857
+ # `POSSIBLE_FRAUD`). Risk codes are listed per feature in the [warnings documentation](/integration/webhooks).
858
+ # Applies to KYC rows and, with business warning codes, to KYB rows.
859
+ # @param status_initialized_as_in_review [Boolean] When `true`, only sessions whose decision initially landed in
860
+ # `In Review` (useful to audit manual-review volume). KYC rows only.
861
+ # @param is_kyc_to_be_reviewed [Boolean] `true` returns sessions whose document verification is flagged for
862
+ # manual review; `false` returns sessions with document verification explicitly not flagged. Omit to disable.
863
+ # KYC rows only.
864
+ # @param euuid [String] Filter by the end user's euuid (UUID assigned to the verifying user, used by Console
865
+ # deep links). Must be a valid UUID; malformed values return a 400 field error. KYC rows only.
866
+ # @param organization_name [String] Comma-separated organization names. Console-oriented; with an API key
867
+ # (already scoped to one application) it only matches your own organization's name.
868
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
869
+ # @return [Didit::Page<Didit::Types::SessionsListResponseResults>]
870
+ def list(
871
+ session_kind: OMIT,
872
+ limit: OMIT,
873
+ offset: OMIT,
874
+ status: OMIT,
875
+ vendor_data: OMIT,
876
+ search: OMIT,
877
+ workflow_id: OMIT,
878
+ date_from: OMIT,
879
+ date_to: OMIT,
880
+ country: OMIT,
881
+ document_type: OMIT,
882
+ document_name: OMIT,
883
+ region: OMIT,
884
+ didit_internal_id: OMIT,
885
+ session_type: OMIT,
886
+ api_service: OMIT,
887
+ screened_full_name: OMIT,
888
+ warning: OMIT,
889
+ status_initialized_as_in_review: OMIT,
890
+ is_kyc_to_be_reviewed: OMIT,
891
+ euuid: OMIT,
892
+ organization_name: OMIT,
893
+ request_options: nil
894
+ )
895
+ @client.request(
896
+ :get,
897
+ "/v3/sessions/",
898
+ query: {
899
+ "session_kind" => session_kind,
900
+ "limit" => limit,
901
+ "offset" => offset,
902
+ "status" => status,
903
+ "vendor_data" => vendor_data,
904
+ "search" => search,
905
+ "workflow_id" => workflow_id,
906
+ "date_from" => date_from,
907
+ "date_to" => date_to,
908
+ "country" => country,
909
+ "document_type" => document_type,
910
+ "document_name" => document_name,
911
+ "region" => region,
912
+ "didit_internal_id" => didit_internal_id,
913
+ "session_type" => session_type,
914
+ "api_service" => api_service,
915
+ "screened_full_name" => screened_full_name,
916
+ "warning" => warning,
917
+ "status_initialized_as_in_review" => status_initialized_as_in_review,
918
+ "is_kyc_to_be_reviewed" => is_kyc_to_be_reviewed,
919
+ "euuid" => euuid,
920
+ "organization_name" => organization_name
921
+ },
922
+ page: Types::SessionsListResponseResults,
923
+ request_options: request_options
924
+ )
925
+ end
926
+
927
+ # List AML screening history
928
+ #
929
+ # List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`,
930
+ # including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves,
931
+ # so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session
932
+ # IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed
933
+ # (the first screening is part of the session decision) and runs from before this history existed are not
934
+ # reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and
935
+ # capped at 100 above that, so follow `next` until it is `null`. A scoped API key needs `decisions: read`; see
936
+ # [Continuous AML
937
+ # monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening).
938
+ #
939
+ # +GET /v3/session/{sessionId}/aml-screening-history/+
940
+ #
941
+ # @param session_id [String] UUID of the verification session (the `session_id` returned by `POST
942
+ # /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server
943
+ # resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the
944
+ # route and returns an HTML `404`.
945
+ # @param node_id [String] Workflow graph node ID of the AML check. Needed only when the session ran more than
946
+ # one AML step; without it the most recent AML check is used. An unknown node returns `404`.
947
+ # @param limit [Integer] Maximum number of screening runs per page. Defaults to 50. A value below 1 or a
948
+ # non-numeric value falls back to 50; a value above 1,000,000 returns `400`.
949
+ # @param offset [Integer] Number of results to skip before the first returned one. Defaults to 0; a negative or
950
+ # non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and
951
+ # `previous` URLs.
952
+ # @param ordering [String] Optional sort override. The default order is `-completed_at`. Pass a result field
953
+ # name (for example `completed_at`, `started_at`, `outcome` or `score`) to sort ascending, prefix it with `-` to
954
+ # sort descending, and separate several fields with commas. Unknown fields are ignored.
955
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
956
+ # @return [Didit::Page<Didit::Types::AMLScreeningRun>]
957
+ def list_aml_screening_history(
958
+ session_id,
959
+ node_id: OMIT,
960
+ limit: OMIT,
961
+ offset: OMIT,
962
+ ordering: OMIT,
963
+ request_options: nil
964
+ )
965
+ @client.request(
966
+ :get,
967
+ "/v3/session/{sessionId}/aml-screening-history/",
968
+ path_params: { "sessionId" => session_id },
969
+ query: {
970
+ "node_id" => node_id,
971
+ "limit" => limit,
972
+ "offset" => offset,
973
+ "ordering" => ordering
974
+ },
975
+ page: Types::AMLScreeningRun,
976
+ request_options: request_options
977
+ )
978
+ end
979
+
980
+ # List session events
981
+ #
982
+ # Read the event timeline of one verification session, newest first by `sent_at`: the screens the user saw,
983
+ # buttons and uploads, failed attempts, status and feature-step changes, and the workflow routing trace. Works
984
+ # for User Verification (KYC) and Business Verification (KYB) session IDs. Events are stored asynchronously, so
985
+ # a new event can take a few seconds to appear. Results are paginated with `limit` and `offset`; follow `next`
986
+ # until it is `null`. A scoped API key needs `sessions: read` and `decisions: read`, and without `media: read`
987
+ # it receives `file_url` as `null`. The routing events are described in [Retrieve
988
+ # session](https://docs.didit.me/sessions-api/retrieve-session).
989
+ #
990
+ # +GET /v3/session/{sessionId}/events/+
991
+ #
992
+ # @param session_id [String] UUID of the verification session (the `session_id` returned by `POST
993
+ # /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server
994
+ # resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the
995
+ # route and returns an HTML `404`.
996
+ # @param limit [Integer] Maximum number of events per page. Defaults to 50. A value below 1 or a non-numeric
997
+ # value falls back to 50; a value above 1,000,000 returns `400`.
998
+ # @param offset [Integer] Number of results to skip before the first returned one. Defaults to 0; a negative or
999
+ # non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and
1000
+ # `previous` URLs.
1001
+ # @param ordering [String] Optional sort override. The default order is `-sent_at`. Pass a result field name
1002
+ # (for example `sent_at`, `created_at`, `event_type`, `feature_step` or `step`) to sort ascending, prefix it
1003
+ # with `-` to sort descending, and separate several fields with commas. Unknown fields are ignored.
1004
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1005
+ # @return [Didit::Page<Didit::Types::SessionEvent>]
1006
+ def list_events(session_id, limit: OMIT, offset: OMIT, ordering: OMIT, request_options: nil)
1007
+ @client.request(
1008
+ :get,
1009
+ "/v3/session/{sessionId}/events/",
1010
+ path_params: { "sessionId" => session_id },
1011
+ query: {
1012
+ "limit" => limit,
1013
+ "offset" => offset,
1014
+ "ordering" => ordering
1015
+ },
1016
+ page: Types::SessionEvent,
1017
+ request_options: request_options
1018
+ )
1019
+ end
1020
+
1021
+ # List a session's check overrides
1022
+ #
1023
+ # Every override of an individual feature (step) status on a User Verification (KYC) or Business Verification
1024
+ # (KYB) session, newest first and not paginated: applied ones, ones waiting for the person to finish the flow
1025
+ # (`pending_until_flow_finishes`) and cancelled ones, each with who asked, their reason, and whether it applied
1026
+ # while the person was still in the flow (`forced`).
1027
+ #
1028
+ # `person_in_flow` tells you whether a new override with `defer_until_flow_finishes: true` would wait.
1029
+ # `flow_finished_at` is when the person last finished the flow; it is `null` while they are still in it (a
1030
+ # resubmission included) and when the session closed before they finished.
1031
+ #
1032
+ # Requires the `read:sessions` privilege; a scoped API key needs read access to decisions.
1033
+ #
1034
+ # +GET /v3/session/{sessionId}/features/overrides/+
1035
+ #
1036
+ # @param session_id [String] UUID of the verification session. Accepts both user (KYC) and business (KYB)
1037
+ # session IDs.
1038
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1039
+ # @return [Didit::Types::SessionsListFeatureOverridesResponse]
1040
+ def list_feature_overrides(session_id, request_options: nil)
1041
+ @client.request(
1042
+ :get,
1043
+ "/v3/session/{sessionId}/features/overrides/",
1044
+ path_params: { "sessionId" => session_id },
1045
+ response: Types::SessionsListFeatureOverridesResponse,
1046
+ request_options: request_options
1047
+ )
1048
+ end
1049
+
1050
+ # List networks for a session
1051
+ #
1052
+ # List the networks the session's vendor user belongs to. Resolves through the session's vendor_data-linked
1053
+ # user.
1054
+ #
1055
+ # +GET /v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/+
1056
+ #
1057
+ # @param session_id [String] Session UUID.
1058
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1059
+ # @return [Didit::Types::EntityNetworkMembershipList]
1060
+ def list_networks(session_id, request_options: nil)
1061
+ @client.request(
1062
+ :get,
1063
+ "/v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/",
1064
+ path_params: { "session_id" => session_id },
1065
+ scope: :application,
1066
+ response: Types::EntityNetworkMembershipList,
1067
+ request_options: request_options
1068
+ )
1069
+ end
1070
+
1071
+ # Preview a session's decision email
1072
+ #
1073
+ # Render the email the person receives when you set a session to `Approved` or `Declined` with `send_email:
1074
+ # true`, without changing the session or sending anything. The response shows the subject and HTML exactly as
1075
+ # they are sent, the recipient, the sender, the language, and whether confirming the change sends the email at
1076
+ # all (`will_be_sent`, `not_sent_reason`).
1077
+ #
1078
+ # The recipient is the person's own address: the one they verified in an email verification step of the flow,
1079
+ # else the one given in `contact_details` when the session was created. The sender is your application's
1080
+ # verified sender domain when white label applies (`sender_kind: customer`), else Didit's sender (`sender_kind:
1081
+ # didit`).
1082
+ #
1083
+ # To send exactly what you previewed, call [Update Session Status](/sessions-api/update-status) with the same
1084
+ # `new_status`, `send_email: true`, `email_address` set to `recipient`, `email_language` set to `language` and
1085
+ # `email_preview_token` set to `preview_token`. The receipt expires after 15 minutes. When the recipient,
1086
+ # language, session status, sender or email changed since the preview, the update returns `409` before anything
1087
+ # changes; preview again and confirm with the new receipt.
1088
+ #
1089
+ # Works for User Verification (KYC) and Business Verification (KYB) sessions in `Approved`, `Declined`, `In
1090
+ # Review`, `Kyc Expired`, `Abandoned` or `Resubmitted` status. The status check runs before body validation.
1091
+ # Requires the `write:sessions` privilege; a scoped API key needs write access to decisions. Responses use
1092
+ # `Cache-Control: no-store`: treat them as sensitive verification content.
1093
+ #
1094
+ # +POST /v3/session/{sessionId}/decision-email-preview/+
1095
+ #
1096
+ # @param session_id [String] UUID of the verification session. Accepts both user (KYC) and business (KYB)
1097
+ # session IDs.
1098
+ # @param new_status [String] The decision whose email you want to preview.
1099
+ # @param email_language [String] Language of the email, the same default as Update Session Status. A language
1100
+ # that is not offered falls back to English; `language` in the response says which one is used.
1101
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1102
+ # @return [Didit::Types::SessionsPreviewDecisionEmailResponse]
1103
+ def preview_decision_email(session_id, new_status:, email_language: OMIT, request_options: nil)
1104
+ @client.request(
1105
+ :post,
1106
+ "/v3/session/{sessionId}/decision-email-preview/",
1107
+ path_params: { "sessionId" => session_id },
1108
+ body: {
1109
+ "new_status" => new_status,
1110
+ "email_language" => email_language
1111
+ },
1112
+ response: Types::SessionsPreviewDecisionEmailResponse,
1113
+ request_options: request_options
1114
+ )
1115
+ end
1116
+
1117
+ # Preview a resubmission email
1118
+ #
1119
+ # Render the email that would accompany a KYC or KYB resubmission without changing the session, resetting
1120
+ # checks, extending its expiry, running checks or sending mail. Requires the `write:sessions` privilege (a
1121
+ # scoped API key needs write access to decisions) and a session in `Approved`, `Declined`, `In Review`, `Kyc
1122
+ # Expired` or `Abandoned` status. The server validates the selected workflow steps and renders its fixed
1123
+ # translated template with the applicable verified white-label sender and branding. The request cannot set a
1124
+ # subject, message body or action URL.
1125
+ #
1126
+ # `email_address` is optional. Without it, the email goes to the person's own address: the one they verified in
1127
+ # an email verification step of the flow, else the one given in `contact_details` when the session was created.
1128
+ # An address you pass wins (`recipient_source: request`). When no address is known and you pass none,
1129
+ # `recipient` and `preview_token` are empty strings and no email can be sent.
1130
+ #
1131
+ # The response includes the recipient and where it comes from, the sender, subject, HTML, language, resolved
1132
+ # steps, whether confirming sends the email (`will_be_sent`, `not_sent_reason`) and a signed `preview_token`.
1133
+ # `requires_user_action` is `false` when every selected step runs without the person: the resubmission then
1134
+ # finishes on its own and no email goes out (`not_sent_reason: no_user_action`).
1135
+ #
1136
+ # This preview does not reserve session state or authorize delivery. After reviewing it, call [Update Session
1137
+ # Status](/sessions-api/update-status) with `new_status: Resubmitted`, the same `nodes_to_resubmit` and
1138
+ # `email_language` you previewed, `send_email: true`, `email_address` set to `recipient` and
1139
+ # `email_preview_token` set to `preview_token`. The receipt expires after 15 minutes. When a receipt is
1140
+ # supplied, changed inputs, message content, sender or session state return `409` before any mutation or send.
1141
+ # Existing integrations may omit the receipt. Regenerate the preview after a conflict. Treat the response as
1142
+ # sensitive verification content; responses use `Cache-Control: no-store`. Render HTML in a sandboxed frame,
1143
+ # never directly in your application DOM.
1144
+ #
1145
+ # +POST /v3/session/{sessionId}/resubmission-preview/+
1146
+ #
1147
+ # @param session_id [String] UUID of the verification session to update. Accepts both user (KYC) and business
1148
+ # (KYB) session IDs - the service resolves the ID across both session types.
1149
+ # @param nodes_to_resubmit [Array<Hash>] Steps to preview, using the same validation, selection and workflow
1150
+ # ordering as a resubmission. Omit to auto-select recorded attempts needing resubmission.
1151
+ # @param email_address [String] Optional. Send the email to this address instead of the person's own. Without
1152
+ # it, the recipient is the address the person verified in the flow, else the one given in `contact_details`. No
1153
+ # email is sent by this call.
1154
+ # @param email_language [String] Language for the notification email. Accepts any string at schema level;
1155
+ # unsupported codes silently fall back to English (`en`).
1156
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1157
+ # @return [Didit::Types::SessionsPreviewResubmissionResponse]
1158
+ def preview_resubmission(
1159
+ session_id,
1160
+ nodes_to_resubmit: OMIT,
1161
+ email_address: OMIT,
1162
+ email_language: OMIT,
1163
+ request_options: nil
1164
+ )
1165
+ @client.request(
1166
+ :post,
1167
+ "/v3/session/{sessionId}/resubmission-preview/",
1168
+ path_params: { "sessionId" => session_id },
1169
+ body: {
1170
+ "nodes_to_resubmit" => nodes_to_resubmit,
1171
+ "email_address" => email_address,
1172
+ "email_language" => email_language
1173
+ },
1174
+ response: Types::SessionsPreviewResubmissionResponse,
1175
+ request_options: request_options
1176
+ )
1177
+ end
1178
+
1179
+ # Regenerate a Key People party's KYC session
1180
+ #
1181
+ # Give a Key People party of a Business Verification (KYB) session a new individual KYC session after its
1182
+ # previous one was deleted or expired before the person started it, so the Key People check can finish again;
1183
+ # send no request body. It works when the party's KYC session was deleted (`kyc_session_deleted: true`) or
1184
+ # expired before the person started it (`Expired`, never started). A session still in progress or one that ended
1185
+ # in any other status (`Approved`, `Declined`, `In Review`, `Abandoned`, ...) returns `409` unless it was
1186
+ # deleted. A party that never had one or a company party always returns `409`. Didit creates a new hosted KYC
1187
+ # session with the workflow the party was verified with (its latest published version) or, when that is no
1188
+ # longer known, the workflow your Key People settings assign to the party's role, so its link lasts that KYC
1189
+ # workflow's session expiration time; it emails the link to the party when an email is on file, clears
1190
+ # `is_skipped`, and recomputes the Key People check and the business session status. It then sends a
1191
+ # `data.updated` [webhook](https://docs.didit.me/integration/webhooks) for the business session with trigger
1192
+ # `console_key_people_regenerate`; to exempt the party instead, use `PATCH
1193
+ # /v3/session/{sessionId}/kyb/parties/{partyUuid}/`. A scoped API key needs `decisions: write`, and without
1194
+ # `sessions: write` it receives `kyc_session_url` as `null`. Deleted sessions qualify even if the person had
1195
+ # already started or finished verification. Imported sessions do not qualify through expiry; they must have been
1196
+ # deleted.
1197
+ #
1198
+ # +POST /v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/+
1199
+ #
1200
+ # @param session_id [String] UUID of the parent Business Verification (KYB) session.
1201
+ # @param party_uuid [String] UUID of the Key People party (`key_people_checks[].submitted.parties[].uuid` on the
1202
+ # business session decision). Must belong to the session referenced by `sessionId`.
1203
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1204
+ # @return [Didit::Types::KYBKeyPeopleParty]
1205
+ def regenerate_kyb_party(session_id, party_uuid, request_options: nil)
1206
+ @client.request(
1207
+ :post,
1208
+ "/v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/",
1209
+ path_params: { "sessionId" => session_id, "partyUuid" => party_uuid },
1210
+ response: Types::KYBKeyPeopleParty,
1211
+ request_options: request_options
1212
+ )
1213
+ end
1214
+
1215
+ # Retrieve the full decision for a verification session
1216
+ #
1217
+ # Retrieve the complete decision report for a verification session - the rolled-up session `status` plus one
1218
+ # report per verification feature the workflow executed. This is the canonical read endpoint for both User
1219
+ # Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level
1220
+ # `session_kind` discriminator tells you which shape you received (`"user"` or `"business"`).
1221
+ #
1222
+ # **Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than
1223
+ # once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`,
1224
+ # `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`,
1225
+ # `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a
1226
+ # `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]`
1227
+ # - never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once;
1228
+ # features the workflow does not include never appear with data. Electronic Signature results are in
1229
+ # `signatures`, which is present only when the workflow has an Electronic Signature step.
1230
+ #
1231
+ # **When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires
1232
+ # when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to
1233
+ # fetch the full report. Polling also works - the endpoint can be called at any point in the session lifecycle
1234
+ # and returns the data produced so far - but webhook-then-fetch is cheaper and faster. Media URLs in the
1235
+ # response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request
1236
+ # the decision to get fresh ones, and do not persist them as long-term references.
1237
+ #
1238
+ # **Statuses.** The top-level `status` is the session lifecycle status (`Not Started`, `In Progress`, `Awaiting
1239
+ # User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Each
1240
+ # feature item additionally carries its own feature-level `status` (`Not Finished`, `Approved`, `Declined`, `In
1241
+ # Review`, ...). A session can be `Approved` overall while an individual feature is `In Review`, depending on
1242
+ # the workflow's decision rules.
1243
+ #
1244
+ # **Authentication and visibility.** Authenticate with the application API key in the `x-api-key` header (a
1245
+ # console user Bearer token with the `read:sessions` permission also works). Only sessions owned by the
1246
+ # authenticated application are visible. If your workflow restricts response attributes, non-allowed fields
1247
+ # inside feature items are returned as `null` while `status`, `warnings`, and `node_id` are always preserved.
1248
+ #
1249
+ # **Rate limits.** GET requests are limited to 600 per minute per API key. Exceeding the limit returns `429`
1250
+ # with `Retry-After` and `X-RateLimit-*` headers.
1251
+ #
1252
+ # +GET /v3/session/{sessionId}/decision/+
1253
+ #
1254
+ # @param session_id [String] UUID of the verification session whose decision you want to retrieve. This is the
1255
+ # `session_id` returned by `POST /v3/session/`. The same path works for both User Verification (KYC) and
1256
+ # Business Verification (KYB) sessions - the server resolves the id against both session types. **Must be a
1257
+ # valid UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router
1258
+ # b...
1259
+ # @param include [String] Comma-separated list of extra payload sections. Supported values: `events` and
1260
+ # `resubmissions`, alone or together (`events,resubmissions`). When `include=events` is passed, the response
1261
+ # additionally contains the session event timeline (`events`, including the `WORKFLOW_BRANCH_EVALUATED` /
1262
+ # `WORKFLOW_STATUS_NODE_REACHED` routing events described on the Retrieve Session page), the full activity
1263
+ # log...
1264
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1265
+ # @return [Didit::Types::SessionDecision]
1266
+ def retrieve_decision(session_id, include: OMIT, request_options: nil)
1267
+ @client.request(
1268
+ :get,
1269
+ "/v3/session/{sessionId}/decision/",
1270
+ path_params: { "sessionId" => session_id },
1271
+ query: {
1272
+ "include" => include
1273
+ },
1274
+ response: Types::SessionDecision,
1275
+ request_options: request_options
1276
+ )
1277
+ end
1278
+
1279
+ # Get a bulk session deletion job
1280
+ #
1281
+ # Progress of a bulk session deletion that `POST /v3/sessions/delete/` answered with `202` (more than 20
1282
+ # matching sessions, selected by `session_numbers` or with `delete_all`). Poll every few seconds while `status`
1283
+ # is `PENDING` or `PROCESSING`; stop when it is `COMPLETED` or `FAILED`.
1284
+ #
1285
+ # The job reports how many sessions ended in each outcome and how many it has processed, never which sessions it
1286
+ # deleted. A `FAILED` job carries the reason in `error`; the sessions it had not reached are still in place, so
1287
+ # repeat the deletion request to delete them.
1288
+ #
1289
+ # **Authentication:** API key in the `x-api-key` header. A job is only visible to the application that created
1290
+ # it; any other `job_id` returns `404`. Missing or invalid credentials return `403`; this API never returns
1291
+ # `401`.
1292
+ #
1293
+ # +GET /v3/sessions/delete/{job_id}/+
1294
+ #
1295
+ # @param job_id [String] The `job_id` returned with the `202` from `POST /v3/sessions/delete/`.
1296
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1297
+ # @return [Didit::Types::SessionDeletionJob]
1298
+ def retrieve_deletion_job(job_id, request_options: nil)
1299
+ @client.request(
1300
+ :get,
1301
+ "/v3/sessions/delete/{job_id}/",
1302
+ path_params: { "job_id" => job_id },
1303
+ response: Types::SessionDeletionJob,
1304
+ request_options: request_options
1305
+ )
1306
+ end
1307
+
1308
+ # Mint a share token for a finished verification session
1309
+ #
1310
+ # Mint a short-lived JWT that lets a specific Didit application import this finished session. Pair with `POST
1311
+ # /v3/session/import-shared/`.
1312
+ #
1313
+ # +POST /v3/session/{sessionId}/share/+
1314
+ #
1315
+ # @param session_id [String] UUID of the source verification session to mint a token for.
1316
+ # @param for_application_id [String] UUID of the Didit application that will redeem the token. Must exist, must
1317
+ # not be deleted, and must differ from the calling application. Find it in the Business Console under **Settings
1318
+ # → Application**.
1319
+ # @param ttl_in_seconds [Integer] Token lifetime, in seconds. Minimum `60`, maximum `86400` (24 h). Defaults to
1320
+ # `3600` (1 h).
1321
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1322
+ # @return [Didit::Types::SessionsShareResponse]
1323
+ def share(session_id, for_application_id:, ttl_in_seconds: OMIT, request_options: nil)
1324
+ @client.request(
1325
+ :post,
1326
+ "/v3/session/{sessionId}/share/",
1327
+ path_params: { "sessionId" => session_id },
1328
+ body: {
1329
+ "for_application_id" => for_application_id,
1330
+ "ttl_in_seconds" => ttl_in_seconds
1331
+ },
1332
+ response: Types::SessionsShareResponse,
1333
+ request_options: request_options
1334
+ )
1335
+ end
1336
+
1337
+ # Simulate a sandbox session's status
1338
+ #
1339
+ # Force a terminal status on a sandbox session after the fact, from your backend, without running the flow.
1340
+ # Sandbox applications only: a live session returns `404`. Works for User Verification (KYC) and Business
1341
+ # Verification (KYB) sessions.
1342
+ #
1343
+ # Set `new_status`, or let `scenario` or `risk` supply it. `risk` (or the first risk the scenario's magic values
1344
+ # carry) adds that warning to the session. The change is recorded in the session's activity.
1345
+ #
1346
+ # `send_webhooks` (default `true`) sends exactly the webhooks a real status change sends. With `false` the
1347
+ # status still changes and the console still updates live, but no webhook is logged or sent, the missed-webhook
1348
+ # recovery never re-sends that decision, and the next status change sends webhooks as usual. The response echoes
1349
+ # the value applied.
1350
+ #
1351
+ # Requires the `write:sessions` privilege; a scoped API key needs write access to sessions. An unknown
1352
+ # `session_id` returns `404` and another application's session returns `403`, both before the body is read; a
1353
+ # live session returns `404` only after the body is validated. To simulate from the hosted flow with the
1354
+ # session's own token, use `POST /v3/session/{sessionId}/sandbox/simulate/`. See [Sandbox & Test
1355
+ # Data](/integration/sandbox-testing) for the scenario catalog.
1356
+ #
1357
+ # +POST /v3/session/{sessionId}/simulate/+
1358
+ #
1359
+ # @param session_id [String] UUID of the sandbox verification session. Accepts both user (KYC) and business
1360
+ # (KYB) session IDs.
1361
+ # @param new_status [String] The status to set. When you leave it out, it defaults to the default status of the
1362
+ # risk case (`risk`, or the first risk the scenario's magic values carry), else to the scenario's default
1363
+ # status.
1364
+ # @param comment [String] Note added to the activity entry the status change records.
1365
+ # @param scenario [String] A scenario slug from the catalog (`GET /v1/sandbox/scenarios/`). It supplies the
1366
+ # default status and, without `risk`, the warning its magic values carry. An unknown slug returns `400`.
1367
+ # @param risk [String] A risk case from the catalog. Its warning is added to the session, with a log type that
1368
+ # follows `new_status`. An unknown value returns `400`.
1369
+ # @param node_id [String] Workflow node the risk warning is attached to. Defaults to the session's current node.
1370
+ # @param send_webhooks [Boolean] `true` sends exactly the webhooks a real status change sends to the sandbox
1371
+ # application's destinations: `status.updated`, plus the `user.status.updated` / `user.data.updated` (or
1372
+ # `business.status.updated` / `business.data.updated`) events the change causes, for destinations subscribed to
1373
+ # them. `false` changes the status without logging or sending any webhook: the missed-webhook recovery never
1374
+ # re-...
1375
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1376
+ # @return [Didit::Types::SandboxSimulateResponse]
1377
+ def simulate(
1378
+ session_id,
1379
+ new_status: OMIT,
1380
+ comment: OMIT,
1381
+ scenario: OMIT,
1382
+ risk: OMIT,
1383
+ node_id: OMIT,
1384
+ send_webhooks: OMIT,
1385
+ request_options: nil
1386
+ )
1387
+ @client.request(
1388
+ :post,
1389
+ "/v3/session/{sessionId}/simulate/",
1390
+ path_params: { "sessionId" => session_id },
1391
+ body: {
1392
+ "new_status" => new_status,
1393
+ "comment" => comment,
1394
+ "scenario" => scenario,
1395
+ "risk" => risk,
1396
+ "node_id" => node_id,
1397
+ "send_webhooks" => send_webhooks
1398
+ },
1399
+ response: Types::SandboxSimulateResponse,
1400
+ request_options: request_options
1401
+ )
1402
+ end
1403
+
1404
+ # Update an AML hit review status
1405
+ #
1406
+ # Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match)
1407
+ # returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id`
1408
+ # (the `id` of an entry in the AML check's `hits` array - see the session decision).
1409
+ #
1410
+ # `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. Reviewer
1411
+ # decisions are preserved across ongoing-monitoring updates, so a hit you mark `False Positive` stays that way
1412
+ # when the provider re-screens.
1413
+ #
1414
+ # A successful call fires a `data.updated` webhook and appends an activity entry (with actor attribution) to the
1415
+ # session's review trail. For graph workflows with multiple AML checks, pass `node_id` to target a specific
1416
+ # check.
1417
+ #
1418
+ # Authenticate with your API key (`x-api-key`) or a user authorization header - either must carry the
1419
+ # `write:sessions` privilege.
1420
+ #
1421
+ # +PATCH /v3/session/{sessionId}/update-aml-hit-status/+
1422
+ #
1423
+ # @param session_id [String] UUID of the verification session. Accepts both user (KYC) and business (KYB)
1424
+ # session IDs - the service resolves the ID across both session types.
1425
+ # @param hit_id [String] The `id` of the hit in the AML check's `hits` array.
1426
+ # @param review_status [String] The new review status for the hit.
1427
+ # @param node_id [String] Optional graph node ID. Use it (here or as a query parameter) when the session has
1428
+ # multiple AML checks.
1429
+ # @param node_id_query [String] Workflow graph node ID. Required only when the session has multiple AML checks
1430
+ # (one per node); omit it for single-AML sessions.
1431
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1432
+ # @return [Didit::Types::SessionsUpdateAmlHitStatusResponse]
1433
+ def update_aml_hit_status(
1434
+ session_id,
1435
+ hit_id:,
1436
+ review_status:,
1437
+ node_id: OMIT,
1438
+ node_id_query: OMIT,
1439
+ request_options: nil
1440
+ )
1441
+ @client.request(
1442
+ :patch,
1443
+ "/v3/session/{sessionId}/update-aml-hit-status/",
1444
+ path_params: { "sessionId" => session_id },
1445
+ query: {
1446
+ "node_id" => node_id_query
1447
+ },
1448
+ body: {
1449
+ "hit_id" => hit_id,
1450
+ "review_status" => review_status,
1451
+ "node_id" => node_id
1452
+ },
1453
+ response: Types::SessionsUpdateAmlHitStatusResponse,
1454
+ request_options: request_options
1455
+ )
1456
+ end
1457
+
1458
+ # Update an AML check status
1459
+ #
1460
+ # Set the status of a session's AML screening check as a whole (the `status` of an `aml_screenings[]` entry in
1461
+ # the session decision), for example `Approved` after your team cleared every hit. Works for KYC and KYB session
1462
+ # IDs; pass `node_id` (query parameter or body field) when the session ran more than one AML step, otherwise the
1463
+ # most recent AML check is updated. When the status actually changes, an `AML_STATUS_UPDATED` activity entry is
1464
+ # recorded and a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) is sent; sending the
1465
+ # current status returns `200` and changes nothing. The session status is not recomputed: use `PATCH
1466
+ # /v3/session/{sessionId}/update-status/` for the session decision and `PATCH
1467
+ # /v3/session/{sessionId}/update-aml-hit-status/` for single hits. A scoped API key needs `decisions: write`.
1468
+ #
1469
+ # +PATCH /v3/session/{sessionId}/update-aml-status/+
1470
+ #
1471
+ # @param session_id [String] UUID of the verification session (the `session_id` returned by `POST
1472
+ # /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server
1473
+ # resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the
1474
+ # route and returns an HTML `404`.
1475
+ # @param status [String] New status of the AML check.
1476
+ # @param node_id [String] Workflow graph node ID of the AML check, as an alternative to the query parameter.
1477
+ # @param node_id_query [String] Workflow graph node ID of the AML check to update. Needed only when the session
1478
+ # ran more than one AML step. Takes precedence over `node_id` in the body.
1479
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1480
+ # @return [Didit::Types::SessionsUpdateAmlStatusResponse]
1481
+ def update_aml_status(session_id, status:, node_id: OMIT, node_id_query: OMIT, request_options: nil)
1482
+ @client.request(
1483
+ :patch,
1484
+ "/v3/session/{sessionId}/update-aml-status/",
1485
+ path_params: { "sessionId" => session_id },
1486
+ query: {
1487
+ "node_id" => node_id_query
1488
+ },
1489
+ body: {
1490
+ "status" => status,
1491
+ "node_id" => node_id
1492
+ },
1493
+ response: Types::SessionsUpdateAmlStatusResponse,
1494
+ request_options: request_options
1495
+ )
1496
+ end
1497
+
1498
+ # Update KYC data extracted from the ID document on a verification session
1499
+ #
1500
+ # Correct the identity fields that were extracted (OCR / NFC) from the user's ID document - misread names,
1501
+ # dates, document numbers, and so on - after the verification has finished. Typical callers are a compliance
1502
+ # analyst working from your own back office, or an automated reconciliation job. Every field in the body is
1503
+ # optional: only the keys you send are written, everything else is left untouched (`PATCH` semantics).
1504
+ #
1505
+ # The session must belong to your application and be in `Approved`, `Declined`, `In Review`, or `Kyc Expired`
1506
+ # status. Sessions in any other state (e.g. still `In Progress`) return `404` with `"No Session matches the
1507
+ # given query."` - distinct from the `"Not found."` returned for an unknown or deleted `sessionId`. The session
1508
+ # must also carry an ID-verification (KYC) record: sessions whose workflow never ran an ID-verification step
1509
+ # return `404` (`"The session does not have a KYC."`). For graph workflows with multiple ID-verification steps,
1510
+ # target a specific step with `node_id` (query parameter or body field); when omitted, the most recent KYC
1511
+ # record is patched.
1512
+ #
1513
+ # Two derived fields are recomputed on every call: `full_name` (from `first_name` + `last_name`) and
1514
+ # `issuing_state_name` (from `issuing_state`). If the free-text `address` changes, the server may also
1515
+ # re-geocode it and refresh `parsed_address` (skipped for sandbox sessions). `extra_fields` and `parsed_address`
1516
+ # are merged key-by-key rather than replaced - see the per-field descriptions for the `null`-to-delete
1517
+ # semantics.
1518
+ #
1519
+ # Submitting at least one valid field fires the `data.updated` [webhook](/integration/webhooks) (trigger
1520
+ # `manual_review`) - even when the submitted values equal the stored ones. When values actually change, a
1521
+ # `KYC_DATA_UPDATED` activity entry recording the changed fields with previous and new values is appended to the
1522
+ # session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and the console
1523
+ # activity timeline. The session's status and decision are **not** re-evaluated - use [Update
1524
+ # Status](#patch-/v3/session/-sessionId-/update-status/) to change the outcome. An empty JSON body (`{}`) is
1525
+ # accepted and simply returns the current KYC data without firing the webhook.
1526
+ #
1527
+ # Accepts an API key or a console user token; either way the credential needs the `write:sessions` permission.
1528
+ # Authentication and permission failures both return `403` - this API never responds `401`. Note that the
1529
+ # session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing
1530
+ # credentials. This endpoint has a dedicated rate limit of 10 requests per minute per API key (invalid requests
1531
+ # count too); the shared write budget of 300 requests per minute also applies.
1532
+ #
1533
+ # +PATCH /v3/session/{sessionId}/update-data/+
1534
+ #
1535
+ # @param session_id [String] UUID of the User Verification (KYC) session whose extracted document data you are
1536
+ # correcting. Business (KYB) session IDs are not valid here - for company data use [Update KYB Company
1537
+ # Data](#patch-/v3/session/-sessionId-/kyb/-companyUuid-/update-data/).
1538
+ # @param document_type [String, nil] Document type code. Accepts the short codes listed in the enum, plus six
1539
+ # long-form aliases normalized server-side before validation: `Passport` → `P`, `Identity Card` → `ID`,
1540
+ # `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`. Any
1541
+ # other value (including `PASSPORT` in caps) returns `400`.
1542
+ # @param document_subtype [String, nil] Document subtype from the document registry, including the region prefix
1543
+ # when the registry distinguishes regional variants.
1544
+ # @param document_number [String, nil] Document number as printed on the ID.
1545
+ # @param personal_number [String, nil] Personal / national identification number where the document carries one
1546
+ # (e.g. Spanish DNI on a passport).
1547
+ # @param date_of_birth [Date, String, nil] Date of birth in `YYYY-MM-DD`. Any other format returns `400`.
1548
+ # @param date_of_issue [Date, String, nil] Issue date of the document in `YYYY-MM-DD`.
1549
+ # @param expiration_date [Date, String, nil] Expiration date of the document in `YYYY-MM-DD`.
1550
+ # @param issuing_state [String, nil] Issuing country as an ISO 3166-1 alpha-3 code. Case-insensitive (`esp` is
1551
+ # stored as `ESP`); the human-readable `issuing_state_name` shown in [Get
1552
+ # Decision](#get-/v3/session/-sessionId-/decision/) is recomputed from this value. Invalid codes return `400`.
1553
+ # @param first_name [String, nil] Given name(s). The stored `full_name` is recomputed as `first_name + ' ' +
1554
+ # last_name` on every call to this endpoint.
1555
+ # @param last_name [String, nil] Family name(s). Also feeds the recomputed `full_name`.
1556
+ # @param gender [String, nil] Sex as printed on the document: `M` (male), `F` (female), or `U` (unknown). Any
1557
+ # other value - including `X` - returns `400`.
1558
+ # @param address [String, nil] Free-text address as printed on the document. When this value changes
1559
+ # (non-sandbox sessions only) and the structured address is still missing or incomplete, the server re-geocodes
1560
+ # it synchronously before responding - the 200 body already reflects the refreshed `parsed_address`. The
1561
+ # re-geocode also requires `issuing_state` to be present on the KYC record.
1562
+ # @param place_of_birth [String, nil] Place of birth as printed on the document.
1563
+ # @param nationality [String, nil] Nationality as printed on the document. Free text up to 32 characters -
1564
+ # typically an ISO 3166-1 alpha-3 code (e.g. `ESP`), but not validated as one.
1565
+ # @param marital_status [String] Marital status where the document carries it. Any other value returns `400`.
1566
+ # @param extra_fields [Hash, nil] Per-key overrides for document-specific extra fields (e.g. `blood_group`,
1567
+ # `dl_categories`, `mrz_string`). Keys are merged into the existing override map: send a key with a value to set
1568
+ # it, or with `null` / `""` to remove that key from the merged view. Send the whole field as `null` to clear all
1569
+ # previously applied overrides. Must be a JSON object, otherwise `400`. The response always returns the m...
1570
+ # @param parsed_address [Hash, nil] Structured address. Only these nested keys are accepted: `address_type`,
1571
+ # `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` - any other key returns `400`. Per-key
1572
+ # semantics: a value sets the key, `null` removes it. `formatted_address` is recomputed server-side by joining
1573
+ # `street_1`, `street_2`, `city`, `region`, `postal_code`, and `country` and is returned in the response - you
1574
+ # ca...
1575
+ # @param node_id [String] Workflow graph node whose KYC record to patch, for graph workflows with multiple
1576
+ # ID-verification steps (also accepted as a `node_id` body field). When omitted, the most recent KYC record on
1577
+ # the session is patched. If no KYC exists for the given node, the call returns `404` (`"The session does not
1578
+ # have a KYC for node '<node_id>'."`).
1579
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1580
+ # @return [Didit::Types::SessionsUpdateDataResponse]
1581
+ def update_data(
1582
+ session_id,
1583
+ document_type: OMIT,
1584
+ document_subtype: OMIT,
1585
+ document_number: OMIT,
1586
+ personal_number: OMIT,
1587
+ date_of_birth: OMIT,
1588
+ date_of_issue: OMIT,
1589
+ expiration_date: OMIT,
1590
+ issuing_state: OMIT,
1591
+ first_name: OMIT,
1592
+ last_name: OMIT,
1593
+ gender: OMIT,
1594
+ address: OMIT,
1595
+ place_of_birth: OMIT,
1596
+ nationality: OMIT,
1597
+ marital_status: OMIT,
1598
+ extra_fields: OMIT,
1599
+ parsed_address: OMIT,
1600
+ node_id: OMIT,
1601
+ request_options: nil
1602
+ )
1603
+ @client.request(
1604
+ :patch,
1605
+ "/v3/session/{sessionId}/update-data/",
1606
+ path_params: { "sessionId" => session_id },
1607
+ query: {
1608
+ "node_id" => node_id
1609
+ },
1610
+ body: {
1611
+ "document_type" => document_type,
1612
+ "document_subtype" => document_subtype,
1613
+ "document_number" => document_number,
1614
+ "personal_number" => personal_number,
1615
+ "date_of_birth" => date_of_birth,
1616
+ "date_of_issue" => date_of_issue,
1617
+ "expiration_date" => expiration_date,
1618
+ "issuing_state" => issuing_state,
1619
+ "first_name" => first_name,
1620
+ "last_name" => last_name,
1621
+ "gender" => gender,
1622
+ "address" => address,
1623
+ "place_of_birth" => place_of_birth,
1624
+ "nationality" => nationality,
1625
+ "marital_status" => marital_status,
1626
+ "extra_fields" => extra_fields,
1627
+ "parsed_address" => parsed_address
1628
+ },
1629
+ response: Types::SessionsUpdateDataResponse,
1630
+ request_options: request_options
1631
+ )
1632
+ end
1633
+
1634
+ # Update a Document AI document
1635
+ #
1636
+ # Correct the fields Document AI extracted from one uploaded document, set its review status, or both, on a KYC
1637
+ # or KYB session. `extracted_data` must be a JSON object and is merged key by key: a key you send replaces the
1638
+ # stored value (a key sent as `null` is stored as `null`) and keys you leave out keep their values. The document
1639
+ # status feeds the Document AI result of its workflow node in the session decision; the session status itself is
1640
+ # not recomputed. Every successful call, including one that changes nothing, sends a `data.updated`
1641
+ # [webhook](https://docs.didit.me/integration/webhooks) with trigger `manual_review`. A scoped API key needs
1642
+ # `decisions: write`; see [Document AI](https://docs.didit.me/core-technology/document-ai/overview).
1643
+ #
1644
+ # +PATCH /v3/document-ai/{sessionId}/documents/{documentUuid}/+
1645
+ #
1646
+ # @param session_id [String] UUID of the verification session (the `session_id` returned by `POST
1647
+ # /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server
1648
+ # resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the
1649
+ # route and returns an HTML `404`.
1650
+ # @param document_uuid [String] UUID of the Document AI document (`document_ai_documents[].items[].uuid` in `GET
1651
+ # /v3/session/{sessionId}/decision/`). It must belong to the session in the path.
1652
+ # @param extracted_data [Hash] Field keys (the keys you configured for the document) and their corrected values.
1653
+ # Must be a JSON object; merged key by key into the stored data. Leave it out rather than sending `null`, which
1654
+ # returns `400`.
1655
+ # @param status [String] New review status of the document.
1656
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1657
+ # @return [Didit::Types::SessionsUpdateDocumentAiDataResponse]
1658
+ def update_document_ai_data(session_id, document_uuid, extracted_data: OMIT, status: OMIT, request_options: nil)
1659
+ @client.request(
1660
+ :patch,
1661
+ "/v3/document-ai/{sessionId}/documents/{documentUuid}/",
1662
+ path_params: { "sessionId" => session_id, "documentUuid" => document_uuid },
1663
+ body: {
1664
+ "extracted_data" => extracted_data,
1665
+ "status" => status
1666
+ },
1667
+ response: Types::SessionsUpdateDocumentAiDataResponse,
1668
+ request_options: request_options
1669
+ )
1670
+ end
1671
+
1672
+ # Update an individual feature (step) status
1673
+ #
1674
+ # Set the status of a single verification feature (step) within a session. Target the feature by its workflow
1675
+ # graph `nodeId`. On non-graph workflows, whose steps have no node, use `default` and also pass `feature_type`
1676
+ # to say which step you mean.
1677
+ #
1678
+ # Works for both User Verification (KYC) and Business Verification (KYB) sessions and every step type: ID/OCR,
1679
+ # Liveness, Face Match, NFC, AML, Proof of Address, Phone, Email, Database Validation, Questionnaire, and the
1680
+ # KYB registry / documents / key-people checks. This endpoint is **not** available for standalone API sessions
1681
+ # (`session_type = API`).
1682
+ #
1683
+ # `new_status` must be one of `Approved`, `Declined`, or `In Review`, and must differ from the feature's current
1684
+ # status.
1685
+ #
1686
+ # **When the override applies.** Without `defer_until_flow_finishes` (or with `false`) the override applies at
1687
+ # once, as it always did; when the person is still in the flow it is recorded as `forced`. With
1688
+ # `defer_until_flow_finishes: true` while the person is still in the flow (the session is `Not Started`, `In
1689
+ # Progress` or `Resubmitted` and has not finished), the override is stored as `pending_until_flow_finishes` and
1690
+ # applies when the flow finishes, after the flow reaches its own decision. On a session whose flow already ended
1691
+ # it applies at once either way. A waiting override is cancelled instead when the person redoes its step before
1692
+ # finishing, when a newer override on the same check replaces it, when the session leaves the flow unfinished
1693
+ # (abandoned, expired, or decided mid-flow), or when you cancel it with `POST
1694
+ # /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`. List a session's overrides with `GET
1695
+ # /v3/session/{sessionId}/features/overrides/`.
1696
+ #
1697
+ # **Effect on the session.** A session that already has a decision keeps it: only the check changes. When the
1698
+ # session has no decision yet and its workflow is waiting on exactly this step, applying the override completes
1699
+ # the step: the workflow moves on, later steps run, and a status node can set the session decision and fire
1700
+ # `status.updated`.
1701
+ #
1702
+ # **Webhooks and activity.** A `data.updated` webhook fires when the override applies (at once, or when the flow
1703
+ # finishes), never while it waits or when it is cancelled. Every override is recorded in the session's activity
1704
+ # as `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` or `FEATURE_OVERRIDE_CANCELLED`, with who made it;
1705
+ # the request's entry carries your `comment`.
1706
+ #
1707
+ # Authenticate with your API key (`x-api-key`) or a user authorization header carrying the `write:sessions`
1708
+ # privilege; a scoped API key needs write access to decisions.
1709
+ #
1710
+ # +PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/+
1711
+ #
1712
+ # @param session_id [String] UUID of the verification session. Accepts both user (KYC) and business (KYB)
1713
+ # session IDs - the service resolves the ID across both session types.
1714
+ # @param node_id [String] Workflow graph node ID of the feature to update (for example `feature_ocr_1`). Use the
1715
+ # literal value `default` for non-graph (single-step) workflows where the feature has no node ID.
1716
+ # @param new_status [String] Target status for this feature. Must differ from the current value.
1717
+ # @param comment [String] Optional free-text note recorded on the session's review trail for this feature
1718
+ # change.
1719
+ # @param feature_type [String] Which kind of step to target. Needed on non-graph workflows (`nodeId` =
1720
+ # `default`), where every step shares no node; optional otherwise. An unknown value returns `400`.
1721
+ # @param defer_until_flow_finishes [Boolean] While the person is still in the flow, store the override as
1722
+ # `pending_until_flow_finishes` and apply it when the flow finishes, instead of at once. Omitted or `false`, the
1723
+ # override applies at once. On a session whose flow already ended it applies at once either way.
1724
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1725
+ # @return [Didit::Types::SessionsUpdateFeatureStatusResponse]
1726
+ def update_feature_status(
1727
+ session_id,
1728
+ node_id,
1729
+ new_status:,
1730
+ comment: OMIT,
1731
+ feature_type: OMIT,
1732
+ defer_until_flow_finishes: OMIT,
1733
+ request_options: nil
1734
+ )
1735
+ @client.request(
1736
+ :patch,
1737
+ "/v3/session/{sessionId}/features/{nodeId}/update-status/",
1738
+ path_params: { "sessionId" => session_id, "nodeId" => node_id },
1739
+ body: {
1740
+ "new_status" => new_status,
1741
+ "comment" => comment,
1742
+ "feature_type" => feature_type,
1743
+ "defer_until_flow_finishes" => defer_until_flow_finishes
1744
+ },
1745
+ response: Types::SessionsUpdateFeatureStatusResponse,
1746
+ request_options: request_options
1747
+ )
1748
+ end
1749
+
1750
+ # Update registry-extracted company data on a Business Verification (KYB) session
1751
+ #
1752
+ # Correct the registry-extracted company data on a Business Verification (KYB) session - company name,
1753
+ # registration number, addresses, status, contact details - identified by `companyUuid`. Typical callers are a
1754
+ # compliance analyst fixing a registry misread, or your back office syncing corrected company data. Every field
1755
+ # in the body is optional (`PATCH` semantics); an empty JSON body (`{}`) is a no-op that simply echoes the
1756
+ # current company record.
1757
+ #
1758
+ # Edits are written in two places at once: fields with a canonical company column (name, registration number,
1759
+ # country, incorporation date, tax number, type, statuses, capital fields (`registered_capital`,
1760
+ # `registered_capital_amount`, `registered_capital_currency`), alternative names, nature of business, website,
1761
+ # email, phone, LEI, location, and `legal_address` → `registered_address`) update that column, and **every**
1762
+ # submitted key is also merged into the `registry_data` snapshot (dates as ISO strings) so the "extracted from
1763
+ # registry" view reflects the correction. Fields without a column - `region`, `registration_date`,
1764
+ # `dissolution_date`, `control_scheme` - land in `registry_data` only. `user_provided_data` (what the end user
1765
+ # confirmed in the hosted flow) is never touched, and `last_console_edit_at` is stamped on every non-empty
1766
+ # PATCH.
1767
+ #
1768
+ # Unlike the KYC/POA update endpoints, there is **no session-status gate**: the company can be edited at any
1769
+ # point in the business session's lifecycle. The company must belong to the session in the path (`404` with
1770
+ # `"KYB company does not belong to the given session."` otherwise) and to your application. Every non-empty
1771
+ # PATCH fires the `data.updated` [webhook](/integration/webhooks) on the business session (trigger
1772
+ # `console_registry_edit`) - even when the submitted values equal the stored ones. The session's status and
1773
+ # decision are **not** re-evaluated, and no review/audit entry is recorded.
1774
+ #
1775
+ # Accepts an API key or a console user token; either way the credential needs the `write:businesses` permission.
1776
+ # Authentication and permission failures both return `403` - this API never responds `401`. Note that the
1777
+ # session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing
1778
+ # credentials. The shared write budget of 300 requests per minute per API key applies.
1779
+ #
1780
+ # For User Verification sessions, the KYC counterpart is `PATCH /v3/session/{sessionId}/update-data/`; to change
1781
+ # the session decision itself use `PATCH /v3/session/{sessionId}/update-status/`.
1782
+ #
1783
+ # +PATCH /v3/session/{sessionId}/kyb/{companyUuid}/update-data/+
1784
+ #
1785
+ # @param session_id [String] UUID of the parent Business Verification (KYB) session.
1786
+ # @param company_uuid [String] UUID of the company record to update (`registry_checks[].company.uuid` on the
1787
+ # business session decision). Must belong to the session referenced by `sessionId`.
1788
+ # @param company_name [String] Legal name of the company. Written to the canonical column and the registry
1789
+ # snapshot.
1790
+ # @param registration_number [String] Official registration number with the company registry.
1791
+ # @param country_code [String] Country of incorporation, ISO 3166-1 alpha-2. Case-insensitive (`us` is stored as
1792
+ # `US`). Alpha-3 codes fail the 2-character limit with `400`.
1793
+ # @param region [String, nil] Subdivision / region tag where the registry has one (e.g. US state). Stored in the
1794
+ # registry snapshot only - it has no canonical column.
1795
+ # @param incorporation_date [Date, String] Incorporation date in `YYYY-MM-DD`. Optional like every other field -
1796
+ # the `PATCH` is partial. Any other date format returns `400`.
1797
+ # @param registration_date [Date, String, nil] Registration date where the registry distinguishes it from
1798
+ # incorporation. Stored in the registry snapshot only.
1799
+ # @param dissolution_date [Date, String, nil] Dissolution date for companies that are no longer active. Stored
1800
+ # in the registry snapshot only.
1801
+ # @param tax_number [String] Tax identification number.
1802
+ # @param legal_address [String] Legal / registered address. Aliased server-side to the canonical
1803
+ # `registered_address` column - the response returns it under `registered_address`, while the registry snapshot
1804
+ # keeps the `legal_address` key you sent.
1805
+ # @param company_type [String] Legal entity type (e.g. `Limited Liability Company`, `PLC`, `GmbH`).
1806
+ # @param registry_status [String, nil] Registry-reported company status. Lowercase, some values contain spaces
1807
+ # (e.g. `struck off`, `no longer authorised`). Any other value returns `400`.
1808
+ # @param verification_status [String, nil] Outcome of the registry verification. Any other value returns `400`.
1809
+ # @param alternative_names [String] Trade names, former legal names, DBA names (free text).
1810
+ # @param nature_of_business [String] Short description of the company's activity.
1811
+ # @param registered_capital [String] Human-readable registered capital (e.g. `USD 50000`). Use
1812
+ # `registered_capital_amount` + `registered_capital_currency` for structured values, or this field for free-form
1813
+ # text.
1814
+ # @param registered_capital_amount [Numeric, nil] Numeric registered-capital amount (up to 20 digits, 2 decimal
1815
+ # places). Sets the `registered_capital_amount` column and is mirrored into `registry_data` as a decimal string;
1816
+ # the response echoes it as a decimal string (e.g. `"1500000.50"`).
1817
+ # @param registered_capital_currency [String, nil] ISO 4217 currency code for `registered_capital_amount`.
1818
+ # Case-insensitive (`usd` is stored as `USD`); values that are not exactly 3 letters return `400` with the ISO
1819
+ # 4217 message. Sets the canonical `registered_capital_currency` column and is mirrored into `registry_data`.
1820
+ # @param website [String] Company website. Bare domains are accepted and normalized with an `https://` prefix
1821
+ # (`docsprobe.example.com` is stored as `https://docsprobe.example.com`); values that still fail URL validation
1822
+ # return `400`.
1823
+ # @param email [String] Contact email on file with the registry.
1824
+ # @param phone [String] Contact phone. Must match `+`, digits, spaces, dashes, dots, or parentheses, with 7-15
1825
+ # digits total - otherwise `400`.
1826
+ # @param legal_entity_identifier [String] LEI, where the company has one.
1827
+ # @param location_of_registration [String] City / subdivision of the registry of record.
1828
+ # @param vat_number [String] EU VAT number. Merged into the `registry_data` snapshot only - editing it here does
1829
+ # not re-run VAT and tax ID validation, so `vat_validation_status` and the other `vat_*` result fields are
1830
+ # unchanged.
1831
+ # @param control_scheme [String] Control / governance scheme when the registry exposes it. Stored in the
1832
+ # registry snapshot only.
1833
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1834
+ # @return [Didit::Types::SessionsUpdateKybCompanyDataResponse]
1835
+ def update_kyb_company_data(
1836
+ session_id,
1837
+ company_uuid,
1838
+ company_name: OMIT,
1839
+ registration_number: OMIT,
1840
+ country_code: OMIT,
1841
+ region: OMIT,
1842
+ incorporation_date: OMIT,
1843
+ registration_date: OMIT,
1844
+ dissolution_date: OMIT,
1845
+ tax_number: OMIT,
1846
+ legal_address: OMIT,
1847
+ company_type: OMIT,
1848
+ registry_status: OMIT,
1849
+ verification_status: OMIT,
1850
+ alternative_names: OMIT,
1851
+ nature_of_business: OMIT,
1852
+ registered_capital: OMIT,
1853
+ registered_capital_amount: OMIT,
1854
+ registered_capital_currency: OMIT,
1855
+ website: OMIT,
1856
+ email: OMIT,
1857
+ phone: OMIT,
1858
+ legal_entity_identifier: OMIT,
1859
+ location_of_registration: OMIT,
1860
+ vat_number: OMIT,
1861
+ control_scheme: OMIT,
1862
+ request_options: nil
1863
+ )
1864
+ @client.request(
1865
+ :patch,
1866
+ "/v3/session/{sessionId}/kyb/{companyUuid}/update-data/",
1867
+ path_params: { "sessionId" => session_id, "companyUuid" => company_uuid },
1868
+ body: {
1869
+ "company_name" => company_name,
1870
+ "registration_number" => registration_number,
1871
+ "country_code" => country_code,
1872
+ "region" => region,
1873
+ "incorporation_date" => incorporation_date,
1874
+ "registration_date" => registration_date,
1875
+ "dissolution_date" => dissolution_date,
1876
+ "tax_number" => tax_number,
1877
+ "legal_address" => legal_address,
1878
+ "company_type" => company_type,
1879
+ "registry_status" => registry_status,
1880
+ "verification_status" => verification_status,
1881
+ "alternative_names" => alternative_names,
1882
+ "nature_of_business" => nature_of_business,
1883
+ "registered_capital" => registered_capital,
1884
+ "registered_capital_amount" => registered_capital_amount,
1885
+ "registered_capital_currency" => registered_capital_currency,
1886
+ "website" => website,
1887
+ "email" => email,
1888
+ "phone" => phone,
1889
+ "legal_entity_identifier" => legal_entity_identifier,
1890
+ "location_of_registration" => location_of_registration,
1891
+ "vat_number" => vat_number,
1892
+ "control_scheme" => control_scheme
1893
+ },
1894
+ response: Types::SessionsUpdateKybCompanyDataResponse,
1895
+ request_options: request_options
1896
+ )
1897
+ end
1898
+
1899
+ # Skip (or re-require) a Key People party on a Business Verification (KYB) session
1900
+ #
1901
+ # Exempt a Key People party from verification, or put it back in scope. This is the operator escape hatch for a
1902
+ # party that can never finish its own check - most often because the individual KYC session handed to a UBO or
1903
+ # director was deleted, which freezes that child's status and leaves the KYB parked in `Awaiting User` with
1904
+ # nothing left that could move it.
1905
+ #
1906
+ # Setting `is_skipped: true` drops the party out of the Key People aggregation and immediately recomputes the
1907
+ # `KYBKeyPeopleCheck` and the parent session status, so the business session can settle and then be approved or
1908
+ # declined. Sending `is_skipped: false` puts the party back in scope and the check goes back to waiting on it.
1909
+ #
1910
+ # Unlike the applicant-facing skip in the hosted Key People screen, this endpoint is **not** gated by the role's
1911
+ # `allow_skip` setting - that flag limits what the applicant may decide, not what your analyst may override.
1912
+ # `requires_verification` is deliberately left untouched, so an overridden party reads as
1913
+ # `requires_verification: true` **and** `is_skipped: true` and the record still shows what the rules asked for.
1914
+ #
1915
+ # The party must belong to the session in the path (`404` with `"Party does not belong to the given session."`
1916
+ # otherwise) and to your application. A PATCH that actually changes the flag fires the `data.updated`
1917
+ # [webhook](/integration/webhooks) on the business session with trigger `console_key_people_skip`; a PATCH that
1918
+ # sets the flag to its current value is a no-op that echoes the party back.
1919
+ #
1920
+ # Accepts an API key or a console user token; either way the credential needs the `write:businesses` permission.
1921
+ #
1922
+ # +PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/+
1923
+ #
1924
+ # @param session_id [String] UUID of the parent Business Verification (KYB) session.
1925
+ # @param party_uuid [String] UUID of the Key People party to update
1926
+ # (`key_people_checks[].submitted.parties[].uuid` on the business session decision). Must belong to the session
1927
+ # referenced by `sessionId`.
1928
+ # @param is_skipped [Boolean] `true` exempts the party from verification so the Key People check can settle
1929
+ # without it; `false` puts it back in scope.
1930
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
1931
+ # @return [Didit::Types::SessionsUpdateKybPartyResponse]
1932
+ def update_kyb_party(session_id, party_uuid, is_skipped:, request_options: nil)
1933
+ @client.request(
1934
+ :patch,
1935
+ "/v3/session/{sessionId}/kyb/parties/{partyUuid}/",
1936
+ path_params: { "sessionId" => session_id, "partyUuid" => party_uuid },
1937
+ body: {
1938
+ "is_skipped" => is_skipped
1939
+ },
1940
+ response: Types::SessionsUpdateKybPartyResponse,
1941
+ request_options: request_options
1942
+ )
1943
+ end
1944
+
1945
+ # Update Proof of Address data extracted from the POA document on a verification session
1946
+ #
1947
+ # Correct the fields extracted from the user's Proof of Address document - utility bill, bank statement, or
1948
+ # other address evidence - after the verification has finished: issuer, dates, the printed name, the address
1949
+ # itself, and banking details. Every field in the body is optional: only the keys you send are written,
1950
+ # everything else is left untouched (`PATCH` semantics).
1951
+ #
1952
+ # The session must belong to your application and be in `Approved`, `Declined`, `In Review`, or `Kyc Expired`
1953
+ # status. Sessions in any other state (e.g. still `In Progress`) return `404` with `"No Session matches the
1954
+ # given query."` - distinct from the `"Not found."` returned for an unknown or deleted `sessionId`. The session
1955
+ # must also carry a POA record: sessions whose workflow never ran a Proof of Address step return `404` (`"The
1956
+ # session does not have a POA."`). For graph workflows with multiple POA steps, target a specific step with
1957
+ # `node_id` (query parameter or body field); when omitted, the most recent POA record is patched.
1958
+ #
1959
+ # `extra_fields` is merged key-by-key: nine known keys (`bank_iban`, `additional_names`, …) write through to
1960
+ # dedicated POA columns, any other key is kept as a custom extra, and `null` / `""` deletes a key.
1961
+ # `poa_parsed_address` accepts only the seven documented keys and recomputes `formatted_address` /
1962
+ # `poa_formatted_address` after every edit. If the free-text `poa_address` changes, the server may also
1963
+ # re-geocode it and refresh the structured address (skipped for sandbox sessions).
1964
+ #
1965
+ # Unlike the KYC variant of this endpoint, the `data.updated` [webhook](/integration/webhooks) (trigger
1966
+ # `manual_review`) fires only when at least one stored value **actually changed** - re-sending identical values
1967
+ # is a silent no-op. When values change, a `POA_DATA_UPDATED` activity entry recording the changed fields with
1968
+ # previous and new values is appended to the session's `reviews`, visible in [Get
1969
+ # Decision](#get-/v3/session/-sessionId-/decision/) and the console activity timeline. The session's status and
1970
+ # decision are **not** re-evaluated - use [Update Status](#patch-/v3/session/-sessionId-/update-status/) to
1971
+ # change the outcome.
1972
+ #
1973
+ # Accepts an API key or a console user token; either way the credential needs the `write:sessions` permission.
1974
+ # Authentication and permission failures both return `403` - this API never responds `401`. Note that the
1975
+ # session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing
1976
+ # credentials. This endpoint has a dedicated rate limit of 10 requests per minute per API key (invalid requests
1977
+ # count too); the shared write budget of 300 requests per minute also applies.
1978
+ #
1979
+ # An empty JSON body `{}` is a no-op: it returns `200` echoing the current POA record without firing the webhook
1980
+ # (`has_changes` stays false).
1981
+ #
1982
+ # +PATCH /v3/session/{sessionId}/update-poa-data/+
1983
+ #
1984
+ # @param session_id [String] UUID of the User Verification (KYC) session whose attached POA record you are
1985
+ # correcting.
1986
+ # @param issuing_state [String, nil] Country that issued the POA document, ISO 3166-1 alpha-3. Case-insensitive
1987
+ # (normalized to uppercase); invalid codes return `400`.
1988
+ # @param document_type [String] POA document category. Values are uppercase - lowercase variants like
1989
+ # `utility_bill` return `400`.
1990
+ # @param document_language [String, nil] Language of the document, typically an ISO 639-1 code (e.g. `es`). Free
1991
+ # text - not validated as a language code.
1992
+ # @param issuer [String, nil] Organization that issued the document (utility company, bank, government agency).
1993
+ # @param issue_date [Date, String, nil] Issue date of the POA document in `YYYY-MM-DD`. Any other format returns
1994
+ # `400`.
1995
+ # @param poa_address [String, nil] Free-text address as printed on the document. When this value changes
1996
+ # (non-sandbox sessions only) and the structured address is still missing or incomplete, the server re-geocodes
1997
+ # it in the background of the same request and may overwrite `poa_parsed_address` / `poa_formatted_address` with
1998
+ # the geocoder result. The re-geocode also requires `issuing_state` to be present on the POA record.
1999
+ # @param name_on_document [String, nil] Recipient name as printed on the document.
2000
+ # @param extra_fields [Hash, nil] Document-specific extras, merged key-by-key. Nine keys map to dedicated POA
2001
+ # columns: `bank_account_number`, `bank_iban`, `bank_sort_code`, `bank_routing_number`, `bank_swift_bic`,
2002
+ # `bank_branch_name`, `bank_branch_address`, `document_phone_number`, and `additional_names` (must be a list of
2003
+ # strings or `null`, otherwise `400`). Any other key is stored as a custom extra field. Per-key semantics: a
2004
+ # va...
2005
+ # @param poa_parsed_address [Hash, nil] Structured address. Only these nested keys are accepted: `address_type`,
2006
+ # `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` - any other key returns `400`. Per-key
2007
+ # semantics: a value sets the key, `null` removes it. `formatted_address` (and the top-level
2008
+ # `poa_formatted_address`) is recomputed server-side by joining `street_1`, `street_2`, `city`, `region`,
2009
+ # `postal_code`, and `count...
2010
+ # @param node_id [String] Workflow graph node whose POA record to patch, for graph workflows with multiple Proof
2011
+ # of Address steps (also accepted as a `node_id` body field). When omitted, the most recent POA record on the
2012
+ # session is patched. If no POA exists for the given node, the call returns `404` (`"The session does not have a
2013
+ # POA for node '<node_id>'."`).
2014
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2015
+ # @return [Didit::Types::SessionsUpdatePoaDataResponse]
2016
+ def update_poa_data(
2017
+ session_id,
2018
+ issuing_state: OMIT,
2019
+ document_type: OMIT,
2020
+ document_language: OMIT,
2021
+ issuer: OMIT,
2022
+ issue_date: OMIT,
2023
+ poa_address: OMIT,
2024
+ name_on_document: OMIT,
2025
+ extra_fields: OMIT,
2026
+ poa_parsed_address: OMIT,
2027
+ node_id: OMIT,
2028
+ request_options: nil
2029
+ )
2030
+ @client.request(
2031
+ :patch,
2032
+ "/v3/session/{sessionId}/update-poa-data/",
2033
+ path_params: { "sessionId" => session_id },
2034
+ query: {
2035
+ "node_id" => node_id
2036
+ },
2037
+ body: {
2038
+ "issuing_state" => issuing_state,
2039
+ "document_type" => document_type,
2040
+ "document_language" => document_language,
2041
+ "issuer" => issuer,
2042
+ "issue_date" => issue_date,
2043
+ "poa_address" => poa_address,
2044
+ "name_on_document" => name_on_document,
2045
+ "extra_fields" => extra_fields,
2046
+ "poa_parsed_address" => poa_parsed_address
2047
+ },
2048
+ response: Types::SessionsUpdatePoaDataResponse,
2049
+ request_options: request_options
2050
+ )
2051
+ end
2052
+
2053
+ # Approve, decline, or request resubmission for a verification session
2054
+ #
2055
+ # Manually override the final decision of a KYC or KYB verification session. Set `new_status` to `Approved` or
2056
+ # `Declined` to record a manual decision, or to `Resubmitted` to clear specific verification steps and let the
2057
+ # user redo them through the same verification URL. The endpoint accepts both user (KYC) and business (KYB)
2058
+ # session IDs.
2059
+ #
2060
+ # Call it once a session has reached a reviewable state: the current status must be `Approved`, `Declined`, `In
2061
+ # Review`, `Kyc Expired`, `Abandoned`, or `Resubmitted`. Sessions that are still `Not Started`, `In Progress`,
2062
+ # or `Awaiting User`, or that ended as `Expired`, return `400`. Your API key needs the `write:sessions`
2063
+ # permission (a scoped API key needs write access to decisions). The eligible-state check runs before body
2064
+ # validation, so an ineligible session returns the `Wrong Current Status` error even when the payload is also
2065
+ # invalid.
2066
+ #
2067
+ # For `Resubmitted`, pass `nodes_to_resubmit` to choose which workflow steps the user must redo, or omit it to
2068
+ # auto-select existing feature attempts in a resubmittable state (`Declined`, `In Review`, `Not Finished`,
2069
+ # `Expired`). Never-attempted features are not auto-selected: list them explicitly in `nodes_to_resubmit`, or
2070
+ # the request returns `400` when no recorded attempt needs resubmission. The selected steps' previous results
2071
+ # move to the resubmission's history (returned by Get Decision with `include=resubmissions`), the steps are
2072
+ # reordered to match the workflow graph, the session's expiration window restarts, and the original verification
2073
+ # URL becomes usable again. Backend-only steps (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) at the head of the
2074
+ # list run immediately without user interaction; if every resubmitted step is backend-only, the session
2075
+ # re-finalizes within the same request. `KYB_REGISTRY` and `KYB_KEY_PEOPLE` cannot be resubmitted directly:
2076
+ # resubmit the relevant child KYC sessions instead and the parent business session recomputes automatically.
2077
+ #
2078
+ # Every call that changes the status fires the `status.updated` [webhook](/integration/webhooks) once the change
2079
+ # commits and appends an activity entry (with actor attribution and your `comment`) to the session's `reviews`,
2080
+ # visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and in the console activity timeline. The
2081
+ # user-profile aggregates linked to the session's `vendor_data` update as well. Declining disables ongoing AML
2082
+ # monitoring for the session; re-approving re-enables it (from `Resubmitted`, `Declined`, or `Kyc Expired`) when
2083
+ # the workflow has monitoring turned on. Approving or declining a child KYC that belongs to a KYB key-people
2084
+ # check recomputes the parent business session's status. Set `send_email: true` (with `email_address`) to notify
2085
+ # the user: a status notice for `Approved`/`Declined`, or a resubmission email containing the verification link
2086
+ # and per-step reasons for `Resubmitted`. To check the email first, preview it with [Preview Decision
2087
+ # Email](/sessions-api/preview-decision-email) (`Approved`, `Declined`) or [Preview Resubmission
2088
+ # Email](/sessions-api/preview-resubmission) (`Resubmitted`) and pass its `preview_token` as
2089
+ # `email_preview_token`: the update then sends exactly the previewed email, or returns `409` before changing
2090
+ # anything when the email or the session changed since the preview or the receipt is older than 15 minutes.
2091
+ #
2092
+ # Repeating `Approved` or `Declined` on a session that already has that status changes nothing and returns
2093
+ # `200`: no webhook, no activity entry and no email. Repeating `Resubmitted` returns `400` (`The new status is
2094
+ # the same as the current status.`). Missing or invalid credentials and missing permissions return `403`; an
2095
+ # expired scoped API key returns `401`.
2096
+ #
2097
+ # +PATCH /v3/session/{sessionId}/update-status/+
2098
+ #
2099
+ # @param session_id [String] UUID of the verification session to update. Accepts both user (KYC) and business
2100
+ # (KYB) session IDs - the service resolves the ID across both session types.
2101
+ # @param new_status [String] Target status. `Approved` and `Declined` record a final manual decision (each can
2102
+ # also overturn the other). `Resubmitted` clears the selected steps and sends the session back to the user. Any
2103
+ # other value returns `400`.
2104
+ # @param comment [String] Free-text reason for the change, stored on the session's review trail and returned in
2105
+ # the `reviews` array of [Get Decision](#get-/v3/session/-sessionId-/decision/). For example `Duplicated user`.
2106
+ # @param nodes_to_resubmit [Array<Hash>] Workflow steps the user must redo. Only acted on when `new_status` is
2107
+ # `Resubmitted`. For `Approved`/`Declined` the entries are still schema-validated (an invalid `feature` value
2108
+ # returns `400`) but schema-valid entries are semantically ignored. If omitted, the server auto-selects existing
2109
+ # OCR, Liveness, Face Match, POA, Phone, Email, AML, Database Validation, and Questionnaire attempts whose
2110
+ # statu...
2111
+ # @param send_email [Boolean] Whether to email the user about the change. Requires `email_address`. For
2112
+ # `Approved`/`Declined` the user receives a status notice; for `Resubmitted` the email includes the verification
2113
+ # link and the per-step resubmission reasons.
2114
+ # @param email_address [String] Recipient for the notification email. **Required when `send_email` is `true`** -
2115
+ # omitting it returns `400`.
2116
+ # @param email_language [String] Language for the notification email. Accepts any string at schema level;
2117
+ # unsupported codes silently fall back to English (`en`).
2118
+ # @param email_preview_token [String] Optional receipt from [Preview Decision
2119
+ # Email](/sessions-api/preview-decision-email) (for `Approved` and `Declined`) or [Preview Resubmission
2120
+ # Email](/sessions-api/preview-resubmission) (for `Resubmitted`): its `preview_token`. Valid only with
2121
+ # `send_email: true`; without it the request returns `400`. The recipient, language, session status, sender and
2122
+ # email (and, for a resubmission, the selected s...
2123
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2124
+ # @return [Didit::Types::SessionsUpdateStatusResponse]
2125
+ def update_status(
2126
+ session_id,
2127
+ new_status:,
2128
+ comment: OMIT,
2129
+ nodes_to_resubmit: OMIT,
2130
+ send_email: OMIT,
2131
+ email_address: OMIT,
2132
+ email_language: OMIT,
2133
+ email_preview_token: OMIT,
2134
+ request_options: nil
2135
+ )
2136
+ @client.request(
2137
+ :patch,
2138
+ "/v3/session/{sessionId}/update-status/",
2139
+ path_params: { "sessionId" => session_id },
2140
+ body: {
2141
+ "new_status" => new_status,
2142
+ "comment" => comment,
2143
+ "nodes_to_resubmit" => nodes_to_resubmit,
2144
+ "send_email" => send_email,
2145
+ "email_address" => email_address,
2146
+ "email_language" => email_language,
2147
+ "email_preview_token" => email_preview_token
2148
+ },
2149
+ response: Types::SessionsUpdateStatusResponse,
2150
+ request_options: request_options
2151
+ )
2152
+ end
2153
+
2154
+ # The +sessions.imports+ resource.
2155
+ class Imports < Didit::Resource
2156
+ # Cancel an import job
2157
+ #
2158
+ # Cancel an import. What was imported stays; the uploaded file and the key are erased.
2159
+ #
2160
+ # +POST /v3/session/imports/{importId}/cancel/+
2161
+ #
2162
+ # @param import_id [String]
2163
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2164
+ # @return [Didit::Types::SessionImportJob]
2165
+ def cancel(import_id, request_options: nil)
2166
+ @client.request(
2167
+ :post,
2168
+ "/v3/session/imports/{importId}/cancel/",
2169
+ path_params: { "importId" => import_id },
2170
+ response: Types::SessionImportJob,
2171
+ request_options: request_options
2172
+ )
2173
+ end
2174
+
2175
+ # Check a provider key
2176
+ #
2177
+ # Read the provider with your key before creating a migration. Nothing is stored.
2178
+ #
2179
+ # +POST /v3/session/imports/providers/check/+
2180
+ #
2181
+ # @param provider [String] Migration source, from `GET /v3/session/imports/providers/`. Required when `source`
2182
+ # is `provider`.
2183
+ # @param credentials [Hash{String => String}] The provider's read-only key, with the field names
2184
+ # `credential_fields` lists. Encrypted at rest, never returned, and erased when the import ends. Send it as a
2185
+ # JSON string in multipart.
2186
+ # @param options [Hash]
2187
+ # @param record_ids [Array<String>] For `api_ids` providers: the first record ID of your export.
2188
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2189
+ # @return [Didit::Types::SessionsImportsCheckProviderResponse]
2190
+ def check_provider(provider:, credentials:, options: OMIT, record_ids: OMIT, request_options: nil)
2191
+ @client.request(
2192
+ :post,
2193
+ "/v3/session/imports/providers/check/",
2194
+ body: {
2195
+ "provider" => provider,
2196
+ "credentials" => credentials,
2197
+ "options" => options,
2198
+ "record_ids" => record_ids
2199
+ },
2200
+ response: Types::SessionsImportsCheckProviderResponse,
2201
+ request_options: request_options
2202
+ )
2203
+ end
2204
+
2205
+ # Create a verification import job
2206
+ #
2207
+ # Create an asynchronous import job for historical User Verification sessions, Business Verification sessions,
2208
+ # transaction monitoring records, or workflow custom status rules. Set `source=provider` to migrate from
2209
+ # another provider: Didit reads Sumsub, Onfido, Persona and ComplyCube with your read-only key, reads Veriff,
2210
+ # iDenfy and MetaMap records by the IDs you upload in `file`, and imports an export file in Didit's format for
2211
+ # the other providers. Record IDs are namespaced by provider (`sumsub:<id>`) so a re-run skips everything
2212
+ # already in Didit. Imports are disabled by default and must be enabled per organization by Didit.
2213
+ #
2214
+ # +POST /v3/session/imports/+
2215
+ #
2216
+ # @param import_type [String] What to import: historical User Verification sessions, historical Business
2217
+ # Verification sessions, workflow custom status rules, or historical transaction monitoring records.
2218
+ # @param workflow_id [String] Workflow UUID that imported sessions or status rules should be attached to.
2219
+ # Required for user_verification, business_verification, and status_rules. Omit for transactions.
2220
+ # @param source_format [String] Optional. Inferred from the URL's file extension when omitted.
2221
+ # @param source_file_url [String] Alternative to file upload. Must be an HTTPS URL resolving to a public
2222
+ # address (private/loopback networks are rejected). Mutually exclusive with `file`.
2223
+ # @param source [String] `provider` makes this a migration from another identity verification provider. Omit
2224
+ # for a file import.
2225
+ # @param provider [String] Migration source, from `GET /v3/session/imports/providers/`. Required when `source`
2226
+ # is `provider`.
2227
+ # @param credentials [Hash{String => String}] The provider's read-only key, with the field names
2228
+ # `credential_fields` lists. Encrypted at rest, never returned, and erased when the import ends. Send it as a
2229
+ # JSON string in multipart.
2230
+ # @param options [Hash]
2231
+ # @param status_mapping [Hash{String => String}] Edits to the provider's default status mapping: source status
2232
+ # to Didit status. `Not Finished` and `Abandoned` are skipped and counted, never imported.
2233
+ # @param dry_run [Boolean] Count what the migration would import (by status, already in Didit, same person,
2234
+ # not finished) and write nothing. The job ends `READY`; start it with `POST
2235
+ # /v3/session/imports/{importId}/start/`.
2236
+ # @param face_templates [Boolean] Build face templates from the imported selfies and search them against the
2237
+ # application's faces and blocklist. Matches are flagged for review only. Requires `lawful_basis_confirmed`.
2238
+ # @param lawful_basis_confirmed [Boolean] Confirms you have a lawful basis to share these selfies with Didit
2239
+ # as processor.
2240
+ # @param file [Pathname, IO, String, Didit::FilePart] Canonical CSV or NDJSON file. Use NDJSON for large
2241
+ # imports. Maximum upload size 25 MB (use `source_file_url` for bigger files). Mutually exclusive with
2242
+ # `source_file_url`.
2243
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2244
+ # @return [Didit::Types::SessionImportJob]
2245
+ def create(
2246
+ import_type: OMIT,
2247
+ workflow_id: OMIT,
2248
+ source_format: OMIT,
2249
+ source_file_url: OMIT,
2250
+ source: OMIT,
2251
+ provider: OMIT,
2252
+ credentials: OMIT,
2253
+ options: OMIT,
2254
+ status_mapping: OMIT,
2255
+ dry_run: OMIT,
2256
+ face_templates: OMIT,
2257
+ lawful_basis_confirmed: OMIT,
2258
+ file: OMIT,
2259
+ request_options: nil
2260
+ )
2261
+ @client.request(
2262
+ :post,
2263
+ "/v3/session/imports/",
2264
+ body: {
2265
+ "import_type" => import_type,
2266
+ "workflow_id" => workflow_id,
2267
+ "source_format" => source_format,
2268
+ "source_file_url" => source_file_url,
2269
+ "source" => source,
2270
+ "provider" => provider,
2271
+ "credentials" => credentials,
2272
+ "options" => options,
2273
+ "status_mapping" => status_mapping,
2274
+ "dry_run" => dry_run,
2275
+ "face_templates" => face_templates,
2276
+ "lawful_basis_confirmed" => lawful_basis_confirmed,
2277
+ "file" => file
2278
+ },
2279
+ encoding: :auto,
2280
+ file_fields: %w[file],
2281
+ response: Types::SessionImportJob,
2282
+ request_options: request_options
2283
+ )
2284
+ end
2285
+
2286
+ # List active import jobs
2287
+ #
2288
+ # What is running or waiting, plus what just ended, for a progress indicator.
2289
+ #
2290
+ # +GET /v3/import-jobs/active/+
2291
+ #
2292
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2293
+ # @return [Didit::Types::SessionsImportsListActiveJobsResponse]
2294
+ def list_active_jobs(request_options: nil)
2295
+ @client.request(
2296
+ :get,
2297
+ "/v3/import-jobs/active/",
2298
+ response: Types::SessionsImportsListActiveJobsResponse,
2299
+ request_options: request_options
2300
+ )
2301
+ end
2302
+
2303
+ # List verification import row errors
2304
+ #
2305
+ # List row-level errors for a verification import job, ordered by `row_number`. Use this endpoint to produce a
2306
+ # corrected retry file containing only failed rows.
2307
+ #
2308
+ # +GET /v3/session/imports/{importId}/errors/+
2309
+ #
2310
+ # @param import_id [String]
2311
+ # @param limit [Integer] Page size. Defaults to 50 when omitted.
2312
+ # @param offset [Integer] Zero-based offset of the first record to return.
2313
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2314
+ # @return [Didit::Page<Didit::Types::SessionImportError>]
2315
+ def list_errors(import_id, limit: OMIT, offset: OMIT, request_options: nil)
2316
+ @client.request(
2317
+ :get,
2318
+ "/v3/session/imports/{importId}/errors/",
2319
+ path_params: { "importId" => import_id },
2320
+ query: {
2321
+ "limit" => limit,
2322
+ "offset" => offset
2323
+ },
2324
+ page: Types::SessionImportError,
2325
+ request_options: request_options
2326
+ )
2327
+ end
2328
+
2329
+ # List import jobs
2330
+ #
2331
+ # Every import of the application in one shape: verification imports and migrations, people and businesses.
2332
+ #
2333
+ # +GET /v3/import-jobs/+
2334
+ #
2335
+ # @param scope [String]
2336
+ # @param limit [Integer]
2337
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2338
+ # @return [Didit::Types::SessionsImportsListJobsResponse]
2339
+ def list_jobs(scope: OMIT, limit: OMIT, request_options: nil)
2340
+ @client.request(
2341
+ :get,
2342
+ "/v3/import-jobs/",
2343
+ query: {
2344
+ "scope" => scope,
2345
+ "limit" => limit
2346
+ },
2347
+ response: Types::SessionsImportsListJobsResponse,
2348
+ request_options: request_options
2349
+ )
2350
+ end
2351
+
2352
+ # List migration providers
2353
+ #
2354
+ # The 15 providers you can migrate verifications from: what each needs to connect, whether its API can list
2355
+ # records, the permissions its key needs and its default status mapping.
2356
+ #
2357
+ # +GET /v3/session/imports/providers/+
2358
+ #
2359
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2360
+ # @return [Didit::Types::SessionsImportsListProvidersResponse]
2361
+ def list_providers(request_options: nil)
2362
+ @client.request(
2363
+ :get,
2364
+ "/v3/session/imports/providers/",
2365
+ response: Types::SessionsImportsListProvidersResponse,
2366
+ request_options: request_options
2367
+ )
2368
+ end
2369
+
2370
+ # Pause an import job
2371
+ #
2372
+ # Pause a queued or running import.
2373
+ #
2374
+ # +POST /v3/session/imports/{importId}/pause/+
2375
+ #
2376
+ # @param import_id [String]
2377
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2378
+ # @return [Didit::Types::SessionImportJob]
2379
+ def pause(import_id, request_options: nil)
2380
+ @client.request(
2381
+ :post,
2382
+ "/v3/session/imports/{importId}/pause/",
2383
+ path_params: { "importId" => import_id },
2384
+ response: Types::SessionImportJob,
2385
+ request_options: request_options
2386
+ )
2387
+ end
2388
+
2389
+ # Resume an import job
2390
+ #
2391
+ # Resume an import you paused. A job paused by the provider's rate limit resumes by itself.
2392
+ #
2393
+ # +POST /v3/session/imports/{importId}/resume/+
2394
+ #
2395
+ # @param import_id [String]
2396
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2397
+ # @return [Didit::Types::SessionImportJob]
2398
+ def resume(import_id, request_options: nil)
2399
+ @client.request(
2400
+ :post,
2401
+ "/v3/session/imports/{importId}/resume/",
2402
+ path_params: { "importId" => import_id },
2403
+ response: Types::SessionImportJob,
2404
+ request_options: request_options
2405
+ )
2406
+ end
2407
+
2408
+ # Retrieve a verification import job
2409
+ #
2410
+ # Retrieve import progress counters and terminal status for one job. Poll until `status` is `COMPLETED` or
2411
+ # `FAILED`; `failed_count` > 0 means some rows were rejected - list them via the errors endpoint.
2412
+ #
2413
+ # +GET /v3/session/imports/{importId}/+
2414
+ #
2415
+ # @param import_id [String]
2416
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2417
+ # @return [Didit::Types::SessionImportJob]
2418
+ def retrieve(import_id, request_options: nil)
2419
+ @client.request(
2420
+ :get,
2421
+ "/v3/session/imports/{importId}/",
2422
+ path_params: { "importId" => import_id },
2423
+ response: Types::SessionImportJob,
2424
+ request_options: request_options
2425
+ )
2426
+ end
2427
+
2428
+ # Download verification import template
2429
+ #
2430
+ # Download the canonical CSV header for verification imports. The column set is determined by `import_type`.
2431
+ # The first column of session templates is the idempotency key `external_id`.
2432
+ #
2433
+ # +GET /v3/session/imports/template/+
2434
+ #
2435
+ # @param import_type [String]
2436
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2437
+ # @return [String, nil] the body bytes, or nil when a block receives the chunks
2438
+ def retrieve_template(import_type: OMIT, request_options: nil, &block)
2439
+ @client.request(
2440
+ :get,
2441
+ "/v3/session/imports/template/",
2442
+ query: {
2443
+ "import_type" => import_type
2444
+ },
2445
+ response: :binary,
2446
+ accept: "text/csv, application/json",
2447
+ request_options: request_options, &block
2448
+ )
2449
+ end
2450
+
2451
+ # Retry a migration
2452
+ #
2453
+ # Run a migration that ended again as a new job, with a new key (the old one was erased). It keeps the
2454
+ # provider, workflow, region, status mapping and face templates choice; everything already in Didit is
2455
+ # skipped.
2456
+ #
2457
+ # +POST /v3/session/imports/{importId}/retry/+
2458
+ #
2459
+ # @param import_id [String]
2460
+ # @param credentials [Hash{String => String}] The provider's read-only key, with the field names
2461
+ # `credential_fields` lists. Encrypted at rest, never returned, and erased when the import ends. Send it as a
2462
+ # JSON string in multipart.
2463
+ # @param file [Pathname, IO, String, Didit::FilePart] The record IDs or export file again, for `api_ids` and
2464
+ # `export_file` providers.
2465
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2466
+ # @return [Didit::Types::SessionImportJob]
2467
+ def retry(import_id, credentials: OMIT, file: OMIT, request_options: nil)
2468
+ @client.request(
2469
+ :post,
2470
+ "/v3/session/imports/{importId}/retry/",
2471
+ path_params: { "importId" => import_id },
2472
+ body: {
2473
+ "credentials" => credentials,
2474
+ "file" => file
2475
+ },
2476
+ encoding: :multipart,
2477
+ file_fields: %w[file],
2478
+ response: Types::SessionImportJob,
2479
+ request_options: request_options
2480
+ )
2481
+ end
2482
+
2483
+ # Start a dry run
2484
+ #
2485
+ # Start a migration whose dry run finished (`READY`): the same job imports for real, with the status mapping
2486
+ # and face templates choice as sent now.
2487
+ #
2488
+ # +POST /v3/session/imports/{importId}/start/+
2489
+ #
2490
+ # @param import_id [String]
2491
+ # @param status_mapping [Hash{String => String}] Edits to the provider's default status mapping: source status
2492
+ # to Didit status. `Not Finished` and `Abandoned` are skipped and counted, never imported.
2493
+ # @param face_templates [Boolean] Build face templates from the imported selfies and search them against the
2494
+ # application's faces and blocklist. Matches are flagged for review only. Requires `lawful_basis_confirmed`.
2495
+ # @param lawful_basis_confirmed [Boolean] Confirms you have a lawful basis to share these selfies with Didit
2496
+ # as processor.
2497
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2498
+ # @return [Didit::Types::SessionImportJob]
2499
+ def start(
2500
+ import_id,
2501
+ status_mapping: OMIT,
2502
+ face_templates: OMIT,
2503
+ lawful_basis_confirmed: OMIT,
2504
+ request_options: nil
2505
+ )
2506
+ @client.request(
2507
+ :post,
2508
+ "/v3/session/imports/{importId}/start/",
2509
+ path_params: { "importId" => import_id },
2510
+ body: {
2511
+ "status_mapping" => status_mapping,
2512
+ "face_templates" => face_templates,
2513
+ "lawful_basis_confirmed" => lawful_basis_confirmed
2514
+ },
2515
+ response: Types::SessionImportJob,
2516
+ request_options: request_options
2517
+ )
2518
+ end
2519
+ end
2520
+
2521
+ # The +sessions.reviews+ resource.
2522
+ class Reviews < Didit::Resource
2523
+ # Add a review note to a session's audit trail
2524
+ #
2525
+ # Append a note to a User Verification (KYC) session's review / activity feed. **This endpoint only records an
2526
+ # entry - it never changes the session.** The session's `status` is left untouched, no status-transition
2527
+ # validation runs, and no webhook fires. To actually approve, decline, or re-open a session (which also writes
2528
+ # a fully-attributed `STATUS_UPDATED` entry to this feed), use `PATCH /v3/session/{session_id}/update-status/`
2529
+ # instead.
2530
+ #
2531
+ # Both body fields are optional and an empty JSON object is accepted. `new_status` is stored purely as a label
2532
+ # on the entry and accepts any of the ten session status values (case-sensitive). `@email` mentions inside
2533
+ # `comment` are stored as plain text only - they trigger no notifications on this endpoint, and the entry's
2534
+ # `mentioned_emails` stays empty.
2535
+ #
2536
+ # Note on attribution: entries created here carry no actor information. In the feed they show `actor_display:
2537
+ # "Unknown"`, `actor_type: "CONSOLE_USER"`, and `activity_type: "STATUS_UPDATED"` (storage defaults), and the
2538
+ # `201` body's `user` field is `"Unknown"`.
2539
+ #
2540
+ # +POST /v3/sessions/{session_id}/reviews/+
2541
+ #
2542
+ # @param session_id [String] UUID of the User Verification (KYC) session. Must belong to the same application
2543
+ # as the API key - cross-application UUIDs, deleted sessions, and Business Verification (KYB) session IDs all
2544
+ # return `404`.
2545
+ # @param new_status [String, nil] Optional status label to record on the entry. Accepts any session status
2546
+ # value, case-sensitive (`"approved"` is rejected with `400`). Recording a status here does **not** change the
2547
+ # session's actual status - use the update-status endpoint for that.
2548
+ # @param comment [String, nil] Optional free-text note (no enforced length limit). Stored verbatim; `@email`
2549
+ # mentions are not processed on this endpoint.
2550
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2551
+ # @return [Didit::Types::SessionsReviewsCreateResponse]
2552
+ def create(session_id, new_status: OMIT, comment: OMIT, request_options: nil)
2553
+ @client.request(
2554
+ :post,
2555
+ "/v3/sessions/{session_id}/reviews/",
2556
+ path_params: { "session_id" => session_id },
2557
+ body: {
2558
+ "new_status" => new_status,
2559
+ "comment" => comment
2560
+ },
2561
+ response: Types::SessionsReviewsCreateResponse,
2562
+ request_options: request_options
2563
+ )
2564
+ end
2565
+
2566
+ # List session reviews and activity log
2567
+ #
2568
+ # Return the audit trail / activity feed for a User Verification (KYC) session, newest first, in a paginated
2569
+ # envelope (`count` / `next` / `previous` / `results`, 50 entries per page by default).
2570
+ #
2571
+ # Feed entries are written by every actor that touches the session: manual decisions made through `PATCH
2572
+ # /v3/session/{session_id}/update-status/` (which records `previous_status` → `new_status`), Console reviewer
2573
+ # activity (comments with `@email` mentions, KYC/POA data edits, file uploads/removals, tag changes,
2574
+ # detail-page views), AML ongoing-monitoring matches, and notes appended via `POST` on this same path. Reading
2575
+ # this feed is the API-side equivalent of the **Activity** panel in the Didit Console session view.
2576
+ #
2577
+ # Only User Verification (KYC) sessions are addressable here; Business Verification (KYB) session IDs return
2578
+ # `404`.
2579
+ #
2580
+ # +GET /v3/sessions/{session_id}/reviews/+
2581
+ #
2582
+ # @param session_id [String] UUID of the User Verification (KYC) session. Must belong to the same application
2583
+ # as the API key - cross-application UUIDs, deleted sessions, and Business Verification (KYB) session IDs all
2584
+ # return `404`.
2585
+ # @param limit [Integer] Page size. Defaults to `50`.
2586
+ # @param offset [Integer] Number of entries to skip from the start of the (ordered) feed. Defaults to `0`. The
2587
+ # `next` / `previous` URLs in the response carry the right values for walking the feed.
2588
+ # @param ordering [String] Sort order. The feed defaults to newest first (`-created_at`); pass `created_at` to
2589
+ # read it oldest first. Unknown values are silently ignored (default order is used); other serializer field
2590
+ # names are also accepted.
2591
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2592
+ # @return [Didit::Page<Didit::Types::ReviewItem>]
2593
+ def list(session_id, limit: OMIT, offset: OMIT, ordering: OMIT, request_options: nil)
2594
+ @client.request(
2595
+ :get,
2596
+ "/v3/sessions/{session_id}/reviews/",
2597
+ path_params: { "session_id" => session_id },
2598
+ query: {
2599
+ "limit" => limit,
2600
+ "offset" => offset,
2601
+ "ordering" => ordering
2602
+ },
2603
+ page: Types::ReviewItem,
2604
+ request_options: request_options
2605
+ )
2606
+ end
2607
+ end
2608
+
2609
+ # The +sessions.signatures+ resource.
2610
+ class Signatures < Didit::Resource
2611
+ # Download a signed document
2612
+ #
2613
+ # Download the signed PDF of one document of an Electronic Signature step. Use the `signed_file` path of
2614
+ # `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field
2615
+ # values stamped, the evidence page (unless `signature_evidence_page` is off) and the PAdES signature with its
2616
+ # timestamp. Didit checks the file against `sha256_signed` before returning it.
2617
+ #
2618
+ # Works for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API
2619
+ # key works. See the [Electronic Signature
2620
+ # report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents).
2621
+ #
2622
+ # +GET /v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/+
2623
+ #
2624
+ # @param session_id [String] The User Verification (KYC) or Business Verification (KYB) session.
2625
+ # @param node_id [String] The Electronic Signature step: `node_id` of the item in `signatures[]`.
2626
+ # @param document_id [String] `id` of the document in `signatures[].documents[]`.
2627
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2628
+ # @return [String, nil] the body bytes, or nil when a block receives the chunks
2629
+ def download_document(session_id, node_id, document_id, request_options: nil, &block)
2630
+ @client.request(
2631
+ :get,
2632
+ "/v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/",
2633
+ path_params: { "sessionId" => session_id, "nodeId" => node_id, "documentId" => document_id },
2634
+ response: :binary,
2635
+ accept: "application/pdf, application/json",
2636
+ request_options: request_options, &block
2637
+ )
2638
+ end
2639
+
2640
+ # Download the signature evidence
2641
+ #
2642
+ # Download a signer's evidence PDF: the level and format, the signer and their verified identity session, the
2643
+ # code confirmation, the IP address, each document with its original SHA-256 and field values, the
2644
+ # certificate, the timestamp and the SHA-256 of every signed file. Use the `evidence_file` path of the
2645
+ # signer's item in `signatures[]`.
2646
+ #
2647
+ # Always pass `signature_id` when a Business Verification step has several signers: without it, the route
2648
+ # picks one of the step's signers. Needs `read:sessions`; your API key works.
2649
+ #
2650
+ # +GET /v3/session/{sessionId}/signatures/{nodeId}/evidence/+
2651
+ #
2652
+ # @param session_id [String] The User Verification (KYC) or Business Verification (KYB) session.
2653
+ # @param node_id [String] The Electronic Signature step: `node_id` of the item in `signatures[]`.
2654
+ # @param signature_id [String] `id` of the signer's item in `signatures[]`.
2655
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2656
+ # @return [String, nil] the body bytes, or nil when a block receives the chunks
2657
+ def download_evidence(session_id, node_id, signature_id: OMIT, request_options: nil, &block)
2658
+ @client.request(
2659
+ :get,
2660
+ "/v3/session/{sessionId}/signatures/{nodeId}/evidence/",
2661
+ path_params: { "sessionId" => session_id, "nodeId" => node_id },
2662
+ query: {
2663
+ "signature_id" => signature_id
2664
+ },
2665
+ response: :binary,
2666
+ accept: "application/pdf, application/json",
2667
+ request_options: request_options, &block
2668
+ )
2669
+ end
2670
+
2671
+ # Download a signature image
2672
+ #
2673
+ # Download the signature or initials a signer applied to a field, as PNG. Use the `image_url` of the field in
2674
+ # `signatures[].documents[].fields[]`. Needs `read:sessions`; your API key works.
2675
+ #
2676
+ # +GET /v3/session/{sessionId}/signatures/{nodeId}/fields/{fieldId}/image/+
2677
+ #
2678
+ # @param session_id [String] The User Verification (KYC) or Business Verification (KYB) session.
2679
+ # @param node_id [String] The Electronic Signature step: `node_id` of the item in `signatures[]`.
2680
+ # @param field_id [String] The field on this signer's copy, as in the field's `image_url`.
2681
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2682
+ # @return [String, nil] the body bytes, or nil when a block receives the chunks
2683
+ def download_field_image(session_id, node_id, field_id, request_options: nil, &block)
2684
+ @client.request(
2685
+ :get,
2686
+ "/v3/session/{sessionId}/signatures/{nodeId}/fields/{fieldId}/image/",
2687
+ path_params: { "sessionId" => session_id, "nodeId" => node_id, "fieldId" => field_id },
2688
+ response: :binary,
2689
+ accept: "image/png, application/json",
2690
+ request_options: request_options, &block
2691
+ )
2692
+ end
2693
+
2694
+ # Validate signatures again
2695
+ #
2696
+ # Re-check the signed documents of an Electronic Signature step. Didit re-reads every signed PDF, checks its
2697
+ # SHA-256 and validates the PAdES signature, the certificate, the revocation data and the timestamp, then
2698
+ # saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send
2699
+ # `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if
2700
+ # any of them hasn't signed.
2701
+ #
2702
+ # Needs `write:sessions`; your API key works. In the console it's the **Validate again** button.
2703
+ #
2704
+ # +POST /v3/session/{sessionId}/signatures/{nodeId}/validate/+
2705
+ #
2706
+ # @param session_id [String] The User Verification (KYC) or Business Verification (KYB) session.
2707
+ # @param node_id [String] The Electronic Signature step: `node_id` of the item in `signatures[]`.
2708
+ # @param signature_id [String] `id` of one signer's item in `signatures[]`.
2709
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2710
+ # @return [Didit::Types::SessionsSignaturesValidateResponse]
2711
+ def validate(session_id, node_id, signature_id: OMIT, request_options: nil)
2712
+ @client.request(
2713
+ :post,
2714
+ "/v3/session/{sessionId}/signatures/{nodeId}/validate/",
2715
+ path_params: { "sessionId" => session_id, "nodeId" => node_id },
2716
+ body: {
2717
+ "signature_id" => signature_id
2718
+ },
2719
+ response: Types::SessionsSignaturesValidateResponse,
2720
+ request_options: request_options
2721
+ )
2722
+ end
2723
+ end
2724
+
2725
+ # The +sessions.webhooks+ resource.
2726
+ class Webhooks < Didit::Resource
2727
+ # List session webhook deliveries
2728
+ #
2729
+ # List every webhook delivery Didit recorded for one verification session, user (KYC) or business (KYB),
2730
+ # newest first, as a plain JSON array (not paginated). Each entry is one attempt to one destination: the first
2731
+ # send, each automatic [retry](https://docs.didit.me/integration/webhooks#retry-policy) and each resend are
2732
+ # separate entries with their own `uuid`, and retries and resends keep the payload's `event_id`.
2733
+ # `request_header` and `request_body` are JSON text; parse them to read the signatures and the payload.
2734
+ # Delivery records are available for about 30 days, so an empty array means no webhook has been sent for the
2735
+ # session yet or every delivery is older than that. A scoped API key needs `sessions: read` and `decisions:
2736
+ # read`.
2737
+ #
2738
+ # +GET /v3/session/{sessionId}/webhooks/+
2739
+ #
2740
+ # @param session_id [String] UUID of the verification session, user (KYC) or business (KYB): the `session_id`
2741
+ # returned by `POST /v3/session/`. The server resolves it against both session types. **Must be a valid
2742
+ # UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router before
2743
+ # any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}`
2744
+ # e...
2745
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2746
+ # @return [Array<Didit::Types::SessionWebhookDelivery>]
2747
+ def list(session_id, request_options: nil)
2748
+ @client.request(
2749
+ :get,
2750
+ "/v3/session/{sessionId}/webhooks/",
2751
+ path_params: { "sessionId" => session_id },
2752
+ response: [:array, Types::SessionWebhookDelivery],
2753
+ request_options: request_options
2754
+ )
2755
+ end
2756
+
2757
+ # Resend session webhook delivery
2758
+ #
2759
+ # Send a recorded session webhook again to the URL it first went to, with the same payload and `event_id` and
2760
+ # a fresh `timestamp`, `X-Timestamp` header and signatures. Didit signs it with the current secret of the
2761
+ # destination the delivery belongs to (or the application-level secret for a delivery to the legacy webhook
2762
+ # URL), waits up to 5 seconds for your endpoint, records the attempt as a new delivery and returns it with
2763
+ # `200` whatever your endpoint answered: read `response_status`. A resend is not retried automatically, and
2764
+ # every call sends again, so make your endpoint idempotent on `event_id`. The path has no trailing slash and
2765
+ # the request has no body. A scoped API key needs `webhooks: write` and `decisions: read`.
2766
+ #
2767
+ # +POST /v3/session/{sessionId}/webhook/{webhook_uuid}/resend+
2768
+ #
2769
+ # @param session_id [String] UUID of the verification session, user (KYC) or business (KYB): the `session_id`
2770
+ # returned by `POST /v3/session/`. The server resolves it against both session types. **Must be a valid
2771
+ # UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router before
2772
+ # any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}`
2773
+ # e...
2774
+ # @param webhook_uuid [String] UUID of the delivery to resend: the `uuid` of an entry returned by `GET
2775
+ # /v3/session/{sessionId}/webhooks/`. It must belong to the session in the path.
2776
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2777
+ # @return [Didit::Types::SessionWebhookDelivery]
2778
+ def resend(session_id, webhook_uuid, request_options: nil)
2779
+ @client.request(
2780
+ :post,
2781
+ "/v3/session/{sessionId}/webhook/{webhook_uuid}/resend",
2782
+ path_params: { "sessionId" => session_id, "webhook_uuid" => webhook_uuid },
2783
+ response: Types::SessionWebhookDelivery,
2784
+ request_options: request_options
2785
+ )
2786
+ end
2787
+
2788
+ # Get session webhook delivery
2789
+ #
2790
+ # Retrieve one webhook delivery of a verification session: the URL it went to, the HTTP status your endpoint
2791
+ # returned, and the exact headers and JSON body Didit sent. `request_header` and `request_body` are JSON text;
2792
+ # to check your [signature verification](https://docs.didit.me/integration/webhooks#signature-verification),
2793
+ # recompute `X-Signature-V2` from the parsed body with the secret of the destination it was sent to (or the
2794
+ # application-level secret for a delivery to the legacy webhook URL). The path has no trailing slash: with one
2795
+ # it returns `404`. A scoped API key needs `sessions: read` and `decisions: read`.
2796
+ #
2797
+ # +GET /v3/session/{sessionId}/webhook/{webhook_uuid}+
2798
+ #
2799
+ # @param session_id [String] UUID of the verification session, user (KYC) or business (KYB): the `session_id`
2800
+ # returned by `POST /v3/session/`. The server resolves it against both session types. **Must be a valid
2801
+ # UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router before
2802
+ # any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}`
2803
+ # e...
2804
+ # @param webhook_uuid [String] UUID of the delivery: the `uuid` of an entry returned by `GET
2805
+ # /v3/session/{sessionId}/webhooks/`. It must belong to the session in the path.
2806
+ # @param request_options [Hash, nil] :timeout, :max_retries, :extra_headers, :extra_query, :extra_body
2807
+ # @return [Didit::Types::SessionWebhookDelivery]
2808
+ def retrieve(session_id, webhook_uuid, request_options: nil)
2809
+ @client.request(
2810
+ :get,
2811
+ "/v3/session/{sessionId}/webhook/{webhook_uuid}",
2812
+ path_params: { "sessionId" => session_id, "webhook_uuid" => webhook_uuid },
2813
+ response: Types::SessionWebhookDelivery,
2814
+ request_options: request_options
2815
+ )
2816
+ end
2817
+ end
2818
+ end
2819
+ end
2820
+ end