Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 54 additions & 35 deletions api.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions openapi/SOURCE.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"verification.json": {
"url": "https://docs.didit.me/openapi-25.json",
"sha256": "12b2fdb05572755d61b93791f6964b7d883ba7b20f7ea9b31543903b6edab8a9",
"fetched_at": "2026-10-29T06:47:08Z"
"sha256": "cd35339ecaadd4fea08e8c9f68ea891b1efef6016a6d8cca68cf8ef71a9758a9",
"fetched_at": "2026-11-02T06:48:43Z"
},
"account.json": {
"url": "https://docs.didit.me/openapi-auth.json",
"sha256": "ae1b5e07df822fe93cae27a9eaa0790948069352c9d98c87eecf7efd644c92cb",
"fetched_at": "2026-10-29T06:47:08Z"
"sha256": "5b45b1896ef3107dd9a601c76d9ba35761bae5f04ac731b6c27876603903bf05",
"fetched_at": "2026-11-02T06:48:43Z"
},
"webhook-vectors.json": {
"generator": "product-automations scripts/server-sdks/make_vectors.py (seeded 2026-10-17)",
Expand Down
295 changes: 272 additions & 23 deletions openapi/account.json

Large diffs are not rendered by default.

39,326 changes: 28,904 additions & 10,422 deletions openapi/verification.json

Large diffs are not rendered by default.

25 changes: 24 additions & 1 deletion src/resources/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import type { APIPromise } from "../core/api-promise.js";
import type { OperationSpec } from "../core/operation.js";
import type { RequestOptions } from "../core/request-options.js";
import { APIResource } from "../core/resource.js";
import type { AnalyticsRetrieveParams } from "../types/analytics.js";
import type { AnalyticsRetrieveParams, AnalyticsRetrieveTodayParams } from "../types/analytics.js";
import type {
ApplicationAnalyticsSummary,
ApplicationAnalyticsToday,
ApplicationAnalyticsWidgetResponse,
} from "../types/components.js";

Expand All @@ -27,6 +28,12 @@ const ANALYTICS_RETRIEVE: OperationSpec = {
"action_type",
],
};
const ANALYTICS_RETRIEVE_TODAY: OperationSpec = {
method: "GET",
path: "/v3/organization/{organization_id}/application/{application_id}/analytics/today/",
scope: "application",
query: ["tz"],
};

