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
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:36:56Z"
"sha256": "c6707376c9bcdf636c1fd5452f61955c2c5ca304cce6a1ea8018d4c087fe8914",
"fetched_at": "2026-11-01T06:30:57Z"
},
"account.json": {
"url": "https://docs.didit.me/openapi-auth.json",
"sha256": "ae1b5e07df822fe93cae27a9eaa0790948069352c9d98c87eecf7efd644c92cb",
"fetched_at": "2026-10-29T06:36:56Z"
"sha256": "5b45b1896ef3107dd9a601c76d9ba35761bae5f04ac731b6c27876603903bf05",
"fetched_at": "2026-11-01T06:30:57Z"
},
"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.

31,497 changes: 24,982 additions & 6,515 deletions openapi/verification.json

Large diffs are not rendered by default.

89 changes: 87 additions & 2 deletions src/didit/resources/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
)
from didit._types import NOT_GIVEN, Body, Headers, NotGiven, Query
from didit.types.components.application_analytics_summary import ApplicationAnalyticsSummary
from didit.types.components.application_analytics_today import ApplicationAnalyticsToday
from didit.types.components.application_analytics_widget_response import (
ApplicationAnalyticsWidgetResponse,
)
Expand All @@ -35,7 +36,7 @@
class Analytics(SyncAPIResource):
"""The ``analytics`` resource of the Didit API.

Methods: ``retrieve``.
Methods: ``retrieve``, ``retrieve_today``.
"""

@cached_property
Expand Down Expand Up @@ -119,11 +120,51 @@ def retrieve(
),
)

def retrieve_today(
self,
*,
tz: str | NotGiven = NOT_GIVEN,
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ApplicationAnalyticsToday:
"""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/``

Args:
tz: IANA time zone whose midnight starts today, for example `Europe/Madrid` or `America/Mexico_City`. Omit it for UTC.
extra_headers: Headers to add to (or, with ``None``, remove from) this request.
extra_query: Query parameters to add to this request.
extra_body: Top-level JSON fields to add to this request's body.
timeout: Overrides the client's timeout for this request, in seconds.
"""
return cast(
"ApplicationAnalyticsToday",
self._client.request(
"get",
"/v3/organization/{organization_id}/application/{application_id}/analytics/today/",
cast_to=ApplicationAnalyticsToday,
scope="application",
auth="api_key",
query={"tz": tz},
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
),
)


class AsyncAnalytics(AsyncAPIResource):
"""The ``analytics`` resource of the Didit API.

Methods: ``retrieve``.
Methods: ``retrieve``, ``retrieve_today``.
"""

@cached_property
Expand Down Expand Up @@ -207,26 +248,70 @@ async def retrieve(
),
)

async def retrieve_today(
self,
*,
tz: str | NotGiven = NOT_GIVEN,
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ApplicationAnalyticsToday:
"""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/``

Args:
tz: IANA time zone whose midnight starts today, for example `Europe/Madrid` or `America/Mexico_City`. Omit it for UTC.
extra_headers: Headers to add to (or, with ``None``, remove from) this request.
extra_query: Query parameters to add to this request.
extra_body: Top-level JSON fields to add to this request's body.
timeout: Overrides the client's timeout for this request, in seconds.
"""
return cast(
"ApplicationAnalyticsToday",
await self._client.request(
"get",
"/v3/organization/{organization_id}/application/{application_id}/analytics/today/",
cast_to=ApplicationAnalyticsToday,
scope="application",
auth="api_key",
query={"tz": tz},
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
),
)


class AnalyticsWithRawResponse:
def __init__(self, resource: Analytics) -> None:
self._resource = resource
self.retrieve = to_raw_response_wrapper(resource.retrieve)
self.retrieve_today = to_raw_response_wrapper(resource.retrieve_today)


class AsyncAnalyticsWithRawResponse:
def __init__(self, resource: AsyncAnalytics) -> None:
self._resource = resource
self.retrieve = async_to_raw_response_wrapper(resource.retrieve)
self.retrieve_today = async_to_raw_response_wrapper(resource.retrieve_today)


class AnalyticsWithStreamingResponse:
def __init__(self, resource: Analytics) -> None:
self._resource = resource
self.retrieve = to_streamed_response_wrapper(resource.retrieve)
self.retrieve_today = to_streamed_response_wrapper(resource.retrieve_today)


class AsyncAnalyticsWithStreamingResponse:
def __init__(self, resource: AsyncAnalytics) -> None:
self._resource = resource
self.retrieve = async_to_streamed_response_wrapper(resource.retrieve)
self.retrieve_today = async_to_streamed_response_wrapper(resource.retrieve_today)
8 changes: 6 additions & 2 deletions src/didit/resources/bank.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ def account_check(
) -> BankAccountCheckResponse:
"""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 @@ -70,7 +72,7 @@ def account_check(

**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 Expand Up @@ -137,6 +139,8 @@ async def account_check(
) -> BankAccountCheckResponse:
"""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 @@ -147,7 +151,7 @@ async def account_check(

**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
Loading