/** `analytics` */
export class Analytics extends APIResource {
Expand All @@ -47,4 +54,20 @@ export class Analytics extends APIResource {
): APIPromise<ApplicationAnalyticsSummary | ApplicationAnalyticsWidgetResponse> {
return this._client.request(ANALYTICS_RETRIEVE, [], params, options);
}

/**
* Get today's verifications by hour
*
* Today's user verification (KYC) sessions, from local midnight in `tz`, counted per local hour they were created in, next to the same hours of the same weekday one week before, and split by the outcome each one holds now: approved, in review or declined. This is the volume card of the Business Console's Home.
*
* `total` is today so far. `previous_total_so_far` counts the comparison day only up to the same local time, so a change between them compares the same part of both days. The hours still to come today are `0`. A day on which the clocks change has 23 or 25 hours: the missing hour stays `0` and the repeated hour holds both.
*
* `GET /v3/organization/{organization_id}/application/{application_id}/analytics/today/`
*/
retrieveToday(
params: AnalyticsRetrieveTodayParams = {},
options?: RequestOptions,
): APIPromise<ApplicationAnalyticsToday> {
return this._client.request(ANALYTICS_RETRIEVE_TODAY, [], params, options);
}
}
4 changes: 3 additions & 1 deletion src/resources/bank.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class Bank extends APIResource {
/**
* Check a bank account
*
* **Not available in production yet.** Bank Verification is switched off in production, so until it is switched on this endpoint answers `404` with `bank_verification_not_available`. Do not build on it yet. The rest of this description is what the endpoint does once it is available.
*
* Check that a bank account belongs to the person or company you name, before you send money to it. No session and no sign-in: send the name and the account, read the result. It is the [account check](/core-technology/bank-verification/account-check) of the Bank Verification step, run from your backend.
*
* **What you send.** The account's `country` (ISO 3166-1 alpha-3), the `account` the way that country writes it, and the `holder` name: `full_name` for a person or `business_name` for a company. A business name checks a business account.
Expand All @@ -29,7 +31,7 @@ export class Bank extends APIResource {
*
* **Every request is a new check.** There is no idempotency key and no endpoint to read a check back, so a retried request runs, and is billed, again. Store the response.
*
* **Sandbox.** A sandbox key calls no bank and is charged nothing. The last 4 characters of the IBAN, else of the account number, choose the answer: `0001` a `close_match` with a `holder_name`, `0002` a `close_match` without one, `0003` and `0006` a `no_match`, `0004` `cannot_verify`, `0005` a `503` and `0009` a `400`. Any other ending is a `match`.
* **Sandbox.** Where Bank Verification is available, a sandbox key calls no bank and is charged nothing. The last 4 characters of the IBAN, else of the account number, choose the answer: `0001` a `close_match` with a `holder_name`, `0002` a `close_match` without one, `0003` and `0006` a `no_match`, `0004` `cannot_verify`, `0005` a `503` and `0009` a `400`. Any other ending is a `match`.
*
* **API keys.** A scoped API key needs write access to sessions.
*
Expand Down
97 changes: 89 additions & 8 deletions src/resources/date-plans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
updated_at: 1,
},
},
BiometricRetention: { p: { deletes_at: 1 } },
BiometricTemplatesListResponse: {
p: { results: { i: { p: { retained_at: 1, expires_at: 1, purged_at: 1 } } } },
},
Expand Down Expand Up @@ -169,6 +170,10 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
},
FeatureStatusOverride: { p: { requested_at: 1, applied_at: 1, cancelled_at: 1 } },
FraudCheckResponse: { p: { created_at: 1, completed_at: 1 } },
GeolocationAttempt: {
p: { measured_at: 1, consent: { p: { accepted_at: 1 } }, received_at: 1, created_at: 1 },
},
GeolocationCheck: { p: { measured_at: 1, consent: { p: { accepted_at: 1 } } } },
IPRiskResponse: { p: { created_at: 1 } },
IdVerificationVerifyResponse: { p: { created_at: 1 } },
ImportJobSummary: { p: { resumes_at: 1, created_at: 1, started_at: 1, completed_at: 1 } },
Expand All @@ -190,32 +195,67 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
InvestigatorSettings: { p: { stage_changed_at: 1 } },
KybListShareholdersResponse: {
p: {
kyb_registry: { p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 } },
kyb_registry: {
p: {
vat_checked_at: 1,
confirmed_by_user_at: 1,
last_console_edit_at: 1,
registry_monitoring: { p: { enrolled_at: 1, cancelled_at: 1, last_event_at: 1 } },
},
},
created_at: 1,
},
},
KybListShareholdersResponse202: {
p: {
kyb_registry: { p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 } },
kyb_registry: {
p: {
vat_checked_at: 1,
confirmed_by_user_at: 1,
last_console_edit_at: 1,
registry_monitoring: { p: { enrolled_at: 1, cancelled_at: 1, last_event_at: 1 } },
},
},
created_at: 1,
},
},
KybListUbosResponse: {
p: {
kyb_registry: { p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 } },
kyb_registry: {
p: {
vat_checked_at: 1,
confirmed_by_user_at: 1,
last_console_edit_at: 1,
registry_monitoring: { p: { enrolled_at: 1, cancelled_at: 1, last_event_at: 1 } },
},
},
created_at: 1,
},
},
KybListUbosResponse202: {
p: {
kyb_registry: { p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 } },
kyb_registry: {
p: {
vat_checked_at: 1,
confirmed_by_user_at: 1,
last_console_edit_at: 1,
registry_monitoring: { p: { enrolled_at: 1, cancelled_at: 1, last_event_at: 1 } },
},
},
created_at: 1,
},
},
KybSearchResponse: { p: { created_at: 1 } },
KybSelectResponse: {
p: {
kyb_registry: { p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 } },
kyb_registry: {
p: {
vat_checked_at: 1,
confirmed_by_user_at: 1,
last_console_edit_at: 1,
registry_monitoring: { p: { enrolled_at: 1, cancelled_at: 1, last_event_at: 1 } },
},
},
created_at: 1,
},
},
Expand Down Expand Up @@ -301,6 +341,8 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
RoutingPublicationPolicyRevision: { p: { published_at: 1 } },
SessionDecision: {
p: {
status_override: { p: { overridden_at: 1 } },
decision_trace: { p: { decided_at: 1 } },
id_verifications: {
i: {
p: {
Expand Down Expand Up @@ -349,13 +391,25 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
signatures: { i: "SignatureResult" },
aml_screenings: { i: "AMLScreening" },
ip_analyses: { i: { p: { matches: { i: { p: { verification_date: 1 } } } } } },
geolocation_checks: { i: "GeolocationCheck" },
geolocation_attempts: { i: "GeolocationAttempt" },
reviews: { i: { p: { created_at: 1 } } },
assignee: { p: { assigned_at: 1 } },
waiting_since: 1,
sla_due_at: 1,
created_at: 1,
expires_at: 1,
registry_checks: {
i: {
p: {
company: { p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 } },
company: {
p: {
vat_checked_at: 1,
confirmed_by_user_at: 1,
last_console_edit_at: 1,
registry_monitoring: { p: { enrolled_at: 1, cancelled_at: 1, last_event_at: 1 } },
},
},
},
},
},
Expand All @@ -375,10 +429,13 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
resubmissions: { i: { p: { created_at: 1 } } },
biometric_consent: { p: { given_at: 1, declined_at: 1, face_data_deleted_at: 1 } },
investigator: "InvestigatorBlock",
biometric_retention: "BiometricRetention",
full_session_video_recorded_at: 1,
},
},
SessionDeletionJob: { p: { created_at: 1, completed_at: 1 } },
SessionEvent: { p: { created_at: 1 } },
SessionFilesExport: { p: { expires_at: 1, created_at: 1, completed_at: 1 } },
SessionImportError: { p: { created_at: 1 } },
SessionImportJob: {
p: {
Expand All @@ -395,6 +452,7 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
SessionsBatchDeleteResponse: {
p: { results: { i: { p: { biometric_template_expires_at: 1 } } } },
},
SessionsCreateKybPartyDraftResponse: { p: { created_at: 1, updated_at: 1 } },
SessionsDeleteResponse: { p: { biometric_template_expires_at: 1 } },
SessionsImportsListActiveJobsResponse: { p: { results: { i: "ImportJobSummary" } } },
SessionsImportsListErrorsResponse: { p: { results: { i: "SessionImportError" } } },
Expand All @@ -404,14 +462,31 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
SessionsListFeatureOverridesResponse: {
p: { flow_finished_at: 1, overrides: { i: "FeatureStatusOverride" } },
},
SessionsListResponse: { p: { results: { i: { p: { created_at: 1 } } } } },
SessionsListKybPartyDraftsResponse: {
p: { parties: { i: { p: { created_at: 1, updated_at: 1 } } } },
},
SessionsListResponse: {
p: {
results: {
i: {
p: {
created_at: 1,
assignee: { p: { assigned_at: 1 } },
waiting_since: 1,
sla_due_at: 1,
},
},
},
},
},
SessionsReviewsCreateResponse: { p: { created_at: 1 } },
SessionsReviewsListResponse: { p: { results: { i: "ReviewItem" } } },
SessionsSignaturesValidateResponse: { p: { signatures: { i: "SignatureResult" } } },
SessionsUpdateFeatureStatusResponse: { p: { override: "FeatureStatusOverride" } },
SessionsUpdateKybCompanyDataResponse: {
p: { vat_checked_at: 1, confirmed_by_user_at: 1, last_console_edit_at: 1 },
},
SessionsUpdateKybPartyDraftResponse: { p: { created_at: 1, updated_at: 1 } },
SignatureFieldResult: { p: { filled_at: 1 } },
SignatureResult: {
p: {
Expand Down Expand Up @@ -498,6 +573,9 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
TravelRuleDiscoveryStep: { p: { at: 1 } },
TravelRuleInboundResponse: { p: { travel_rule: "TravelRuleTransferDetail" } },
TravelRuleListVaspsResponse: { p: { results: { i: "VaspDirectoryEntry" } } },
TravelRuleManualMatchResponse: {
p: { deposit: "TravelRuleTransferRow", message: "TravelRuleTransferRow" },
},
TravelRuleMessage: {
p: { fulfilled_at: 1, attachment: "TravelRuleMessageAttachment", created_at: 1 },
},
Expand Down Expand Up @@ -556,6 +634,7 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
},
TravelRuleTransferRow: { p: { txn_date: 1, deadline_at: 1, created_at: 1 } },
TravelRuleTransfersListResponse: { p: { results: { i: "TravelRuleTransferRow" } } },
TravelRuleUnmatchedDepositsListResponse: { p: { results: { i: "TravelRuleTransferRow" } } },
TravelRuleWalletAddressesListResponse: { p: { results: { i: "WalletAddressEntry" } } },
TravelRuleWalletProofReview: { p: { method_chosen_at: 1, decided_at: 1, created_at: 1 } },
TravelRuleWalletProofsListResponse: { p: { results: { i: "TravelRuleWalletProofReview" } } },
Expand Down Expand Up @@ -583,7 +662,9 @@ export const DATE_PLANS: Readonly<Record<string, DatePlan>> = {
UserListItem: {
p: { last_session_at: 1, first_session_at: 1, last_activity_at: 1, created_at: 1 },
},
UserSessionListItem: { p: { created_at: 1 } },
UserSessionListItem: {
p: { created_at: 1, assignee: { p: { assigned_at: 1 } }, waiting_since: 1, sla_due_at: 1 },
},
UsersCreateResponse: {
p: {
last_session_at: 1,
Expand Down
2 changes: 1 addition & 1 deletion src/resources/id-verification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class IdVerification extends APIResource {
*
* **How it works.** Send the document's `front_image` (required) and, for two-sided documents, the `back_image`. Upload uncropped photos with all four corners of the document visible - the service detects, aligns, and crops the document itself, so do not pre-crop. The document is classified automatically (you never declare the country or document type), the visual zone is read with OCR, and the MRZ and any barcodes are decoded. Cross-checks then validate dates, number formats, and MRZ check digits, and compare the visual zone against the MRZ. With `perform_document_liveness=true`, the images are additionally screened for screen replays, printed copies, and portrait manipulation.
*
* **Decision logic.** `status` is `Approved` unless at least one warning resolves to a decline. Fraud and hard-failure risks always decline: `DOCUMENT_EXPIRED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, plus extraction failures (`NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`, `DOCUMENT_NUMBER_NOT_DETECTED`). (`PORTRAIT_IMAGE_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `INVALID_DATE`, and `MRZ_NOT_DETECTED` exist in workflow sessions but are never produced by this standalone endpoint.) Three risk groups are configurable per request via `invalid_mrz_action`, `inconsistent_data_action`, and `expiration_date_not_detected_action` (`DECLINE` or `NO_ACTION`). All other warnings (e.g. `POSSIBLE_DUPLICATED_USER`) are informational and never decline on their own. When `perform_document_liveness=true` (the default) and the forgery check returns no usable score - the provider failed, answered non-200, or answered HTTP 200 with `status="ERR"` - the call returns `200` with `status: "In Review"` and a `DOCUMENT_LIVENESS_NOT_COMPUTED` warning (`log_type: "warning"`) instead of `Approved`: a check that did not run is not evidence that the document is genuine. This escalation is not configurable and never overrides a `Declined`; with `perform_document_liveness=false` the check is skipped and the status follows the remaining warnings as before. A document that cannot be processed at all returns `400` with `{"error": "COULD_NOT_RECOGNIZE_DOCUMENT"}`; a readable but problematic document returns `200` with `status: "Declined"` - always inspect `id_verification.status` and `id_verification.warnings`, not just the HTTP code.
* **Decision logic.** `status` is `Approved` unless at least one warning resolves to a decline. Fraud and hard-failure risks always decline: `DOCUMENT_EXPIRED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, plus extraction failures (`NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`, `DOCUMENT_NUMBER_NOT_DETECTED`). (`PORTRAIT_IMAGE_NOT_DETECTED`, `INVALID_DATE`, and `MRZ_NOT_DETECTED` exist in workflow sessions but are never produced by this standalone endpoint. `COULD_NOT_DETECT_DOCUMENT_TYPE` is returned here when the front image does not match a known official document design with high confidence, and declines the request.) Three risk groups are configurable per request via `invalid_mrz_action`, `inconsistent_data_action`, and `expiration_date_not_detected_action` (`DECLINE` or `NO_ACTION`). All other warnings (e.g. `POSSIBLE_DUPLICATED_USER`) are informational and never decline on their own. When `perform_document_liveness=true` (the default) and the forgery check returns no usable score - the provider failed, answered non-200, or answered HTTP 200 with `status="ERR"` - the call returns `200` with `status: "In Review"` and a `DOCUMENT_LIVENESS_NOT_COMPUTED` warning (`log_type: "warning"`) instead of `Approved`: a check that did not run is not evidence that the document is genuine. This escalation is not configurable and never overrides a `Declined`; with `perform_document_liveness=false` the check is skipped and the status follows the remaining warnings as before. A document that cannot be processed at all returns `400` with `{"error": "COULD_NOT_RECOGNIZE_DOCUMENT"}`; a readable but problematic document returns `200` with `status: "Declined"` - always inspect `id_verification.status` and `id_verification.warnings`, not just the HTTP code.
*
* **Billing.** Each `200` response consumes one ID Verification API credit (paid from your plan credit or top-up balance). When the organization's balance cannot cover the call, the endpoint returns `403` with the not-enough-credits error before any image processing.
*
Expand Down
Loading