diff --git a/openapi/SOURCE.json b/openapi/SOURCE.json index 802d23f..6ac0193 100644 --- a/openapi/SOURCE.json +++ b/openapi/SOURCE.json @@ -1,13 +1,13 @@ { "verification.json": { "url": "https://docs.didit.me/openapi-25.json", - "sha256": "12b2fdb05572755d61b93791f6964b7d883ba7b20f7ea9b31543903b6edab8a9", - "fetched_at": "2026-10-29T06:36:56Z" + "sha256": "cd35339ecaadd4fea08e8c9f68ea891b1efef6016a6d8cca68cf8ef71a9758a9", + "fetched_at": "2026-11-02T06:40:50Z" }, "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-02T06:40:50Z" }, "webhook-vectors.json": { "generator": "product-automations scripts/server-sdks/make_vectors.py (seeded 2026-10-17)", diff --git a/openapi/account.json b/openapi/account.json index b832f39..22b6117 100644 --- a/openapi/account.json +++ b/openapi/account.json @@ -207,12 +207,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n \"https://apx.didit.me/auth/v2/programmatic/register/\",\n json={\n \"email\": \"you@yourdomain.com\",\n \"password\": \"MyStr0ng!Pass\",\n },\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json())\n# {'message': 'Registration successful...', 'email': 'you@yourdomain.com'}" + "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.account.register(\n email=\"you@yourdomain.com\",\n password=\"MyStr0ng!Pass\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n \"https://apx.didit.me/auth/v2/programmatic/register/\",\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n email: \"you@yourdomain.com\",\n password: \"MyStr0ng!Pass\",\n }),\n },\n);\nif (!resp.ok) throw new Error(`Register failed: ${resp.status}`);\nconst data = await resp.json();\nconsole.log(data);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.account.register({\n email: \"you@yourdomain.com\",\n password: \"MyStr0ng!Pass\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.Register(ctx, didit.RegisterRequest{\n\tEmail: \"you@yourdomain.com\",\n\tPassword: \"MyStr0ng!Pass\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.RegisterRequest;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.account().register(RegisterRequest.builder()\n .email(\"you@yourdomain.com\")\n .password(\"MyStr0ng!Pass\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->register([\n 'email' => 'you@yourdomain.com',\n 'password' => 'MyStr0ng!Pass',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.account.register(\n email: \"you@yourdomain.com\",\n password: \"MyStr0ng!Pass\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Account.RegisterAsync(new RegisterRequest\n{\n Email = \"you@yourdomain.com\",\n Password = \"MyStr0ng!Pass\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "security": [ @@ -362,12 +387,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n \"https://apx.didit.me/auth/v2/programmatic/verify-email/\",\n json={\n \"email\": \"you@yourdomain.com\",\n \"code\": \"A3K9F2\",\n },\n timeout=10,\n)\nresp.raise_for_status()\ndata = resp.json()\n\napi_key = data[\"application\"][\"api_key\"]\nprint(f\"Save this for x-api-key: {api_key}\")" + "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.account.verify_email(\n email=\"you@yourdomain.com\",\n code=\"A3K9F2\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n \"https://apx.didit.me/auth/v2/programmatic/verify-email/\",\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n email: \"you@yourdomain.com\",\n code: \"A3K9F2\",\n }),\n },\n);\nif (!resp.ok) throw new Error(`Verify failed: ${resp.status}`);\nconst { application, access_token } = await resp.json();\n// application.api_key -> x-api-key for verification.didit.me/v3\n// access_token -> Authorization: Bearer ... for this auth API" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.account.verifyEmail({\n email: \"you@yourdomain.com\",\n code: \"A3K9F2\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.VerifyEmail(ctx, didit.VerifyEmailRequest{\n\tEmail: \"you@yourdomain.com\",\n\tCode: \"A3K9F2\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.VerifyEmailRequest;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.account().verifyEmail(VerifyEmailRequest.builder()\n .email(\"you@yourdomain.com\")\n .code(\"A3K9F2\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->verifyEmail([\n 'email' => 'you@yourdomain.com',\n 'code' => 'A3K9F2',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.account.verify_email(\n email: \"you@yourdomain.com\",\n code: \"A3K9F2\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Account.VerifyEmailAsync(new VerifyEmailRequest\n{\n Email = \"you@yourdomain.com\",\n Code = \"A3K9F2\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "security": [ @@ -410,7 +460,7 @@ }, "responses": { "200": { - "description": "Login successful. Returns a fresh JWT pair. Use the `access_token` as `Authorization: Bearer ` against `/organizations/me/...` to look up the `org_id`, `app_id`, and `api_key`.", + "description": "Login successful. Returns a fresh JWT pair. Use the `access_token` as `Authorization: Bearer ` against `/organizations/me/...` to look up the `org_id`, `app_id`, and `api_key`. When the account has an authenticator app or a passkey, the response carries `2fa_required: true` and a `temp_token` instead of tokens.", "content": { "application/json": { "schema": { @@ -497,7 +547,7 @@ } }, "403": { - "description": "The account was recovered and must set up a new sign-in method before it can log in. A link to do that was emailed to the account's address.", + "description": "The account was recovered and must set up a new sign-in method before it can log in. A link to do that was emailed to the account's address. An account whose organization enforces SSO gets `403` with `error: sso_required`, `organization_name`, `organization_slug` and `sso_url`.", "content": { "application/json": { "schema": { @@ -557,12 +607,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n \"https://apx.didit.me/auth/v2/programmatic/login/\",\n json={\n \"email\": \"you@yourdomain.com\",\n \"password\": \"MyStr0ng!Pass\",\n },\n timeout=10,\n)\nresp.raise_for_status()\ntokens = resp.json()\naccess_token = tokens[\"access_token\"]\n\n# Use against the Account Management endpoints on this host\norgs = requests.get(\n \"https://apx.didit.me/auth/v2/organizations/me/\",\n headers={\"Authorization\": f\"Bearer {access_token}\"},\n timeout=10,\n).json()" + "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.account.login(\n email=\"you@yourdomain.com\",\n password=\"MyStr0ng!Pass\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n \"https://apx.didit.me/auth/v2/programmatic/login/\",\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n email: \"you@yourdomain.com\",\n password: \"MyStr0ng!Pass\",\n }),\n },\n);\nif (!resp.ok) throw new Error(`Login failed: ${resp.status}`);\nconst { access_token } = await resp.json();\n\n// Use against the Account Management endpoints on this host\nconst orgs = await fetch(\n \"https://apx.didit.me/auth/v2/organizations/me/\",\n { headers: { Authorization: `Bearer ${access_token}` } },\n).then((r) => r.json());" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.account.login({\n email: \"you@yourdomain.com\",\n password: \"MyStr0ng!Pass\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.Login(ctx, didit.LoginRequest{\n\tEmail: \"you@yourdomain.com\",\n\tPassword: \"MyStr0ng!Pass\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.LoginRequest;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.account().login(LoginRequest.builder()\n .email(\"you@yourdomain.com\")\n .password(\"MyStr0ng!Pass\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->login([\n 'email' => 'you@yourdomain.com',\n 'password' => 'MyStr0ng!Pass',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.account.login(\n email: \"you@yourdomain.com\",\n password: \"MyStr0ng!Pass\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Account.LoginAsync(new LoginRequest\n{\n Email = \"you@yourdomain.com\",\n Password = \"MyStr0ng!Pass\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "security": [ @@ -684,12 +759,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n \"https://apx.didit.me/auth/v2/organizations/me/\",\n headers={\"Authorization\": f\"Bearer {access_token}\"},\n timeout=10,\n)\nresp.raise_for_status()\norgs = resp.json()[\"results\"] # paginated: count, next, previous, results\nfirst_org_id = orgs[0][\"uuid\"]" + "source": "from didit import Didit\n\n# Use the access token that account.login returns.\nclient = Didit(account_token=\"YOUR_ACCESS_TOKEN\")\n\nfor item in client.account.organizations.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n \"https://apx.didit.me/auth/v2/organizations/me/\",\n { headers: { Authorization: `Bearer ${accessToken}` } },\n);\nif (!resp.ok) throw new Error(`List orgs failed: ${resp.status}`);\nconst { results: orgs } = await resp.json(); // paginated: count, next, previous, results\nconst firstOrgId = orgs[0].uuid;" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Use the access token that account.login returns.\nconst didit = new Didit({ accountToken: \"YOUR_ACCESS_TOKEN\" });\n\nfor await (const item of didit.account.organizations.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Use the access token that account.login returns.\nclient := didit.NewClient(option.WithAccountToken(\"YOUR_ACCESS_TOKEN\"))\n\niter := client.Account.Organizations.ListAutoPaging(ctx, didit.AccountOrganizationsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Use the access token that account.login returns.\nDidit client = Didit.builder().accountToken(\"YOUR_ACCESS_TOKEN\").build();\n\nfor (var item : client.account().organizations().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->organizations->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Use the access token that account.login returns.\ndidit = Didit::Client.new(account_token: \"YOUR_ACCESS_TOKEN\")\n\ndidit.account.organizations.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Use the access token that account.login returns.\nusing var client = new DiditClient(new DiditClientOptions { AccountToken = \"YOUR_ACCESS_TOKEN\" });\n\nawait foreach (var item in await client.Account.Organizations.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "parameters": [ @@ -952,12 +1052,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n f\"https://apx.didit.me/auth/v2/organizations/me/{org_id}/applications/\",\n headers={\"Authorization\": f\"Bearer {access_token}\"},\n json={\n \"name\": \"Acme Customer App\",\n \"website_url\": \"https://acme.example\",\n \"redirect_uris\": [\"https://acme.example/callback\"],\n },\n timeout=10,\n)\nresp.raise_for_status()\napp = resp.json()\nprint(\"Save this:\", app[\"api_key\"])" + "source": "from didit import Didit\n\n# Use the access token that account.login returns.\nclient = Didit(account_token=\"YOUR_ACCESS_TOKEN\")\n\nresult = client.account.applications.create(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n name=\"Acme Customer App\",\n website_url=\"https://acme.example\",\n redirect_uris=[\"https://acme.example/callback\"],\n terms_url=\"https://acme.example/terms\",\n privacy_url=\"https://acme.example/privacy\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n `https://apx.didit.me/auth/v2/organizations/me/${orgId}/applications/`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n name: \"Acme Customer App\",\n website_url: \"https://acme.example\",\n redirect_uris: [\"https://acme.example/callback\"],\n }),\n },\n);\nif (!resp.ok) throw new Error(`Create app failed: ${resp.status}`);\nconst app = await resp.json();\nconsole.log(\"Save this:\", app.api_key);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Use the access token that account.login returns.\nconst didit = new Didit({ accountToken: \"YOUR_ACCESS_TOKEN\" });\n\nconst result = await didit.account.applications.create(\"a1b2c3d4-5678-90ab-cdef-111111111111\", {\n name: \"Acme Customer App\",\n website_url: \"https://acme.example\",\n redirect_uris: [\"https://acme.example/callback\"],\n terms_url: \"https://acme.example/terms\",\n privacy_url: \"https://acme.example/privacy\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Use the access token that account.login returns.\nclient := didit.NewClient(option.WithAccountToken(\"YOUR_ACCESS_TOKEN\"))\n\nresult, err := client.Account.Applications.Create(ctx, \"a1b2c3d4-5678-90ab-cdef-111111111111\", didit.ApplicationCreateRequest{\n\tName: didit.String(\"Acme Customer App\"),\n\tWebsiteURL: didit.String(\"https://acme.example\"),\n\tRedirectURIs: didit.Some([]string{\"https://acme.example/callback\"}),\n\tTermsURL: didit.String(\"https://acme.example/terms\"),\n\tPrivacyURL: didit.String(\"https://acme.example/privacy\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.ApplicationCreateRequest;\n\n// Use the access token that account.login returns.\nDidit client = Didit.builder().accountToken(\"YOUR_ACCESS_TOKEN\").build();\n\nvar result = client.account().applications().create(\"a1b2c3d4-5678-90ab-cdef-111111111111\", ApplicationCreateRequest.builder()\n .name(\"Acme Customer App\")\n .websiteUrl(\"https://acme.example\")\n .redirectUris(List.of(\"https://acme.example/callback\"))\n .termsUrl(\"https://acme.example/terms\")\n .privacyUrl(\"https://acme.example/privacy\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->applications->create('a1b2c3d4-5678-90ab-cdef-111111111111', [\n 'name' => 'Acme Customer App',\n 'website_url' => 'https://acme.example',\n 'redirect_uris' => ['https://acme.example/callback'],\n 'terms_url' => 'https://acme.example/terms',\n 'privacy_url' => 'https://acme.example/privacy',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Use the access token that account.login returns.\ndidit = Didit::Client.new(account_token: \"YOUR_ACCESS_TOKEN\")\n\nresult = didit.account.applications.create(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n name: \"Acme Customer App\",\n website_url: \"https://acme.example\",\n redirect_uris: [\"https://acme.example/callback\"],\n terms_url: \"https://acme.example/terms\",\n privacy_url: \"https://acme.example/privacy\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Use the access token that account.login returns.\nusing var client = new DiditClient(new DiditClientOptions { AccountToken = \"YOUR_ACCESS_TOKEN\" });\n\nvar result = await client.Account.Applications.CreateAsync(\"a1b2c3d4-5678-90ab-cdef-111111111111\", new ApplicationCreateRequest\n{\n Name = \"Acme Customer App\",\n WebsiteUrl = \"https://acme.example\",\n RedirectUris = new string[] { \"https://acme.example/callback\" },\n TermsUrl = \"https://acme.example/terms\",\n PrivacyUrl = \"https://acme.example/privacy\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -1203,6 +1328,43 @@ { "BearerAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Use the access token that account.login returns.\nclient = Didit(account_token=\"YOUR_ACCESS_TOKEN\")\n\nfor item in client.account.applications.list(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Use the access token that account.login returns.\nconst didit = new Didit({ accountToken: \"YOUR_ACCESS_TOKEN\" });\n\nfor await (const item of didit.account.applications.list(\"a1b2c3d4-5678-90ab-cdef-111111111111\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Use the access token that account.login returns.\nclient := didit.NewClient(option.WithAccountToken(\"YOUR_ACCESS_TOKEN\"))\n\niter := client.Account.Applications.ListAutoPaging(ctx, \"a1b2c3d4-5678-90ab-cdef-111111111111\", didit.AccountApplicationsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Use the access token that account.login returns.\nDidit client = Didit.builder().accountToken(\"YOUR_ACCESS_TOKEN\").build();\n\nfor (var item : client.account().applications().list(\"a1b2c3d4-5678-90ab-cdef-111111111111\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->applications->list('a1b2c3d4-5678-90ab-cdef-111111111111') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Use the access token that account.login returns.\ndidit = Didit::Client.new(account_token: \"YOUR_ACCESS_TOKEN\")\n\ndidit.account.applications.list(\"a1b2c3d4-5678-90ab-cdef-111111111111\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Use the access token that account.login returns.\nusing var client = new DiditClient(new DiditClientOptions { AccountToken = \"YOUR_ACCESS_TOKEN\" });\n\nawait foreach (var item in await client.Account.Applications.ListAsync(\"a1b2c3d4-5678-90ab-cdef-111111111111\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] } }, @@ -1388,12 +1550,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n f\"https://apx.didit.me/auth/v2/organizations/me/{org_id}/applications/{app_id}/\",\n headers={\"Authorization\": f\"Bearer {access_token}\"},\n timeout=10,\n)\nresp.raise_for_status()\napp = resp.json()\napi_key = app[\"api_key\"] # use as x-api-key on verification.didit.me" + "source": "from didit import Didit\n\n# Use the access token that account.login returns.\nclient = Didit(account_token=\"YOUR_ACCESS_TOKEN\")\n\nresult = client.account.applications.retrieve(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n \"b2c3d4e5-6789-01bc-defg-222222222222\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n `https://apx.didit.me/auth/v2/organizations/me/${orgId}/applications/${appId}/`,\n { headers: { Authorization: `Bearer ${accessToken}` } },\n);\nif (!resp.ok) throw new Error(`Get app failed: ${resp.status}`);\nconst app = await resp.json();\nconst apiKey = app.api_key; // use as x-api-key on verification.didit.me" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Use the access token that account.login returns.\nconst didit = new Didit({ accountToken: \"YOUR_ACCESS_TOKEN\" });\n\nconst result = await didit.account.applications.retrieve(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n \"b2c3d4e5-6789-01bc-defg-222222222222\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Use the access token that account.login returns.\nclient := didit.NewClient(option.WithAccountToken(\"YOUR_ACCESS_TOKEN\"))\n\nresult, err := client.Account.Applications.Retrieve(ctx, \"a1b2c3d4-5678-90ab-cdef-111111111111\", \"b2c3d4e5-6789-01bc-defg-222222222222\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Use the access token that account.login returns.\nDidit client = Didit.builder().accountToken(\"YOUR_ACCESS_TOKEN\").build();\n\nvar result = client.account().applications().retrieve(\"a1b2c3d4-5678-90ab-cdef-111111111111\", \"b2c3d4e5-6789-01bc-defg-222222222222\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->applications->retrieve('a1b2c3d4-5678-90ab-cdef-111111111111', 'b2c3d4e5-6789-01bc-defg-222222222222');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Use the access token that account.login returns.\ndidit = Didit::Client.new(account_token: \"YOUR_ACCESS_TOKEN\")\n\nresult = didit.account.applications.retrieve(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n \"b2c3d4e5-6789-01bc-defg-222222222222\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Use the access token that account.login returns.\nusing var client = new DiditClient(new DiditClientOptions { AccountToken = \"YOUR_ACCESS_TOKEN\" });\n\nvar result = await client.Account.Applications.RetrieveAsync(\"a1b2c3d4-5678-90ab-cdef-111111111111\", \"b2c3d4e5-6789-01bc-defg-222222222222\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -1633,12 +1820,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.patch(\n f\"https://apx.didit.me/auth/v2/organizations/me/{org_id}/applications/{app_id}/\",\n headers={\"Authorization\": f\"Bearer {access_token}\"},\n json={\n \"name\": \"Acme Production App\",\n \"website_url\": \"https://app.acme.example\",\n },\n timeout=10,\n)\nresp.raise_for_status()\nupdated = resp.json()" + "source": "from didit import Didit\n\n# Use the access token that account.login returns.\nclient = Didit(account_token=\"YOUR_ACCESS_TOKEN\")\n\nresult = client.account.applications.update(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n \"b2c3d4e5-6789-01bc-defg-222222222222\",\n name=\"Acme Production App\",\n website_url=\"https://app.acme.example\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n `https://apx.didit.me/auth/v2/organizations/me/${orgId}/applications/${appId}/`,\n {\n method: \"PATCH\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n name: \"Acme Production App\",\n website_url: \"https://app.acme.example\",\n }),\n },\n);\nif (!resp.ok) throw new Error(`Update app failed: ${resp.status}`);\nconst updated = await resp.json();" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Use the access token that account.login returns.\nconst didit = new Didit({ accountToken: \"YOUR_ACCESS_TOKEN\" });\n\nconst result = await didit.account.applications.update(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n \"b2c3d4e5-6789-01bc-defg-222222222222\",\n {\n name: \"Acme Production App\",\n website_url: \"https://app.acme.example\",\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Use the access token that account.login returns.\nclient := didit.NewClient(option.WithAccountToken(\"YOUR_ACCESS_TOKEN\"))\n\nresult, err := client.Account.Applications.Update(ctx, \"a1b2c3d4-5678-90ab-cdef-111111111111\", \"b2c3d4e5-6789-01bc-defg-222222222222\", didit.ApplicationUpdateRequest{\n\tName: didit.String(\"Acme Production App\"),\n\tWebsiteURL: didit.String(\"https://app.acme.example\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.ApplicationUpdateRequest;\n\n// Use the access token that account.login returns.\nDidit client = Didit.builder().accountToken(\"YOUR_ACCESS_TOKEN\").build();\n\nvar result = client.account().applications().update(\"a1b2c3d4-5678-90ab-cdef-111111111111\", \"b2c3d4e5-6789-01bc-defg-222222222222\", ApplicationUpdateRequest.builder()\n .name(\"Acme Production App\")\n .websiteUrl(\"https://app.acme.example\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->applications->update('a1b2c3d4-5678-90ab-cdef-111111111111', 'b2c3d4e5-6789-01bc-defg-222222222222', [\n 'name' => 'Acme Production App',\n 'website_url' => 'https://app.acme.example',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Use the access token that account.login returns.\ndidit = Didit::Client.new(account_token: \"YOUR_ACCESS_TOKEN\")\n\nresult = didit.account.applications.update(\n \"a1b2c3d4-5678-90ab-cdef-111111111111\",\n \"b2c3d4e5-6789-01bc-defg-222222222222\",\n name: \"Acme Production App\",\n website_url: \"https://app.acme.example\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Use the access token that account.login returns.\nusing var client = new DiditClient(new DiditClientOptions { AccountToken = \"YOUR_ACCESS_TOKEN\" });\n\nvar result = await client.Account.Applications.UpdateAsync(\"a1b2c3d4-5678-90ab-cdef-111111111111\", \"b2c3d4e5-6789-01bc-defg-222222222222\", new ApplicationUpdateRequest\n{\n Name = \"Acme Production App\",\n WebsiteUrl = \"https://app.acme.example\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -1761,6 +1973,43 @@ }, "security": [ {} + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.account.resend_otp(\n email=\"dev@example.com\",\n password=\"S3cure-Passw0rd!\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.account.resendOtp({\n email: \"dev@example.com\",\n password: \"S3cure-Passw0rd!\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.ResendOTP(ctx, didit.AccountResendOTPParams{\n\tEmail: \"dev@example.com\",\n\tPassword: \"S3cure-Passw0rd!\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.AccountResendOtpParams;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.account().resendOtp(AccountResendOtpParams.builder()\n .email(\"dev@example.com\")\n .password(\"S3cure-Passw0rd!\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "account->resendOtp([\n 'email' => 'dev@example.com',\n 'password' => 'S3cure-Passw0rd!',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.account.resend_otp(\n email: \"dev@example.com\",\n password: \"S3cure-Passw0rd!\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Account.ResendOtpAsync(new AccountResendOtpParams\n{\n Email = \"dev@example.com\",\n Password = \"S3cure-Passw0rd!\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } } diff --git a/openapi/verification.json b/openapi/verification.json index 7736883..2c77fb3 100644 --- a/openapi/verification.json +++ b/openapi/verification.json @@ -119,12 +119,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/email/risk/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"], \"Content-Type\": \"application/json\"},\n json={\n \"email\": \"alice@example.com\",\n \"country_code\": \"US\",\n \"vendor_data\": \"lead-123\",\n \"metadata\": {\"source\": \"signup_prescreen\"},\n },\n timeout=15,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result[\"status\"]) # Approved / In Review / Declined\nprint(result[\"email\"][\"is_breached\"], result[\"email\"][\"is_disposable\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.assess_risk(\n email=\"alice@example.com\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/email/risk/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n email: 'alice@example.com',\n country_code: 'US',\n vendor_data: 'lead-123',\n metadata: { source: 'signup_prescreen' },\n }),\n});\nconst data = await res.json();\nconsole.log(data.status, data.email.is_breached, data.email.is_disposable);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.assessRisk({\n email: \"alice@example.com\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.AssessRisk(ctx, didit.EmailRiskRequest{\n\tEmail: \"alice@example.com\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.EmailRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().assessRisk(EmailRiskRequest.builder()\n .email(\"alice@example.com\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "email->assessRisk([\n 'email' => 'alice@example.com',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.assess_risk(email: \"alice@example.com\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.AssessRiskAsync(new EmailRiskRequest\n{\n Email = \"alice@example.com\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -267,8 +292,12 @@ "is_breached": true, "no_of_breaches": 4, "reason_codes": [ - "BREACH_EXPOSURE", - "FREQUENT_BREACH" + { + "code": "IR-F784B630", + "direction": "risk", + "message": "Email's digital footprint diversity is Very Low", + "impact_level": "low" + } ] }, "enrichment": { @@ -283,8 +312,12 @@ "is_breached": true, "no_of_breaches": 4, "reason_codes": [ - "BREACH_EXPOSURE", - "FREQUENT_BREACH" + { + "code": "IR-F784B630", + "direction": "risk", + "message": "Email's digital footprint diversity is Very Low", + "impact_level": "low" + } ] } }, @@ -337,12 +370,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/ip/risk/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"], \"Content-Type\": \"application/json\"},\n json={\n \"ip_address\": \"8.8.8.8\",\n \"claimed_country\": \"ESP\",\n \"user_agent\": \"Mozilla/5.0\",\n \"vendor_data\": \"lead-123\",\n },\n timeout=15,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result[\"status\"]) # Approved / In Review\nprint(result[\"ip\"][\"ip_country_code\"], result[\"ip\"][\"country_mismatch\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.ip.assess_risk(\n ip_address=\"8.8.8.8\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/ip/risk/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n ip_address: '8.8.8.8',\n claimed_country: 'ESP',\n user_agent: 'Mozilla/5.0',\n vendor_data: 'lead-123',\n }),\n});\nconst data = await res.json();\nconsole.log(data.status, data.ip.country_mismatch);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.ip.assessRisk({\n ip_address: \"8.8.8.8\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IP.AssessRisk(ctx, didit.IPRiskRequest{\n\tIPAddress: \"8.8.8.8\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.IPRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.ip().assessRisk(IPRiskRequest.builder()\n .ipAddress(\"8.8.8.8\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "ip->assessRisk([\n 'ip_address' => '8.8.8.8',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.ip.assess_risk(ip_address: \"8.8.8.8\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Ip.AssessRiskAsync(new IPRiskRequest\n{\n IpAddress = \"8.8.8.8\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -497,12 +555,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/phone/risk/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"], \"Content-Type\": \"application/json\"},\n json={\n \"phone_number\": \"+14155552671\",\n \"country_code\": \"US\",\n \"vendor_data\": \"lead-123\",\n \"metadata\": {\"source\": \"signup_prescreen\"},\n },\n timeout=15,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result[\"status\"]) # Approved / In Review / Declined\nprint(result[\"phone\"][\"phone_intelligence\"][\"score\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.assess_risk(\n phone_number=\"+14155552671\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/phone/risk/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n phone_number: '+14155552671',\n country_code: 'US',\n vendor_data: 'lead-123',\n metadata: { source: 'signup_prescreen' },\n }),\n});\nconst data = await res.json();\nconsole.log(data.status, data.phone.phone_intelligence?.score);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.assessRisk({\n phone_number: \"+14155552671\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.AssessRisk(ctx, didit.PhoneRiskRequest{\n\tPhoneNumber: \"+14155552671\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.PhoneRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().assessRisk(PhoneRiskRequest.builder()\n .phoneNumber(\"+14155552671\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "phone->assessRisk([\n 'phone_number' => '+14155552671',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.assess_risk(phone_number: \"+14155552671\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.AssessRiskAsync(new PhoneRiskRequest\n{\n PhoneNumber = \"+14155552671\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -640,8 +723,12 @@ "is_recently_ported": true, "carrier_type": "voip", "reason_codes": [ - "DISPOSABLE_NUMBER", - "RECENT_PORT" + { + "code": "IR-5AC67A32", + "direction": "risk", + "message": "Phone type identified as non-mobile", + "impact_level": "medium" + } ] }, "enrichment": { @@ -654,8 +741,12 @@ "is_recently_ported": true, "carrier_type": "voip", "reason_codes": [ - "DISPOSABLE_NUMBER", - "RECENT_PORT" + { + "code": "IR-5AC67A32", + "direction": "risk", + "message": "Phone type identified as non-mobile", + "impact_level": "medium" + } ] } }, @@ -843,7 +934,7 @@ } }, "400": { - "description": "Bad request — the payload failed validation (missing or unknown `workflow_id`, invalid `language`, blocklisted `vendor_data`, malformed `portrait_image`, `address` without `country`/`poa_country`, invalid `sandbox_scenario`, `sign` documents, fields or values the workflow's Electronic Signature step refuses, such as `signature_document_not_supported`, `signature_document_conversion_failed`, `field_anchor_not_found` or `field_value_missing`, etc.) or your organization does not have enough credits to start the session.\n\nThe body is an object keyed by the offending field name (or `detail` for non-field errors). Values are an **array of strings** for input-validation failures (e.g. missing required field, invalid language, oversized portrait image) and a **plain string** for failures detected while creating the session (unknown `workflow_id`, blocklisted `vendor_data`, no reference face available for a Face Match workflow). Handle both shapes.", + "description": "Bad request — the payload failed validation (missing or unknown `workflow_id`, invalid `language`, blocklisted `vendor_data`, malformed `portrait_image`, `address` without `country`/`poa_country`, invalid `sandbox_scenario`, `sign` documents, fields or values the workflow's E-signature step refuses, such as `signature_document_not_supported`, `signature_document_conversion_failed`, `field_anchor_not_found` or `field_value_missing`, etc.) or your organization does not have enough credits to start the session.\n\nThe body is an object keyed by the offending field name (or `detail` for non-field errors). Values are an **array of strings** for input-validation failures (e.g. missing required field, invalid language, oversized portrait image) and a **plain string** for failures detected while creating the session (unknown `workflow_id`, blocklisted `vendor_data`, no reference face available for a Face Match workflow). Handle both shapes.", "content": { "application/json": { "schema": { @@ -909,7 +1000,7 @@ } }, "403": { - "description": "Authentication or authorization failed. The endpoint returns `403` whenever the `x-api-key` header is missing, malformed, the API key has expired, or the API key is valid but the client does not have permission to create sessions in this application (for example the API key belongs to a different organization). These failures share the body `{\"detail\": \"You do not have permission to perform this action.\"}`. Check that the `x-api-key` header is present and belongs to the intended application, re-fetch the application API key via the [Auth API](/auth-api/get-credentials) if needed, and retry.\n\n**Deleted application:** for a few minutes after an application is deleted, a request made with one of its API keys can answer `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`. Do not retry: the application and its API keys no longer exist. After those few minutes, the key is refused like any other invalid key.", + "description": "Authentication or authorization failed. A wrong, revoked or expired key returns `401`. The endpoint returns `403` when the `x-api-key` header is missing or the API key is valid but the client does not have permission to create sessions in this application (for example the API key belongs to a different organization). These failures share the body `{\"detail\": \"You do not have permission to perform this action.\"}`. Check that the `x-api-key` header is present and belongs to the intended application, re-fetch the application API key via the [Auth API](/auth-api/get-credentials) if needed, and retry.\n\n**Deleted application:** for a few minutes after an application is deleted, a request made with one of its API keys can answer `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`. Do not retry: the application and its API keys no longer exist. After those few minutes, the key is refused like any other invalid key.", "content": { "application/json": { "schema": { @@ -1032,12 +1123,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = \"https://verification.didit.me/v3/session/\"\nheaders = {\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n}\npayload = {\n \"workflow_id\": \"11111111-2222-3333-4444-555555555555\",\n \"vendor_data\": \"user-123\",\n \"callback\": \"https://example.com/verification/callback\",\n \"callback_method\": \"both\",\n \"metadata\": {\"user_type\": \"premium\", \"account_id\": \"ABC123\"},\n \"language\": \"en\",\n \"contact_details\": {\n \"email\": \"john.doe@example.com\",\n \"send_notification_emails\": True,\n \"email_lang\": \"en\",\n \"phone\": \"+14155552671\",\n },\n \"expected_details\": {\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"date_of_birth\": \"1990-05-15\",\n \"id_country\": \"USA\",\n \"expected_document_types\": [\"P\", \"ID\"],\n },\n}\n\nresponse = requests.post(url, json=payload, headers=headers, timeout=15)\nresponse.raise_for_status()\nsession = response.json()\nprint(session[\"session_id\"], session[\"url\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.create(\n workflow_id=\"11111111-2222-3333-4444-555555555555\",\n vendor_data=\"user-123\",\n callback=\"https://example.com/verification/callback\",\n callback_method=\"both\",\n metadata={\"user_type\": \"premium\", \"account_id\": \"ABC123\"},\n language=\"en\",\n contact_details={\n \"email\": \"john.doe@example.com\",\n \"send_notification_emails\": True,\n \"email_lang\": \"en\",\n \"phone\": \"+14155552671\",\n },\n expected_details={\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"date_of_birth\": \"1990-05-15\",\n \"nationality\": \"USA\",\n \"id_country\": \"USA\",\n \"expected_document_types\": [\"P\", \"ID\"],\n },\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch('https://verification.didit.me/v3/session/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n workflow_id: '11111111-2222-3333-4444-555555555555',\n vendor_data: 'user-123',\n callback: 'https://example.com/verification/callback',\n callback_method: 'both',\n metadata: { user_type: 'premium', account_id: 'ABC123' },\n language: 'en',\n contact_details: {\n email: 'john.doe@example.com',\n send_notification_emails: true,\n email_lang: 'en',\n phone: '+14155552671',\n },\n expected_details: {\n first_name: 'John',\n last_name: 'Doe',\n date_of_birth: '1990-05-15',\n id_country: 'USA',\n expected_document_types: ['P', 'ID'],\n },\n }),\n});\n\nif (!response.ok) {\n throw new Error(`Session create failed: ${response.status}`);\n}\nconst session = await response.json();\nconsole.log(session.session_id, session.url);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.create({\n workflow_id: \"11111111-2222-3333-4444-555555555555\",\n vendor_data: \"user-123\",\n callback: \"https://example.com/verification/callback\",\n callback_method: \"both\",\n metadata: { user_type: \"premium\", account_id: \"ABC123\" },\n language: \"en\",\n contact_details: {\n email: \"john.doe@example.com\",\n send_notification_emails: true,\n email_lang: \"en\",\n phone: \"+14155552671\",\n },\n expected_details: {\n first_name: \"John\",\n last_name: \"Doe\",\n date_of_birth: \"1990-05-15\",\n nationality: \"USA\",\n id_country: \"USA\",\n expected_document_types: [\"P\", \"ID\"],\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Create(ctx, didit.SessionsCreateParams{\n\tWorkflowID: \"11111111-2222-3333-4444-555555555555\",\n\tVendorData: didit.String(\"user-123\"),\n\tCallback: didit.String(\"https://example.com/verification/callback\"),\n\tCallbackMethod: didit.Some(didit.SessionsCreateParamsCallbackMethod(\"both\")),\n\tMetadata: didit.Some[any](map[string]any{\"user_type\": \"premium\", \"account_id\": \"ABC123\"}),\n\tLanguage: didit.Some(didit.SessionsCreateParamsLanguage(\"en\")),\n\tContactDetails: didit.Some(didit.SessionsCreateParamsContactDetails{\n\t\tEmail: didit.String(\"john.doe@example.com\"),\n\t\tSendNotificationEmails: didit.Bool(true),\n\t\tEmailLang: didit.Some(didit.SessionsCreateParamsContactDetailsEmailLang(\"en\")),\n\t\tPhone: didit.String(\"+14155552671\"),\n\t}),\n\tExpectedDetails: didit.Some(didit.SessionsCreateParamsExpectedDetails{\n\t\tFirstName: didit.String(\"John\"),\n\t\tLastName: didit.String(\"Doe\"),\n\t\tDateOfBirth: didit.String(\"1990-05-15\"),\n\t\tNationality: didit.String(\"USA\"),\n\t\tIDCountry: didit.String(\"USA\"),\n\t\tExpectedDocumentTypes: didit.Some([]didit.SessionsCreateParamsExpectedDetailsExpectedDocumentTypes{\"P\", \"ID\"}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().create(SessionsCreateParams.builder()\n .workflowId(\"11111111-2222-3333-4444-555555555555\")\n .vendorData(\"user-123\")\n .callback(\"https://example.com/verification/callback\")\n .callbackMethod(SessionsCreateParams.CallbackMethod.of(\"both\"))\n .metadata(Map.of(\"user_type\", \"premium\", \"account_id\", \"ABC123\"))\n .language(SessionsCreateParams.Language.of(\"en\"))\n .contactDetails(SessionsCreateParams.ContactDetails.builder()\n .email(\"john.doe@example.com\")\n .sendNotificationEmails(true)\n .emailLang(SessionsCreateParams.ContactDetails.EmailLang.of(\"en\"))\n .phone(\"+14155552671\")\n .build())\n .expectedDetails(SessionsCreateParams.ExpectedDetails.builder()\n .firstName(\"John\")\n .lastName(\"Doe\")\n .dateOfBirth(LocalDate.parse(\"1990-05-15\"))\n .nationality(\"USA\")\n .idCountry(\"USA\")\n .expectedDocumentTypes(List.of(SessionsCreateParams.ExpectedDetails.ExpectedDocumentTypes.of(\"P\"), SessionsCreateParams.ExpectedDetails.ExpectedDocumentTypes.of(\"ID\")))\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->create([\n 'workflow_id' => '11111111-2222-3333-4444-555555555555',\n 'vendor_data' => 'user-123',\n 'callback' => 'https://example.com/verification/callback',\n 'callback_method' => 'both',\n 'metadata' => ['user_type' => 'premium', 'account_id' => 'ABC123'],\n 'language' => 'en',\n 'contact_details' => [\n 'email' => 'john.doe@example.com',\n 'send_notification_emails' => true,\n 'email_lang' => 'en',\n 'phone' => '+14155552671',\n ],\n 'expected_details' => [\n 'first_name' => 'John',\n 'last_name' => 'Doe',\n 'date_of_birth' => '1990-05-15',\n 'nationality' => 'USA',\n 'id_country' => 'USA',\n 'expected_document_types' => ['P', 'ID'],\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.create(\n workflow_id: \"11111111-2222-3333-4444-555555555555\",\n vendor_data: \"user-123\",\n callback: \"https://example.com/verification/callback\",\n callback_method: \"both\",\n metadata: { user_type: \"premium\", account_id: \"ABC123\" },\n language: \"en\",\n contact_details: {\n email: \"john.doe@example.com\",\n send_notification_emails: true,\n email_lang: \"en\",\n phone: \"+14155552671\",\n },\n expected_details: {\n first_name: \"John\",\n last_name: \"Doe\",\n date_of_birth: \"1990-05-15\",\n nationality: \"USA\",\n id_country: \"USA\",\n expected_document_types: [\"P\", \"ID\"],\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CreateAsync(new SessionsCreateParams\n{\n WorkflowId = \"11111111-2222-3333-4444-555555555555\",\n VendorData = \"user-123\",\n Callback = \"https://example.com/verification/callback\",\n CallbackMethod = new SessionsCreateParamsCallbackMethod(\"both\"),\n Metadata = new Dictionary { [\"user_type\"] = \"premium\", [\"account_id\"] = \"ABC123\" },\n Language = new SessionsCreateParamsLanguage(\"en\"),\n ContactDetails = new SessionsCreateParamsContactDetails\n {\n Email = \"john.doe@example.com\",\n SendNotificationEmails = true,\n EmailLang = new SessionsCreateParamsContactDetailsEmailLang(\"en\"),\n Phone = \"+14155552671\",\n },\n ExpectedDetails = new SessionsCreateParamsExpectedDetails\n {\n FirstName = \"John\",\n LastName = \"Doe\",\n DateOfBirth = \"1990-05-15\",\n Nationality = \"USA\",\n IdCountry = \"USA\",\n ExpectedDocumentTypes = new SessionsCreateParamsExpectedDetailsExpectedDocumentTypes[] { \"P\", \"ID\" },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -1063,6 +1179,12 @@ "example": "user-123", "x-readme-id": "0.1" }, + "multi_account_segment": { + "type": "string", + "maxLength": 64, + "description": "Optional duplicate-detection realm inside your organization. Duplicate face checks compare this session only with other sessions that carry the same segment, so separate account bases (personal and business accounts, or one per B2B sub-client) do not flag a person who legitimately holds one account in each. Omit it to use the single default realm, which is what every session uses today. Blocklist and allowlist matching ignore this field.", + "example": "business-accounts" + }, "callback": { "type": "string", "description": "URL to redirect the user to after verification completes. Didit automatically appends `verificationSessionId` and `status` (Approved, Declined, In Review) as query parameters. Custom URL schemes (e.g. `myapp://`) are supported for mobile callbacks. If omitted, the workflow's default `callback_url` is used. When the application has allowed domains (`allowed_domains` on `PATCH /v3/webhook/`), an `http` or `https` callback must be on one of those origins (same scheme, host and port), otherwise the request fails with 400 on `callback`: `callback must be on one of the application's allowed domains: https://app.example.com`. Custom URL schemes are always accepted.", @@ -1406,7 +1528,7 @@ }, "sign": { "type": "object", - "description": "Electronic Signature input for this session. `documents` are the documents to sign, for a workflow whose Electronic Signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{\"sign\": \"signature_document_changed\"}`. See [Electronic signature documents](/sessions-api/create-session#electronic-signature-documents).", + "description": "E-signature input for this session. `documents` are the documents to sign, for a workflow whose E-signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{\"sign\": \"signature_document_changed\"}`. See [E-signature documents](/sessions-api/create-session#e-signature-documents).", "properties": { "documents": { "type": "array", @@ -1901,7 +2023,7 @@ } }, "403": { - "description": "Imports not enabled, sandbox application, or missing/invalid API key (this endpoint returns `403`, never `401`, for authentication failures). Verification imports are disabled by default and must be enabled per organization by Didit.", + "description": "Imports not enabled, sandbox application, or missing API key (a wrong, revoked or expired key gets `401`). Verification imports are disabled by default and must be enabled per organization by Didit.", "content": { "application/json": { "examples": { @@ -1943,6 +2065,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.create(\n import_type=\"user_verification\",\n workflow_id=\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n source_file_url=\"https://files.example.com/exports/sessions.ndjson\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.create({\n import_type: \"user_verification\",\n workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n source_file_url: \"https://files.example.com/exports/sessions.ndjson\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Create(ctx, didit.SessionsImportsCreateParams{\n\tImportType: didit.Some(didit.SessionsImportsCreateParamsImportType(\"user_verification\")),\n\tWorkflowID: didit.String(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\"),\n\tSourceFileURL: didit.String(\"https://files.example.com/exports/sessions.ndjson\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsImportsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().create(SessionsImportsCreateParams.builder()\n .importType(SessionsImportsCreateParams.ImportType.of(\"user_verification\"))\n .workflowId(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\")\n .sourceFileUrl(\"https://files.example.com/exports/sessions.ndjson\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->create([\n 'import_type' => 'user_verification',\n 'workflow_id' => '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n 'source_file_url' => 'https://files.example.com/exports/sessions.ndjson',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.create(\n import_type: \"user_verification\",\n workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n source_file_url: \"https://files.example.com/exports/sessions.ndjson\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CreateAsync(new SessionsImportsCreateParams\n{\n ImportType = new SessionsImportsCreateParamsImportType(\"user_verification\"),\n WorkflowId = \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n SourceFileUrl = \"https://files.example.com/exports/sessions.ndjson\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -1990,7 +2149,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot download import templates. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot download import templates. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -2009,6 +2168,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.imports.retrieve_template()\nwith open(\"download.csv\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.imports.retrieveTemplate();\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Imports.RetrieveTemplate(ctx, didit.SessionsImportsRetrieveTemplateParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().imports().retrieveTemplate()\n .writeTo(Path.of(\"download.csv\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->retrieveTemplate();\n$content->saveTo('download.csv');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.imports.retrieve_template\nFile.binwrite(\"download.csv\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Imports.RetrieveTemplateAsync();\nawait content.SaveToAsync(\"download.csv\");" + } ] } }, @@ -2063,7 +2259,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot read import jobs for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot read import jobs for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -2082,6 +2278,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -2202,7 +2435,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot read import jobs for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot read import jobs for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -2221,13 +2454,50 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.imports.list_errors(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.imports.listErrors(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.Imports.ListErrorsAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsListErrorsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().imports().listErrors(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->listErrors('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.imports.list_errors(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.Imports.ListErrorsAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] } }, "/v3/session/{sessionId}/decision/": { "get": { "summary": "Retrieve the full decision for a verification session", - "description": "Retrieve the complete decision report for a verification session — the rolled-up session `status` plus one report per verification feature the workflow executed. This is the canonical read endpoint for both User Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level `session_kind` discriminator tells you which shape you received (`\"user\"` or `\"business\"`).\n\n**Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` — never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. Electronic Signature results are in `signatures`, which is present only when the workflow has an Electronic Signature step.\n\n**When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to fetch the full report. Polling also works — the endpoint can be called at any point in the session lifecycle and returns the data produced so far — but webhook-then-fetch is cheaper and faster. Media URLs in the response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request the decision to get fresh ones, and do not persist them as long-term references.\n\n**Statuses.** The top-level `status` is the session lifecycle status (`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Each feature item additionally carries its own feature-level `status` (`Not Finished`, `Approved`, `Declined`, `In Review`, ...). A session can be `Approved` overall while an individual feature is `In Review`, depending on the workflow's decision rules.\n\n**Authentication and visibility.** Authenticate with the application API key in the `x-api-key` header (a console user Bearer token with the `read:sessions` permission also works). Only sessions owned by the authenticated application are visible. If your workflow restricts response attributes, non-allowed fields inside feature items are returned as `null` while `status`, `warnings`, and `node_id` are always preserved.\n\n**Rate limits.** GET requests are limited to 600 per minute per API key. Exceeding the limit returns `429` with `Retry-After` and `X-RateLimit-*` headers.", + "description": "Retrieve the complete decision report for a verification session — the rolled-up session `status` plus one report per verification feature the workflow executed. This is the canonical read endpoint for both User Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level `session_kind` discriminator tells you which shape you received (`\"user\"` or `\"business\"`).\n\n**Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` — never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. E-signature results are in `signatures`, which is present only when the workflow has an E-signature step.\n\n**When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to fetch the full report. Polling also works — the endpoint can be called at any point in the session lifecycle and returns the data produced so far — but webhook-then-fetch is cheaper and faster. Media URLs in the response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request the decision to get fresh ones, and do not persist them as long-term references.\n\n**Statuses.** The top-level `status` is the session lifecycle status (`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Each feature item additionally carries its own feature-level `status` (`Not Finished`, `Approved`, `Declined`, `In Review`, ...). A session can be `Approved` overall while an individual feature is `In Review`, depending on the workflow's decision rules.\n\n**Authentication and visibility.** Authenticate with the application API key in the `x-api-key` header (a console user Bearer token with the `read:sessions` permission also works). Only sessions owned by the authenticated application are visible. If your workflow restricts response attributes, non-allowed fields inside feature items are returned as `null` while `status`, `warnings`, and `node_id` are always preserved.\n\n**Rate limits.** GET requests are limited to 600 per minute per API key. Exceeding the limit returns `429` with `Retry-After` and `X-RateLimit-*` headers.", "operationId": "get_v3_session_decision", "x-didit-sdk": { "resource": "sessions", @@ -3413,7 +3683,7 @@ "entity_type": "person", "hits": [ { - "id": "cPtTGRKkyddAcAC4xgsLCm", + "id": "hit_7c1e9a40b2d35f86e0a4c912", "url": "https://news.example.org/articles/sample", "match": false, "score": 0.73, @@ -4092,21 +4362,7 @@ } ], "accounts": null, - "registry_data": { - "addresses_detail": [ - { - "type": "registered", - "address": "1 Example Street, London, EC1A 1AA", - "country": "GB" - } - ], - "industries": [ - { - "code": "62012", - "description": "Business and domestic software development" - } - ] - }, + "registry_data": {}, "user_provided_data": { "company_name": "ACME HOLDINGS", "registration_number": "12345678" @@ -4116,19 +4372,38 @@ "is_editable": false }, "ownership_structure": { - "nodes": [ - { - "id": "company", - "name": "ACME HOLDINGS LTD", - "type": "company" - }, + "shareholders": [ { - "id": "ubo-1", "name": "John Doe", - "type": "person", - "ownership_percent": 75.0 + "first_name": "John", + "last_name": "Doe", + "date_of_birth": null, + "country_of_birth": null, + "company_name": null, + "registration_number": null, + "entity_type": "person", + "nationality": null, + "designation": null, + "roles": [ + "shareholder" + ], + "ownership_min_shares": "75", + "ownership_max_shares": "75", + "voting_min_shares": null, + "voting_max_shares": null, + "appointment_date": null, + "is_active": true, + "shareholding": { + "share_class": "ORDINARY", + "number_of_shares": 750.0, + "currency": "GBP", + "nominal_value": 1.0, + "total_value": null, + "percentage": 75.0 + } } - ] + ], + "beneficial_owners": [] }, "warnings": [] } @@ -4436,7 +4711,7 @@ } }, "403": { - "description": "Authentication or authorization failed. **This endpoint never returns `401`** — Didit's API-key authentication does not emit a `WWW-Authenticate` challenge, so missing or invalid credentials also surface as `403`. Two `detail` strings distinguish the failure modes:\n\n- `\"Authentication credentials were not provided or are invalid.\"` — no `x-api-key` header (and no `Authorization: Bearer` token), or the supplied credential failed introspection (revoked, expired, or malformed).\n- `\"You do not have permission to perform this action.\"` — the credential is valid but not allowed to read this session: a console-user Bearer token lacks the `read:sessions` permission or cannot access the owning application, or an API key belongs to a different organization than the session.\n\nNote that for a completely unknown `sessionId` the endpoint resolves the owning application before validating credentials, so a missing session returns `404` even when the credential is missing or invalid.", + "description": "Authentication or authorization failed. A missing key returns `403`; a wrong, revoked or expired key returns `401`. Two `detail` strings distinguish the failure modes:\n\n- `\"Authentication credentials were not provided or are invalid.\"` — no `x-api-key` header (and no `Authorization: Bearer` token), or the supplied credential failed introspection (revoked, expired, or malformed).\n- `\"You do not have permission to perform this action.\"` — the credential is valid but not allowed to read this session: a console-user Bearer token lacks the `read:sessions` permission or cannot access the owning application, or an API key belongs to a different organization than the session.\n\nNote that for a completely unknown `sessionId` the endpoint resolves the owning application before validating credentials, so a missing session returns `404` even when the credential is missing or invalid.", "content": { "application/json": { "schema": { @@ -4594,12 +4869,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nsession_id = \"11111111-2222-3333-4444-555555555555\"\nurl = f\"https://verification.didit.me/v3/session/{session_id}/decision/\"\nheaders = {\n 'x-api-key': 'YOUR_API_KEY',\n \"Accept\": \"application/json\",\n}\n\nresponse = requests.get(url, headers=headers, timeout=15)\nresponse.raise_for_status()\ndecision = response.json()\n\nprint(\"session_kind:\", decision[\"session_kind\"])\nprint(\"top-level status:\", decision[\"status\"])\n\n# nfc_verifications is ALWAYS an array — never a singular `nfc` field.\nfor nfc in decision.get(\"nfc_verifications\") or []:\n print(\"nfc node_id:\", nfc[\"node_id\"], \"status:\", nfc[\"status\"])\n\nfor id_check in decision.get(\"id_verifications\") or []:\n print(\"id node_id:\", id_check[\"node_id\"], \"status:\", id_check[\"status\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.retrieve_decision(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '11111111-2222-3333-4444-555555555555';\nconst response = await fetch(\n `https://verification.didit.me/v3/session/${sessionId}/decision/`,\n {\n method: 'GET',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n Accept: 'application/json',\n },\n }\n);\n\nif (!response.ok) {\n throw new Error(`Decision fetch failed: ${response.status}`);\n}\nconst decision = await response.json();\n\nconsole.log('session_kind:', decision.session_kind);\nconsole.log('top-level status:', decision.status);\n\n// nfc_verifications is ALWAYS an array — never a singular `nfc` field.\nfor (const nfc of decision.nfc_verifications ?? []) {\n console.log('nfc node_id:', nfc.node_id, 'status:', nfc.status);\n}\n\nfor (const idCheck of decision.id_verifications ?? []) {\n console.log('id node_id:', idCheck.node_id, 'status:', idCheck.status);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.retrieveDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RetrieveDecision(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsRetrieveDecisionParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().retrieveDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->retrieveDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.retrieve_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RetrieveDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -4607,7 +4907,7 @@ "/v3/session/{sessionId}/delete/": { "delete": { "summary": "Delete a verification session (KYC or KYB)", - "description": "Delete a single verification session, User Verification (KYC) or Business Verification (KYB), by its `session_id`. The id is resolved against KYC sessions first, then KYB sessions, so both kinds are deleted through this one URL.\n\n**What is deleted:**\n- The session and every verification attempt it holds, including results that a resubmission replaced: the decision, extracted data, all related feature records (ID verification, face, liveness, face match, AML, registry checks, IP analysis, and so on), its reviews and its activity log.\n- All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded files (KYC); uploaded company documents and extra files (KYB). Electronic Signature documents, signed PDFs, evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media URLs (`https:///...`) stop resolving.\n- The session's face data. Its face embedding is deleted too, unless you choose to keep an image-free template (see **Face biometric data**).\n- Webhook deliveries still queued for the session, and their retries. Webhooks already delivered are not affected.\n- For a Business Verification (KYB) session: the verifications it created for its key people (KYC) and its corporate owners (KYB), recursively, reported as `deleted_child_verifications`. A verification it only links to, such as an existing approved KYC it reused, is not deleted.\n\nThe session disappears from every read endpoint immediately: `GET /v3/session/{sessionId}/decision/` returns `404` and `GET /v3/sessions/` stops listing it. Ongoing AML monitoring and KYB registry monitoring started by the deleted verifications stop.\n\n**What is not affected:** blocklist entries created from this session (face or document) are **not** removed; manage those with the blocklist endpoints. Share tokens issued for the session are not revoked, but there is nothing left for them to import: an import with one returns `400` with `{\"share_token\": [\"Original session does not exist.\"]}`. Credits already consumed are **not** refunded. The parent User or Business entity is **not** deleted; use `POST /v3/users/delete/` or `POST /v3/businesses/delete/` for those. If the User's profile portrait came from this session, the portrait is removed with it.\n\n**Face biometric data:** by default the session's face embedding is deleted with the session (`face_retention_outcome: deleted`). An application that opted in to biometric-template retention (`face_retention_policy: retain_until_user_deleted` on `PATCH /v3/webhook/`), or a request with `retain_face_embeddings: true`, keeps one separately managed, image-free face biometric template anchored to the session's User (`retained_with_user`) so that duplicate detection, Face Search, and biometric authentication keep working. The template never contains the face image, media, identity fields, the decision, or the deleted session's id; it is biometric data deleted at `biometric_template_expires_at`, or earlier on User deletion, privacy erasure, or an explicit purge through `/v3/biometric-templates/`. A session without a linked User cannot retain a template (`ineligible_no_vendor_user`). Send `deletion_instruction: privacy_erasure` for data-subject requests: it purges every retained template for that User and never retains a new one.\n\n**Irreversible:** deletion is permanent and there is no restore endpoint. Export anything you need (for example a decision PDF) before you call it.\n\n**Side effects:** no webhook is emitted for deletions.\n\n**Response:** `200 OK` once the deletion has completed, with a JSON body reporting the `face_retention_outcome`, the retained template's expiry and, for a KYB session, `deleted_child_verifications`. Earlier versions of this endpoint returned `204 No Content`; update clients that assert on `204`. Keep your `instruction_id` in your own erasure log.\n\n**Idempotency:** not idempotent at the HTTP level: the first call returns `200`; repeating it returns `404` because the session no longer resolves. After a `503` the session is still in place; repeat the same request to finish deleting it.\n\n**Authentication:** send your application's API key in the `x-api-key` header; the session must belong to that application. Console user access tokens (`Authorization: Bearer ...`) may also call this endpoint when they carry the `delete:sessions` permission. Authentication and permission failures both return `403`; this API never returns `401`.\n\n**Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.\n\nTo bulk-delete KYC sessions by their numeric `session_number`, use `POST /v3/sessions/delete/` instead.\n\n**Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request.", + "description": "Delete a single verification session, User Verification (KYC) or Business Verification (KYB), by its `session_id`. The id is resolved against KYC sessions first, then KYB sessions, so both kinds are deleted through this one URL.\n\n**What is deleted:**\n- The session and every verification attempt it holds, including results that a resubmission replaced: the decision, extracted data, all related feature records (ID verification, face, liveness, face match, AML, registry checks, IP analysis, and so on), its reviews and its activity log.\n- All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded files (KYC); uploaded company documents and extra files (KYB). E-signature documents, signed PDFs, evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media URLs (`https:///...`) stop resolving.\n- The session's face data. Its face embedding is deleted too, unless you choose to keep an image-free template (see **Face biometric data**).\n- Webhook deliveries still queued for the session, and their retries. Webhooks already delivered are not affected.\n- For a Business Verification (KYB) session: the verifications it created for its key people (KYC) and its corporate owners (KYB), recursively, reported as `deleted_child_verifications`. A verification it only links to, such as an existing approved KYC it reused, is not deleted.\n\nThe session disappears from every read endpoint immediately: `GET /v3/session/{sessionId}/decision/` returns `404` and `GET /v3/sessions/` stops listing it. Ongoing AML monitoring and KYB registry monitoring started by the deleted verifications stop.\n\n**What is not affected:** blocklist entries created from this session (face or document) are **not** removed; manage those with the blocklist endpoints. Share tokens issued for the session are not revoked, but there is nothing left for them to import: an import with one returns `400` with `{\"share_token\": [\"Original session does not exist.\"]}`. Credits already consumed are **not** refunded. The parent User or Business entity is **not** deleted; use `POST /v3/users/delete/` or `POST /v3/businesses/delete/` for those. If the User's profile portrait came from this session, the portrait is removed with it.\n\n**Face biometric data:** by default the session's face embedding is deleted with the session (`face_retention_outcome: deleted`). An application that opted in to biometric-template retention (`face_retention_policy: retain_until_user_deleted` on `PATCH /v3/webhook/`), or a request with `retain_face_embeddings: true`, keeps one separately managed, image-free face biometric template anchored to the session's User (`retained_with_user`) so that duplicate detection, Face Search, and biometric authentication keep working. The template never contains the face image, media, identity fields, the decision, or the deleted session's id; it is biometric data deleted at `biometric_template_expires_at`, or earlier on User deletion, privacy erasure, or an explicit purge through `/v3/biometric-templates/`. A session without a linked User cannot retain a template (`ineligible_no_vendor_user`). Send `deletion_instruction: privacy_erasure` for data-subject requests: it purges every retained template for that User and never retains a new one.\n\n**Irreversible:** deletion is permanent and there is no restore endpoint. Export anything you need (for example a decision PDF) before you call it.\n\n**Side effects:** no webhook is emitted for deletions.\n\n**Response:** `200 OK` once the deletion has completed, with a JSON body reporting the `face_retention_outcome`, the retained template's expiry and, for a KYB session, `deleted_child_verifications`. Earlier versions of this endpoint returned `204 No Content`; update clients that assert on `204`. Keep your `instruction_id` in your own erasure log.\n\n**Idempotency:** not idempotent at the HTTP level: the first call returns `200`; repeating it returns `404` because the session no longer resolves. After a `503` the session is still in place; repeat the same request to finish deleting it.\n\n**Authentication:** send your application's API key in the `x-api-key` header; the session must belong to that application. Console user access tokens (`Authorization: Bearer ...`) may also call this endpoint when they carry the `delete:sessions` permission. Authentication and permission failures both return `403`; this API never returns `401`.\n\n**Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.\n\nTo bulk-delete KYC sessions by their numeric `session_number`, use `POST /v3/sessions/delete/` instead.\n\n**Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request.", "operationId": "delete_v3_session_by_id", "x-didit-sdk": { "resource": "sessions", @@ -4747,7 +5047,7 @@ } }, "403": { - "description": "Authentication or permission failure. Missing/invalid credentials also return `403` — this API never returns `401`. Exception: when the `sessionId` does not resolve to a live session, the pre-auth owner lookup returns `404` first, even with missing or invalid credentials.", + "description": "Authentication or permission failure. A missing key also returns `403`; a wrong, revoked or expired key returns `401`. Exception: when the `sessionId` does not resolve to a live session, the pre-auth owner lookup returns `404` first, even with missing or invalid credentials.", "content": { "application/json": { "schema": { @@ -4885,12 +5185,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.delete(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json={\"retain_face_embeddings\": True, \"face_retention_days\": 365},\n)\nresponse.raise_for_status()\nprint(response.json()[\"face_retention_outcome\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.delete(\n \"11111111-2222-3333-4444-555555555555\",\n retain_face_embeddings=True,\n face_retention_days=365,\n instruction_id=\"post-approval-cleanup-2026-08\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch(\n 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/',\n {\n method: 'DELETE',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ deletion_instruction: 'privacy_erasure', instruction_id: 'dsar-2026-0142' }),\n },\n);\nconst body = await resp.json();\nconsole.log(body.face_retention_outcome);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.delete(\"11111111-2222-3333-4444-555555555555\", {\n retain_face_embeddings: true,\n face_retention_days: 365,\n instruction_id: \"post-approval-cleanup-2026-08\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsDeleteParams{\n\tRetainFaceEmbeddings: didit.Bool(true),\n\tFaceRetentionDays: didit.Int(365),\n\tInstructionID: didit.String(\"post-approval-cleanup-2026-08\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().delete(\"11111111-2222-3333-4444-555555555555\", SessionsDeleteParams.builder()\n .retainFaceEmbeddings(true)\n .faceRetentionDays(365L)\n .instructionId(\"post-approval-cleanup-2026-08\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->delete('11111111-2222-3333-4444-555555555555', [\n 'retain_face_embeddings' => true,\n 'face_retention_days' => 365,\n 'instruction_id' => 'post-approval-cleanup-2026-08',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.delete(\n \"11111111-2222-3333-4444-555555555555\",\n retain_face_embeddings: true,\n face_retention_days: 365,\n instruction_id: \"post-approval-cleanup-2026-08\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsDeleteParams\n{\n RetainFaceEmbeddings = true,\n FaceRetentionDays = 365,\n InstructionId = \"post-approval-cleanup-2026-08\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -5022,7 +5347,7 @@ } }, "403": { - "description": "Authentication, authorization, or session-status failure. **This endpoint never returns `401`** — Didit's API-key authentication does not emit a `WWW-Authenticate` challenge, so missing or invalid credentials also surface as `403`. Distinguish the failure modes by the `detail` string:\n\n- `\"Authentication credentials were not provided or are invalid.\"` — no `x-api-key` header (and no `Authorization: Bearer` token), or the supplied credential failed introspection (revoked, expired, or malformed).\n- `\"You do not have permission to perform this action.\"` — the credential is valid but cannot read this session: a console-user Bearer token lacks the `read:sessions` permission or cannot access the owning application, or an API key belongs to a different organization than the session.\n- `\"You can only generate a PDF for sessions in review, declined, approved or kyc expired\"` — the KYC session exists but is not in an eligible status yet (for example `Not Started` or `In Progress`). Wait for the `status.updated` webhook before requesting the report.\n- `\"You can only generate a PDF for sessions in review, declined or approved\"` — same condition for KYB sessions.\n\nNote that for a completely unknown `sessionId` the endpoint resolves the owning application before validating credentials, so a missing session returns `404` even when the credential is missing or invalid.", + "description": "Authentication, authorization, or session-status failure. A missing key returns `403`; a wrong, revoked or expired key returns `401`. Distinguish the failure modes by the `detail` string:\n\n- `\"Authentication credentials were not provided or are invalid.\"` — no `x-api-key` header (and no `Authorization: Bearer` token), or the supplied credential failed introspection (revoked, expired, or malformed).\n- `\"You do not have permission to perform this action.\"` — the credential is valid but cannot read this session: a console-user Bearer token lacks the `read:sessions` permission or cannot access the owning application, or an API key belongs to a different organization than the session.\n- `\"You can only generate a PDF for sessions in review, declined, approved or kyc expired\"` — the KYC session exists but is not in an eligible status yet (for example `Not Started` or `In Progress`). Wait for the `status.updated` webhook before requesting the report.\n- `\"You can only generate a PDF for sessions in review, declined or approved\"` — same condition for KYB sessions.\n\nNote that for a completely unknown `sessionId` the endpoint resolves the owning application before validating credentials, so a missing session returns `404` even when the credential is missing or invalid.", "content": { "application/json": { "schema": { @@ -5164,12 +5489,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.get(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/generate-pdf/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n stream=True,\n timeout=60,\n)\nresponse.raise_for_status()\nwith open(\"report.pdf\", \"wb\") as fh:\n for chunk in response.iter_content(chunk_size=8192):\n fh.write(chunk)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.generate_pdf(\n \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { writeFile } from 'node:fs/promises';\n\nconst response = await fetch(\n 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/generate-pdf/',\n { headers: { 'x-api-key': 'YOUR_API_KEY' } },\n);\nif (!response.ok) throw new Error(`PDF generation failed: HTTP ${response.status}`);\nawait writeFile('report.pdf', Buffer.from(await response.arrayBuffer()));" + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.generatePdf(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.GeneratePDF(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().generatePdf(\"11111111-2222-3333-4444-555555555555\")\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->generatePdf('11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.generate_pdf(\"11111111-2222-3333-4444-555555555555\")\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.GeneratePdfAsync(\"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.pdf\");" } ] } @@ -5426,7 +5776,8 @@ "EMAIL", "KYB_REGISTRY", "KYB_KEY_PEOPLE", - "KYB" + "KYB", + "GEOLOCATION" ], "example": "OCR" } @@ -5641,7 +5992,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions, or a `session_id` that belongs to another application.", + "description": "Missing credentials or insufficient permissions, or a `session_id` that belongs to another application.", "content": { "application/json": { "examples": { @@ -5715,12 +6066,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/\",\n headers={\n \"x-api-key\": \"YOUR_API_KEY\",\n \"Content-Type\": \"application/json\",\n },\n json={\n \"new_status\": \"Resubmitted\",\n \"nodes_to_resubmit\": [\n {\"node_id\": \"feature_ocr\", \"feature\": \"OCR\"},\n {\"node_id\": \"feature_liveness\", \"feature\": \"LIVENESS\"},\n ],\n \"send_email\": True,\n \"email_address\": \"user@example.com\",\n \"email_language\": \"en\",\n },\n)\nresponse.raise_for_status()\nprint(response.json()) # {'session_id': '11111111-2222-3333-4444-555555555555'}" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_status(\n \"11111111-2222-3333-4444-555555555555\",\n new_status=\"Approved\",\n comment=\"All checks passed manual review\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/',\n {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n new_status: 'Declined',\n comment: 'Suspected fraud',\n }),\n },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst { session_id } = await response.json();" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateStatus(\"11111111-2222-3333-4444-555555555555\", {\n new_status: \"Approved\",\n comment: \"All checks passed manual review\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateStatusParams{\n\tNewStatus: \"Approved\",\n\tComment: didit.String(\"All checks passed manual review\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateStatusParams.builder()\n .newStatus(SessionsUpdateStatusParams.NewStatus.of(\"Approved\"))\n .comment(\"All checks passed manual review\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateStatus('11111111-2222-3333-4444-555555555555', [\n 'new_status' => 'Approved',\n 'comment' => 'All checks passed manual review',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_status(\n \"11111111-2222-3333-4444-555555555555\",\n new_status: \"Approved\",\n comment: \"All checks passed manual review\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateStatusParams\n{\n NewStatus = \"Approved\",\n Comment = \"All checks passed manual review\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -5728,7 +6104,7 @@ "/v3/id-verification/": { "post": { "summary": "ID Verification (document OCR + fraud checks)", - "description": "OCR an identity document and run document fraud checks in one call — returns the extracted holder fields, the parsed MRZ, an `Approved`/`Declined`/`In Review` `status`, and a `warnings` list explaining every issue found. Supports 14,000+ document types from 220+ countries and territories.\n\n**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.\n\n**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.\n\n**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.\n\n**Session persistence (`save_api_request`, default `true`).** When `true`, the call is persisted as an API-type session: it appears in the Business Console, the returned `request_id` is a real session id you can pass to `GET /v3/session/{sessionId}/decision/`, the cropped document/portrait images are stored and returned as short-lived media URLs (`https:///ocr/...`), and a `status.updated` webhook is emitted to your configured webhook endpoints. When `false`, nothing is stored, `request_id` is a one-off correlation UUID, and `portrait_image`/`front_image`/`back_image` are returned inline as base64-encoded JPEG strings.\n\n**Sandbox.** Sandbox API keys skip all processing and billing: after request validation (malformed input still returns `400`), the endpoint returns a static `Approved` mock payload (a fictional \"Sandbox User\" USA identity card), no session is persisted, and no credits are consumed.\n\n**Authentication.** Send your application's API key in the `x-api-key` header. Missing or invalid credentials return `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — this API never returns `401`.\n\n**Rate limit.** Shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.", + "description": "OCR an identity document and run document fraud checks in one call — returns the extracted holder fields, the parsed MRZ, an `Approved`/`Declined`/`In Review` `status`, and a `warnings` list explaining every issue found. Supports 14,000+ document types from 220+ countries and territories.\n\n**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.\n\n**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.\n\n**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.\n\n**Session persistence (`save_api_request`, default `true`).** When `true`, the call is persisted as an API-type session: it appears in the Business Console, the returned `request_id` is a real session id you can pass to `GET /v3/session/{sessionId}/decision/`, the cropped document/portrait images are stored and returned as short-lived media URLs (`https:///ocr/...`), and a `status.updated` webhook is emitted to your configured webhook endpoints. When `false`, nothing is stored, `request_id` is a one-off correlation UUID, and `portrait_image`/`front_image`/`back_image` are returned inline as base64-encoded JPEG strings.\n\n**Sandbox.** Sandbox API keys skip all processing and billing: after request validation (malformed input still returns `400`), the endpoint returns a static `Approved` mock payload (a fictional \"Sandbox User\" USA identity card), no session is persisted, and no credits are consumed.\n\n**Authentication.** Send your application's API key in the `x-api-key` header. Missing or invalid credentials return `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — this API never returns `401`.\n\n**Rate limit.** Shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`.", "operationId": "post_v3id-verification", "x-didit-sdk": { "resource": "id_verification", @@ -6546,7 +6922,7 @@ "properties": { "risk": { "type": "string", - "description": "Machine-readable risk code. Always-decline risks: `DOCUMENT_EXPIRED`, `MINIMUM_AGE_NOT_MET`, `PORTRAIT_IMAGE_NOT_DETECTED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT` (400-only, never a warning), `DOCUMENT_NUMBER_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`. Governed by request options: `MRZ_NOT_DETECTED` / `MRZ_VALIDATION_FAILED` (`invalid_mrz_action`), `DATA_INCONSISTENT` / `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` / `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS` (`inconsistent_data_action`), `EXPIRATION_DATE_NOT_DETECTED` (`expiration_date_not_detected_action`). Other risks (e.g. `POSSIBLE_DUPLICATED_USER`) are informational. `DOCUMENT_LIVENESS_NOT_COMPUTED` is raised when `perform_document_liveness=true` but the forgery check returned no usable score; it sets `status` to `In Review`.", + "description": "Machine-readable risk code. Always-decline risks: `DOCUMENT_EXPIRED`, `MINIMUM_AGE_NOT_MET`, `PORTRAIT_IMAGE_NOT_DETECTED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT` (400-only, never a warning), `DOCUMENT_NUMBER_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`. Governed by request options: `MRZ_NOT_DETECTED` / `MRZ_VALIDATION_FAILED` (`invalid_mrz_action`), `DATA_INCONSISTENT` / `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` / `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS` (`inconsistent_data_action`), `EXPIRATION_DATE_NOT_DETECTED` (`expiration_date_not_detected_action`). Other risks (e.g. `POSSIBLE_DUPLICATED_USER`) are informational. `DOCUMENT_LIVENESS_NOT_COMPUTED` is raised when `perform_document_liveness=true` but the forgery check returned no usable score; it sets `status` to `In Review`. `COULD_NOT_DETECT_DOCUMENT_TYPE` is also returned when the front of the document does not match a known official document design with high confidence, for example an edited or computer-generated document, or a design that is not supported yet.", "example": "DOCUMENT_EXPIRED" }, "feature": { @@ -6703,7 +7079,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", "content": { "application/json": { "examples": { @@ -6761,12 +7137,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = 'https://verification.didit.me/v3/id-verification/'\nheaders = {'x-api-key': 'YOUR_API_KEY'}\n\nwith open('id_front.jpg', 'rb') as front_f, open('id_back.jpg', 'rb') as back_f:\n files = {\n 'front_image': ('id_front.jpg', front_f, 'image/jpeg'),\n 'back_image': ('id_back.jpg', back_f, 'image/jpeg'),\n }\n data = {\n 'perform_document_liveness': 'true',\n 'save_api_request': 'true',\n 'vendor_data': 'user-123',\n }\n resp = requests.post(url, headers=headers, files=files, data=data, timeout=120)\n\nresp.raise_for_status()\nid_v = resp.json()['id_verification']\nprint('status:', id_v['status'])\nprint('name:', id_v.get('full_name'))\nprint('document:', id_v.get('document_type'), id_v.get('document_number'))\nfor w in id_v.get('warnings', []):\n print('warning:', w['risk'], '-', w['log_type'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_verification.verify(\n front_image=open(\"front_image.jpg\", \"rb\"),\n back_image=open(\"back_image.jpg\", \"rb\"),\n perform_document_liveness=True,\n save_api_request=True,\n vendor_data=\"user-123\",\n metadata={\"flow\": \"onboarding\"},\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import fs from 'node:fs';\n\nconst form = new FormData();\nform.append('front_image', new Blob([fs.readFileSync('./id_front.jpg')]), 'id_front.jpg');\nform.append('back_image', new Blob([fs.readFileSync('./id_back.jpg')]), 'id_back.jpg');\nform.append('perform_document_liveness', 'true');\nform.append('save_api_request', 'true');\nform.append('vendor_data', 'user-123');\n\nconst response = await fetch('https://verification.didit.me/v3/id-verification/', {\n method: 'POST',\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n body: form,\n});\n\nif (!response.ok) throw new Error(`ID verification failed: ${response.status}`);\nconst body = await response.json();\nconsole.log('status:', body.id_verification.status);\nconsole.log('warnings:', body.id_verification.warnings.map((w) => w.risk));" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idVerification.verify({\n front_image: await fileFromPath(\"front_image.jpg\"),\n back_image: await fileFromPath(\"back_image.jpg\"),\n perform_document_liveness: true,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"onboarding\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{\n\tFrontImage: didit.FileFromPath(\"front_image.jpg\"),\n\tBackImage: didit.Some(didit.FileFromPath(\"back_image.jpg\")),\n\tPerformDocumentLiveness: didit.Bool(true),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData: didit.String(\"user-123\"),\n\tMetadata: didit.Some(map[string]any{\"flow\": \"onboarding\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.IdVerificationVerifyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idVerification().verify(IdVerificationVerifyParams.builder()\n .frontImage(Path.of(\"front_image.jpg\"))\n .backImage(Path.of(\"back_image.jpg\"))\n .performDocumentLiveness(true)\n .saveApiRequest(true)\n .vendorData(\"user-123\")\n .metadata(Map.of(\"flow\", \"onboarding\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idVerification->verify([\n 'front_image' => File::fromPath('front_image.jpg'),\n 'back_image' => File::fromPath('back_image.jpg'),\n 'perform_document_liveness' => true,\n 'save_api_request' => true,\n 'vendor_data' => 'user-123',\n 'metadata' => ['flow' => 'onboarding'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_verification.verify(\n front_image: Pathname(\"front_image.jpg\"),\n back_image: Pathname(\"back_image.jpg\"),\n perform_document_liveness: true,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"onboarding\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdVerification.VerifyAsync(new IdVerificationVerifyParams\n{\n FrontImage = FileUpload.FromPath(\"front_image.jpg\"),\n BackImage = FileUpload.FromPath(\"back_image.jpg\"),\n PerformDocumentLiveness = true,\n SaveApiRequest = true,\n VendorData = \"user-123\",\n Metadata = new Dictionary { [\"flow\"] = \"onboarding\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -7231,7 +7632,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", "content": { "application/json": { "examples": { @@ -7289,12 +7690,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = 'https://verification.didit.me/v3/face-match/'\nheaders = {'x-api-key': 'YOUR_API_KEY'}\n\nwith open('selfie.jpg', 'rb') as user_f, open('id_portrait.jpg', 'rb') as ref_f:\n files = {\n 'user_image': ('selfie.jpg', user_f, 'image/jpeg'),\n 'ref_image': ('id_portrait.jpg', ref_f, 'image/jpeg'),\n }\n data = {\n 'face_match_score_decline_threshold': 50,\n 'save_api_request': 'true',\n 'vendor_data': 'user-123',\n }\n resp = requests.post(url, headers=headers, files=files, data=data, timeout=60)\n\nresp.raise_for_status()\nbody = resp.json()\nprint('status:', body['face_match']['status'])\nprint('score:', body['face_match']['score'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.face_match.compare(\n user_image=open(\"user_image.jpg\", \"rb\"),\n ref_image=open(\"ref_image.jpg\", \"rb\"),\n face_match_score_decline_threshold=50.0,\n rotate_image=False,\n save_api_request=True,\n vendor_data=\"user-123\",\n metadata={\"flow\": \"login\"},\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import fs from 'node:fs';\n\nconst form = new FormData();\nform.append('user_image', new Blob([fs.readFileSync('./selfie.jpg')]), 'selfie.jpg');\nform.append('ref_image', new Blob([fs.readFileSync('./id_portrait.jpg')]), 'id_portrait.jpg');\nform.append('face_match_score_decline_threshold', '50');\nform.append('save_api_request', 'true');\nform.append('vendor_data', 'user-123');\n\nconst response = await fetch('https://verification.didit.me/v3/face-match/', {\n method: 'POST',\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n body: form,\n});\n\nif (!response.ok) throw new Error(`Face match failed: ${response.status}`);\nconst body = await response.json();\nconsole.log('status:', body.face_match.status, 'score:', body.face_match.score);" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.faceMatch.compare({\n user_image: await fileFromPath(\"user_image.jpg\"),\n ref_image: await fileFromPath(\"ref_image.jpg\"),\n face_match_score_decline_threshold: 50.0,\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"login\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FaceMatch.Compare(ctx, didit.FaceMatchCompareParams{\n\tUserImage: didit.FileFromPath(\"user_image.jpg\"),\n\tRefImage: didit.FileFromPath(\"ref_image.jpg\"),\n\tFaceMatchScoreDeclineThreshold: didit.Float(50.0),\n\tRotateImage: didit.Bool(false),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData: didit.String(\"user-123\"),\n\tMetadata: didit.Some(map[string]any{\"flow\": \"login\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.FaceMatchCompareParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.faceMatch().compare(FaceMatchCompareParams.builder()\n .userImage(Path.of(\"user_image.jpg\"))\n .refImage(Path.of(\"ref_image.jpg\"))\n .faceMatchScoreDeclineThreshold(50.0)\n .rotateImage(false)\n .saveApiRequest(true)\n .vendorData(\"user-123\")\n .metadata(Map.of(\"flow\", \"login\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "faceMatch->compare([\n 'user_image' => File::fromPath('user_image.jpg'),\n 'ref_image' => File::fromPath('ref_image.jpg'),\n 'face_match_score_decline_threshold' => 50.0,\n 'rotate_image' => false,\n 'save_api_request' => true,\n 'vendor_data' => 'user-123',\n 'metadata' => ['flow' => 'login'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.face_match.compare(\n user_image: Pathname(\"user_image.jpg\"),\n ref_image: Pathname(\"ref_image.jpg\"),\n face_match_score_decline_threshold: 50.0,\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"login\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FaceMatch.CompareAsync(new FaceMatchCompareParams\n{\n UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n RefImage = FileUpload.FromPath(\"ref_image.jpg\"),\n FaceMatchScoreDeclineThreshold = 50.0,\n RotateImage = false,\n SaveApiRequest = true,\n VendorData = \"user-123\",\n Metadata = new Dictionary { [\"flow\"] = \"login\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -7720,7 +8146,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", "content": { "application/json": { "examples": { @@ -7778,12 +8204,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = 'https://verification.didit.me/v3/age-estimation/'\nheaders = {'x-api-key': 'YOUR_API_KEY'}\n\nwith open('selfie.jpg', 'rb') as f:\n files = {'user_image': ('selfie.jpg', f, 'image/jpeg')}\n data = {\n 'age_estimation_decline_threshold': 18,\n 'face_liveness_score_decline_threshold': 30,\n 'save_api_request': 'true',\n 'vendor_data': 'user-123',\n }\n resp = requests.post(url, headers=headers, files=files, data=data, timeout=60)\n\nresp.raise_for_status()\nresult = resp.json()['age_estimation']\nprint('status:', result['status'])\nprint('estimated age:', result['age_estimation'])\nprint('liveness score:', result['score'])\nfor w in result['warnings']:\n print('warning:', w['risk'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.age_estimation.estimate(\n user_image=open(\"user_image.jpg\", \"rb\"),\n face_liveness_score_decline_threshold=30.0,\n age_estimation_decline_threshold=18,\n rotate_image=False,\n save_api_request=True,\n vendor_data=\"user-123\",\n metadata={\"flow\": \"age-gate\"},\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import fs from 'node:fs';\n\nconst form = new FormData();\nform.append('user_image', new Blob([fs.readFileSync('./selfie.jpg')]), 'selfie.jpg');\nform.append('age_estimation_decline_threshold', '18');\nform.append('face_liveness_score_decline_threshold', '30');\nform.append('save_api_request', 'true');\nform.append('vendor_data', 'user-123');\n\nconst response = await fetch('https://verification.didit.me/v3/age-estimation/', {\n method: 'POST',\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n body: form,\n});\n\nif (!response.ok) throw new Error(`Age estimation failed: ${response.status}`);\nconst { age_estimation } = await response.json();\nconsole.log('status:', age_estimation.status, 'age:', age_estimation.age_estimation, 'liveness:', age_estimation.score);" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.ageEstimation.estimate({\n user_image: await fileFromPath(\"user_image.jpg\"),\n face_liveness_score_decline_threshold: 30.0,\n age_estimation_decline_threshold: 18,\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"age-gate\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AgeEstimation.Estimate(ctx, didit.AgeEstimationEstimateParams{\n\tUserImage: didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tAgeEstimationDeclineThreshold: didit.Int(18),\n\tRotateImage: didit.Bool(false),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData: didit.String(\"user-123\"),\n\tMetadata: didit.Some(map[string]any{\"flow\": \"age-gate\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.AgeEstimationEstimateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.ageEstimation().estimate(AgeEstimationEstimateParams.builder()\n .userImage(Path.of(\"user_image.jpg\"))\n .faceLivenessScoreDeclineThreshold(30.0)\n .ageEstimationDeclineThreshold(18L)\n .rotateImage(false)\n .saveApiRequest(true)\n .vendorData(\"user-123\")\n .metadata(Map.of(\"flow\", \"age-gate\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "ageEstimation->estimate([\n 'user_image' => File::fromPath('user_image.jpg'),\n 'face_liveness_score_decline_threshold' => 30.0,\n 'age_estimation_decline_threshold' => 18,\n 'rotate_image' => false,\n 'save_api_request' => true,\n 'vendor_data' => 'user-123',\n 'metadata' => ['flow' => 'age-gate'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.age_estimation.estimate(\n user_image: Pathname(\"user_image.jpg\"),\n face_liveness_score_decline_threshold: 30.0,\n age_estimation_decline_threshold: 18,\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"age-gate\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AgeEstimation.EstimateAsync(new AgeEstimationEstimateParams\n{\n UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n FaceLivenessScoreDeclineThreshold = 30.0,\n AgeEstimationDeclineThreshold = 18,\n RotateImage = false,\n SaveApiRequest = true,\n VendorData = \"user-123\",\n Metadata = new Dictionary { [\"flow\"] = \"age-gate\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -8525,7 +8976,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any document processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any document processing happens.", "content": { "application/json": { "examples": { @@ -8583,12 +9034,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = 'https://verification.didit.me/v3/poa/'\nheaders = {'x-api-key': 'YOUR_API_KEY'}\n\nwith open('utility-bill.pdf', 'rb') as f:\n files = {'document': ('utility-bill.pdf', f, 'application/pdf')}\n data = {\n 'expected_address': 'Av. Monseñor Tavella 1291, Salta, Argentina',\n 'expected_country': 'ARG',\n 'expected_first_name': 'Sophia',\n 'expected_last_name': 'Martinez',\n 'poa_languages_allowed': 'en,es',\n 'vendor_data': 'user-123',\n }\n # LLM-based extraction takes 5-15s (multi-page PDFs up to ~30s) - allow headroom\n resp = requests.post(url, headers=headers, files=files, data=data, timeout=45)\n\nresp.raise_for_status()\npoa = resp.json()['poa']\nprint('status:', poa['status'])\nprint('issuer:', poa['issuer'], '| issued:', poa['issue_date'])\nprint('address:', poa['poa_formatted_address'])\nfor w in poa['warnings']:\n print('warning:', w['risk'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.proof_of_address.verify(\n document=open(\"document.pdf\", \"rb\"),\n expected_address=\"Av. Monseñor Tavella 1291, Salta, Argentina\",\n expected_country=\"ARG\",\n expected_first_name=\"Sophia\",\n expected_last_name=\"Martinez\",\n poa_languages_allowed=\"en,es\",\n save_api_request=True,\n vendor_data=\"user-123\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import fs from 'node:fs';\n\nconst form = new FormData();\nform.append('document', new Blob([fs.readFileSync('./utility-bill.pdf')]), 'utility-bill.pdf');\nform.append('expected_address', 'Av. Monseñor Tavella 1291, Salta, Argentina');\nform.append('expected_country', 'ARG');\nform.append('expected_first_name', 'Sophia');\nform.append('expected_last_name', 'Martinez');\nform.append('poa_languages_allowed', 'en,es');\nform.append('vendor_data', 'user-123');\n\n// LLM-based extraction takes 5-15s (multi-page PDFs up to ~30s) - allow >=45s\nconst response = await fetch('https://verification.didit.me/v3/poa/', {\n method: 'POST',\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n body: form,\n signal: AbortSignal.timeout(45_000),\n});\n\nif (!response.ok) throw new Error(`POA verification failed: ${response.status}`);\nconst { poa } = await response.json();\nconsole.log('status:', poa.status);\nconsole.log('warnings:', poa.warnings.map((w) => w.risk));" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.proofOfAddress.verify({\n document: await fileFromPath(\"document.pdf\"),\n expected_address: \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n expected_country: \"ARG\",\n expected_first_name: \"Sophia\",\n expected_last_name: \"Martinez\",\n poa_languages_allowed: \"en,es\",\n save_api_request: true,\n vendor_data: \"user-123\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.ProofOfAddress.Verify(ctx, didit.ProofOfAddressVerifyParams{\n\tDocument: didit.FileFromPath(\"document.pdf\"),\n\tExpectedAddress: didit.String(\"Av. Monseñor Tavella 1291, Salta, Argentina\"),\n\tExpectedCountry: didit.String(\"ARG\"),\n\tExpectedFirstName: didit.String(\"Sophia\"),\n\tExpectedLastName: didit.String(\"Martinez\"),\n\tPOALanguagesAllowed: didit.String(\"en,es\"),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData: didit.String(\"user-123\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.ProofOfAddressVerifyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.proofOfAddress().verify(ProofOfAddressVerifyParams.builder()\n .document(Path.of(\"document.pdf\"))\n .expectedAddress(\"Av. Monseñor Tavella 1291, Salta, Argentina\")\n .expectedCountry(\"ARG\")\n .expectedFirstName(\"Sophia\")\n .expectedLastName(\"Martinez\")\n .poaLanguagesAllowed(\"en,es\")\n .saveApiRequest(true)\n .vendorData(\"user-123\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "proofOfAddress->verify([\n 'document' => File::fromPath('document.pdf'),\n 'expected_address' => 'Av. Monseñor Tavella 1291, Salta, Argentina',\n 'expected_country' => 'ARG',\n 'expected_first_name' => 'Sophia',\n 'expected_last_name' => 'Martinez',\n 'poa_languages_allowed' => 'en,es',\n 'save_api_request' => true,\n 'vendor_data' => 'user-123',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.proof_of_address.verify(\n document: Pathname(\"document.pdf\"),\n expected_address: \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n expected_country: \"ARG\",\n expected_first_name: \"Sophia\",\n expected_last_name: \"Martinez\",\n poa_languages_allowed: \"en,es\",\n save_api_request: true,\n vendor_data: \"user-123\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.ProofOfAddress.VerifyAsync(new ProofOfAddressVerifyParams\n{\n Document = FileUpload.FromPath(\"document.pdf\"),\n ExpectedAddress = \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n ExpectedCountry = \"ARG\",\n ExpectedFirstName = \"Sophia\",\n ExpectedLastName = \"Martinez\",\n PoaLanguagesAllowed = \"en,es\",\n SaveApiRequest = true,\n VendorData = \"user-123\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -9206,7 +9682,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls — and contract-billed organizations whose rate card has no Document AI API entry — return `403` with `{\"error\": ...}` before any document processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls — and contract-billed organizations whose rate card has no Document AI API entry — return `403` with `{\"error\": ...}` before any document processing happens.", "content": { "application/json": { "examples": { @@ -9266,7 +9742,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.document_ai.analyze(\n document=open(\"document.pdf\", \"rb\"),\n fields=\"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.documentAi.analyze({\n document: await fileFromPath(\"document.pdf\"),\n fields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.DocumentAi.Analyze(ctx, didit.DocumentAiAnalyzeParams{\n\tDocument: didit.FileFromPath(\"document.pdf\"),\n\tFields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.DocumentAiAnalyzeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.documentAi().analyze(DocumentAiAnalyzeParams.builder()\n .document(Path.of(\"document.pdf\"))\n .fields(\"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "documentAi->analyze([\n 'document' => File::fromPath('document.pdf'),\n 'fields' => '[{\"key\": \"employer_name\", \"name\": \"Employer name\", \"instruction\": \"The employer or company issuing the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": false}, {\"key\": \"employee_name\", \"name\": \"Employee name\", \"instruction\": \"The full name of the employee as printed on the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": true}, {\"key\": \"net_pay\", \"name\": \"Net pay\", \"instruction\": \"The net amount paid to the employee for the period.\", \"type\": \"number\", \"required\": true, \"is_full_name\": false}, {\"key\": \"pay_date\", \"name\": \"Pay date\", \"instruction\": \"The payment date shown on the payslip.\", \"type\": \"date\", \"required\": false, \"is_full_name\": false}]',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.document_ai.analyze(\n document: Pathname(\"document.pdf\"),\n fields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.DocumentAi.AnalyzeAsync(new DocumentAiAnalyzeParams\n{\n Document = FileUpload.FromPath(\"document.pdf\"),\n Fields = \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/aml/": { @@ -9412,6 +9925,14 @@ "example": "decline_aml_hit" } } + }, + "example": { + "full_name": "Antonio Ejemplo Modelo", + "entity_type": "person", + "date_of_birth": "1972-02-29", + "nationality": "ES", + "include_adverse_media": false, + "vendor_data": "user-1234" } } } @@ -9425,12 +9946,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/aml/\",\n headers={\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": \"aml-user-1234-2026-08-20\",\n },\n json={\n \"full_name\": \"Antonio Ejemplo Modelo\",\n \"entity_type\": \"person\",\n \"date_of_birth\": \"1972-02-29\",\n \"nationality\": \"ES\",\n \"include_adverse_media\": False,\n \"vendor_data\": \"user-1234\",\n },\n timeout=60, # adverse media enrichment can add ~30s\n)\nresp.raise_for_status()\nprint(resp.json()[\"aml\"][\"status\"]) # Approved / In Review / Declined" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml.screen(\n full_name=\"Antonio Ejemplo Modelo\",\n entity_type=\"person\",\n date_of_birth=\"1972-02-29\",\n nationality=\"ES\",\n include_adverse_media=False,\n vendor_data=\"user-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/aml/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n 'Idempotency-Key': 'aml-user-1234-2026-08-20',\n },\n body: JSON.stringify({\n full_name: 'Antonio Ejemplo Modelo',\n entity_type: 'person',\n date_of_birth: '1972-02-29',\n nationality: 'ES',\n include_adverse_media: false,\n vendor_data: 'user-1234',\n }),\n});\nconst data = await res.json();\nconsole.log(data.aml.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.aml.screen({\n full_name: \"Antonio Ejemplo Modelo\",\n entity_type: \"person\",\n date_of_birth: \"1972-02-29\",\n nationality: \"ES\",\n include_adverse_media: false,\n vendor_data: \"user-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AML.Screen(ctx, didit.AMLScreenParams{\n\tFullName: \"Antonio Ejemplo Modelo\",\n\tEntityType: didit.Some(didit.AMLScreenParamsEntityType(\"person\")),\n\tDateOfBirth: didit.String(\"1972-02-29\"),\n\tNationality: didit.String(\"ES\"),\n\tIncludeAdverseMedia: didit.Bool(false),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport me.didit.Didit;\nimport me.didit.types.AmlScreenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.aml().screen(AmlScreenParams.builder()\n .fullName(\"Antonio Ejemplo Modelo\")\n .entityType(AmlScreenParams.EntityType.of(\"person\"))\n .dateOfBirth(LocalDate.parse(\"1972-02-29\"))\n .nationality(\"ES\")\n .includeAdverseMedia(false)\n .vendorData(\"user-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "aml->screen([\n 'full_name' => 'Antonio Ejemplo Modelo',\n 'entity_type' => 'person',\n 'date_of_birth' => '1972-02-29',\n 'nationality' => 'ES',\n 'include_adverse_media' => false,\n 'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml.screen(\n full_name: \"Antonio Ejemplo Modelo\",\n entity_type: \"person\",\n date_of_birth: \"1972-02-29\",\n nationality: \"ES\",\n include_adverse_media: false,\n vendor_data: \"user-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Aml.ScreenAsync(new AmlScreenParams\n{\n FullName = \"Antonio Ejemplo Modelo\",\n EntityType = new AmlScreenParamsEntityType(\"person\"),\n DateOfBirth = \"1972-02-29\",\n Nationality = \"ES\",\n IncludeAdverseMedia = false,\n VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -9479,7 +10025,7 @@ "id": { "type": "string", "nullable": true, - "description": "Stable identifier of the matched entity in the screening datasets." + "description": "Didit's stable identifier for the hit: `hit_` followed by 24 hexadecimal characters. The same matched entity keeps the same `id` when the subject is screened again. Pass it as `hit_id` to the AML hit review endpoints." }, "url": { "type": "string", @@ -9519,9 +10065,24 @@ "type": "array", "nullable": true, "items": { - "type": "string" + "type": "string", + "enum": [ + "PEP", + "PEP Level 1", + "PEP Level 2", + "PEP Level 3", + "PEP Level 4", + "Sanctions", + "Adverse Media", + "Warnings and Regulatory Enforcement", + "Fitness and Probity", + "SIP", + "SIE", + "Insolvency", + "Other Lists" + ] }, - "description": "Datasets the entity appears in (e.g. `PEP`, `PEP Level 1`, sanctions list names)." + "description": "Risk categories the entity is listed under: `PEP` (with its level, `PEP Level 1` to `PEP Level 4`), `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`, `SIP`, `SIE` or `Insolvency`. `Other Lists` when the entity's source states none of these categories." }, "features": { "type": "object", @@ -9935,7 +10496,7 @@ "entity_type": "person", "hits": [ { - "id": "kDpfszrbkDdaxpMVZw3NLg", + "id": "hit_7c1e9a40b2d35f86e0a4c912", "url": "https://news.example.org/articles/sample", "match": false, "score": 0.93, @@ -10134,7 +10695,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", "content": { "application/json": { "examples": { @@ -10714,7 +11275,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", "content": { "application/json": { "examples": { @@ -10772,12 +11333,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = 'https://verification.didit.me/v3/face-search/'\nheaders = {'x-api-key': 'YOUR_API_KEY'}\n\nwith open('selfie.jpg', 'rb') as f:\n files = {'user_image': ('selfie.jpg', f, 'image/jpeg')}\n data = {\n 'search_type': 'most_similar',\n 'save_api_request': 'true',\n 'vendor_data': 'user-123',\n }\n resp = requests.post(url, headers=headers, files=files, data=data, timeout=60)\n\nresp.raise_for_status()\nbody = resp.json()\nprint('status:', body['face_search']['status'])\nprint('matches:', body['face_search']['total_matches'])\nfor m in body['face_search']['matches']:\n print(f\" session={m['session_id']} similarity={m['similarity_percentage']} blocklisted={m['is_blocklisted']}\")" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.face_search.search(\n user_image=open(\"user_image.jpg\", \"rb\"),\n search_type=\"most_similar\",\n rotate_image=False,\n save_api_request=True,\n vendor_data=\"user-123\",\n metadata={\"flow\": \"dedup_check\"},\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import fs from 'node:fs';\n\nconst form = new FormData();\nform.append('user_image', new Blob([fs.readFileSync('./selfie.jpg')]), 'selfie.jpg');\nform.append('search_type', 'most_similar');\nform.append('save_api_request', 'true');\nform.append('vendor_data', 'user-123');\n\nconst response = await fetch('https://verification.didit.me/v3/face-search/', {\n method: 'POST',\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n body: form,\n});\n\nif (!response.ok) throw new Error(`Face search failed: ${response.status}`);\nconst body = await response.json();\nconsole.log('status:', body.face_search.status, 'matches:', body.face_search.total_matches);\nbody.face_search.matches.forEach(m =>\n console.log(` session=${m.session_id} similarity=${m.similarity_percentage} blocklisted=${m.is_blocklisted}`)\n);" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.faceSearch.search({\n user_image: await fileFromPath(\"user_image.jpg\"),\n search_type: \"most_similar\",\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"dedup_check\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FaceSearch.Search(ctx, didit.FaceSearchSearchParams{\n\tUserImage: didit.FileFromPath(\"user_image.jpg\"),\n\tSearchType: didit.Some(didit.FaceSearchSearchParamsSearchType(\"most_similar\")),\n\tRotateImage: didit.Bool(false),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData: didit.String(\"user-123\"),\n\tMetadata: didit.Some(map[string]any{\"flow\": \"dedup_check\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.FaceSearchSearchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.faceSearch().search(FaceSearchSearchParams.builder()\n .userImage(Path.of(\"user_image.jpg\"))\n .searchType(FaceSearchSearchParams.SearchType.of(\"most_similar\"))\n .rotateImage(false)\n .saveApiRequest(true)\n .vendorData(\"user-123\")\n .metadata(Map.of(\"flow\", \"dedup_check\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "faceSearch->search([\n 'user_image' => File::fromPath('user_image.jpg'),\n 'search_type' => 'most_similar',\n 'rotate_image' => false,\n 'save_api_request' => true,\n 'vendor_data' => 'user-123',\n 'metadata' => ['flow' => 'dedup_check'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.face_search.search(\n user_image: Pathname(\"user_image.jpg\"),\n search_type: \"most_similar\",\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"dedup_check\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FaceSearch.SearchAsync(new FaceSearchSearchParams\n{\n UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n SearchType = new FaceSearchSearchParamsSearchType(\"most_similar\"),\n RotateImage = false,\n SaveApiRequest = true,\n VendorData = \"user-123\",\n Metadata = new Dictionary { [\"flow\"] = \"dedup_check\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -10821,7 +11407,8 @@ "schema": { "type": "integer", "default": 50, - "minimum": 1 + "minimum": 1, + "maximum": 1000000 }, "example": 20 }, @@ -10833,7 +11420,8 @@ "schema": { "type": "integer", "default": 0, - "minimum": 0 + "minimum": 0, + "maximum": 1000000 }, "example": 20 }, @@ -10899,6 +11487,35 @@ }, "example": "2026-06-30" }, + { + "name": "tags", + "in": "query", + "required": false, + "schema": { + "type": "string" + }, + "description": "Comma-separated tag ids (`tags` of your application). Returns the sessions that carry any of them. Ids that are not valid UUIDs are ignored, and when none is valid the list is empty." + }, + { + "name": "decided_from", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "ISO 8601 datetime. Returns the sessions whose status last changed at or after it. It filters on the time of the last status change, not on creation time." + }, + { + "name": "decided_to", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + }, + "description": "ISO 8601 datetime. Returns the sessions whose status last changed before it. Combine with `decided_from` for a half-open window." + }, { "name": "country", "in": "query", @@ -11061,7 +11678,7 @@ "properties": { "count": { "type": "integer", - "description": "Number of sessions matching the filters. Exact for KYC rows; for KYB rows it is capped at 100 (use `next` to know whether more pages exist). For `session_kind=all` it is the sum of both kinds.", + "description": "Number of sessions matching the filters: exact up to 100 and capped at 100 beyond that, so do not use it as a total. Use `next` to know whether more pages exist. For `session_kind=all` it is the sum of both kinds, each capped at 100.", "example": 2 }, "next": { @@ -11312,7 +11929,7 @@ } }, "403": { - "description": "Missing, malformed, or revoked API key. This API never returns `401`; all authentication failures are `403`.\n\n**Deleted application:** for a few minutes after an application is deleted, a request made with one of its API keys can answer `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`. Do not retry: the application and its API keys no longer exist. After those few minutes, the key is refused like any other invalid key.", + "description": "Missing, malformed, or revoked API key. A missing key returns `403`; a wrong, revoked or expired key returns `401`.\n\n**Deleted application:** for a few minutes after an application is deleted, a request made with one of its API keys can answer `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`. Do not retry: the application and its API keys no longer exist. After those few minutes, the key is refused like any other invalid key.", "content": { "application/json": { "schema": { @@ -11365,12 +11982,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = \"https://verification.didit.me/v3/sessions/\"\nheaders = {\"x-api-key\": \"YOUR_API_KEY\"}\nparams = {\n \"session_kind\": \"user\", # \"user\" (default) | \"business\" | \"all\"\n \"status\": \"Approved,In Review\", # comma-separated, OR within the list\n \"date_from\": \"2026-06-01\",\n \"limit\": 20,\n}\n\nwhile url:\n response = requests.get(url, headers=headers, params=params)\n response.raise_for_status()\n page = response.json()\n for session in page[\"results\"]:\n print(session[\"session_kind\"], session[\"session_id\"], session[\"status\"])\n url, params = page[\"next\"], None # \"next\" already carries the query string" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const params = new URLSearchParams({\n session_kind: 'all',\n status: 'Approved,In Review',\n date_from: '2026-06-01',\n limit: '20',\n});\n\nconst response = await fetch(\n `https://verification.didit.me/v3/sessions/?${params}`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\n\nconst { count, next, results } = await response.json();\nfor (const session of results) {\n // session.session_kind is \"user\" (KYC) or \"business\" (KYB)\n console.log(session.session_kind, session.session_id, session.status);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListAutoPaging(ctx, didit.SessionsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->list() as $item) {\n print_r($item);\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] } @@ -11586,12 +12228,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/share/\",\n headers={\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n json={\n \"for_application_id\": \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n \"ttl_in_seconds\": 7200,\n },\n)\nresponse.raise_for_status()\nshare_token = response.json()[\"share_token\"]" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.share(\n \"11111111-2222-3333-4444-555555555555\",\n for_application_id=\"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n ttl_in_seconds=7200,\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/share/',\n {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n for_application_id: 'a5f3bca2-46e2-411e-90ef-a580900a57ee',\n ttl_in_seconds: 7200,\n }),\n },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst { share_token } = await response.json();" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.share(\"11111111-2222-3333-4444-555555555555\", {\n for_application_id: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n ttl_in_seconds: 7200,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Share(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsShareParams{\n\tForApplicationID: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n\tTTLInSeconds: didit.Int(7200),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsShareParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().share(\"11111111-2222-3333-4444-555555555555\", SessionsShareParams.builder()\n .forApplicationId(\"a5f3bca2-46e2-411e-90ef-a580900a57ee\")\n .ttlInSeconds(7200L)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->share('11111111-2222-3333-4444-555555555555', [\n 'for_application_id' => 'a5f3bca2-46e2-411e-90ef-a580900a57ee',\n 'ttl_in_seconds' => 7200,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.share(\n \"11111111-2222-3333-4444-555555555555\",\n for_application_id: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n ttl_in_seconds: 7200\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ShareAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsShareParams\n{\n ForApplicationId = \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n TtlInSeconds = 7200,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -11693,7 +12360,7 @@ } }, "403": { - "description": "Missing/invalid API key (this endpoint returns `403`, never `401`, for authentication failures), or this source session has already been imported into the calling application (one redeem per receiver).", + "description": "Missing API key (a wrong, revoked or expired key gets `401`), or this source session has already been imported into the calling application (one redeem per receiver).", "content": { "application/json": { "examples": { @@ -11788,12 +12455,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/session/import-shared/\",\n headers={\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n json={\n \"share_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"trust_review\": False,\n \"workflow_id\": \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n \"vendor_data\": \"user-1\",\n },\n)\nresponse.raise_for_status()\nimported = response.json()" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.import_shared(\n share_token=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n trust_review=False,\n workflow_id=\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n vendor_data=\"user-1\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/session/import-shared/',\n {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n share_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',\n trust_review: false,\n workflow_id: '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n vendor_data: 'user-1',\n }),\n },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst imported = await response.json();" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.importShared({\n share_token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n trust_review: false,\n workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n vendor_data: \"user-1\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ImportShared(ctx, didit.SessionsImportSharedParams{\n\tShareToken: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n\tTrustReview: false,\n\tWorkflowID: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n\tVendorData: didit.String(\"user-1\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsImportSharedParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().importShared(SessionsImportSharedParams.builder()\n .shareToken(\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\")\n .trustReview(false)\n .workflowId(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\")\n .vendorData(\"user-1\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->importShared([\n 'share_token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',\n 'trust_review' => false,\n 'workflow_id' => '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n 'vendor_data' => 'user-1',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.import_shared(\n share_token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n trust_review: false,\n workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n vendor_data: \"user-1\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ImportSharedAsync(new SessionsImportSharedParams\n{\n ShareToken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n TrustReview = false,\n WorkflowId = \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n VendorData = \"user-1\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -11880,6 +12572,12 @@ "description": "Switches the search to asynchronous mode: the API returns immediately and POSTs an unsigned `kyb.registry_search.resolved` callback to this URL when the candidate list is ready." } } + }, + "example": { + "country_code": "GB", + "name": "Tesco", + "search_type": "contains", + "vendor_data": "company-1234" } } } @@ -11893,12 +12591,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/kyb/search/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"country_code\": \"GB\", \"name\": \"Tesco\"},\n timeout=60, # synchronous mode waits for the registry to resolve\n)\nresp.raise_for_status()\ncandidates = resp.json()[\"kyb_registry\"][\"companies\"]\nkyb_response_id = candidates[0][\"kyb_response_id\"] # pass to /v3/kyb/select/" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.search(\n country_code=\"GB\",\n name=\"Tesco\",\n search_type=\"contains\",\n vendor_data=\"company-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/kyb/search/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ country_code: 'GB', name: 'Tesco' }),\n});\nconst data = await res.json();\nconst kybResponseId = data.kyb_registry.companies[0].kyb_response_id;" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.search({\n country_code: \"GB\",\n name: \"Tesco\",\n search_type: \"contains\",\n vendor_data: \"company-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Search(ctx, didit.KYBSearchParams{\n\tCountryCode: \"GB\",\n\tName: didit.String(\"Tesco\"),\n\tSearchType: didit.Some(didit.KYBSearchParamsSearchType(\"contains\")),\n\tVendorData: didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.KybSearchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().search(KybSearchParams.builder()\n .countryCode(\"GB\")\n .name(\"Tesco\")\n .searchType(KybSearchParams.SearchType.of(\"contains\"))\n .vendorData(\"company-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "kyb->search([\n 'country_code' => 'GB',\n 'name' => 'Tesco',\n 'search_type' => 'contains',\n 'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.search(\n country_code: \"GB\",\n name: \"Tesco\",\n search_type: \"contains\",\n vendor_data: \"company-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.SearchAsync(new KybSearchParams\n{\n CountryCode = \"GB\",\n Name = \"Tesco\",\n SearchType = new KybSearchParamsSearchType(\"contains\"),\n VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -11998,7 +12721,7 @@ } }, "400": { - "description": "Validation error. Field-level problems use DRF's standard envelope; the name/registration-number rule reports under `non_field_errors`.", + "description": "Validation error. Field-level problems use DRF's standard envelope; the name/registration-number rule reports under `non_field_errors`. A country the registries do not cover answers `400` with `code: kyb_registry_country_unsupported`.", "content": { "application/json": { "examples": { @@ -12033,13 +12756,20 @@ "Enter a valid URL." ] } + }, + "Country not covered": { + "summary": "No company registry covers the country", + "value": { + "detail": "Company registry search is not available for this country. Enter the company details manually to continue.", + "code": "kyb_registry_country_unsupported" + } } } } } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Also returned before searching when the applicable search fee cannot be covered (`code: \"insufficient_credits\"`), or when a contract search rate is missing.", + "description": "Permission denied. Returned when the `x-api-key` header is missing; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Also returned before searching when the applicable search fee cannot be covered (`code: \"insufficient_credits\"`), or when a contract search rate is missing.", "content": { "application/json": { "examples": { @@ -12054,7 +12784,7 @@ } }, "429": { - "description": "Rate limit exceeded. All POST/PATCH/DELETE endpoints share a budget of 300 write requests per minute per API key. The response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and `Retry-After` headers.", + "description": "Rate limit exceeded, or the search allowance is spent. All POST/PATCH/DELETE endpoints share a budget of 300 write requests per minute per API key, with `X-RateLimit-*` and `Retry-After` headers. Separately, paid registry searches are limited to 600 per application per hour: past that the response is `429` with `code: kyb_registry_search_limit_reached`, and searches served only by free sources still work. Wait and search again later.", "content": { "application/json": { "examples": { @@ -12063,6 +12793,13 @@ "value": { "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute." } + }, + "Search allowance spent": { + "summary": "More than 600 paid searches in the last hour", + "value": { + "detail": "The maximum number of company registry searches for this session has been reached. Enter the company details manually to continue.", + "code": "kyb_registry_search_limit_reached" + } } }, "schema": { @@ -12070,6 +12807,9 @@ "properties": { "detail": { "type": "string" + }, + "code": { + "type": "string" } } } @@ -12132,6 +12872,10 @@ "application/json": { "schema": { "$ref": "#/components/schemas/KYBRegistryCandidateRequest" + }, + "example": { + "kyb_response_id": "69aeeb95febb0f1704042259", + "vendor_data": "company-1234" } } } @@ -12145,12 +12889,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nsearch = requests.post(\n \"https://verification.didit.me/v3/kyb/search/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"country_code\": \"GB\", \"name\": \"Tesco\"},\n timeout=60,\n).json()\nkyb_response_id = search[\"kyb_registry\"][\"companies\"][0][\"kyb_response_id\"]\n\nresp = requests.post(\n \"https://verification.didit.me/v3/kyb/select/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"kyb_response_id\": kyb_response_id, \"vendor_data\": \"company-1234\"},\n timeout=90, # waits for the registry to resolve the full profile\n)\nresp.raise_for_status()\ncompany = resp.json()[\"kyb_registry\"]\nprint(company[\"company_name\"], company[\"registry_status\"], company[\"status\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.select(\n kyb_response_id=\"69aeeb95febb0f1704042259\",\n vendor_data=\"company-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/kyb/select/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n kyb_response_id: '69aeeb95febb0f1704042259',\n vendor_data: 'company-1234',\n }),\n});\nconst data = await res.json();\nconsole.log(data.kyb_registry.company_name, data.kyb_registry.registry_status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.select({\n kyb_response_id: \"69aeeb95febb0f1704042259\",\n vendor_data: \"company-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Select(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData: didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().select(KYBRegistryCandidateRequest.builder()\n .kybResponseId(\"69aeeb95febb0f1704042259\")\n .vendorData(\"company-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "kyb->select([\n 'kyb_response_id' => '69aeeb95febb0f1704042259',\n 'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.select(\n kyb_response_id: \"69aeeb95febb0f1704042259\",\n vendor_data: \"company-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.SelectAsync(new KYBRegistryCandidateRequest\n{\n KybResponseId = \"69aeeb95febb0f1704042259\",\n VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -12656,8 +13425,7 @@ "description": "Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts." }, "registry_data": { - "type": "object", - "description": "Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead." + "$ref": "#/components/schemas/KYBRegistryData" }, "user_provided_data": { "type": "object", @@ -12707,6 +13475,55 @@ "type": "string", "nullable": true, "description": "The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`." + }, + "registry_monitoring": { + "type": "object", + "nullable": true, + "description": "The latest registry monitor for the company, or `null` when none exists.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string" + }, + "unavailable_reason": { + "type": "string", + "nullable": true + }, + "enrolled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "cancelled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "last_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "next_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "last_event_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "events_count": { + "type": "integer" + }, + "watched_fields": { + "description": "The company fields the monitor watches." + } + } } } }, @@ -12802,24 +13619,7 @@ "next_account": "26 February 2026", "due_by_date": "26 August 2026" }, - "registry_data": { - "name": "Tesco PLC", - "registration_number": "00445790", - "status": "active", - "type": "Public Limited Company", - "incorporation_date": "1947-11-27", - "tax_number": "GB412 8925 93", - "country_code": "GB", - "fetch_status": "resolved", - "industries_detail": [ - { - "code": "47110", - "name": "Retail Sale In Non-specialised Stores With Food, Beverages Or Tobacco Predominating", - "description": null, - "meta_detail": [] - } - ] - }, + "registry_data": {}, "user_provided_data": null, "confirmed_by_user_at": null, "last_console_edit_at": null, @@ -12884,7 +13684,7 @@ } }, "400": { - "description": "Validation error. Field-level problems use DRF's standard envelope.", + "description": "Validation error. Field-level problems use DRF's standard envelope. A country the registries do not cover answers `400` with `code: kyb_registry_country_unsupported`.", "content": { "application/json": { "examples": { @@ -12903,13 +13703,20 @@ "KYB registry select must be saved so billing and retrieval can be tracked." ] } + }, + "Country not covered": { + "summary": "No company registry covers the country", + "value": { + "detail": "Company registry search is not available for this country. Enter the company details manually to continue.", + "code": "kyb_registry_country_unsupported" + } } } } } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", "content": { "application/json": { "examples": { @@ -13404,7 +14211,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any image processing happens.", "content": { "application/json": { "examples": { @@ -13462,12 +14269,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nurl = 'https://verification.didit.me/v3/passive-liveness/'\nheaders = {'x-api-key': 'YOUR_API_KEY'}\n\nwith open('selfie.jpg', 'rb') as f:\n files = {'user_image': ('selfie.jpg', f, 'image/jpeg')}\n data = {\n 'face_liveness_score_decline_threshold': 30,\n 'save_api_request': 'true',\n 'vendor_data': 'user-123',\n }\n resp = requests.post(url, headers=headers, files=files, data=data, timeout=60)\n\nresp.raise_for_status()\nbody = resp.json()\nprint('status:', body['liveness']['status'])\nprint('score:', body['liveness']['score'])\nfor w in body['liveness']['warnings']:\n print('warning:', w['risk'], '-', w['log_type'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.passive_liveness.check(\n user_image=open(\"user_image.jpg\", \"rb\"),\n face_liveness_score_decline_threshold=30.0,\n rotate_image=False,\n save_api_request=True,\n vendor_data=\"user-123\",\n metadata={\"flow\": \"withdrawal\"},\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import fs from 'node:fs';\n\nconst form = new FormData();\nform.append('user_image', new Blob([fs.readFileSync('./selfie.jpg')]), 'selfie.jpg');\nform.append('face_liveness_score_decline_threshold', '30');\nform.append('save_api_request', 'true');\nform.append('vendor_data', 'user-123');\n\nconst response = await fetch('https://verification.didit.me/v3/passive-liveness/', {\n method: 'POST',\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n body: form,\n});\n\nif (!response.ok) throw new Error(`Passive liveness failed: ${response.status}`);\nconst body = await response.json();\nconsole.log('status:', body.liveness.status, 'score:', body.liveness.score);\nbody.liveness.warnings.forEach(w => console.log('warning:', w.risk, '-', w.log_type));" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.passiveLiveness.check({\n user_image: await fileFromPath(\"user_image.jpg\"),\n face_liveness_score_decline_threshold: 30.0,\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"withdrawal\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.PassiveLiveness.Check(ctx, didit.PassiveLivenessCheckParams{\n\tUserImage: didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tRotateImage: didit.Bool(false),\n\tSaveAPIRequest: didit.Bool(true),\n\tVendorData: didit.String(\"user-123\"),\n\tMetadata: didit.Some(map[string]any{\"flow\": \"withdrawal\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.PassiveLivenessCheckParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.passiveLiveness().check(PassiveLivenessCheckParams.builder()\n .userImage(Path.of(\"user_image.jpg\"))\n .faceLivenessScoreDeclineThreshold(30.0)\n .rotateImage(false)\n .saveApiRequest(true)\n .vendorData(\"user-123\")\n .metadata(Map.of(\"flow\", \"withdrawal\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "passiveLiveness->check([\n 'user_image' => File::fromPath('user_image.jpg'),\n 'face_liveness_score_decline_threshold' => 30.0,\n 'rotate_image' => false,\n 'save_api_request' => true,\n 'vendor_data' => 'user-123',\n 'metadata' => ['flow' => 'withdrawal'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.passive_liveness.check(\n user_image: Pathname(\"user_image.jpg\"),\n face_liveness_score_decline_threshold: 30.0,\n rotate_image: false,\n save_api_request: true,\n vendor_data: \"user-123\",\n metadata: { flow: \"withdrawal\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.PassiveLiveness.CheckAsync(new PassiveLivenessCheckParams\n{\n UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n FaceLivenessScoreDeclineThreshold = 30.0,\n RotateImage = false,\n SaveApiRequest = true,\n VendorData = \"user-123\",\n Metadata = new Dictionary { [\"flow\"] = \"withdrawal\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -13789,6 +14621,70 @@ "type": "string", "description": "Bank card number (CHN bank-card verification)." }, + "company_registration_number": { + "type": "string", + "description": "Company registration number as issued by the companies register: the CNPJ in Brazil (e.g. `11222333000181`), the registration number in South Africa (e.g. `1936/007721/06`). Required by the company registry and company directors services (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`)." + }, + "company_name": { + "type": "string", + "description": "Registered company name, cross-checked against the register entry. Optional for `zaf_company_registry`." + }, + "initials": { + "type": "string", + "description": "The person's initials as printed on the document. Required by `zaf_drivers_license`; accepted by `zaf_bank_account_holder`." + }, + "licence_number": { + "type": "string", + "description": "Driving licence number as printed on the card, for `zaf_drivers_license`. When omitted, `document_number` is used." + }, + "refugee_file_number": { + "type": "string", + "description": "Refugee file number issued by South Africa's Department of Home Affairs. Required by `zaf_refugee`." + }, + "bank_name": { + "type": "string", + "description": "Name of the bank that holds the account. Required by `zaf_bank_account_holder`." + }, + "bank_account_number": { + "type": "string", + "description": "Bank account number. Required by `zaf_bank_account_holder`; accepted by `zaf_fraud_prevention`." + }, + "account_type": { + "type": "string", + "description": "Bank account type for `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare` or `notKnown`, case-insensitive. Any other value returns `400`. Omit it when you do not know the type: the account-type cross-check is then reported as not confirmed." + }, + "phone_number": { + "type": "string", + "description": "Contact mobile number, for the services that cross-check contactability (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`)." + }, + "right_thumb": { + "type": "string", + "description": "Base64-encoded right thumb fingerprint for `zaf_dha_fingerprint_match`, with `left_thumb` or on its own." + }, + "left_thumb": { + "type": "string", + "description": "Base64-encoded left thumb fingerprint for `zaf_dha_fingerprint_match`, with `right_thumb` or on its own." + }, + "score_level": { + "type": "integer", + "description": "Minimum biometric score level for `zaf_criminal_face_screening`. Defaults to `3`." + }, + "max_matches": { + "type": "integer", + "description": "Maximum number of candidate matches `zaf_criminal_face_screening` returns. Defaults to `1`." + }, + "vehicle_register_number": { + "type": "string", + "description": "Vehicle register number. Required, with `vehicle_licence_plate` and `vin`, by `zaf_vehicle_ownership`." + }, + "vehicle_licence_plate": { + "type": "string", + "description": "Vehicle licence plate number. Required, with `vehicle_register_number` and `vin`, by `zaf_vehicle_ownership`." + }, + "vin": { + "type": "string", + "description": "Vehicle Identification Number (VIN or chassis number). Required, with `vehicle_register_number` and `vehicle_licence_plate`, by `zaf_vehicle_ownership`." + }, "ssn": { "type": "string", "description": "Social Security Number (USA)." @@ -13844,6 +14740,17 @@ "description": "Free-form JSON stored with the request and echoed back." } } + }, + "example": { + "issuing_state": "BRA", + "services": [ + "bra_cpf" + ], + "identification_number": "12345678900", + "first_name": "John", + "last_name": "Doe", + "date_of_birth": "1980-01-01", + "vendor_data": "user-1234" } }, "multipart/form-data": { @@ -14140,6 +15047,70 @@ "type": "string", "description": "Bank card number (CHN bank-card verification)." }, + "company_registration_number": { + "type": "string", + "description": "Company registration number as issued by the companies register: the CNPJ in Brazil (e.g. `11222333000181`), the registration number in South Africa (e.g. `1936/007721/06`). Required by the company registry and company directors services (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`)." + }, + "company_name": { + "type": "string", + "description": "Registered company name, cross-checked against the register entry. Optional for `zaf_company_registry`." + }, + "initials": { + "type": "string", + "description": "The person's initials as printed on the document. Required by `zaf_drivers_license`; accepted by `zaf_bank_account_holder`." + }, + "licence_number": { + "type": "string", + "description": "Driving licence number as printed on the card, for `zaf_drivers_license`. When omitted, `document_number` is used." + }, + "refugee_file_number": { + "type": "string", + "description": "Refugee file number issued by South Africa's Department of Home Affairs. Required by `zaf_refugee`." + }, + "bank_name": { + "type": "string", + "description": "Name of the bank that holds the account. Required by `zaf_bank_account_holder`." + }, + "bank_account_number": { + "type": "string", + "description": "Bank account number. Required by `zaf_bank_account_holder`; accepted by `zaf_fraud_prevention`." + }, + "account_type": { + "type": "string", + "description": "Bank account type for `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare` or `notKnown`, case-insensitive. Any other value returns `400`. Omit it when you do not know the type: the account-type cross-check is then reported as not confirmed." + }, + "phone_number": { + "type": "string", + "description": "Contact mobile number, for the services that cross-check contactability (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`)." + }, + "right_thumb": { + "type": "string", + "description": "Base64-encoded right thumb fingerprint for `zaf_dha_fingerprint_match`, with `left_thumb` or on its own." + }, + "left_thumb": { + "type": "string", + "description": "Base64-encoded left thumb fingerprint for `zaf_dha_fingerprint_match`, with `right_thumb` or on its own." + }, + "score_level": { + "type": "integer", + "description": "Minimum biometric score level for `zaf_criminal_face_screening`. Defaults to `3`." + }, + "max_matches": { + "type": "integer", + "description": "Maximum number of candidate matches `zaf_criminal_face_screening` returns. Defaults to `1`." + }, + "vehicle_register_number": { + "type": "string", + "description": "Vehicle register number. Required, with `vehicle_licence_plate` and `vin`, by `zaf_vehicle_ownership`." + }, + "vehicle_licence_plate": { + "type": "string", + "description": "Vehicle licence plate number. Required, with `vehicle_register_number` and `vin`, by `zaf_vehicle_ownership`." + }, + "vin": { + "type": "string", + "description": "Vehicle Identification Number (VIN or chassis number). Required, with `vehicle_register_number` and `vehicle_licence_plate`, by `zaf_vehicle_ownership`." + }, "ssn": { "type": "string", "description": "Social Security Number (USA)." @@ -14213,12 +15184,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/database-validation/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\n \"issuing_state\": \"BRA\",\n \"services\": [\"bra_cpf\"],\n \"identification_number\": \"12345678900\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"date_of_birth\": \"1980-01-01\",\n \"vendor_data\": \"user-1234\",\n },\n timeout=45,\n)\nresp.raise_for_status()\ndv = resp.json()[\"database_validation\"]\nprint(dv[\"status\"], dv[\"match_type\"]) # e.g. Approved full_match\n\n# Biometric services need a selfie via multipart/form-data:\n# requests.post(..., data={\"issuing_state\": \"ARG\", \"services\": '[\"arg_renaper\"]',\n# \"identification_number\": \"12345678\", \"gender\": \"M\", ...},\n# files={\"selfie\": open(\"selfie.jpg\", \"rb\")})" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.database_validation.validate(\n issuing_state=\"BRA\",\n services=[\"bra_cpf\"],\n identification_number=\"12345678900\",\n first_name=\"John\",\n last_name=\"Doe\",\n date_of_birth=\"1980-01-01\",\n vendor_data=\"user-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/database-validation/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n issuing_state: 'BRA',\n services: ['bra_cpf'],\n identification_number: '12345678900',\n first_name: 'John',\n last_name: 'Doe',\n date_of_birth: '1980-01-01',\n vendor_data: 'user-1234',\n }),\n});\nconst data = await res.json();\nconsole.log(data.database_validation.status, data.database_validation.match_type);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.databaseValidation.validate({\n issuing_state: \"BRA\",\n services: [\"bra_cpf\"],\n identification_number: \"12345678900\",\n first_name: \"John\",\n last_name: \"Doe\",\n date_of_birth: \"1980-01-01\",\n vendor_data: \"user-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.DatabaseValidation.Validate(ctx, didit.DatabaseValidationValidateParams{\n\tIssuingState: \"BRA\",\n\tServices: didit.Some([]string{\"bra_cpf\"}),\n\tIdentificationNumber: didit.String(\"12345678900\"),\n\tFirstName: didit.String(\"John\"),\n\tLastName: didit.String(\"Doe\"),\n\tDateOfBirth: didit.String(\"1980-01-01\"),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.DatabaseValidationValidateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.databaseValidation().validate(DatabaseValidationValidateParams.builder()\n .issuingState(\"BRA\")\n .services(List.of(\"bra_cpf\"))\n .identificationNumber(\"12345678900\")\n .firstName(\"John\")\n .lastName(\"Doe\")\n .dateOfBirth(LocalDate.parse(\"1980-01-01\"))\n .vendorData(\"user-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "databaseValidation->validate([\n 'issuing_state' => 'BRA',\n 'services' => ['bra_cpf'],\n 'identification_number' => '12345678900',\n 'first_name' => 'John',\n 'last_name' => 'Doe',\n 'date_of_birth' => '1980-01-01',\n 'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.database_validation.validate(\n issuing_state: \"BRA\",\n services: [\"bra_cpf\"],\n identification_number: \"12345678900\",\n first_name: \"John\",\n last_name: \"Doe\",\n date_of_birth: \"1980-01-01\",\n vendor_data: \"user-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.DatabaseValidation.ValidateAsync(new DatabaseValidationValidateParams\n{\n IssuingState = \"BRA\",\n Services = new string[] { \"bra_cpf\" },\n IdentificationNumber = \"12345678900\",\n FirstName = \"John\",\n LastName = \"Doe\",\n DateOfBirth = \"1980-01-01\",\n VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -14761,7 +15757,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", "content": { "application/json": { "examples": { @@ -14882,12 +15878,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/phone/send/\",\n headers={\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Content-Type\": \"application/json\",\n },\n json={\n \"phone_number\": \"+14155552671\",\n \"options\": {\n \"code_size\": 6,\n \"preferred_channel\": \"whatsapp\",\n \"locale\": \"en-US\",\n },\n \"vendor_data\": \"user-1234\",\n },\n timeout=15,\n)\nresp.raise_for_status()\nprint(resp.json()) # {request_id, status, reason, vendor_data, metadata}\n# Then verify with POST /v3/phone/check/ using the same phone_number" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.send_code(\n phone_number=\"+14155552671\",\n options={\n \"locale\": \"en-US\",\n \"preferred_channel\": \"whatsapp\",\n },\n vendor_data=\"user-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/phone/send/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n phone_number: '+14155552671',\n options: { code_size: 6, preferred_channel: 'whatsapp', locale: 'en-US' },\n vendor_data: 'user-1234',\n }),\n});\nif (!res.ok) throw new Error(`Phone send failed: ${res.status}`);\nconst data = await res.json();\nconsole.log(data); // { request_id, status, reason, vendor_data, metadata }\n// Then verify with POST /v3/phone/check/ using the same phone_number" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.sendCode({\n phone_number: \"+14155552671\",\n options: {\n locale: \"en-US\",\n preferred_channel: \"whatsapp\",\n },\n vendor_data: \"user-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.SendCode(ctx, didit.PhoneSendCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tOptions: didit.Some(didit.PhoneSendCodeParamsOptions{\n\t\tLocale: didit.String(\"en-US\"),\n\t\tPreferredChannel: didit.Some(didit.PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.PhoneSendCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().sendCode(PhoneSendCodeParams.builder()\n .phoneNumber(\"+14155552671\")\n .options(PhoneSendCodeParams.Options.builder()\n .locale(\"en-US\")\n .preferredChannel(PhoneSendCodeParams.Options.PreferredChannel.of(\"whatsapp\"))\n .build())\n .vendorData(\"user-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "phone->sendCode([\n 'phone_number' => '+14155552671',\n 'options' => [\n 'locale' => 'en-US',\n 'preferred_channel' => 'whatsapp',\n ],\n 'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.send_code(\n phone_number: \"+14155552671\",\n options: {\n locale: \"en-US\",\n preferred_channel: \"whatsapp\",\n },\n vendor_data: \"user-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.SendCodeAsync(new PhoneSendCodeParams\n{\n PhoneNumber = \"+14155552671\",\n Options = new PhoneSendCodeParamsOptions\n {\n Locale = \"en-US\",\n PreferredChannel = new PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\"),\n },\n VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -15155,7 +16176,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment (`{\"detail\": ...}`) — this API never returns `401`. Also returned before any send when the organization has never topped up (anti-abuse gate) or when its balance cannot cover the destination's send price (`{\"error\": ...}`).", + "description": "Permission denied. Returned when the `x-api-key` header is missing (`{\"detail\": ...}`); a wrong, revoked or expired key returns `401`. Also returned before any send when the organization has never topped up (anti-abuse gate) or when its balance cannot cover the destination's send price (`{\"error\": ...}`).", "content": { "application/json": { "examples": { @@ -15291,12 +16312,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/phone/check/\",\n headers={\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Content-Type\": \"application/json\",\n },\n json={\n \"phone_number\": \"+14155552671\", # same number as the send call\n \"code\": \"123456\",\n \"voip_number_action\": \"DECLINE\",\n },\n timeout=15,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result[\"status\"]) # Approved / Declined / Failed / Expired or Not Found\nif result[\"status\"] in (\"Approved\", \"Declined\"):\n print(result[\"phone\"][\"carrier\"], result[\"phone\"][\"is_virtual\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.check_code(\n phone_number=\"+14155552671\",\n code=\"123456\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/phone/check/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n phone_number: '+14155552671', // same number as the send call\n code: '123456',\n voip_number_action: 'DECLINE',\n }),\n});\nconst data = await res.json();\nif (data.status === 'Approved') {\n // full phone report is in data.phone (carrier, is_virtual, matches, ...)\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.checkCode({\n phone_number: \"+14155552671\",\n code: \"123456\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.CheckCode(ctx, didit.PhoneCheckCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tCode: \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.PhoneCheckCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().checkCode(PhoneCheckCodeParams.builder()\n .phoneNumber(\"+14155552671\")\n .code(\"123456\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "phone->checkCode([\n 'phone_number' => '+14155552671',\n 'code' => '123456',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.check_code(\n phone_number: \"+14155552671\",\n code: \"123456\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.CheckCodeAsync(new PhoneCheckCodeParams\n{\n PhoneNumber = \"+14155552671\",\n Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -15347,6 +16393,48 @@ "default": "NO_ACTION", "description": "What to do when the carrier lookup reports a virtual line type — `voip`, `isp`, or `vpn` (`phone.is_virtual`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings`." }, + "enable_enrichment": { + "type": "boolean", + "default": false, + "description": "When `true`, also run phone intelligence on the number: a risk score, the line type, whether it was recently ported and a trust index. Billed as one `phone_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it.", + "example": false + }, + "phone_intelligence_score_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the phone intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, + "phone_type_risk_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the number is a high-risk line type. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, + "recent_port_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the number was ported to another carrier recently. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, + "low_phone_trust_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the phone intelligence trust index is at or below the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, "enable_social": { "type": "boolean", "default": false, @@ -15682,7 +16770,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — this API never returns `401`. Checks are free, so there is no credit check here.", + "description": "Permission denied. Returned when the `x-api-key` header is missing; a wrong, revoked or expired key returns `401`. Checks are free, so there is no credit check here.", "content": { "application/json": { "examples": { @@ -15786,7 +16874,7 @@ "/v3/bank/account-check/": { "post": { "summary": "Check a bank account", - "description": "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.\n\n**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.\n\n**What you get back.** `result` is `match`, `close_match`, `no_match` or `cannot_verify`. On a `close_match`, `holder_name` is the name the bank holds the account under, when the bank returned it. `account` comes back masked to its last 4 characters.\n\n**Billing.** Each check the bank answers is billed once at the Account check price of the account's country, whatever the result: a `no_match`, an account that does not exist and a `cannot_verify` are billed too. A request answered with an error is never billed.\n\n**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.\n\n**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`.\n\n**API keys.** A scoped API key needs write access to sessions.", + "description": "**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.\n\nCheck 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.\n\n**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.\n\n**What you get back.** `result` is `match`, `close_match`, `no_match` or `cannot_verify`. On a `close_match`, `holder_name` is the name the bank holds the account under, when the bank returned it. `account` comes back masked to its last 4 characters.\n\n**Billing.** Each check the bank answers is billed once at the Account check price of the account's country, whatever the result: a `no_match`, an account that does not exist and a `cannot_verify` are billed too. A request answered with an error is never billed.\n\n**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.\n\n**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`.\n\n**API keys.** A scoped API key needs write access to sessions.", "operationId": "post_v3_bank_account_check", "tags": [ "Standalone APIs" @@ -15921,6 +17009,15 @@ "field": "holder", "reason": "required" } + }, + "Consent required": { + "summary": "The country's account check needs the account holder's consent", + "value": { + "detail": "Account checks in this country need the account holder's explicit consent. Ask for it, then send `consent=true`.", + "code": "invalid_account_input", + "field": "consent", + "reason": "required" + } } } } @@ -15995,7 +17092,7 @@ } }, "404": { - "description": "No account check serves this account yet, so nothing was checked or billed. `country_not_covered`: none serves its country, or its kind of account (person or business) there. `bank_not_covered`: none serves its bank. `bank_verification_not_available`: Bank Verification is not available yet.", + "description": "No account check serves this account yet, so nothing was checked or billed. `country_not_covered`: none serves its country, or its kind of account (person or business) there. `bank_not_covered`: none serves its bank. `bank_verification_not_available`: Bank Verification is not enabled in production yet, which is the answer for every request there until it is switched on.", "content": { "application/json": { "schema": { @@ -16052,12 +17149,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/bank/account-check/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\n \"country\": \"GBR\",\n \"account\": {\"sort_code\": \"20-45-67\", \"account_number\": \"31926819\"},\n \"holder\": {\"full_name\": \"Maria Oliveira\"},\n \"vendor_data\": \"payout_20481\",\n },\n timeout=30,\n)\nresp.raise_for_status()\ncheck = resp.json()\nif check[\"result\"] == \"match\":\n pass # send the payout\nelif check[\"result\"] == \"close_match\":\n print(check[\"holder_name\"]) # the name the bank holds, when it returned one" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.bank.account_check(\n country=\"GBR\",\n account={\n \"account_number\": \"31926819\",\n \"sort_code\": \"20-45-67\",\n },\n holder={\n \"full_name\": \"Maria Oliveira\",\n },\n vendor_data=\"payout_20481\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/bank/account-check/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n country: 'GBR',\n account: { sort_code: '20-45-67', account_number: '31926819' },\n holder: { full_name: 'Maria Oliveira' },\n vendor_data: 'payout_20481',\n }),\n});\nconst check = await res.json();\n// check.result: match, close_match, no_match or cannot_verify" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.bank.accountCheck({\n country: \"GBR\",\n account: {\n account_number: \"31926819\",\n sort_code: \"20-45-67\",\n },\n holder: {\n full_name: \"Maria Oliveira\",\n },\n vendor_data: \"payout_20481\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Bank.AccountCheck(ctx, didit.BankAccountCheckRequest{\n\tCountry: \"GBR\",\n\tAccount: didit.BankAccountCheckRequestAccount{\n\t\tAccountNumber: didit.String(\"31926819\"),\n\t\tSortCode: didit.String(\"20-45-67\"),\n\t},\n\tHolder: didit.BankAccountCheckHolder{\n\t\tFullName: didit.String(\"Maria Oliveira\"),\n\t},\n\tVendorData: didit.String(\"payout_20481\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BankAccountCheckHolder;\nimport me.didit.types.BankAccountCheckPersonHolder;\nimport me.didit.types.BankAccountCheckRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.bank().accountCheck(BankAccountCheckRequest.builder()\n .country(\"GBR\")\n .account(BankAccountCheckRequest.Account.builder()\n .accountNumber(\"31926819\")\n .sortCode(\"20-45-67\")\n .build())\n .holder(BankAccountCheckHolder.ofBankAccountCheckPersonHolder(BankAccountCheckPersonHolder.builder()\n .fullName(\"Maria Oliveira\")\n .build()))\n .vendorData(\"payout_20481\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "bank->accountCheck([\n 'country' => 'GBR',\n 'account' => [\n 'account_number' => '31926819',\n 'sort_code' => '20-45-67',\n ],\n 'holder' => [\n 'full_name' => 'Maria Oliveira',\n ],\n 'vendor_data' => 'payout_20481',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.bank.account_check(\n country: \"GBR\",\n account: {\n account_number: \"31926819\",\n sort_code: \"20-45-67\",\n },\n holder: {\n full_name: \"Maria Oliveira\",\n },\n vendor_data: \"payout_20481\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Bank.AccountCheckAsync(new BankAccountCheckRequest\n{\n Country = \"GBR\",\n Account = new()\n {\n AccountNumber = \"31926819\",\n SortCode = \"20-45-67\",\n },\n Holder = new()\n {\n FullName = \"Maria Oliveira\",\n },\n VendorData = \"payout_20481\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -16085,12 +17207,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/email/send/\",\n headers={\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Content-Type\": \"application/json\",\n },\n json={\n \"email\": \"alice@example.com\",\n \"options\": {\"code_size\": 6, \"locale\": \"en\"},\n \"vendor_data\": \"user-1234\",\n },\n timeout=15,\n)\nresp.raise_for_status()\nprint(resp.json()) # {request_id, status, reason, vendor_data, metadata}\n# Then verify with POST /v3/email/check/ using the same email" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.send_code(\n email=\"alice@example.com\",\n options={\n \"locale\": \"en\",\n },\n vendor_data=\"user-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/email/send/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n email: 'alice@example.com',\n options: { code_size: 6, locale: 'en' },\n vendor_data: 'user-1234',\n }),\n});\nif (!res.ok) throw new Error(`Email send failed: ${res.status}`);\nconst data = await res.json();\nconsole.log(data); // { request_id, status, reason, vendor_data, metadata }\n// Then verify with POST /v3/email/check/ using the same email" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.sendCode({\n email: \"alice@example.com\",\n options: {\n locale: \"en\",\n },\n vendor_data: \"user-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.SendCode(ctx, didit.EmailSendCodeParams{\n\tEmail: \"alice@example.com\",\n\tOptions: didit.Some(didit.EmailSendCodeParamsOptions{\n\t\tLocale: didit.Some(didit.EmailSendCodeParamsOptionsLocale(\"en\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.EmailSendCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().sendCode(EmailSendCodeParams.builder()\n .email(\"alice@example.com\")\n .options(EmailSendCodeParams.Options.builder()\n .locale(EmailSendCodeParams.Options.Locale.of(\"en\"))\n .build())\n .vendorData(\"user-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "email->sendCode([\n 'email' => 'alice@example.com',\n 'options' => [\n 'locale' => 'en',\n ],\n 'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.send_code(\n email: \"alice@example.com\",\n options: {\n locale: \"en\",\n },\n vendor_data: \"user-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.SendCodeAsync(new EmailSendCodeParams\n{\n Email = \"alice@example.com\",\n Options = new EmailSendCodeParamsOptions\n {\n Locale = new EmailSendCodeParamsOptionsLocale(\"en\"),\n },\n VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -16375,7 +17522,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment (`{\"detail\": ...}`) — this API never returns `401`. Also returned before any send when the organization's balance cannot cover one Email Verification API credit (`{\"error\": ...}`).", + "description": "Permission denied. Returned when the `x-api-key` header is missing (`{\"detail\": ...}`); a wrong, revoked or expired key returns `401`. Also returned before any send when the organization's balance cannot cover one Email Verification API credit (`{\"error\": ...}`).", "content": { "application/json": { "examples": { @@ -16472,12 +17619,37 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/email/check/\",\n headers={\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Content-Type\": \"application/json\",\n },\n json={\n \"email\": \"alice@example.com\", # same address as the send call\n \"code\": \"123456\",\n \"disposable_email_action\": \"DECLINE\",\n },\n timeout=15,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result[\"status\"]) # Approved / Declined / Failed / Expired or Not Found\nif result[\"status\"] in (\"Approved\", \"Declined\"):\n print(result[\"email\"][\"is_breached\"], result[\"email\"][\"is_disposable\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.check_code(\n email=\"alice@example.com\",\n code=\"123456\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/email/check/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n email: 'alice@example.com', // same address as the send call\n code: '123456',\n disposable_email_action: 'DECLINE',\n }),\n});\nconst data = await res.json();\nif (data.status === 'Approved') {\n // full email report is in data.email (breaches, is_disposable, matches, ...)\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.checkCode({\n email: \"alice@example.com\",\n code: \"123456\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.CheckCode(ctx, didit.EmailCheckCodeParams{\n\tEmail: \"alice@example.com\",\n\tCode: \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.EmailCheckCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().checkCode(EmailCheckCodeParams.builder()\n .email(\"alice@example.com\")\n .code(\"123456\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "email->checkCode([\n 'email' => 'alice@example.com',\n 'code' => '123456',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.check_code(\n email: \"alice@example.com\",\n code: \"123456\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.CheckCodeAsync(new EmailCheckCodeParams\n{\n Email = \"alice@example.com\",\n Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -16526,6 +17698,39 @@ "default": "NO_ACTION", "description": "What to do when the domain belongs to a disposable/temporary-mail provider (`email.is_disposable`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings`." }, + "enable_enrichment": { + "type": "boolean", + "default": false, + "description": "When `true`, also run email intelligence on the address: a risk score and its breach history. Billed as one `email_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it.", + "example": false + }, + "email_intelligence_score_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the email intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, + "recent_email_breach_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the address appears in a recent known data breach. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, + "frequent_email_breach_action": { + "type": "string", + "enum": [ + "NO_ACTION", + "DECLINE" + ], + "default": "NO_ACTION", + "description": "Action when the address appears in many known data breaches. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`." + }, "enable_social": { "type": "boolean", "default": false, @@ -16811,7 +18016,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — this API never returns `401`. Checks are free, so there is no credit check here.", + "description": "Permission denied. Returned when the `x-api-key` header is missing; a wrong, revoked or expired key returns `401`. Checks are free, so there is no credit check here.", "content": { "application/json": { "examples": { @@ -17032,14 +18237,39 @@ "source": "curl -X GET 'https://verification.didit.me/v3/workflows/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Accept: application/json'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.get(\n \"https://verification.didit.me/v3/workflows/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n timeout=10,\n)\nresp.raise_for_status()\npage = resp.json()\nfor workflow in page[\"results\"]:\n print(workflow[\"uuid\"], workflow[\"workflow_label\"], workflow[\"status\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.workflows.list():\n print(item)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(\"https://verification.didit.me/v3/workflows/\", {\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n});\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst page = await res.json();\npage.results.forEach((w) => console.log(w.uuid, w.workflow_label, w.status));" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.workflows.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Workflows.ListAutoPaging(ctx, didit.WorkflowsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.workflows().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "workflows->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.workflows.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Workflows.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] }, @@ -17172,10 +18402,28 @@ } }, "400": { - "description": "Validation error. Common causes: a top-level key outside the accepted whitelist (e.g. `workflow_type`), an unknown `feature` value, a feature placed before its dependency (e.g., `FACE_MATCH` before `OCR`), a passive feature (`AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `KYB_KEY_PEOPLE`) used as the first step, a `QUESTIONNAIRE` feature whose `config.questionnaire_uuid` does not exist for this application, or an out-of-range threshold. Body is a DRF validation error object — keys are field names, values are arrays of human-readable messages.", + "description": "Validation error. Common causes: a top-level key outside the accepted whitelist (e.g. `workflow_type`), an unknown `feature` value, a feature placed before its dependency (e.g., `FACE_MATCH` before `OCR`), a passive feature (`AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `KYB_KEY_PEOPLE`) used as the first step, a `QUESTIONNAIRE` feature whose `config.questionnaire_uuid` does not exist for this application, a `SIGNATURE` feature that would go live with no document to sign, a `SIGNATURE` feature at `signature_level: \"aes\"` while Advanced (AES) is not available (`aes_not_available`, see `signature_availability` on the workflow), or an out-of-range threshold. Body is a DRF validation error object — keys are field names, values are arrays of human-readable messages.", "content": { "application/json": { "examples": { + "Advanced (AES) not available": { + "value": { + "features": { + "signature_level": [ + "Node 'signature': Advanced (AES) is not available yet (aes_not_available)." + ] + } + } + }, + "Signature step with no document": { + "value": { + "features": { + "non_field_errors": [ + "Node 'signature': Add a document to sign, or let each session bring its own." + ] + } + } + }, "Missing feature": { "value": { "features": [ @@ -17249,14 +18497,39 @@ "source": "curl -X POST 'https://verification.didit.me/v3/workflows/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"workflow_label\": \"Standard KYC\",\n \"features\": [\n {\"feature\": \"OCR\"},\n {\"feature\": \"LIVENESS\", \"config\": {\"face_liveness_method\": \"passive\"}},\n {\"feature\": \"FACE_MATCH\", \"config\": {\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60}}\n ]\n }'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\npayload = {\n \"workflow_label\": \"Standard KYC\",\n \"features\": [\n {\"feature\": \"OCR\"},\n {\"feature\": \"LIVENESS\", \"config\": {\"face_liveness_method\": \"passive\"}},\n {\"feature\": \"FACE_MATCH\"},\n ],\n}\nresp = requests.post(\n \"https://verification.didit.me/v3/workflows/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json=payload,\n timeout=10,\n)\nresp.raise_for_status()\nworkflow = resp.json()\nprint(\"Workflow id:\", workflow[\"uuid\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.create(\n workflow_label=\"Standard KYC\",\n features=[{\n \"feature\": \"OCR\",\n \"config\": {\"duplicated_user_action\": \"review\"},\n }, {\n \"feature\": \"LIVENESS\",\n \"config\": {\"face_liveness_method\": \"passive\"},\n }, {\n \"feature\": \"FACE_MATCH\",\n \"config\": {\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60},\n }],\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(\"https://verification.didit.me/v3/workflows/\", {\n method: \"POST\",\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n workflow_label: \"Standard KYC\",\n features: [\n { feature: \"OCR\" },\n { feature: \"LIVENESS\", config: { face_liveness_method: \"passive\" } },\n { feature: \"FACE_MATCH\" },\n ],\n }),\n});\nif (!res.ok) throw new Error(`Didit ${res.status}: ${await res.text()}`);\nconst workflow = await res.json();\nconsole.log(\"Workflow id:\", workflow.uuid);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.create({\n workflow_label: \"Standard KYC\",\n features: [{\n feature: \"OCR\",\n config: { duplicated_user_action: \"review\" },\n }, {\n feature: \"LIVENESS\",\n config: { face_liveness_method: \"passive\" },\n }, {\n feature: \"FACE_MATCH\",\n config: { face_match_score_decline_threshold: 40, face_match_score_review_threshold: 60 },\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Create(ctx, didit.SimpleWorkflowRequest{\n\tWorkflowLabel: didit.String(\"Standard KYC\"),\n\tFeatures: []didit.SimpleWorkflowFeature{{\n\t\tFeature: \"OCR\",\n\t\tConfig: didit.Some(map[string]any{\"duplicated_user_action\": \"review\"}),\n\t}, {\n\t\tFeature: \"LIVENESS\",\n\t\tConfig: didit.Some(map[string]any{\"face_liveness_method\": \"passive\"}),\n\t}, {\n\t\tFeature: \"FACE_MATCH\",\n\t\tConfig: didit.Some(map[string]any{\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SimpleWorkflowFeature;\nimport me.didit.types.SimpleWorkflowRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().create(SimpleWorkflowRequest.builder()\n .workflowLabel(\"Standard KYC\")\n .features(List.of(\n SimpleWorkflowFeature.builder()\n .feature(SimpleWorkflowFeature.Feature.of(\"OCR\"))\n .config(Map.of(\"duplicated_user_action\", \"review\"))\n .build(),\n SimpleWorkflowFeature.builder()\n .feature(SimpleWorkflowFeature.Feature.of(\"LIVENESS\"))\n .config(Map.of(\"face_liveness_method\", \"passive\"))\n .build(),\n SimpleWorkflowFeature.builder()\n .feature(SimpleWorkflowFeature.Feature.of(\"FACE_MATCH\"))\n .config(Map.of(\"face_match_score_decline_threshold\", 40, \"face_match_score_review_threshold\", 60))\n .build()))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "workflows->create([\n 'workflow_label' => 'Standard KYC',\n 'features' => [[\n 'feature' => 'OCR',\n 'config' => ['duplicated_user_action' => 'review'],\n ], [\n 'feature' => 'LIVENESS',\n 'config' => ['face_liveness_method' => 'passive'],\n ], [\n 'feature' => 'FACE_MATCH',\n 'config' => ['face_match_score_decline_threshold' => 40, 'face_match_score_review_threshold' => 60],\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.create(\n workflow_label: \"Standard KYC\",\n features: [{\n feature: \"OCR\",\n config: { duplicated_user_action: \"review\" },\n }, {\n feature: \"LIVENESS\",\n config: { face_liveness_method: \"passive\" },\n }, {\n feature: \"FACE_MATCH\",\n config: { face_match_score_decline_threshold: 40, face_match_score_review_threshold: 60 },\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.CreateAsync(new SimpleWorkflowRequest\n{\n WorkflowLabel = \"Standard KYC\",\n Features = new SimpleWorkflowFeature[]\n {\n new()\n {\n Feature = \"OCR\",\n Config = new Dictionary { [\"duplicated_user_action\"] = \"review\" },\n },\n new()\n {\n Feature = \"LIVENESS\",\n Config = new Dictionary { [\"face_liveness_method\"] = \"passive\" },\n },\n new()\n {\n Feature = \"FACE_MATCH\",\n Config = new Dictionary { [\"face_match_score_decline_threshold\"] = 40, [\"face_match_score_review_threshold\"] = 60 },\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -17400,14 +18673,39 @@ "source": "curl -X GET 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.get(\n f\"https://verification.didit.me/v3/workflows/{settings_uuid}/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n timeout=10,\n)\nresp.raise_for_status()\nworkflow = resp.json()\nprint(workflow[\"workflow_label\"], workflow[\"status\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(`https://verification.didit.me/v3/workflows/${settingsUuid}/`, {\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n});\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst workflow = await res.json();\nconsole.log(workflow.workflow_label, workflow.status);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "workflows->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -17507,7 +18805,7 @@ } }, "400": { - "description": "Validation error — a top-level key outside the accepted whitelist, an unknown feature, invalid ordering, out-of-range threshold, referencing a non-existent questionnaire, or `status: \"draft\"` sent for a published version (`\"Cannot revert a published version to draft.\"`). The response body is a DRF validation error keyed by field name." + "description": "Validation error — a top-level key outside the accepted whitelist, an unknown feature, invalid ordering, out-of-range threshold, referencing a non-existent questionnaire, a `SIGNATURE` feature that would go live with no document to sign, a new `SIGNATURE` feature at `signature_level: \"aes\"` while Advanced (AES) is not available (`aes_not_available`, see `signature_availability` on the workflow; a step that already stores `aes` keeps it), or `status: \"draft\"` sent for a published version (`\"Cannot revert a published version to draft.\"`). The response body is a DRF validation error keyed by field name." }, "403": { "description": "API key missing or invalid.", @@ -17548,14 +18846,39 @@ "source": "curl -X PATCH 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"workflow_label\": \"Premium KYC\"}'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.patch(\n f\"https://verification.didit.me/v3/workflows/{settings_uuid}/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json={\"workflow_label\": \"Premium KYC\"},\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json()[\"workflow_label\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.update(\n \"11111111-2222-3333-4444-555555555555\",\n features=[{\n \"feature\": \"OCR\",\n }, {\n \"feature\": \"AML\",\n }],\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(`https://verification.didit.me/v3/workflows/${settingsUuid}/`, {\n method: \"PATCH\",\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ workflow_label: \"Premium KYC\" }),\n});\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst workflow = await res.json();\nconsole.log(workflow.workflow_label);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.update(\"11111111-2222-3333-4444-555555555555\", {\n features: [{\n feature: \"OCR\",\n }, {\n feature: \"AML\",\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SimpleWorkflowUpdateRequest{\n\tFeatures: didit.Some([]didit.SimpleWorkflowFeature{{\n\t\tFeature: \"OCR\",\n\t}, {\n\t\tFeature: \"AML\",\n\t}}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SimpleWorkflowFeature;\nimport me.didit.types.SimpleWorkflowUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().update(\"11111111-2222-3333-4444-555555555555\", SimpleWorkflowUpdateRequest.builder()\n .features(List.of(\n SimpleWorkflowFeature.builder()\n .feature(SimpleWorkflowFeature.Feature.of(\"OCR\"))\n .build(),\n SimpleWorkflowFeature.builder()\n .feature(SimpleWorkflowFeature.Feature.of(\"AML\"))\n .build()))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "workflows->update('11111111-2222-3333-4444-555555555555', [\n 'features' => [[\n 'feature' => 'OCR',\n ], [\n 'feature' => 'AML',\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.update(\n \"11111111-2222-3333-4444-555555555555\",\n features: [{\n feature: \"OCR\",\n }, {\n feature: \"AML\",\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new SimpleWorkflowUpdateRequest\n{\n Features = new SimpleWorkflowFeature[]\n {\n new()\n {\n Feature = \"OCR\",\n },\n new()\n {\n Feature = \"AML\",\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -17635,14 +18958,39 @@ "source": "curl -X DELETE 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.delete(\n f\"https://verification.didit.me/v3/workflows/{settings_uuid}/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n timeout=10,\n)\nresp.raise_for_status() # raises on 4xx/5xx; 204 is success" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.workflows.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(`https://verification.didit.me/v3/workflows/${settingsUuid}/`, {\n method: \"DELETE\",\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n});\nif (res.status !== 204) throw new Error(`Didit ${res.status}`);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.workflows.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Workflows.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.workflows().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "workflows->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.workflows.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Workflows.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ] } @@ -17788,14 +19136,39 @@ "source": "curl -X GET 'https://verification.didit.me/v3/questionnaires/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.get(\n \"https://verification.didit.me/v3/questionnaires/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n timeout=10,\n)\nresp.raise_for_status()\npage = resp.json()\nfor q in page[\"results\"]:\n print(q[\"uuid\"], q[\"title\"], q[\"status\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.questionnaires.list():\n print(item)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(\"https://verification.didit.me/v3/questionnaires/\", {\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n});\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst page = await res.json();\npage.results.forEach((q) => console.log(q.uuid, q.title, q.status));" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.questionnaires.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Questionnaires.ListAutoPaging(ctx, didit.QuestionnairesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.questionnaires().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "questionnaires->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.questionnaires.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Questionnaires.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] }, @@ -18011,14 +19384,39 @@ "source": "curl -X POST 'https://verification.didit.me/v3/questionnaires/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"title\": \"Customer Onboarding\",\n \"default_language\": \"en\",\n \"languages\": [\"en\"],\n \"form_elements\": [\n {\n \"id\": \"occupation\",\n \"element_type\": \"short_text\",\n \"label\": {\"en\": \"What is your occupation?\"},\n \"is_required\": true\n }\n ]\n }'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\npayload = {\n \"title\": \"Customer Onboarding\",\n \"default_language\": \"en\",\n \"languages\": [\"en\"],\n \"form_elements\": [\n {\n \"id\": \"occupation\",\n \"element_type\": \"short_text\",\n \"label\": {\"en\": \"What is your occupation?\"},\n \"is_required\": True,\n },\n ],\n}\nresp = requests.post(\n \"https://verification.didit.me/v3/questionnaires/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json=payload,\n timeout=10,\n)\nresp.raise_for_status()\nquestionnaire = resp.json()\nprint(\"Questionnaire id:\", questionnaire[\"questionnaire_id\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.create(\n title=\"Customer Onboarding\",\n description=\"Additional information needed for verification\",\n languages=[\"en\"],\n default_language=\"en\",\n is_active=True,\n form_elements=[{\n \"id\": \"occupation\",\n \"element_type\": \"short_text\",\n \"label\": {\"en\": \"What is your occupation?\"},\n \"placeholder\": {\"en\": \"Software engineer\"},\n \"is_required\": True,\n }, {\n \"id\": \"source_of_funds\",\n \"element_type\": \"multiple_choice\",\n \"label\": {\"en\": \"Source of funds\"},\n \"is_required\": True,\n \"options\": [{\n \"value\": \"employment\",\n \"label\": {\"en\": \"Employment\"},\n }, {\n \"value\": \"business\",\n \"label\": {\"en\": \"Business\"},\n }, {\n \"value\": \"investments\",\n \"label\": {\"en\": \"Investments\"},\n }, {\n \"value\": \"other\",\n \"label\": {\"en\": \"Other\"},\n }],\n }],\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(\"https://verification.didit.me/v3/questionnaires/\", {\n method: \"POST\",\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n title: \"Customer Onboarding\",\n default_language: \"en\",\n languages: [\"en\"],\n form_elements: [\n {\n id: \"occupation\",\n element_type: \"short_text\",\n label: { en: \"What is your occupation?\" },\n is_required: true,\n },\n ],\n }),\n});\nif (!res.ok) throw new Error(`Didit ${res.status}: ${await res.text()}`);\nconst questionnaire = await res.json();\nconsole.log(\"Questionnaire id:\", questionnaire.questionnaire_id);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.create({\n title: \"Customer Onboarding\",\n description: \"Additional information needed for verification\",\n languages: [\"en\"],\n default_language: \"en\",\n is_active: true,\n form_elements: [{\n id: \"occupation\",\n element_type: \"short_text\",\n label: { en: \"What is your occupation?\" },\n placeholder: { en: \"Software engineer\" },\n is_required: true,\n }, {\n id: \"source_of_funds\",\n element_type: \"multiple_choice\",\n label: { en: \"Source of funds\" },\n is_required: true,\n options: [{\n value: \"employment\",\n label: { en: \"Employment\" },\n }, {\n value: \"business\",\n label: { en: \"Business\" },\n }, {\n value: \"investments\",\n label: { en: \"Investments\" },\n }, {\n value: \"other\",\n label: { en: \"Other\" },\n }],\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Create(ctx, didit.SimpleQuestionnaireRequest{\n\tTitle: \"Customer Onboarding\",\n\tDescription: didit.String(\"Additional information needed for verification\"),\n\tLanguages: []string{\"en\"},\n\tDefaultLanguage: didit.String(\"en\"),\n\tIsActive: didit.Bool(true),\n\tFormElements: []didit.SimpleQuestionnaireElement{{\n\t\tID: didit.String(\"occupation\"),\n\t\tElementType: \"short_text\",\n\t\tLabel: map[string]string{\"en\": \"What is your occupation?\"},\n\t\tPlaceholder: didit.Some(map[string]string{\"en\": \"Software engineer\"}),\n\t\tIsRequired: didit.Bool(true),\n\t}, {\n\t\tID: didit.String(\"source_of_funds\"),\n\t\tElementType: \"multiple_choice\",\n\t\tLabel: map[string]string{\"en\": \"Source of funds\"},\n\t\tIsRequired: didit.Bool(true),\n\t\tOptions: didit.Some([]didit.SimpleQuestionnaireElementOptions{{\n\t\t\tValue: didit.String(\"employment\"),\n\t\t\tLabel: map[string]string{\"en\": \"Employment\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"business\"),\n\t\t\tLabel: map[string]string{\"en\": \"Business\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"investments\"),\n\t\t\tLabel: map[string]string{\"en\": \"Investments\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"other\"),\n\t\t\tLabel: map[string]string{\"en\": \"Other\"},\n\t\t}}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SimpleQuestionnaireElement;\nimport me.didit.types.SimpleQuestionnaireRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().create(SimpleQuestionnaireRequest.builder()\n .title(\"Customer Onboarding\")\n .description(\"Additional information needed for verification\")\n .languages(List.of(\"en\"))\n .defaultLanguage(\"en\")\n .isActive(true)\n .formElements(List.of(\n SimpleQuestionnaireElement.builder()\n .id(\"occupation\")\n .elementType(SimpleQuestionnaireElement.ElementType.of(\"short_text\"))\n .label(Map.of(\"en\", \"What is your occupation?\"))\n .placeholder(Map.of(\"en\", \"Software engineer\"))\n .isRequired(true)\n .build(),\n SimpleQuestionnaireElement.builder()\n .id(\"source_of_funds\")\n .elementType(SimpleQuestionnaireElement.ElementType.of(\"multiple_choice\"))\n .label(Map.of(\"en\", \"Source of funds\"))\n .isRequired(true)\n .options(List.of(\n SimpleQuestionnaireElement.Options.builder()\n .value(\"employment\")\n .label(Map.of(\"en\", \"Employment\"))\n .build(),\n SimpleQuestionnaireElement.Options.builder()\n .value(\"business\")\n .label(Map.of(\"en\", \"Business\"))\n .build(),\n SimpleQuestionnaireElement.Options.builder()\n .value(\"investments\")\n .label(Map.of(\"en\", \"Investments\"))\n .build(),\n SimpleQuestionnaireElement.Options.builder()\n .value(\"other\")\n .label(Map.of(\"en\", \"Other\"))\n .build()))\n .build()))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "questionnaires->create([\n 'title' => 'Customer Onboarding',\n 'description' => 'Additional information needed for verification',\n 'languages' => ['en'],\n 'default_language' => 'en',\n 'is_active' => true,\n 'form_elements' => [[\n 'id' => 'occupation',\n 'element_type' => 'short_text',\n 'label' => ['en' => 'What is your occupation?'],\n 'placeholder' => ['en' => 'Software engineer'],\n 'is_required' => true,\n ], [\n 'id' => 'source_of_funds',\n 'element_type' => 'multiple_choice',\n 'label' => ['en' => 'Source of funds'],\n 'is_required' => true,\n 'options' => [[\n 'value' => 'employment',\n 'label' => ['en' => 'Employment'],\n ], [\n 'value' => 'business',\n 'label' => ['en' => 'Business'],\n ], [\n 'value' => 'investments',\n 'label' => ['en' => 'Investments'],\n ], [\n 'value' => 'other',\n 'label' => ['en' => 'Other'],\n ]],\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.create(\n title: \"Customer Onboarding\",\n description: \"Additional information needed for verification\",\n languages: [\"en\"],\n default_language: \"en\",\n is_active: true,\n form_elements: [{\n id: \"occupation\",\n element_type: \"short_text\",\n label: { en: \"What is your occupation?\" },\n placeholder: { en: \"Software engineer\" },\n is_required: true,\n }, {\n id: \"source_of_funds\",\n element_type: \"multiple_choice\",\n label: { en: \"Source of funds\" },\n is_required: true,\n options: [{\n value: \"employment\",\n label: { en: \"Employment\" },\n }, {\n value: \"business\",\n label: { en: \"Business\" },\n }, {\n value: \"investments\",\n label: { en: \"Investments\" },\n }, {\n value: \"other\",\n label: { en: \"Other\" },\n }],\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.CreateAsync(new SimpleQuestionnaireRequest\n{\n Title = \"Customer Onboarding\",\n Description = \"Additional information needed for verification\",\n Languages = new string[] { \"en\" },\n DefaultLanguage = \"en\",\n IsActive = true,\n FormElements = new SimpleQuestionnaireElement[]\n {\n new()\n {\n Id = \"occupation\",\n ElementType = \"short_text\",\n Label = new Dictionary { [\"en\"] = \"What is your occupation?\" },\n Placeholder = new Dictionary { [\"en\"] = \"Software engineer\" },\n IsRequired = true,\n },\n new()\n {\n Id = \"source_of_funds\",\n ElementType = \"multiple_choice\",\n Label = new Dictionary { [\"en\"] = \"Source of funds\" },\n IsRequired = true,\n Options = new SimpleQuestionnaireElementOptions[]\n {\n new()\n {\n Value = \"employment\",\n Label = new Dictionary { [\"en\"] = \"Employment\" },\n },\n new()\n {\n Value = \"business\",\n Label = new Dictionary { [\"en\"] = \"Business\" },\n },\n new()\n {\n Value = \"investments\",\n Label = new Dictionary { [\"en\"] = \"Investments\" },\n },\n new()\n {\n Value = \"other\",\n Label = new Dictionary { [\"en\"] = \"Other\" },\n },\n },\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -18179,14 +19577,39 @@ "source": "curl -X GET 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.get(\n f\"https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n timeout=10,\n)\nresp.raise_for_status()\nquestionnaire = resp.json()\nprint(questionnaire[\"title\"], questionnaire[\"status\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(`https://verification.didit.me/v3/questionnaires/${questionnaireUuid}/`, {\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n});\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst questionnaire = await res.json();\nconsole.log(questionnaire.title, questionnaire.status);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "questionnaires->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -18322,14 +19745,39 @@ "source": "curl -X PATCH 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"title\": \"Updated Customer Onboarding\"}'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.patch(\n f\"https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json={\"title\": \"Updated Customer Onboarding\"},\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json()[\"questionnaire_id\"], resp.json()[\"status\"])" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.update(\n \"11111111-2222-3333-4444-555555555555\",\n title=\"Updated Customer Onboarding\",\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(`https://verification.didit.me/v3/questionnaires/${questionnaireUuid}/`, {\n method: \"PATCH\",\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ title: \"Updated Customer Onboarding\" }),\n});\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst q = await res.json();\nconsole.log(q.questionnaire_id, q.status);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.update(\"11111111-2222-3333-4444-555555555555\", {\n title: \"Updated Customer Onboarding\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SimpleQuestionnaireUpdateRequest{\n\tTitle: didit.String(\"Updated Customer Onboarding\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SimpleQuestionnaireUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().update(\"11111111-2222-3333-4444-555555555555\", SimpleQuestionnaireUpdateRequest.builder()\n .title(\"Updated Customer Onboarding\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "questionnaires->update('11111111-2222-3333-4444-555555555555', [\n 'title' => 'Updated Customer Onboarding',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.update(\n \"11111111-2222-3333-4444-555555555555\",\n title: \"Updated Customer Onboarding\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new SimpleQuestionnaireUpdateRequest\n{\n Title = \"Updated Customer Onboarding\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -18409,14 +19857,39 @@ "source": "curl -X DELETE 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import requests\n\nresp = requests.delete(\n f\"https://verification.didit.me/v3/questionnaires/{questionnaire_uuid}/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n timeout=10,\n)\nresp.raise_for_status() # raises on 4xx/5xx; 204 is success" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.questionnaires.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const res = await fetch(`https://verification.didit.me/v3/questionnaires/${questionnaireUuid}/`, {\n method: \"DELETE\",\n headers: { 'x-api-key': 'YOUR_API_KEY' },\n});\nif (res.status !== 204) throw new Error(`Didit ${res.status}`);" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.questionnaires.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Questionnaires.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.questionnaires().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "questionnaires->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.questionnaires.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Questionnaires.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ] } @@ -18442,7 +19915,8 @@ "schema": { "type": "integer", "default": 50, - "minimum": 1 + "minimum": 1, + "maximum": 1000000 }, "description": "Page size. Defaults to 50 when omitted. There is no enforced maximum, but keep pages small for latency." }, @@ -18452,7 +19926,8 @@ "schema": { "type": "integer", "default": 0, - "minimum": 0 + "minimum": 0, + "maximum": 1000000 }, "description": "Zero-based offset of the first record to return. Prefer following the `next` URL from the previous page over computing this by hand." } @@ -18466,12 +19941,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/users/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n params={'limit': 50},\n)\nresp.raise_for_status()\npage = resp.json()\nfor user in page['results']:\n print(user['vendor_data'], user['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.users.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const url = new URL('https://verification.didit.me/v3/users/');\nurl.searchParams.set('limit', '50');\n\nconst page = await fetch(url, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n}).then((r) => r.json());\n\nconsole.log(page.count, page.results.length);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.users.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Users.ListAutoPaging(ctx, didit.UsersListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.users().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.users.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Users.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -18622,7 +20122,7 @@ } }, "403": { - "description": "Invalid or revoked API key, or the key cannot list users for this application. Note: on this endpoint an *invalid* key returns `403` (not `401`).", + "description": "The key cannot list users for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -18692,12 +20192,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/users/user-abc-123/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n)\nresp.raise_for_status()\nuser = resp.json()\nprint(user['didit_internal_id'], user['status'], user['session_count'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.retrieve(\n \"user-abc-123\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const vendorData = encodeURIComponent('user-abc-123');\nconst user = await fetch(\n `https://verification.didit.me/v3/users/${vendorData}/`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n).then((r) => r.json());\n\nconsole.log(user.didit_internal_id, user.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.retrieve(\"user-abc-123\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Retrieve(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().retrieve(\"user-abc-123\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->retrieve('user-abc-123');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.retrieve(\"user-abc-123\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.RetrieveAsync(\"user-abc-123\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -18820,7 +20345,7 @@ } }, "403": { - "description": "Invalid or revoked API key, or the key cannot read this application's users. Note: on this endpoint an *invalid* key returns `403` (not `401`).", + "description": "Invalid or revoked API key, or the key cannot read this application's users. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -18902,12 +20427,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/users/user-abc-123/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'display_name': 'Jane S.', 'status': 'FLAGGED'},\n)\nresp.raise_for_status()\nprint(resp.json()['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.update(\n \"user-abc-123\",\n display_name=\"Jane S.\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/users/user-abc-123/', {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ display_name: 'Jane S.', status: 'FLAGGED' }),\n});\nconst user = await resp.json();\nconsole.log(user.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.update(\"user-abc-123\", {\n display_name: \"Jane S.\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Update(ctx, \"user-abc-123\", didit.UsersUpdateParams{\n\tDisplayName: didit.String(\"Jane S.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.UsersUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().update(\"user-abc-123\", UsersUpdateParams.builder()\n .displayName(\"Jane S.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->update('user-abc-123', [\n 'display_name' => 'Jane S.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.update(\n \"user-abc-123\",\n display_name: \"Jane S.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UpdateAsync(\"user-abc-123\", new UsersUpdateParams\n{\n DisplayName = \"Jane S.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -19043,7 +20593,7 @@ } }, "403": { - "description": "Invalid or revoked API key, or the key cannot update users for this application. Note: on this endpoint an *invalid* key returns `403` (not `401`).", + "description": "The key cannot update users for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -19391,12 +20941,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.get(\n \"https://verification.didit.me/v3/users/user-abc-123/generate-pdf/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n stream=True,\n timeout=120,\n)\nresponse.raise_for_status()\nwith open(\"user-history.pdf\", \"wb\") as fh:\n for chunk in response.iter_content(chunk_size=8192):\n fh.write(chunk)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.users.generate_pdf(\n \"user-abc-123\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { writeFile } from 'node:fs/promises';\n\nconst vendorData = encodeURIComponent('user-abc-123');\nconst response = await fetch(\n `https://verification.didit.me/v3/users/${vendorData}/generate-pdf/`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!response.ok) throw new Error(`PDF generation failed: HTTP ${response.status}`);\nawait writeFile('user-history.pdf', Buffer.from(await response.arrayBuffer()));" + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.users.generatePdf(\"user-abc-123\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Users.GeneratePDF(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.users().generatePdf(\"user-abc-123\")\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->generatePdf('user-abc-123');\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.users.generate_pdf(\"user-abc-123\")\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Users.GeneratePdfAsync(\"user-abc-123\");\nawait content.SaveToAsync(\"download.pdf\");" } ] } @@ -19404,7 +20979,7 @@ "/v3/users/delete/": { "post": { "summary": "Batch delete users", - "description": "**Permanently delete** users: the user records are removed permanently. For everyday blocking prefer [Update User Status](#patch-/v3/users/-vendor_data-/update-status/) with `BLOCKED`. Select users with `vendor_data_list`, with `didit_internal_id_list`, or with both at once; or pass `delete_all: true`. This endpoint never narrows `delete_all` with filters. The Console's People filters are refused with a `400` (see the `400` response), so a narrowed intent does not turn into a full wipe. Two exceptions: `filter_has_approved_sessions` and `filter_has_declined_sessions` are not refused and not applied, so with `delete_all: true` they still delete every user; do not send them.\n\n**Biometric templates:** every image-free biometric template retained for these users after session deletion (see `/v3/biometric-templates/`) is purged before the user is deleted, so the person stops matching in duplicate detection and Face Search. If a template cannot be purged because a biometric store is unavailable, the call returns `503`, no user in the request is deleted, and repeating the request finishes the job.\n\n**Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request.", + "description": "**Permanently delete** users: the user records are removed permanently. For everyday blocking prefer [Update User Status](#patch-/v3/users/-vendor_data-/update-status/) with `BLOCKED`. Select users with `vendor_data_list`, with `didit_internal_id_list`, or with both at once; or pass `delete_all: true`. This endpoint never narrows `delete_all` with filters. The Console's People filters are refused with a `400` (see the `400` response), so a narrowed intent does not turn into a full wipe. Two exceptions: `filter_has_approved_sessions` and `filter_has_declined_sessions` are not refused and not applied, so with `delete_all: true` they still delete every user; do not send them.\n\n**Biometric templates:** unless you set `retain_face_embeddings` to `true`, every image-free biometric template retained for these users after session deletion (see `/v3/biometric-templates/`) is purged before the user is deleted, so the person stops matching in duplicate detection and Face Search. With `retain_face_embeddings: true` and `face_retention_days`, you choose to keep one image-free biometric template per person for that many days, and nothing else about the person is kept. If a template cannot be purged because a biometric store is unavailable, the call returns `503`, no user in the request is deleted, and repeating the request finishes the job.\n\n**Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request.", "operationId": "batch_delete_users", "x-didit-sdk": { "resource": "users", @@ -19442,6 +21017,18 @@ "type": "boolean", "default": false, "description": "If `true`, deletes every user in the application." + }, + "retain_face_embeddings": { + "type": "boolean", + "default": false, + "description": "Your explicit choice to keep one image-free biometric template of each deleted person for duplicate detection, for `face_retention_days`. Everything else about the person is deleted. Omit it, or send `false`, to delete the templates with the users. When `true`, `face_retention_days` is required." + }, + "face_retention_days": { + "type": "integer", + "minimum": 1, + "maximum": 3650, + "description": "Number of days the image-free biometric template is kept when `retain_face_embeddings` is `true`. Required with it, and rejected without it with a `400` on `face_retention_days`.", + "example": 365 } } }, @@ -19468,6 +21055,16 @@ "value": { "delete_all": true } + }, + "Keep face templates": { + "summary": "Delete users and keep anonymous face templates for 365 days", + "value": { + "vendor_data_list": [ + "user-123" + ], + "retain_face_embeddings": true, + "face_retention_days": 365 + } } } } @@ -19482,12 +21079,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/users/delete/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'vendor_data_list': ['user-123', 'user-456']},\n)\nresp.raise_for_status()\nprint('deleted', resp.json()['deleted'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.batch_delete(\n vendor_data_list=[\"user-123\", \"user-456\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/users/delete/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ vendor_data_list: ['user-123', 'user-456'] }),\n});\nconst body = await resp.json();\nconsole.log('deleted', body.deleted);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.batchDelete({\n vendor_data_list: [\"user-123\", \"user-456\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.BatchDelete(ctx, didit.UsersBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.UsersBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().batchDelete(UsersBatchDeleteParams.builder()\n .vendorDataList(List.of(\"user-123\", \"user-456\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->batchDelete([\n 'vendor_data_list' => ['user-123', 'user-456'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.batch_delete(vendor_data_list: [\"user-123\", \"user-456\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.BatchDeleteAsync(new UsersBatchDeleteParams\n{\n VendorDataList = new string[] { \"user-123\", \"user-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -19556,7 +21178,7 @@ } }, "403": { - "description": "Invalid or revoked API key, or the key cannot delete users for this application. Note: on this endpoint an *invalid* key returns `403` (not `401`).", + "description": "Invalid or revoked API key, or the key cannot delete users for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -20138,7 +21760,7 @@ } }, "403": { - "description": "Missing or invalid API key. This API returns `403` for authentication failures — never `401`.", + "description": "Missing API key. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "schema": { @@ -20203,12 +21825,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/sessions/delete/\",\n headers={\n \"x-api-key\": \"YOUR_API_KEY\",\n \"Content-Type\": \"application/json\",\n },\n json={\"session_numbers\": [\"1001\", \"1002\", \"1003\"]},\n)\nresponse.raise_for_status()\nif response.status_code == 202: # more than 20 sessions: poll the job\n job_id = response.json()[\"job_id\"]\nelse: # 200: one result per matched session\n print(response.json()[\"results\"])\n\n# Destructive: delete every KYC session in the application\n# requests.post(\n# \"https://verification.didit.me/v3/sessions/delete/\",\n# headers={\"x-api-key\": \"YOUR_API_KEY\"},\n# json={\"delete_all\": True},\n# )" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.batch_delete(\n session_numbers=[\"1001\", \"1002\", \"1003\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/sessions/delete/',\n {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ session_numbers: ['1001', '1002', '1003'] }),\n },\n);\nif (response.status !== 200 && response.status !== 202) throw new Error(`HTTP ${response.status}`);\nconst body = await response.json();\n// 200: body.results, one per matched session. 202: poll /v3/sessions/delete/${body.job_id}/" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.batchDelete({\n session_numbers: [\"1001\", \"1002\", \"1003\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.BatchDelete(ctx, didit.SessionsBatchDeleteParams{\n\tSessionNumbers: didit.Some([]string{\"1001\", \"1002\", \"1003\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().batchDelete(SessionsBatchDeleteParams.builder()\n .sessionNumbers(List.of(\"1001\", \"1002\", \"1003\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->batchDelete([\n 'session_numbers' => ['1001', '1002', '1003'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.batch_delete(session_numbers: [\"1001\", \"1002\", \"1003\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.BatchDeleteAsync(new SessionsBatchDeleteParams\n{\n SessionNumbers = new string[] { \"1001\", \"1002\", \"1003\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -20253,12 +21900,37 @@ { "lang": "python", "label": "Python", - "source": "import time\nimport requests\n\nurl = 'https://verification.didit.me/v3/sessions/delete/JOB_ID/'\nwhile True:\n job = requests.get(url, headers={'x-api-key': 'YOUR_API_KEY'}).json()\n if job['status'] in ('COMPLETED', 'FAILED'):\n break\n time.sleep(3)\nprint(job['status'], job['outcomes'], job['error'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.retrieve_deletion_job(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const url = 'https://verification.didit.me/v3/sessions/delete/JOB_ID/';\nlet job;\ndo {\n await new Promise((r) => setTimeout(r, 3000));\n job = await (await fetch(url, { headers: { 'x-api-key': 'YOUR_API_KEY' } })).json();\n} while (job.status === 'PENDING' || job.status === 'PROCESSING');\nconsole.log(job.status, job.outcomes, job.error);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.retrieveDeletionJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RetrieveDeletionJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().retrieveDeletionJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->retrieveDeletionJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.retrieve_deletion_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RetrieveDeletionJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -20335,7 +22007,7 @@ } }, "403": { - "description": "Missing or invalid API key. This API returns `403` for authentication failures, never `401`.", + "description": "Missing API key. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "schema": { @@ -20584,7 +22256,7 @@ } }, "403": { - "description": "Missing, malformed, expired, or revoked `x-api-key`. Authentication is checked before the session lookup, so an invalid key returns `403` even when the session UUID does not exist.", + "description": "Missing, malformed, expired, or revoked `x-api-key`. Authentication is checked before the session lookup, so a missing key returns `403` even when the session UUID does not exist.", "content": { "application/json": { "schema": { @@ -20647,14 +22319,39 @@ "source": "curl -s 'https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/?limit=50' \\\n -H 'x-api-key: YOUR_API_KEY'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import os, requests\n\nsession_id = \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\"\nurl = f\"https://verification.didit.me/v3/sessions/{session_id}/reviews/\"\n\nwhile url: # walk every page of the feed\n resp = requests.get(url, headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]}, timeout=10)\n resp.raise_for_status()\n page = resp.json()\n for entry in page[\"results\"]:\n print(entry[\"created_at\"], entry[\"activity_type\"], entry[\"actor_display\"], entry.get(\"new_status\"))\n url = page[\"next\"]" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.reviews.list(\n \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n):\n print(item)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "const sessionId = \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\";\nconst res = await fetch(\n `https://verification.didit.me/v3/sessions/${sessionId}/reviews/`,\n { headers: { 'x-api-key': 'YOUR_API_KEY' } },\n);\nif (!res.ok) throw new Error(`Didit ${res.status}`);\nconst { count, results } = await res.json();\nconsole.log(`${count} feed entries`);\nfor (const entry of results) {\n console.log(entry.created_at, entry.activity_type, entry.actor_display, entry.new_status ?? \"\");\n}" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.reviews.list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.Reviews.ListAutoPaging(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().reviews().list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->reviews->list('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.reviews.list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.Reviews.ListAsync(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] }, @@ -20845,7 +22542,7 @@ } }, "403": { - "description": "Missing, malformed, expired, or revoked `x-api-key`. Authentication is checked before the session lookup, so an invalid key returns `403` even when the session UUID does not exist.", + "description": "Missing, malformed, expired, or revoked `x-api-key`. Authentication is checked before the session lookup, so a missing key returns `403` even when the session UUID does not exist.", "content": { "application/json": { "schema": { @@ -20908,14 +22605,39 @@ "source": "# Records an audit-trail note only -- the session's status does NOT change.\ncurl -s -X POST https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"new_status\": \"In Review\",\n \"comment\": \"Flagging for manual document re-check.\"\n }'" }, { - "lang": "Python", - "label": "Python (requests)", - "source": "import os, requests\n\n# Records an audit-trail note only -- the session's status does NOT change.\n# To approve/decline a session use PATCH /v3/session/{session_id}/update-status/.\nsession_id = \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\"\nresp = requests.post(\n f\"https://verification.didit.me/v3/sessions/{session_id}/reviews/\",\n headers={\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Content-Type\": \"application/json\",\n },\n json={\n \"new_status\": \"In Review\",\n \"comment\": \"Flagging for manual document re-check.\",\n },\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json()) # {'user': 'Unknown', 'new_status': 'In Review', ...}" + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.reviews.create(\n \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n new_status=\"In Review\",\n comment=\"Flagging for manual document re-check.\",\n)\nprint(result)" }, { - "lang": "JavaScript", - "label": "Node.js (fetch)", - "source": "// Records an audit-trail note only -- the session's status does NOT change.\n// To approve/decline a session use PATCH /v3/session/{session_id}/update-status/.\nconst sessionId = \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\";\nconst res = await fetch(\n `https://verification.didit.me/v3/sessions/${sessionId}/reviews/`,\n {\n method: \"POST\",\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n new_status: \"In Review\",\n comment: \"Flagging for manual document re-check.\",\n }),\n },\n);\nif (!res.ok) throw new Error(`Didit ${res.status}: ${await res.text()}`);\nconsole.log(await res.json()); // { user: 'Unknown', new_status: 'In Review', ... }" + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.reviews.create(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", {\n new_status: \"In Review\",\n comment: \"Flagging for manual document re-check.\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Reviews.Create(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsCreateParams{\n\tNewStatus: didit.Some(didit.SessionsReviewsCreateParamsNewStatus(\"In Review\")),\n\tComment: didit.String(\"Flagging for manual document re-check.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsReviewsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().reviews().create(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", SessionsReviewsCreateParams.builder()\n .newStatus(SessionsReviewsCreateParams.NewStatus.of(\"In Review\"))\n .comment(\"Flagging for manual document re-check.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->reviews->create('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d', [\n 'new_status' => 'In Review',\n 'comment' => 'Flagging for manual document re-check.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.reviews.create(\n \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n new_status: \"In Review\",\n comment: \"Flagging for manual document re-check.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Reviews.CreateAsync(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", new SessionsReviewsCreateParams\n{\n NewStatus = new SessionsReviewsCreateParamsNewStatus(\"In Review\"),\n Comment = \"Flagging for manual document re-check.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -20943,12 +22665,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nfrom decimal import Decimal\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/billing/balance/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\ndata = resp.json()\nbalance = Decimal(data['balance'])\nif balance < Decimal('50'):\n print(f'Low balance: ${balance} - top up before launching new sessions.')\nelse:\n print(f'Balance OK: ${balance}')" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.billing.retrieve_balance()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/billing/balance/', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Billing balance failed: ${resp.status}`);\nconst { balance, auto_refill_enabled, auto_refill_threshold } = await resp.json();\nconsole.log({ balance, auto_refill_enabled, auto_refill_threshold });" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.billing.retrieveBalance();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Billing.RetrieveBalance(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.billing().retrieveBalance();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "billing->retrieveBalance();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.billing.retrieve_balance\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Billing.RetrieveBalanceAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -21005,7 +22752,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot read billing data for this organization. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot read billing data for this organization. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -21108,12 +22855,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/billing/top-up/',\n headers={\n 'x-api-key': os.environ['DIDIT_API_KEY'],\n 'Content-Type': 'application/json',\n },\n json={\n 'amount_in_dollars': 500,\n 'success_url': 'https://yourapp.com/billing/success',\n 'cancel_url': 'https://yourapp.com/billing/cancel',\n },\n timeout=10,\n)\nresp.raise_for_status()\nsession = resp.json()\nprint('Redirect customer to:', session['checkout_session_url'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.billing.top_up(\n amount_in_dollars=50.0,\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/billing/top-up/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n amount_in_dollars: 500,\n success_url: 'https://yourapp.com/billing/success',\n cancel_url: 'https://yourapp.com/billing/cancel',\n }),\n});\nif (!resp.ok) throw new Error(`Top-up failed: ${resp.status}`);\nconst { checkout_session_url } = await resp.json();\nwindow.location.assign(checkout_session_url);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.billing.topUp({\n amount_in_dollars: 50.0,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Billing.TopUp(ctx, didit.BillingTopUpParams{\n\tAmountInDollars: 50.0,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BillingTopUpParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.billing().topUp(BillingTopUpParams.builder()\n .amountInDollars(50.0)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "billing->topUp([\n 'amount_in_dollars' => 50.0,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.billing.top_up(amount_in_dollars: 50.0)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Billing.TopUpAsync(new BillingTopUpParams\n{\n AmountInDollars = 50.0,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -21185,7 +22957,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot create top-up sessions for this organization. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot create top-up sessions for this organization. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -21243,12 +23015,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/webhook/destinations/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nfor dest in resp.json():\n print(f\"{dest['label']:30s} {dest['url']:50s} {dest['health_status']}\")" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.list()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/webhook/destinations/', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nconst destinations = await resp.json();\nfor (const d of destinations) {\n console.log(d.label, d.url, d.health_status, `${d.error_rate_percentage}% errors`);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.list();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().list();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->list();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.list.each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.ListAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -21771,7 +23568,7 @@ } }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -21827,12 +23624,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/webhook/destinations/',\n headers={\n 'x-api-key': os.environ['DIDIT_API_KEY'],\n 'Content-Type': 'application/json',\n },\n json={\n 'label': 'Production session webhooks',\n 'url': 'https://yourapp.com/webhooks/didit',\n 'webhook_version': 'v3',\n 'subscribed_events': ['status.updated', 'data.updated'],\n },\n timeout=10,\n)\nresp.raise_for_status()\ndestination = resp.json()\n# Store secret_shared_key in your secret manager.\nprint('Destination UUID:', destination['uuid'])\nprint('Signing secret:', destination['secret_shared_key'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.create(\n label=\"Production session webhooks\",\n url=\"https://yourapp.com/webhooks/didit\",\n webhook_version=\"v3\",\n subscribed_events=[\"status.updated\", \"data.updated\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/webhook/destinations/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n label: 'Production session webhooks',\n url: 'https://yourapp.com/webhooks/didit',\n webhook_version: 'v3',\n subscribed_events: ['status.updated', 'data.updated'],\n }),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst destination = await resp.json();\nconsole.log('Store this secret securely:', destination.secret_shared_key);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.create({\n label: \"Production session webhooks\",\n url: \"https://yourapp.com/webhooks/didit\",\n webhook_version: \"v3\",\n subscribed_events: [\"status.updated\", \"data.updated\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Create(ctx, didit.WebhooksDestinationsCreateParams{\n\tLabel: \"Production session webhooks\",\n\tURL: \"https://yourapp.com/webhooks/didit\",\n\tWebhookVersion: didit.Some(didit.WebhooksDestinationsCreateParamsWebhookVersion(\"v3\")),\n\tSubscribedEvents: didit.Some([]didit.WebhookEvent{didit.WebhookEvent(\"status.updated\"), didit.WebhookEvent(\"data.updated\")}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.WebhookEvent;\nimport me.didit.types.WebhooksDestinationsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().create(WebhooksDestinationsCreateParams.builder()\n .label(\"Production session webhooks\")\n .url(\"https://yourapp.com/webhooks/didit\")\n .webhookVersion(WebhooksDestinationsCreateParams.WebhookVersion.of(\"v3\"))\n .subscribedEvents(List.of(WebhookEvent.of(\"status.updated\"), WebhookEvent.of(\"data.updated\")))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->create([\n 'label' => 'Production session webhooks',\n 'url' => 'https://yourapp.com/webhooks/didit',\n 'webhook_version' => 'v3',\n 'subscribed_events' => ['status.updated', 'data.updated'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.create(\n label: \"Production session webhooks\",\n url: \"https://yourapp.com/webhooks/didit\",\n webhook_version: \"v3\",\n subscribed_events: [\"status.updated\", \"data.updated\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.CreateAsync(new WebhooksDestinationsCreateParams\n{\n Label = \"Production session webhooks\",\n Url = \"https://yourapp.com/webhooks/didit\",\n WebhookVersion = new WebhooksDestinationsCreateParamsWebhookVersion(\"v3\"),\n SubscribedEvents = new WebhookEvent[] { \"status.updated\", \"data.updated\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -21854,7 +23676,8 @@ "url": { "type": "string", "format": "uri", - "description": "HTTPS URL that will receive `POST` requests. Must be unique among the application's destinations. Use a stable, hardened endpoint: Didit retries failed deliveries on a backoff schedule." + "description": "HTTPS URL that will receive `POST` requests. Must be unique among the application's destinations. Use a stable, hardened endpoint: Didit retries failed deliveries on a backoff schedule.", + "maxLength": 2000 }, "enabled": { "type": "boolean", @@ -22132,7 +23955,7 @@ } }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -22203,12 +24026,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nuuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/webhook/destinations/{uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const uuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/webhook/destinations/${uuid}/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Lookup failed: ${resp.status}`);\nconst destination = await resp.json();\nconsole.log(destination);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -22388,7 +24236,7 @@ } }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -22531,12 +24379,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nuuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.patch(\n f'https://verification.didit.me/v3/webhook/destinations/{uuid}/',\n headers={\n 'x-api-key': os.environ['DIDIT_API_KEY'],\n 'Content-Type': 'application/json',\n },\n json={'enabled': False},\n timeout=10,\n)\nresp.raise_for_status()\nprint('Paused destination:', resp.json()['label'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.update(\n \"11111111-2222-3333-4444-555555555555\",\n enabled=False,\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const uuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/webhook/destinations/${uuid}/`, {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ enabled: false }),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconsole.log(await resp.json());" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.update(\"11111111-2222-3333-4444-555555555555\", {\n enabled: false,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsUpdateParams{\n\tEnabled: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.WebhooksDestinationsUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().update(\"11111111-2222-3333-4444-555555555555\", WebhooksDestinationsUpdateParams.builder()\n .enabled(false)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->update('11111111-2222-3333-4444-555555555555', [\n 'enabled' => false,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.update(\n \"11111111-2222-3333-4444-555555555555\",\n enabled: false\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new WebhooksDestinationsUpdateParams\n{\n Enabled = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -22738,7 +24611,7 @@ } }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -22821,12 +24694,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nuuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.delete(\n f'https://verification.didit.me/v3/webhook/destinations/{uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nassert resp.status_code == 204" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.webhooks.destinations.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const uuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/webhook/destinations/${uuid}/`, {\n method: 'DELETE',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (resp.status !== 204) throw new Error(`Delete failed: ${resp.status}`);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.webhooks.destinations.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Webhooks.Destinations.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.webhooks().destinations().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Webhooks.Destinations.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ], "responses": { @@ -22834,7 +24732,7 @@ "description": "Destination, signing secret and delivery log deleted permanently. No response body." }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -22909,8 +24807,7 @@ "schema": { "type": "object", "required": [ - "wallet_address", - "blockchain" + "wallet_address" ], "properties": { "wallet_address": { @@ -22920,7 +24817,7 @@ }, "blockchain": { "type": "string", - "description": "Network identifier. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), and ARB (Arbitrum One). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`.", + "description": "Optional network identifier. When omitted, the network is read from the address format: `bc1`, `1` and `3` addresses are Bitcoin (BTC), `T` addresses are Tron (TRX) and base58 public keys are Solana (SOL). A `0x` address is valid on every EVM network, so omitting `blockchain` for it answers 422 with the candidate networks in `candidate_chains`. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar) and HBAR (Hedera). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`.", "enum": [ "BTC", "LIGHTNING", @@ -22938,6 +24835,10 @@ "BASE", "OP", "ARB", + "AVAX", + "ADA", + "XLM", + "HBAR", "CELO", "MODE", "PLUME" @@ -22955,6 +24856,10 @@ ] } } + }, + "example": { + "wallet_address": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a", + "blockchain": "ETH" } } } @@ -22968,12 +24873,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/wallet-screening/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'wallet_address': '0x94f1b9b64e2932f6a2db338f616844400cd58e8a',\n 'blockchain': 'ETH',\n },\n timeout=20,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result['risk_score'], result['severity'], result['sanctions_hit'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.wallet_screening.screen(\n wallet_address=\"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n blockchain=\"ETH\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const result = await fetch('https://verification.didit.me/v3/wallet-screening/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n wallet_address: '0x94f1b9b64e2932f6a2db338f616844400cd58e8a',\n blockchain: 'ETH',\n }),\n}).then((r) => r.json());\nconsole.log(result.risk_score, result.severity, result.sanctions_hit);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.walletScreening.screen({\n wallet_address: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n blockchain: \"ETH\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.WalletScreening.Screen(ctx, didit.WalletScreeningScreenParams{\n\tWalletAddress: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n\tBlockchain: didit.Some(didit.WalletScreeningScreenParamsBlockchain(\"ETH\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.WalletScreeningScreenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.walletScreening().screen(WalletScreeningScreenParams.builder()\n .walletAddress(\"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\")\n .blockchain(WalletScreeningScreenParams.Blockchain.of(\"ETH\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "walletScreening->screen([\n 'wallet_address' => '0x94f1b9b64e2932f6a2db338f616844400cd58e8a',\n 'blockchain' => 'ETH',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.wallet_screening.screen(\n wallet_address: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n blockchain: \"ETH\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.WalletScreening.ScreenAsync(new WalletScreeningScreenParams\n{\n WalletAddress = \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n Blockchain = new WalletScreeningScreenParamsBlockchain(\"ETH\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -23163,7 +25093,7 @@ } }, "400": { - "description": "Validation error — malformed wallet address, missing `wallet_address`, unsupported `blockchain`, or LIGHTNING without an Elliptic or Chainalysis BYOK Marketplace connection." + "description": "Validation error — malformed wallet address, missing `wallet_address`, unsupported `blockchain`, `blockchain` omitted for an address whose format names no network, or LIGHTNING without an Elliptic or Chainalysis BYOK Marketplace connection." }, "401": { "description": "Missing or invalid `x-api-key`." @@ -23171,6 +25101,44 @@ "409": { "description": "No AML provider is configured for the application, or the configured provider does not support wallet screening yet. Configure transaction monitoring first." }, + "422": { + "description": "`blockchain` omitted for a `0x` address, which every EVM network shares. Nothing is screened or billed; resend with `blockchain` set to one of `candidate_chains`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "blockchain": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "A 0x address is valid on every EVM chain. Send blockchain as one of: ETH, BNB, MATIC, BASE, ARB, OP, CELO, MODE, PLUME." + ] + }, + "candidate_chains": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "ETH", + "BNB", + "MATIC", + "BASE", + "ARB", + "OP", + "CELO", + "MODE", + "PLUME" + ] + } + } + } + } + } + }, "502": { "description": "The AML provider could not complete the screening. Retry later." } @@ -23224,12 +25192,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\n# `result` is the dict returned by POST /v3/wallet-screening/, unmodified\nresponse = requests.post(\n 'https://verification.didit.me/v3/wallet-screening/pdf/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n json=result,\n timeout=30,\n)\nresponse.raise_for_status()\nwith open('wallet_screening_report.pdf', 'wb') as fh:\n fh.write(response.content)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.wallet_screening.screen_pdf(\n provider=\"your-provider\",\n screening_type=\"WALLET_SCREENING\",\n risk_score=1,\n severity=\"UNKNOWN\",\n status=\"SCREENED\",\n summary=\"your-summary\",\n wallet_address=\"your-wallet-address\",\n blockchain=\"your-blockchain\",\n source_of_funds=[{}],\n destination_of_funds=[{}],\n counterparty_connections=[{}],\n sanctions_hit=True,\n dominant_risk_category=\"your-dominant-risk-category\",\n report_signature=\"your-report-signature\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "// `result` is the object returned by POST /v3/wallet-screening/, unmodified\nconst response = await fetch('https://verification.didit.me/v3/wallet-screening/pdf/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(result),\n});\nif (!response.ok) throw new Error(`PDF generation failed: HTTP ${response.status}`);\nconst pdfBuffer = Buffer.from(await response.arrayBuffer());" + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.walletScreening.screenPdf({\n provider: \"your-provider\",\n screening_type: \"WALLET_SCREENING\",\n risk_score: 1,\n severity: \"UNKNOWN\",\n status: \"SCREENED\",\n summary: \"your-summary\",\n wallet_address: \"your-wallet-address\",\n blockchain: \"your-blockchain\",\n source_of_funds: [{}],\n destination_of_funds: [{}],\n counterparty_connections: [{}],\n sanctions_hit: true,\n dominant_risk_category: \"your-dominant-risk-category\",\n report_signature: \"your-report-signature\",\n});\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.WalletScreening.ScreenPDF(ctx, didit.WalletScreeningResultParam{\n\tProvider: \"your-provider\",\n\tScreeningType: \"WALLET_SCREENING\",\n\tRiskScore: 1,\n\tSeverity: \"UNKNOWN\",\n\tStatus: \"SCREENED\",\n\tSummary: \"your-summary\",\n\tWalletAddress: \"your-wallet-address\",\n\tBlockchain: \"your-blockchain\",\n\tSourceOfFunds: []didit.WalletScreeningResultParamSourceOfFunds{{}},\n\tDestinationOfFunds: []didit.WalletScreeningResultParamDestinationOfFunds{{}},\n\tCounterpartyConnections: []didit.WalletScreeningResultParamCounterpartyConnections{{}},\n\tSanctionsHit: true,\n\tDominantRiskCategory: didit.String(\"your-dominant-risk-category\"),\n\tReportSignature: \"your-report-signature\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.WalletScreeningResult;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.walletScreening().screenPdf(WalletScreeningResult.builder()\n .provider(\"your-provider\")\n .screeningType(WalletScreeningResult.ScreeningType.of(\"WALLET_SCREENING\"))\n .riskScore(1L)\n .severity(WalletScreeningResult.Severity.of(\"UNKNOWN\"))\n .status(WalletScreeningResult.Status.of(\"SCREENED\"))\n .summary(\"your-summary\")\n .walletAddress(\"your-wallet-address\")\n .blockchain(\"your-blockchain\")\n .sourceOfFunds(List.of(WalletScreeningResult.SourceOfFunds.builder()\n .build()))\n .destinationOfFunds(List.of(WalletScreeningResult.DestinationOfFunds.builder()\n .build()))\n .counterpartyConnections(List.of(WalletScreeningResult.CounterpartyConnections.builder()\n .build()))\n .sanctionsHit(true)\n .dominantRiskCategory(\"your-dominant-risk-category\")\n .reportSignature(\"your-report-signature\")\n .build())\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "walletScreening->screenPdf([\n 'provider' => 'your-provider',\n 'screening_type' => 'WALLET_SCREENING',\n 'risk_score' => 1,\n 'severity' => 'UNKNOWN',\n 'status' => 'SCREENED',\n 'summary' => 'your-summary',\n 'wallet_address' => 'your-wallet-address',\n 'blockchain' => 'your-blockchain',\n 'source_of_funds' => [[]],\n 'destination_of_funds' => [[]],\n 'counterparty_connections' => [[]],\n 'sanctions_hit' => true,\n 'dominant_risk_category' => 'your-dominant-risk-category',\n 'report_signature' => 'your-report-signature',\n]);\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.wallet_screening.screen_pdf(\n provider: \"your-provider\",\n screening_type: \"WALLET_SCREENING\",\n risk_score: 1,\n severity: \"UNKNOWN\",\n status: \"SCREENED\",\n summary: \"your-summary\",\n wallet_address: \"your-wallet-address\",\n blockchain: \"your-blockchain\",\n source_of_funds: [{}],\n destination_of_funds: [{}],\n counterparty_connections: [{}],\n sanctions_hit: true,\n dominant_risk_category: \"your-dominant-risk-category\",\n report_signature: \"your-report-signature\"\n)\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.WalletScreening.ScreenPdfAsync(new WalletScreeningResult\n{\n Provider = \"your-provider\",\n ScreeningType = \"WALLET_SCREENING\",\n RiskScore = 1,\n Severity = \"UNKNOWN\",\n Status = \"SCREENED\",\n Summary = \"your-summary\",\n WalletAddress = \"your-wallet-address\",\n Blockchain = \"your-blockchain\",\n SourceOfFunds = new WalletScreeningResultSourceOfFunds[] { new() },\n DestinationOfFunds = new WalletScreeningResultDestinationOfFunds[] { new() },\n CounterpartyConnections = new WalletScreeningResultCounterpartyConnections[] { new() },\n SanctionsHit = true,\n DominantRiskCategory = \"your-dominant-risk-category\",\n ReportSignature = \"your-report-signature\",\n});\nawait content.SaveToAsync(\"download.pdf\");" } ], "responses": { @@ -23306,7 +25299,8 @@ "schema": { "type": "integer", "default": 50, - "minimum": 1 + "minimum": 1, + "maximum": 1000000 }, "description": "Page size. Defaults to 50 when omitted. There is no enforced maximum, but keep pages small for latency." }, @@ -23316,7 +25310,8 @@ "schema": { "type": "integer", "default": 0, - "minimum": 0 + "minimum": 0, + "maximum": 1000000 }, "description": "Zero-based offset of the first record to return. Prefer following the `next` URL from the previous page." }, @@ -23328,6 +25323,15 @@ "type": "string" }, "description": "Return only transactions whose Travel Rule transfer is in this exact status (for example `ON_HOLD` or `AWAITING_COUNTERPARTY`). `count` follows this filter; `total_transactions` still counts every transaction in the application." + }, + { + "name": "assignee", + "in": "query", + "required": false, + "schema": { + "type": "string" + }, + "description": "Comma-separated; a transaction matches when it meets any value. `unassigned` is what nobody holds yet, `rules` is what the rules decided on their own without a reviewer, and a member email matches the reviewer assigned to it. `me` is the signed-in Console reviewer, so an API key sending `me` gets `400`." } ], "x-codeSamples": [ @@ -23339,12 +25343,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/transactions/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'limit': 50},\n timeout=10,\n)\nresp.raise_for_status()\npage = resp.json()\nfor tx in page['results']:\n print(\n tx['transaction_number'],\n tx['status'],\n tx['severity'],\n f\"{tx['amount']} {tx['currency']}\",\n tx.get('subject_name') or tx.get('subject_vendor_data'),\n )" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const url = new URL('https://verification.didit.me/v3/transactions/');\nurl.searchParams.set('limit', '50');\nconst page = await fetch(url, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n}).then((r) => r.json());\nfor (const tx of page.results) {\n console.log(tx.transaction_number, tx.status, tx.severity, tx.amount, tx.currency);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.ListAutoPaging(ctx, didit.TransactionsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -23615,7 +25644,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot list transactions for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot list transactions for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -23665,12 +25694,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/transactions/',\n headers={\n 'x-api-key': os.environ['DIDIT_API_KEY'],\n 'Content-Type': 'application/json',\n },\n json={\n 'transaction_id': 'your-txn-2026-05-17-001',\n 'transaction_category': 'finance',\n 'transaction_details': {\n 'direction': 'outbound',\n 'amount': 1500,\n 'currency': 'EUR',\n 'action_type': 'withdrawal',\n },\n 'subject': {\n 'entity_type': 'individual',\n 'vendor_data': 'user-12345',\n 'full_name': 'Maria Garcia',\n },\n },\n timeout=15,\n)\nresp.raise_for_status()\ntx = resp.json()\nprint(tx['txn_id'], '->', tx['status'], tx['severity'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.create(\n transaction_id=\"your-txn-2026-05-17-001\",\n transaction_category=\"finance\",\n transaction_details={\n \"direction\": \"outbound\",\n \"amount\": 1500.0,\n \"currency\": \"EUR\",\n \"action_type\": \"withdrawal\",\n },\n subject={\n \"entity_type\": \"individual\",\n \"vendor_data\": \"user-12345\",\n \"full_name\": \"Maria Garcia\",\n },\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/transactions/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n transaction_id: 'your-txn-2026-05-17-001',\n transaction_category: 'finance',\n transaction_details: {\n direction: 'outbound',\n amount: 1500,\n currency: 'EUR',\n action_type: 'withdrawal',\n },\n subject: {\n entity_type: 'individual',\n vendor_data: 'user-12345',\n full_name: 'Maria Garcia',\n },\n }),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst tx = await resp.json();\nconsole.log(tx.txn_id, tx.status, tx.severity);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.create({\n transaction_id: \"your-txn-2026-05-17-001\",\n transaction_category: \"finance\",\n transaction_details: {\n direction: \"outbound\",\n amount: 1500.0,\n currency: \"EUR\",\n action_type: \"withdrawal\",\n },\n subject: {\n entity_type: \"individual\",\n vendor_data: \"user-12345\",\n full_name: \"Maria Garcia\",\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Create(ctx, didit.TransactionsCreateParams{\n\tTransactionID: \"your-txn-2026-05-17-001\",\n\tTransactionCategory: \"finance\",\n\tTransactionDetails: didit.TransactionsCreateParamsTransactionDetails{\n\t\tDirection: \"outbound\",\n\t\tAmount: 1500.0,\n\t\tCurrency: \"EUR\",\n\t\tActionType: didit.String(\"withdrawal\"),\n\t},\n\tSubject: didit.TransactionsCreateParamsSubject{\n\t\tEntityType: didit.String(\"individual\"),\n\t\tVendorData: \"user-12345\",\n\t\tFullName: \"Maria Garcia\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TransactionsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().create(TransactionsCreateParams.builder()\n .transactionId(\"your-txn-2026-05-17-001\")\n .transactionCategory(TransactionsCreateParams.TransactionCategory.of(\"finance\"))\n .transactionDetails(TransactionsCreateParams.TransactionDetails.builder()\n .direction(TransactionsCreateParams.TransactionDetails.Direction.of(\"outbound\"))\n .amount(1500.0)\n .currency(\"EUR\")\n .actionType(\"withdrawal\")\n .build())\n .subject(TransactionsCreateParams.Subject.builder()\n .entityType(\"individual\")\n .vendorData(\"user-12345\")\n .fullName(\"Maria Garcia\")\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->create([\n 'transaction_id' => 'your-txn-2026-05-17-001',\n 'transaction_category' => 'finance',\n 'transaction_details' => [\n 'direction' => 'outbound',\n 'amount' => 1500.0,\n 'currency' => 'EUR',\n 'action_type' => 'withdrawal',\n ],\n 'subject' => [\n 'entity_type' => 'individual',\n 'vendor_data' => 'user-12345',\n 'full_name' => 'Maria Garcia',\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.create(\n transaction_id: \"your-txn-2026-05-17-001\",\n transaction_category: \"finance\",\n transaction_details: {\n direction: \"outbound\",\n amount: 1500.0,\n currency: \"EUR\",\n action_type: \"withdrawal\",\n },\n subject: {\n entity_type: \"individual\",\n vendor_data: \"user-12345\",\n full_name: \"Maria Garcia\",\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.CreateAsync(new TransactionsCreateParams\n{\n TransactionId = \"your-txn-2026-05-17-001\",\n TransactionCategory = \"finance\",\n TransactionDetails = new()\n {\n Direction = \"outbound\",\n Amount = 1500.0,\n Currency = \"EUR\",\n ActionType = \"withdrawal\",\n },\n Subject = new()\n {\n EntityType = \"individual\",\n VendorData = \"user-12345\",\n FullName = \"Maria Garcia\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -23732,7 +25786,7 @@ }, "amount": { "type": "number", - "description": "Transaction amount (up to 18 decimal places). Send it as a decimal string (e.g. `\"0.123456789012345678\"`) when exact precision matters: a JSON number is parsed as a binary float first, so digits beyond about 15 significant digits are rounded before the amount is stored.", + "description": "Transaction amount (up to 18 decimal places). Send it as a decimal string (e.g. `\"0.123456789012345678\"`) when exact precision matters: a JSON number is parsed as a binary float first, so digits beyond about 15 significant digits are rounded before the amount is stored. Must be zero or greater: the direction carries the sign, and a negative amount returns `400`.", "example": 1500 }, "currency": { @@ -23747,7 +25801,7 @@ "amount_in_default_currency": { "type": "number", "nullable": true, - "description": "Pre-converted amount in the default currency. If omitted, automatic FX conversion is attempted." + "description": "Pre-converted amount in the default currency. If omitted, automatic FX conversion is attempted. Must be zero or greater." }, "default_currency": { "type": "string", @@ -23774,7 +25828,7 @@ "properties": { "crypto_chain": { "type": "string", - "description": "Actual network used for screening. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism) and ARB (Arbitrum One). Always specify this for multi-network tokens. When it is missing for USDT, USDC or ETH sent with a 0x transaction hash, Didit looks the hash up on Ethereum, BNB Chain, Polygon, Base, Arbitrum and Optimism and screens it on the network where it is found; if no network has it, the transaction is not screened and custom_values.aml_screening_status is FAILED with the reason in custom_values.aml_screening_error. When it is missing for USDT or USDC screened by wallet (no transaction hash), a Tron address is screened on Tron, a Solana address on Solana, and a 0x address on the first of those six networks where it has sent a transaction or holds the token, or on Ethereum when it is active on none of them. Connected-provider coverage varies; LIGHTNING requires a supported connected provider.", + "description": "Actual network used for screening. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar) and HBAR (Hedera). Common network names are accepted too, for example POLYGON or POL for MATIC, BSC for BNB and TRON for TRX. Always specify this for multi-network tokens. When it is missing for USDT, USDC or ETH sent with a 0x transaction hash, Didit looks the hash up on Ethereum, BNB Chain, Polygon, Base, Arbitrum and Optimism and screens it on the network where it is found; if no network has it, the transaction is not screened and custom_values.aml_screening_status is FAILED with the reason in custom_values.aml_screening_error. When it is missing for USDT or USDC screened by wallet (no transaction hash), a Tron address is screened on Tron, a Solana address on Solana, and a 0x address on the first of those six networks where it has sent a transaction or holds the token, or on Ethereum when it is active on none of them. Connected-provider coverage varies; LIGHTNING requires a supported connected provider.", "example": "BASE" } } @@ -24521,7 +26575,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot submit transactions for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot submit transactions for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -24612,12 +26666,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nuuid = 'abcdef12-3456-7890-abcd-ef1234567890'\nresp = requests.get(\n f'https://verification.didit.me/v3/transactions/{uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\ntx = resp.json()\nfor alert in tx['alerts']:\n print(alert.get('code'), alert.get('severity'))" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.retrieve(\n \"abcdef12-3456-7890-abcd-ef1234567890\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const uuid = 'abcdef12-3456-7890-abcd-ef1234567890';\nconst resp = await fetch(`https://verification.didit.me/v3/transactions/${uuid}/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Lookup failed: ${resp.status}`);\nconst tx = await resp.json();\nconsole.log(tx.status, tx.severity, tx.alerts.length, 'alerts');" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Retrieve(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->retrieve('abcdef12-3456-7890-abcd-ef1234567890');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.RetrieveAsync(\"abcdef12-3456-7890-abcd-ef1234567890\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -24719,7 +26798,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot read this application's transactions. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot read this application's transactions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -24832,7 +26911,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/transactions/sdk-token/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'vendor_data': 'user-042', 'ttl_seconds': 900, 'max_uses': 3},\n timeout=10,\n)\nresp.raise_for_status()\ntoken = resp.json()\nprint(token['sdk_token'], token['expires_at'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.create_sdk_token(\n vendor_data=\"user-042\",\n ttl_seconds=900,\n max_uses=3,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.createSdkToken({\n vendor_data: \"user-042\",\n ttl_seconds: 900,\n max_uses: 3,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.CreateSDKToken(ctx, didit.TransactionsCreateSDKTokenParams{\n\tVendorData: \"user-042\",\n\tTTLSeconds: didit.Int(900),\n\tMaxUses: didit.Int(3),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TransactionsCreateSdkTokenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().createSdkToken(TransactionsCreateSdkTokenParams.builder()\n .vendorData(\"user-042\")\n .ttlSeconds(900L)\n .maxUses(3L)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->createSdkToken([\n 'vendor_data' => 'user-042',\n 'ttl_seconds' => 900,\n 'max_uses' => 3,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.create_sdk_token(\n vendor_data: \"user-042\",\n ttl_seconds: 900,\n max_uses: 3\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.CreateSdkTokenAsync(new TransactionsCreateSdkTokenParams\n{\n VendorData = \"user-042\",\n TtlSeconds = 900,\n MaxUses = 3,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -25408,7 +27517,8 @@ "schema": { "type": "integer", "default": 50, - "minimum": 1 + "minimum": 1, + "maximum": 1000000 }, "description": "Page size. Defaults to 50 when omitted. There is no enforced maximum, but keep pages small for latency." }, @@ -25418,7 +27528,8 @@ "schema": { "type": "integer", "default": 0, - "minimum": 0 + "minimum": 0, + "maximum": 1000000 }, "description": "Zero-based offset of the first record to return. Prefer following the `next` URL from the previous page over computing this by hand." } @@ -25432,12 +27543,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/businesses/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n params={'limit': 50},\n)\nresp.raise_for_status()\npage = resp.json()\nfor biz in page['results']:\n print(biz['vendor_data'], biz['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.businesses.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const url = new URL('https://verification.didit.me/v3/businesses/');\nurl.searchParams.set('limit', '50');\n\nconst page = await fetch(url, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n}).then((r) => r.json());\nconsole.log(page.count, page.results.length);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.businesses.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Businesses.ListAutoPaging(ctx, didit.BusinessesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.businesses().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.businesses.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Businesses.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -25519,7 +27655,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot list businesses for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot list businesses for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -25577,12 +27713,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/customization/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n)\nresp.raise_for_status()\nbranding = resp.json()\nprint(branding['font_family'], branding['color_primary'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.customization.retrieve()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const branding = await fetch(\n 'https://verification.didit.me/v3/customization/',\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n).then((r) => r.json());\nconsole.log(branding.font_family, branding.color_primary);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.customization.retrieve();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Customization.Retrieve(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.customization().retrieve();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "customization->retrieve();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.customization.retrieve\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Customization.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -25631,7 +27792,7 @@ } }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -25757,12 +27918,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/customization/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'color_primary': '#123456', 'font_family': 'AR One Sans'},\n)\nresp.raise_for_status()\nprint(resp.json()['color_primary'])\n\n# Upload a logo (multipart):\nwith open('logo.png', 'rb') as logo:\n requests.patch(\n 'https://verification.didit.me/v3/customization/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n files={'image_rectangular': logo},\n )" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.customization.update(\n image_rectangular=open(\"image_rectangular.jpg\", \"rb\"),\n image_rectangular_dark=open(\"image_rectangular_dark.jpg\", \"rb\"),\n image_favicon=open(\"image_favicon.jpg\", \"rb\"),\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/customization/', {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ color_primary: '#123456', font_family: 'AR One Sans' }),\n});\nconst branding = await resp.json();\nconsole.log(branding.color_primary);" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.customization.update({\n image_rectangular: await fileFromPath(\"image_rectangular.jpg\"),\n image_rectangular_dark: await fileFromPath(\"image_rectangular_dark.jpg\"),\n image_favicon: await fileFromPath(\"image_favicon.jpg\"),\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Customization.Update(ctx, didit.CustomizationUpdateParams{\n\tImageRectangular: didit.Some(didit.FileFromPath(\"image_rectangular.jpg\")),\n\tImageRectangularDark: didit.Some(didit.FileFromPath(\"image_rectangular_dark.jpg\")),\n\tImageFavicon: didit.Some(didit.FileFromPath(\"image_favicon.jpg\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.CustomizationUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.customization().update(CustomizationUpdateParams.builder()\n .imageRectangular(Path.of(\"image_rectangular.jpg\"))\n .imageRectangularDark(Path.of(\"image_rectangular_dark.jpg\"))\n .imageFavicon(Path.of(\"image_favicon.jpg\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "customization->update([\n 'image_rectangular' => File::fromPath('image_rectangular.jpg'),\n 'image_rectangular_dark' => File::fromPath('image_rectangular_dark.jpg'),\n 'image_favicon' => File::fromPath('image_favicon.jpg'),\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.customization.update(\n image_rectangular: Pathname(\"image_rectangular.jpg\"),\n image_rectangular_dark: Pathname(\"image_rectangular_dark.jpg\"),\n image_favicon: Pathname(\"image_favicon.jpg\")\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Customization.UpdateAsync(new CustomizationUpdateParams\n{\n ImageRectangular = FileUpload.FromPath(\"image_rectangular.jpg\"),\n ImageRectangularDark = FileUpload.FromPath(\"image_rectangular_dark.jpg\"),\n ImageFavicon = FileUpload.FromPath(\"image_favicon.jpg\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -25872,7 +28058,7 @@ } }, "403": { - "description": "API key missing, malformed, expired, or scoped to a different application. Didit returns 403 (never 401) for all authentication failures on this endpoint.", + "description": "API key missing, malformed, expired, or scoped to a different application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -25931,12 +28117,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/businesses/company-123/',\n headers={'x-api-key': 'YOUR_API_KEY'},\n)\nresp.raise_for_status()\nbiz = resp.json()\nprint(biz['didit_internal_id'], biz['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.retrieve(\n \"company-123\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const vendorData = encodeURIComponent('company-123');\nconst biz = await fetch(\n `https://verification.didit.me/v3/businesses/${vendorData}/`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n).then((r) => r.json());\nconsole.log(biz.didit_internal_id, biz.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieve(\"company-123\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Retrieve(ctx, \"company-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieve(\"company-123\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->retrieve('company-123');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve(\"company-123\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveAsync(\"company-123\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -25993,7 +28204,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot read this application's businesses. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot read this application's businesses. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -26166,12 +28377,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/businesses/company-123/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'display_name': 'Acme Corp', 'status': 'FLAGGED'},\n)\nresp.raise_for_status()\nprint(resp.json()['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.update(\n \"company-123\",\n display_name=\"Acme Corp\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/businesses/company-123/', {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ display_name: 'Acme Corp', status: 'FLAGGED' }),\n});\nconst biz = await resp.json();\nconsole.log(biz.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.update(\"company-123\", {\n display_name: \"Acme Corp\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Update(ctx, \"company-123\", didit.BusinessesUpdateParams{\n\tDisplayName: didit.String(\"Acme Corp\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().update(\"company-123\", BusinessesUpdateParams.builder()\n .displayName(\"Acme Corp\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->update('company-123', [\n 'display_name' => 'Acme Corp',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.update(\n \"company-123\",\n display_name: \"Acme Corp\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.UpdateAsync(\"company-123\", new BusinessesUpdateParams\n{\n DisplayName = \"Acme Corp\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -26259,7 +28495,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot update businesses for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot update businesses for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -26395,12 +28631,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/businesses/company-123/update-status/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'status': 'BLOCKED'},\n)\nresp.raise_for_status()\nprint(resp.json()['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.update_status(\n \"company-123\",\n status=\"FLAGGED\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/businesses/company-123/update-status/', {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ status: 'BLOCKED' }),\n});\nconst biz = await resp.json();\nconsole.log(biz.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.updateStatus(\"company-123\", {\n status: \"FLAGGED\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.UpdateStatus(ctx, \"company-123\", didit.BusinessesUpdateStatusParams{\n\tStatus: \"FLAGGED\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesUpdateStatusParams;\nimport me.didit.types.EntityStatusUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().updateStatus(\"company-123\", BusinessesUpdateStatusParams.builder()\n .status(EntityStatusUpdateRequest.Status.of(\"FLAGGED\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->updateStatus('company-123', [\n 'status' => 'FLAGGED',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.update_status(\n \"company-123\",\n status: \"FLAGGED\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.UpdateStatusAsync(\"company-123\", new BusinessesUpdateStatusParams\n{\n Status = \"FLAGGED\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -26487,7 +28748,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot update businesses for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot update businesses for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -26618,12 +28879,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/businesses/delete/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'vendor_data_list': ['company-123', 'company-456']},\n)\nresp.raise_for_status()\nprint('deleted', resp.json()['deleted'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.batch_delete(\n vendor_data_list=[\"company-123\", \"company-456\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/businesses/delete/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ vendor_data_list: ['company-123', 'company-456'] }),\n});\nconst body = await resp.json();\nconsole.log('deleted', body.deleted);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.batchDelete({\n vendor_data_list: [\"company-123\", \"company-456\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.BatchDelete(ctx, didit.BusinessesBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"company-123\", \"company-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().batchDelete(BusinessesBatchDeleteParams.builder()\n .vendorDataList(List.of(\"company-123\", \"company-456\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->batchDelete([\n 'vendor_data_list' => ['company-123', 'company-456'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.batch_delete(vendor_data_list: [\"company-123\", \"company-456\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.BatchDeleteAsync(new BusinessesBatchDeleteParams\n{\n VendorDataList = new string[] { \"company-123\", \"company-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -26670,7 +28956,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot delete businesses for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot delete businesses for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -26815,12 +29101,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/users/aml-monitoring/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'is_enabled': True, 'vendor_data_list': ['user-123', 'user-456']},\n)\nresp.raise_for_status()\njob = resp.json()\nprint(job['status'], job['outcomes'])\nfor row in job['results']:\n print(row['vendor_data'], row['outcome'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.set_aml_monitoring(\n is_enabled=True,\n estimate_only=True,\n vendor_data_list=[\"user-123\", \"user-456\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/users/aml-monitoring/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ is_enabled: true, vendor_data_list: ['user-123', 'user-456'] }),\n});\nconst job = await resp.json();\nconsole.log(job.status, job.outcomes);\nfor (const row of job.results) console.log(row.vendor_data, row.outcome);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.setAmlMonitoring({\n is_enabled: true,\n estimate_only: true,\n vendor_data_list: [\"user-123\", \"user-456\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.SetAMLMonitoring(ctx, didit.UsersSetAMLMonitoringParams{\n\tIsEnabled: true,\n\tEstimateOnly: didit.Bool(true),\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.UsersSetAmlMonitoringParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().setAmlMonitoring(UsersSetAmlMonitoringParams.builder()\n .isEnabled(true)\n .estimateOnly(true)\n .vendorDataList(List.of(\"user-123\", \"user-456\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->setAmlMonitoring([\n 'is_enabled' => true,\n 'estimate_only' => true,\n 'vendor_data_list' => ['user-123', 'user-456'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.set_aml_monitoring(\n is_enabled: true,\n estimate_only: true,\n vendor_data_list: [\"user-123\", \"user-456\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.SetAmlMonitoringAsync(new UsersSetAmlMonitoringParams\n{\n IsEnabled = true,\n EstimateOnly = true,\n VendorDataList = new string[] { \"user-123\", \"user-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -27012,12 +29323,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/businesses/aml-monitoring/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'is_enabled': True, 'vendor_data_list': ['company-123', 'company-456']},\n)\nresp.raise_for_status()\njob = resp.json()\nprint(job['status'], job['outcomes'])\nfor row in job['results']:\n print(row['vendor_data'], row['outcome'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.set_aml_monitoring(\n is_enabled=True,\n estimate_only=True,\n vendor_data_list=[\"company-123\", \"company-456\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/businesses/aml-monitoring/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ is_enabled: true, vendor_data_list: ['company-123', 'company-456'] }),\n});\nconst job = await resp.json();\nconsole.log(job.status, job.outcomes);\nfor (const row of job.results) console.log(row.vendor_data, row.outcome);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setAmlMonitoring({\n is_enabled: true,\n estimate_only: true,\n vendor_data_list: [\"company-123\", \"company-456\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetAMLMonitoring(ctx, didit.BusinessesSetAMLMonitoringParams{\n\tIsEnabled: true,\n\tEstimateOnly: didit.Bool(true),\n\tVendorDataList: didit.Some([]string{\"company-123\", \"company-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesSetAmlMonitoringParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().setAmlMonitoring(BusinessesSetAmlMonitoringParams.builder()\n .isEnabled(true)\n .estimateOnly(true)\n .vendorDataList(List.of(\"company-123\", \"company-456\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->setAmlMonitoring([\n 'is_enabled' => true,\n 'estimate_only' => true,\n 'vendor_data_list' => ['company-123', 'company-456'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_aml_monitoring(\n is_enabled: true,\n estimate_only: true,\n vendor_data_list: [\"company-123\", \"company-456\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetAmlMonitoringAsync(new BusinessesSetAmlMonitoringParams\n{\n IsEnabled = true,\n EstimateOnly = true,\n VendorDataList = new string[] { \"company-123\", \"company-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -27149,12 +29485,37 @@ { "lang": "python", "label": "Python", - "source": "import time\nimport requests\n\nurl = 'https://verification.didit.me/v3/aml-monitoring/jobs/JOB_ID/'\nwhile True:\n job = requests.get(url, headers={'x-api-key': 'YOUR_API_KEY'}).json()\n if job['status'] in ('COMPLETED', 'FAILED'):\n break\n time.sleep(2)\nprint(job['outcomes'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml_monitoring.retrieve_job(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const url = 'https://verification.didit.me/v3/aml-monitoring/jobs/JOB_ID/';\nlet job;\ndo {\n await new Promise((r) => setTimeout(r, 2000));\n job = await (await fetch(url, { headers: { 'x-api-key': process.env.DIDIT_API_KEY } })).json();\n} while (job.status === 'PENDING' || job.status === 'PROCESSING');\nconsole.log(job.outcomes);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.amlMonitoring.retrieveJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AMLMonitoring.RetrieveJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.amlMonitoring().retrieveJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "amlMonitoring->retrieveJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml_monitoring.retrieve_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AmlMonitoring.RetrieveJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -27387,12 +29748,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/users/user-abc-123/update-status/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'status': 'BLOCKED'},\n)\nresp.raise_for_status()\nprint(resp.json()['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.update_status(\n \"user-123\",\n status=\"ACTIVE\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/users/user-abc-123/update-status/', {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ status: 'BLOCKED' }),\n});\nconst user = await resp.json();\nconsole.log(user.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.updateStatus(\"user-123\", {\n status: \"ACTIVE\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.UpdateStatus(ctx, \"user-123\", didit.UsersUpdateStatusParams{\n\tStatus: \"ACTIVE\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.EntityStatusUpdateRequest;\nimport me.didit.types.UsersUpdateStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().updateStatus(\"user-123\", UsersUpdateStatusParams.builder()\n .status(EntityStatusUpdateRequest.Status.of(\"ACTIVE\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->updateStatus('user-123', [\n 'status' => 'ACTIVE',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.update_status(\n \"user-123\",\n status: \"ACTIVE\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UpdateStatusAsync(\"user-123\", new UsersUpdateStatusParams\n{\n Status = \"ACTIVE\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -27545,7 +29931,7 @@ } }, "403": { - "description": "Invalid or revoked API key, or the key cannot update users for this application. Note: on this endpoint an *invalid* key returns `403` (not `401`).", + "description": "The key cannot update users for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -27698,12 +30084,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/businesses/create/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={\n 'vendor_data': 'company-456',\n 'legal_name': 'New Corp Ltd',\n 'country_code': 'US',\n },\n)\nresp.raise_for_status()\nbiz = resp.json()\nprint(biz['didit_internal_id'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.create(\n vendor_data=\"company-456\",\n legal_name=\"New Corp Ltd\",\n country_code=\"US\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/businesses/create/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n vendor_data: 'company-456',\n legal_name: 'New Corp Ltd',\n country_code: 'US',\n }),\n});\nconst biz = await resp.json();\nconsole.log(biz.didit_internal_id);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.create({\n vendor_data: \"company-456\",\n legal_name: \"New Corp Ltd\",\n country_code: \"US\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Create(ctx, didit.BusinessesCreateParams{\n\tVendorData: didit.String(\"company-456\"),\n\tLegalName: didit.String(\"New Corp Ltd\"),\n\tCountryCode: didit.String(\"US\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().create(BusinessesCreateParams.builder()\n .vendorData(\"company-456\")\n .legalName(\"New Corp Ltd\")\n .countryCode(\"US\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->create([\n 'vendor_data' => 'company-456',\n 'legal_name' => 'New Corp Ltd',\n 'country_code' => 'US',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.create(\n vendor_data: \"company-456\",\n legal_name: \"New Corp Ltd\",\n country_code: \"US\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.CreateAsync(new BusinessesCreateParams\n{\n VendorData = \"company-456\",\n LegalName = \"New Corp Ltd\",\n CountryCode = \"US\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -27775,7 +30186,7 @@ } }, "403": { - "description": "Missing, invalid, or revoked API key, or the key cannot create businesses for this application. This endpoint returns `403` (never `401`) for authentication failures, including requests with no credentials at all.", + "description": "Missing, invalid, or revoked API key, or the key cannot create businesses for this application. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -27995,12 +30406,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/users/create/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={'vendor_data': 'user-abc-123', 'full_name': 'John Doe'},\n)\nresp.raise_for_status()\nuser = resp.json()\nprint(user['didit_internal_id'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.create(\n vendor_data=\"user-abc-123\",\n full_name=\"John Doe\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/users/create/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ vendor_data: 'user-abc-123', full_name: 'John Doe' }),\n});\nconst user = await resp.json();\nconsole.log(user.didit_internal_id);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.create({\n vendor_data: \"user-abc-123\",\n full_name: \"John Doe\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Create(ctx, didit.UsersCreateParams{\n\tVendorData: \"user-abc-123\",\n\tFullName: didit.String(\"John Doe\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.UsersCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().create(UsersCreateParams.builder()\n .vendorData(\"user-abc-123\")\n .fullName(\"John Doe\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->create([\n 'vendor_data' => 'user-abc-123',\n 'full_name' => 'John Doe',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.create(\n vendor_data: \"user-abc-123\",\n full_name: \"John Doe\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.CreateAsync(new UsersCreateParams\n{\n VendorData = \"user-abc-123\",\n FullName = \"John Doe\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -28250,7 +30686,7 @@ } }, "403": { - "description": "Invalid or revoked API key, or the key cannot create users for this application. A scoped API key needs `users` write, and also `sessions` write when `send_verification_link` is `true`; nothing is written. Note: on this endpoint an *invalid* key returns `403` (not `401`).", + "description": "Invalid or revoked API key, or the key cannot create users for this application. A scoped API key needs `users` write, and also `sessions` write when `send_verification_link` is `true`; nothing is written. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -28381,12 +30817,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/vendor-users/by-id/f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418/faces/upload/',\n headers={'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json'},\n json={\n 'image': '/9j/4AAQSkZJRgABAQEA...',\n 'comment': 'Imported from previous KYC provider',\n },\n)\nresp.raise_for_status()\nface = resp.json()\nprint(face['uuid'], face['image_url'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.upload_face(\n \"11111111-2222-3333-4444-555555555555\",\n image=\"/9j/4AAQSkZJRgABAQEA...\",\n comment=\"Imported from previous KYC provider\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/vendor-users/by-id/f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418/faces/upload/', {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n image: '/9j/4AAQSkZJRgABAQEA...',\n comment: 'Imported from previous KYC provider',\n }),\n});\nconst face = await resp.json();\nconsole.log(face.uuid, face.image_url);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.uploadFace(\"11111111-2222-3333-4444-555555555555\", {\n image: \"/9j/4AAQSkZJRgABAQEA...\",\n comment: \"Imported from previous KYC provider\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.UploadFace(ctx, \"11111111-2222-3333-4444-555555555555\", didit.UsersUploadFaceParams{\n\tImage: \"/9j/4AAQSkZJRgABAQEA...\",\n\tComment: didit.String(\"Imported from previous KYC provider\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.UsersUploadFaceParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().uploadFace(\"11111111-2222-3333-4444-555555555555\", UsersUploadFaceParams.builder()\n .image(\"/9j/4AAQSkZJRgABAQEA...\")\n .comment(\"Imported from previous KYC provider\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->uploadFace('11111111-2222-3333-4444-555555555555', [\n 'image' => '/9j/4AAQSkZJRgABAQEA...',\n 'comment' => 'Imported from previous KYC provider',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.upload_face(\n \"11111111-2222-3333-4444-555555555555\",\n image: \"/9j/4AAQSkZJRgABAQEA...\",\n comment: \"Imported from previous KYC provider\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UploadFaceAsync(\"11111111-2222-3333-4444-555555555555\", new UsersUploadFaceParams\n{\n Image = \"/9j/4AAQSkZJRgABAQEA...\",\n Comment = \"Imported from previous KYC provider\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -29082,7 +31543,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions. This API returns `403` for authentication failures — never `401`.", + "description": "Missing credentials or insufficient permissions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -29168,12 +31629,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-data/\",\n headers={\n \"x-api-key\": \"YOUR_API_KEY\",\n \"Content-Type\": \"application/json\",\n },\n json={\n \"first_name\": \"Carmen\",\n \"last_name\": \"Espanola Espanola\",\n \"date_of_birth\": \"1980-01-01\",\n \"issuing_state\": \"ESP\",\n \"extra_fields\": {\"blood_group\": \"O+\"},\n \"parsed_address\": {\"city\": \"Madrid\", \"postal_code\": \"28013\", \"country\": \"ES\"},\n },\n)\nresponse.raise_for_status()\nkyc = response.json() # full current KYC record\nprint(kyc[\"first_name\"], kyc[\"parsed_address\"][\"formatted_address\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_data(\n \"11111111-2222-3333-4444-555555555555\",\n date_of_birth=\"1980-01-01\",\n issuing_state=\"ESP\",\n first_name=\"Carmen\",\n last_name=\"Espanola Espanola\",\n marital_status=\"MARRIED\",\n extra_fields={\"blood_group\": \"O+\"},\n parsed_address={\n \"city\": \"Madrid\",\n \"street_1\": \"Avda de Madrid 34\",\n \"postal_code\": \"28013\",\n \"country\": \"ES\",\n },\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-data/',\n {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n first_name: 'Carmen',\n last_name: 'Espanola Espanola',\n date_of_birth: '1980-01-01',\n issuing_state: 'ESP',\n parsed_address: { city: 'Madrid', postal_code: '28013', country: 'ES' },\n }),\n },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst kyc = await response.json(); // full current KYC record" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateData(\"11111111-2222-3333-4444-555555555555\", {\n date_of_birth: \"1980-01-01\",\n issuing_state: \"ESP\",\n first_name: \"Carmen\",\n last_name: \"Espanola Espanola\",\n marital_status: \"MARRIED\",\n extra_fields: { blood_group: \"O+\" },\n parsed_address: {\n city: \"Madrid\",\n street_1: \"Avda de Madrid 34\",\n postal_code: \"28013\",\n country: \"ES\",\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateData(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateDataParams{\n\tDateOfBirth: didit.String(\"1980-01-01\"),\n\tIssuingState: didit.String(\"ESP\"),\n\tFirstName: didit.String(\"Carmen\"),\n\tLastName: didit.String(\"Espanola Espanola\"),\n\tMaritalStatus: didit.Some(didit.SessionsUpdateDataParamsMaritalStatus(\"MARRIED\")),\n\tExtraFields: didit.Some(map[string]any{\"blood_group\": \"O+\"}),\n\tParsedAddress: didit.Some(didit.SessionsUpdateDataParamsParsedAddress{\n\t\tCity: didit.String(\"Madrid\"),\n\t\tStreet1: didit.String(\"Avda de Madrid 34\"),\n\t\tPostalCode: didit.String(\"28013\"),\n\t\tCountry: didit.String(\"ES\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateData(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateDataParams.builder()\n .dateOfBirth(LocalDate.parse(\"1980-01-01\"))\n .issuingState(\"ESP\")\n .firstName(\"Carmen\")\n .lastName(\"Espanola Espanola\")\n .maritalStatus(SessionsUpdateDataParams.MaritalStatus.of(\"MARRIED\"))\n .extraFields(Map.of(\"blood_group\", \"O+\"))\n .parsedAddress(SessionsUpdateDataParams.ParsedAddress.builder()\n .city(\"Madrid\")\n .street1(\"Avda de Madrid 34\")\n .postalCode(\"28013\")\n .country(\"ES\")\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateData('11111111-2222-3333-4444-555555555555', [\n 'date_of_birth' => '1980-01-01',\n 'issuing_state' => 'ESP',\n 'first_name' => 'Carmen',\n 'last_name' => 'Espanola Espanola',\n 'marital_status' => 'MARRIED',\n 'extra_fields' => ['blood_group' => 'O+'],\n 'parsed_address' => [\n 'city' => 'Madrid',\n 'street_1' => 'Avda de Madrid 34',\n 'postal_code' => '28013',\n 'country' => 'ES',\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_data(\n \"11111111-2222-3333-4444-555555555555\",\n date_of_birth: \"1980-01-01\",\n issuing_state: \"ESP\",\n first_name: \"Carmen\",\n last_name: \"Espanola Espanola\",\n marital_status: \"MARRIED\",\n extra_fields: { blood_group: \"O+\" },\n parsed_address: {\n city: \"Madrid\",\n street_1: \"Avda de Madrid 34\",\n postal_code: \"28013\",\n country: \"ES\",\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateDataAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateDataParams\n{\n DateOfBirth = \"1980-01-01\",\n IssuingState = \"ESP\",\n FirstName = \"Carmen\",\n LastName = \"Espanola Espanola\",\n MaritalStatus = new SessionsUpdateDataParamsMaritalStatus(\"MARRIED\"),\n ExtraFields = new Dictionary { [\"blood_group\"] = \"O+\" },\n ParsedAddress = new SessionsUpdateDataParamsParsedAddress\n {\n City = \"Madrid\",\n Street1 = \"Avda de Madrid 34\",\n PostalCode = \"28013\",\n Country = \"ES\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -29464,7 +31950,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions.", + "description": "Missing credentials or insufficient permissions.", "content": { "application/json": { "examples": { @@ -29521,7 +32007,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/features/feature_ocr_1/update-status/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\", \"Content-Type\": \"application/json\"},\n json={\"new_status\": \"Approved\", \"comment\": \"Document manually verified by compliance.\"},\n)\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_feature_status(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_ocr_1\",\n new_status=\"Approved\",\n comment=\"Document manually verified by compliance.\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateFeatureStatus(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_ocr_1\",\n {\n new_status: \"Approved\",\n comment: \"Document manually verified by compliance.\",\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateFeatureStatus(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", didit.SessionsUpdateFeatureStatusParams{\n\tNewStatus: \"Approved\",\n\tComment: didit.String(\"Document manually verified by compliance.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateFeatureStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateFeatureStatus(\"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", SessionsUpdateFeatureStatusParams.builder()\n .newStatus(SessionsUpdateFeatureStatusParams.NewStatus.of(\"Approved\"))\n .comment(\"Document manually verified by compliance.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateFeatureStatus('11111111-2222-3333-4444-555555555555', 'feature_ocr_1', [\n 'new_status' => 'Approved',\n 'comment' => 'Document manually verified by compliance.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_feature_status(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_ocr_1\",\n new_status: \"Approved\",\n comment: \"Document manually verified by compliance.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateFeatureStatusAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", new SessionsUpdateFeatureStatusParams\n{\n NewStatus = \"Approved\",\n Comment = \"Document manually verified by compliance.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -29529,7 +32045,7 @@ "/v3/session/{sessionId}/update-aml-hit-status/": { "patch": { "summary": "Update an AML hit review status", - "description": "Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match) returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id` (the `id` of an entry in the AML check's `hits` array — see the session decision).\n\n`review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. Reviewer decisions are preserved across ongoing-monitoring updates, so a hit you mark `False Positive` stays that way when the provider re-screens.\n\nA successful call fires a `data.updated` webhook and appends an activity entry (with actor attribution) to the session's review trail. For graph workflows with multiple AML checks, pass `node_id` to target a specific check.\n\nAuthenticate with your API key (`x-api-key`) or a user authorization header — either must carry the `write:sessions` privilege.", + "description": "Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match) returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id` (the `id` of an entry in the AML check's `hits` array — see the session decision). A hit id returned in the earlier format is still accepted; the response always names the hit by its current `id`.\n\n`review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. Reviewer decisions are preserved across ongoing-monitoring updates, so a hit you mark `False Positive` stays that way when the provider re-screens.\n\nA successful call fires a `data.updated` webhook and appends an activity entry (with actor attribution) to the session's review trail. For graph workflows with multiple AML checks, pass `node_id` to target a specific check.\n\nAuthenticate with your API key (`x-api-key`) or a user authorization header — either must carry the `write:sessions` privilege.", "operationId": "patch_v3_session_update_aml_hit_status", "x-didit-sdk": { "resource": "sessions", @@ -29581,8 +32097,8 @@ "properties": { "hit_id": { "type": "string", - "description": "The `id` of the hit in the AML check's `hits` array.", - "example": "abc123" + "description": "The `id` of the hit in the AML check's `hits` array (`hit_...`). A hit id returned in the earlier format is still accepted.", + "example": "hit_7c1e9a40b2d35f86e0a4c912" }, "review_status": { "type": "string", @@ -29601,6 +32117,10 @@ "example": "feature_aml_1" } } + }, + "example": { + "hit_id": "hit_7c1e9a40b2d35f86e0a4c912", + "review_status": "False Positive" } } } @@ -29624,7 +32144,7 @@ }, "hit_id": { "type": "string", - "description": "The updated hit, with surrounding whitespace removed." + "description": "The `id` of the updated hit, as the session decision returns it, also when the request named the hit by an id in the earlier format." }, "review_status": { "type": "string", @@ -29640,7 +32160,7 @@ }, "example": { "message": "Hit status updated successfully", - "hit_id": "abc123", + "hit_id": "hit_7c1e9a40b2d35f86e0a4c912", "review_status": "False Positive" } } @@ -29659,7 +32179,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions. This API returns `403` for authentication failures — never `401`.", + "description": "Missing credentials or insufficient permissions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -29693,7 +32213,7 @@ "Hit Not Found": { "summary": "Unknown hit_id", "value": { - "detail": "Hit with ID 'abc123' not found in the AML check." + "detail": "Hit with ID 'hit_9d2e7f41c0a8b3e65d1f0c47' not found in the AML check." } } } @@ -29710,7 +32230,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-aml-hit-status/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\", \"Content-Type\": \"application/json\"},\n json={\"hit_id\": \"abc123\", \"review_status\": \"False Positive\"},\n)\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_aml_hit_status(\n \"11111111-2222-3333-4444-555555555555\",\n hit_id=\"hit_7c1e9a40b2d35f86e0a4c912\",\n review_status=\"False Positive\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", {\n hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n review_status: \"False Positive\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateAMLHitStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateAMLHitStatusParams{\n\tHitID: \"hit_7c1e9a40b2d35f86e0a4c912\",\n\tReviewStatus: \"False Positive\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateAmlHitStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateAmlHitStatusParams.builder()\n .hitId(\"hit_7c1e9a40b2d35f86e0a4c912\")\n .reviewStatus(SessionsUpdateAmlHitStatusParams.ReviewStatus.of(\"False Positive\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateAmlHitStatus('11111111-2222-3333-4444-555555555555', [\n 'hit_id' => 'hit_7c1e9a40b2d35f86e0a4c912',\n 'review_status' => 'False Positive',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_aml_hit_status(\n \"11111111-2222-3333-4444-555555555555\",\n hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n review_status: \"False Positive\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateAmlHitStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateAmlHitStatusParams\n{\n HitId = \"hit_7c1e9a40b2d35f86e0a4c912\",\n ReviewStatus = \"False Positive\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -29779,7 +32329,8 @@ "properties": { "hit_id": { "type": "string", - "example": "abc123" + "example": "hit_7c1e9a40b2d35f86e0a4c912", + "description": "The `id` of the hit in the AML check's `hits` array (`hit_...`). A hit id returned in the earlier format is still accepted." }, "review_status": { "type": "string", @@ -29800,6 +32351,18 @@ "example": "feature_aml_1" } } + }, + "example": { + "hit_updates": [ + { + "hit_id": "hit_7c1e9a40b2d35f86e0a4c912", + "review_status": "Confirmed Match" + }, + { + "hit_id": "hit_3b8f20d6a91c4e75f0b2d6a8", + "review_status": "False Positive" + } + ] } } } @@ -29825,15 +32388,15 @@ "items": { "type": "string" }, - "description": "The `hit_id` of every entry in `hit_updates`, in request order, including hits whose status did not change." + "description": "The `id` of the hit each entry in `hit_updates` names, as the session decision returns it, in request order, including hits whose status did not change." } } }, "example": { "message": "Updated 2 hit(s) successfully", "updated_hits": [ - "abc123", - "def456" + "hit_7c1e9a40b2d35f86e0a4c912", + "hit_3b8f20d6a91c4e75f0b2d6a8" ] } } @@ -29852,7 +32415,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions. This API returns `403` for authentication failures — never `401`.", + "description": "Missing credentials or insufficient permissions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -29877,7 +32440,7 @@ "content": { "application/json": { "example": { - "detail": "Hits not found: zzz999" + "detail": "Hits not found: hit_9d2e7f41c0a8b3e65d1f0c47" } } } @@ -29892,7 +32455,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/bulk-update-aml-hit-status/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\", \"Content-Type\": \"application/json\"},\n json={\n \"hit_updates\": [\n {\"hit_id\": \"abc123\", \"review_status\": \"Confirmed Match\"},\n {\"hit_id\": \"def456\", \"review_status\": \"False Positive\"},\n ]\n },\n)\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.bulk_update_aml_hit_status(\n \"11111111-2222-3333-4444-555555555555\",\n hit_updates=[{\n \"hit_id\": \"hit_7c1e9a40b2d35f86e0a4c912\",\n \"review_status\": \"Confirmed Match\",\n }, {\n \"hit_id\": \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n \"review_status\": \"False Positive\",\n }],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.bulkUpdateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", {\n hit_updates: [{\n hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n review_status: \"Confirmed Match\",\n }, {\n hit_id: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n review_status: \"False Positive\",\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.BulkUpdateAMLHitStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsBulkUpdateAMLHitStatusParams{\n\tHitUpdates: []didit.SessionsBulkUpdateAMLHitStatusParamsHitUpdates{{\n\t\tHitID: \"hit_7c1e9a40b2d35f86e0a4c912\",\n\t\tReviewStatus: \"Confirmed Match\",\n\t}, {\n\t\tHitID: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n\t\tReviewStatus: \"False Positive\",\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsBulkUpdateAmlHitStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().bulkUpdateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", SessionsBulkUpdateAmlHitStatusParams.builder()\n .hitUpdates(List.of(\n SessionsBulkUpdateAmlHitStatusParams.HitUpdates.builder()\n .hitId(\"hit_7c1e9a40b2d35f86e0a4c912\")\n .reviewStatus(SessionsBulkUpdateAmlHitStatusParams.HitUpdates.ReviewStatus.of(\"Confirmed Match\"))\n .build(),\n SessionsBulkUpdateAmlHitStatusParams.HitUpdates.builder()\n .hitId(\"hit_3b8f20d6a91c4e75f0b2d6a8\")\n .reviewStatus(SessionsBulkUpdateAmlHitStatusParams.HitUpdates.ReviewStatus.of(\"False Positive\"))\n .build()))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->bulkUpdateAmlHitStatus('11111111-2222-3333-4444-555555555555', [\n 'hit_updates' => [[\n 'hit_id' => 'hit_7c1e9a40b2d35f86e0a4c912',\n 'review_status' => 'Confirmed Match',\n ], [\n 'hit_id' => 'hit_3b8f20d6a91c4e75f0b2d6a8',\n 'review_status' => 'False Positive',\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.bulk_update_aml_hit_status(\n \"11111111-2222-3333-4444-555555555555\",\n hit_updates: [{\n hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n review_status: \"Confirmed Match\",\n }, {\n hit_id: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n review_status: \"False Positive\",\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.BulkUpdateAmlHitStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsBulkUpdateAmlHitStatusParams\n{\n HitUpdates = new SessionsBulkUpdateAmlHitStatusParamsHitUpdates[]\n {\n new()\n {\n HitId = \"hit_7c1e9a40b2d35f86e0a4c912\",\n ReviewStatus = \"Confirmed Match\",\n },\n new()\n {\n HitId = \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n ReviewStatus = \"False Positive\",\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -30295,7 +32888,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions. This API returns `403` for authentication failures — never `401`.", + "description": "Missing credentials or insufficient permissions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -30381,12 +32974,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-poa-data/\",\n headers={\n \"x-api-key\": \"YOUR_API_KEY\",\n \"Content-Type\": \"application/json\",\n },\n json={\n \"issuing_state\": \"ESP\",\n \"document_type\": \"BANK_STATEMENT\",\n \"issuer\": \"Banco Example S.A.\",\n \"issue_date\": \"2026-05-02\",\n \"name_on_document\": \"Carmen Espanola\",\n \"poa_address\": \"Avda de Madrid 34, 28013 Madrid\",\n \"extra_fields\": {\"bank_iban\": \"ES9121000418450200051332\"},\n \"poa_parsed_address\": {\"city\": \"Madrid\", \"postal_code\": \"28013\", \"country\": \"ES\"},\n },\n)\nresponse.raise_for_status()\npoa = response.json() # full current POA record\nprint(poa[\"issuer\"], poa[\"poa_formatted_address\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_poa_data(\n \"11111111-2222-3333-4444-555555555555\",\n issuing_state=\"ESP\",\n document_type=\"BANK_STATEMENT\",\n issuer=\"Banco Example S.A.\",\n issue_date=\"2026-05-02\",\n poa_address=\"Avda de Madrid 34, 28013 Madrid\",\n name_on_document=\"Carmen Espanola\",\n extra_fields={\"bank_iban\": \"ES9121000418450200051332\", \"additional_names\": [\"Carmen E. Espanola\"]},\n poa_parsed_address={\n \"city\": \"Madrid\",\n \"street_1\": \"Avda de Madrid 34\",\n \"postal_code\": \"28013\",\n \"country\": \"ES\",\n },\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-poa-data/',\n {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n issuing_state: 'ESP',\n document_type: 'BANK_STATEMENT',\n issuer: 'Banco Example S.A.',\n issue_date: '2026-05-02',\n name_on_document: 'Carmen Espanola',\n poa_address: 'Avda de Madrid 34, 28013 Madrid',\n poa_parsed_address: { city: 'Madrid', postal_code: '28013', country: 'ES' },\n }),\n },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst poa = await response.json(); // full current POA record" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updatePoaData(\"11111111-2222-3333-4444-555555555555\", {\n issuing_state: \"ESP\",\n document_type: \"BANK_STATEMENT\",\n issuer: \"Banco Example S.A.\",\n issue_date: \"2026-05-02\",\n poa_address: \"Avda de Madrid 34, 28013 Madrid\",\n name_on_document: \"Carmen Espanola\",\n extra_fields: { bank_iban: \"ES9121000418450200051332\", additional_names: [\"Carmen E. Espanola\"] },\n poa_parsed_address: {\n city: \"Madrid\",\n street_1: \"Avda de Madrid 34\",\n postal_code: \"28013\",\n country: \"ES\",\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdatePOAData(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdatePOADataParams{\n\tIssuingState: didit.String(\"ESP\"),\n\tDocumentType: didit.Some(didit.SessionsUpdatePOADataParamsDocumentType(\"BANK_STATEMENT\")),\n\tIssuer: didit.String(\"Banco Example S.A.\"),\n\tIssueDate: didit.String(\"2026-05-02\"),\n\tPOAAddress: didit.String(\"Avda de Madrid 34, 28013 Madrid\"),\n\tNameOnDocument: didit.String(\"Carmen Espanola\"),\n\tExtraFields: didit.Some(map[string]any{\"bank_iban\": \"ES9121000418450200051332\", \"additional_names\": []any{\"Carmen E. Espanola\"}}),\n\tPOAParsedAddress: didit.Some(didit.SessionsUpdatePOADataParamsPOAParsedAddress{\n\t\tCity: didit.String(\"Madrid\"),\n\t\tStreet1: didit.String(\"Avda de Madrid 34\"),\n\t\tPostalCode: didit.String(\"28013\"),\n\t\tCountry: didit.String(\"ES\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdatePoaDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updatePoaData(\"11111111-2222-3333-4444-555555555555\", SessionsUpdatePoaDataParams.builder()\n .issuingState(\"ESP\")\n .documentType(SessionsUpdatePoaDataParams.DocumentType.of(\"BANK_STATEMENT\"))\n .issuer(\"Banco Example S.A.\")\n .issueDate(LocalDate.parse(\"2026-05-02\"))\n .poaAddress(\"Avda de Madrid 34, 28013 Madrid\")\n .nameOnDocument(\"Carmen Espanola\")\n .extraFields(Map.of(\"bank_iban\", \"ES9121000418450200051332\", \"additional_names\", List.of(\"Carmen E. Espanola\")))\n .poaParsedAddress(SessionsUpdatePoaDataParams.PoaParsedAddress.builder()\n .city(\"Madrid\")\n .street1(\"Avda de Madrid 34\")\n .postalCode(\"28013\")\n .country(\"ES\")\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updatePoaData('11111111-2222-3333-4444-555555555555', [\n 'issuing_state' => 'ESP',\n 'document_type' => 'BANK_STATEMENT',\n 'issuer' => 'Banco Example S.A.',\n 'issue_date' => '2026-05-02',\n 'poa_address' => 'Avda de Madrid 34, 28013 Madrid',\n 'name_on_document' => 'Carmen Espanola',\n 'extra_fields' => ['bank_iban' => 'ES9121000418450200051332', 'additional_names' => ['Carmen E. Espanola']],\n 'poa_parsed_address' => [\n 'city' => 'Madrid',\n 'street_1' => 'Avda de Madrid 34',\n 'postal_code' => '28013',\n 'country' => 'ES',\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_poa_data(\n \"11111111-2222-3333-4444-555555555555\",\n issuing_state: \"ESP\",\n document_type: \"BANK_STATEMENT\",\n issuer: \"Banco Example S.A.\",\n issue_date: \"2026-05-02\",\n poa_address: \"Avda de Madrid 34, 28013 Madrid\",\n name_on_document: \"Carmen Espanola\",\n extra_fields: { bank_iban: \"ES9121000418450200051332\", additional_names: [\"Carmen E. Espanola\"] },\n poa_parsed_address: {\n city: \"Madrid\",\n street_1: \"Avda de Madrid 34\",\n postal_code: \"28013\",\n country: \"ES\",\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdatePoaDataAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdatePoaDataParams\n{\n IssuingState = \"ESP\",\n DocumentType = new SessionsUpdatePoaDataParamsDocumentType(\"BANK_STATEMENT\"),\n Issuer = \"Banco Example S.A.\",\n IssueDate = \"2026-05-02\",\n PoaAddress = \"Avda de Madrid 34, 28013 Madrid\",\n NameOnDocument = \"Carmen Espanola\",\n ExtraFields = new Dictionary { [\"bank_iban\"] = \"ES9121000418450200051332\", [\"additional_names\"] = new object[] { \"Carmen E. Espanola\" } },\n PoaParsedAddress = new SessionsUpdatePoaDataParamsPoaParsedAddress\n {\n City = \"Madrid\",\n Street1 = \"Avda de Madrid 34\",\n PostalCode = \"28013\",\n Country = \"ES\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -30860,10 +33478,7 @@ "description": "Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts." }, "registry_data": { - "type": "object", - "nullable": true, - "additionalProperties": true, - "description": "Raw registry payload snapshot. Every key you PATCH is merged into this map (dates serialized as ISO strings), so the \"extracted from registry\" view reflects operator corrections." + "$ref": "#/components/schemas/KYBRegistryData" }, "user_provided_data": { "type": "object", @@ -31026,7 +33641,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions. This API returns `403` for authentication failures — never `401`.", + "description": "Missing credentials or insufficient permissions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -31106,12 +33721,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.patch(\n \"https://verification.didit.me/v3/session/33333333-4444-5555-6666-777777777777/kyb/\"\n \"88888888-9999-aaaa-bbbb-cccccccccccc/update-data/\",\n headers={\n \"x-api-key\": \"YOUR_API_KEY\",\n \"Content-Type\": \"application/json\",\n },\n json={\n \"company_name\": \"Docs Probe Corp\",\n \"registration_number\": \"DPC-001\",\n \"country_code\": \"US\",\n \"incorporation_date\": \"2015-04-12\",\n \"legal_address\": \"1 Example Plaza, Wilmington, DE 19801\",\n \"registry_status\": \"active\",\n },\n)\nresponse.raise_for_status()\ncompany = response.json() # full company record\nprint(company[\"company_name\"], company[\"registered_address\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_company_data(\n \"33333333-4444-5555-6666-777777777777\",\n \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n company_name=\"Docs Probe Corp\",\n registration_number=\"DPC-001\",\n country_code=\"US\",\n incorporation_date=\"2015-04-12\",\n legal_address=\"1 Example Plaza, Wilmington, DE 19801\",\n company_type=\"Limited Liability Company\",\n registry_status=\"active\",\n verification_status=\"verified\",\n nature_of_business=\"Software development\",\n registered_capital=\"USD 50000\",\n website=\"docsprobe.example.com\",\n email=\"legal@docsprobe.example.com\",\n phone=\"+1 302 555 0143\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const response = await fetch(\n 'https://verification.didit.me/v3/session/33333333-4444-5555-6666-777777777777/kyb/' +\n '88888888-9999-aaaa-bbbb-cccccccccccc/update-data/',\n {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n company_name: 'Docs Probe Corp',\n registration_number: 'DPC-001',\n country_code: 'US',\n incorporation_date: '2015-04-12',\n legal_address: '1 Example Plaza, Wilmington, DE 19801',\n registry_status: 'active',\n }),\n },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst company = await response.json(); // full company record" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybCompanyData(\n \"33333333-4444-5555-6666-777777777777\",\n \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n {\n company_name: \"Docs Probe Corp\",\n registration_number: \"DPC-001\",\n country_code: \"US\",\n incorporation_date: \"2015-04-12\",\n legal_address: \"1 Example Plaza, Wilmington, DE 19801\",\n company_type: \"Limited Liability Company\",\n registry_status: \"active\",\n verification_status: \"verified\",\n nature_of_business: \"Software development\",\n registered_capital: \"USD 50000\",\n website: \"docsprobe.example.com\",\n email: \"legal@docsprobe.example.com\",\n phone: \"+1 302 555 0143\",\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBCompanyData(ctx, \"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", didit.SessionsUpdateKYBCompanyDataParams{\n\tCompanyName: didit.String(\"Docs Probe Corp\"),\n\tRegistrationNumber: didit.String(\"DPC-001\"),\n\tCountryCode: didit.String(\"US\"),\n\tIncorporationDate: didit.String(\"2015-04-12\"),\n\tLegalAddress: didit.String(\"1 Example Plaza, Wilmington, DE 19801\"),\n\tCompanyType: didit.String(\"Limited Liability Company\"),\n\tRegistryStatus: didit.Some(didit.SessionsUpdateKYBCompanyDataParamsRegistryStatus(\"active\")),\n\tVerificationStatus: didit.Some(didit.SessionsUpdateKYBCompanyDataParamsVerificationStatus(\"verified\")),\n\tNatureOfBusiness: didit.String(\"Software development\"),\n\tRegisteredCapital: didit.String(\"USD 50000\"),\n\tWebsite: didit.String(\"docsprobe.example.com\"),\n\tEmail: didit.String(\"legal@docsprobe.example.com\"),\n\tPhone: didit.String(\"+1 302 555 0143\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybCompanyDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybCompanyData(\"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", SessionsUpdateKybCompanyDataParams.builder()\n .companyName(\"Docs Probe Corp\")\n .registrationNumber(\"DPC-001\")\n .countryCode(\"US\")\n .incorporationDate(LocalDate.parse(\"2015-04-12\"))\n .legalAddress(\"1 Example Plaza, Wilmington, DE 19801\")\n .companyType(\"Limited Liability Company\")\n .registryStatus(SessionsUpdateKybCompanyDataParams.RegistryStatus.of(\"active\"))\n .verificationStatus(SessionsUpdateKybCompanyDataParams.VerificationStatus.of(\"verified\"))\n .natureOfBusiness(\"Software development\")\n .registeredCapital(\"USD 50000\")\n .website(\"docsprobe.example.com\")\n .email(\"legal@docsprobe.example.com\")\n .phone(\"+1 302 555 0143\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateKybCompanyData('33333333-4444-5555-6666-777777777777', '88888888-9999-aaaa-bbbb-cccccccccccc', [\n 'company_name' => 'Docs Probe Corp',\n 'registration_number' => 'DPC-001',\n 'country_code' => 'US',\n 'incorporation_date' => '2015-04-12',\n 'legal_address' => '1 Example Plaza, Wilmington, DE 19801',\n 'company_type' => 'Limited Liability Company',\n 'registry_status' => 'active',\n 'verification_status' => 'verified',\n 'nature_of_business' => 'Software development',\n 'registered_capital' => 'USD 50000',\n 'website' => 'docsprobe.example.com',\n 'email' => 'legal@docsprobe.example.com',\n 'phone' => '+1 302 555 0143',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_company_data(\n \"33333333-4444-5555-6666-777777777777\",\n \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n company_name: \"Docs Probe Corp\",\n registration_number: \"DPC-001\",\n country_code: \"US\",\n incorporation_date: \"2015-04-12\",\n legal_address: \"1 Example Plaza, Wilmington, DE 19801\",\n company_type: \"Limited Liability Company\",\n registry_status: \"active\",\n verification_status: \"verified\",\n nature_of_business: \"Software development\",\n registered_capital: \"USD 50000\",\n website: \"docsprobe.example.com\",\n email: \"legal@docsprobe.example.com\",\n phone: \"+1 302 555 0143\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybCompanyDataAsync(\"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", new SessionsUpdateKybCompanyDataParams\n{\n CompanyName = \"Docs Probe Corp\",\n RegistrationNumber = \"DPC-001\",\n CountryCode = \"US\",\n IncorporationDate = \"2015-04-12\",\n LegalAddress = \"1 Example Plaza, Wilmington, DE 19801\",\n CompanyType = \"Limited Liability Company\",\n RegistryStatus = new SessionsUpdateKybCompanyDataParamsRegistryStatus(\"active\"),\n VerificationStatus = new SessionsUpdateKybCompanyDataParamsVerificationStatus(\"verified\"),\n NatureOfBusiness = \"Software development\",\n RegisteredCapital = \"USD 50000\",\n Website = \"docsprobe.example.com\",\n Email = \"legal@docsprobe.example.com\",\n Phone = \"+1 302 555 0143\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -31270,7 +33910,7 @@ } }, "403": { - "description": "Missing/invalid credentials or insufficient permissions. This API returns `403` for authentication failures — never `401`.", + "description": "Missing credentials or insufficient permissions. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "examples": { @@ -31334,7 +33974,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_party(\n \"33333333-4444-5555-6666-777777777777\",\n \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n is_skipped=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybParty(\n \"33333333-4444-5555-6666-777777777777\",\n \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n {\n is_skipped: true,\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBParty(ctx, \"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", didit.SessionsUpdateKYBPartyParams{\n\tIsSkipped: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybPartyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybParty(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", SessionsUpdateKybPartyParams.builder()\n .isSkipped(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateKybParty('33333333-4444-5555-6666-777777777777', '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41', [\n 'is_skipped' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_party(\n \"33333333-4444-5555-6666-777777777777\",\n \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n is_skipped: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybPartyAsync(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", new SessionsUpdateKybPartyParams\n{\n IsSkipped = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/travel-rule/settings/": { @@ -31361,6 +34038,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/settings/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_settings()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveSettings();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveSettings(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveSettings();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->retrieveSettings();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_settings\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveSettingsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -31504,6 +34216,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"is_enabled\": true, \"legal_name\": \"Origin CASP SL\", \"jurisdiction\": \"EU\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.update_settings(\n is_enabled=True,\n legal_name=\"Origin CASP SL\",\n jurisdiction=\"EU\",\n name_matching_strictness=\"DEFAULT\",\n confirmation_timeout_hours=48,\n timeout_outcome=\"HOLD\",\n is_discoverable=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.updateSettings({\n is_enabled: true,\n legal_name: \"Origin CASP SL\",\n jurisdiction: \"EU\",\n name_matching_strictness: \"DEFAULT\",\n confirmation_timeout_hours: 48,\n timeout_outcome: \"HOLD\",\n is_discoverable: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UpdateSettings(ctx, didit.TravelRuleSettingsUpdate{\n\tIsEnabled: didit.Bool(true),\n\tLegalName: didit.String(\"Origin CASP SL\"),\n\tJurisdiction: didit.String(\"EU\"),\n\tNameMatchingStrictness: didit.Some(didit.TravelRuleSettingsUpdateNameMatchingStrictness(\"DEFAULT\")),\n\tConfirmationTimeoutHours: didit.Int(48),\n\tTimeoutOutcome: didit.Some(didit.TravelRuleSettingsUpdateTimeoutOutcome(\"HOLD\")),\n\tIsDiscoverable: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleSettingsUpdate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().updateSettings(TravelRuleSettingsUpdate.builder()\n .isEnabled(true)\n .legalName(\"Origin CASP SL\")\n .jurisdiction(\"EU\")\n .nameMatchingStrictness(TravelRuleSettingsUpdate.NameMatchingStrictness.of(\"DEFAULT\"))\n .confirmationTimeoutHours(48L)\n .timeoutOutcome(TravelRuleSettingsUpdate.TimeoutOutcome.of(\"HOLD\"))\n .isDiscoverable(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->updateSettings([\n 'is_enabled' => true,\n 'legal_name' => 'Origin CASP SL',\n 'jurisdiction' => 'EU',\n 'name_matching_strictness' => 'DEFAULT',\n 'confirmation_timeout_hours' => 48,\n 'timeout_outcome' => 'HOLD',\n 'is_discoverable' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.update_settings(\n is_enabled: true,\n legal_name: \"Origin CASP SL\",\n jurisdiction: \"EU\",\n name_matching_strictness: \"DEFAULT\",\n confirmation_timeout_hours: 48,\n timeout_outcome: \"HOLD\",\n is_discoverable: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UpdateSettingsAsync(new TravelRuleSettingsUpdate\n{\n IsEnabled = true,\n LegalName = \"Origin CASP SL\",\n Jurisdiction = \"EU\",\n NameMatchingStrictness = new TravelRuleSettingsUpdateNameMatchingStrictness(\"DEFAULT\"),\n ConfirmationTimeoutHours = 48,\n TimeoutOutcome = new TravelRuleSettingsUpdateTimeoutOutcome(\"HOLD\"),\n IsDiscoverable = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -31559,6 +34306,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/settings/compliance-email/confirmation/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.send_compliance_email_confirmation()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.sendComplianceEmailConfirmation();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.SendComplianceEmailConfirmation(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().sendComplianceEmailConfirmation();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->sendComplianceEmailConfirmation();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.send_compliance_email_confirmation\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.SendComplianceEmailConfirmationAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -31666,6 +34448,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/wallet-addresses/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.wallet_addresses.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.walletAddresses.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.WalletAddresses.ListAutoPaging(ctx, didit.TravelRuleWalletAddressesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().walletAddresses().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletAddresses->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_addresses.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.WalletAddresses.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -31740,6 +34557,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"address\": \"0xBeneficiaryWallet01\", \"chain\": \"ETH\", \"holder_name\": \"Ana Diaz\", \"self_declared\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.create(\n address=\"0xBeneficiaryWallet01\",\n chain=\"ETH\",\n holder_vendor_data=\"user-042\",\n holder_name=\"Ana Diaz\",\n self_declared=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.create({\n address: \"0xBeneficiaryWallet01\",\n chain: \"ETH\",\n holder_vendor_data: \"user-042\",\n holder_name: \"Ana Diaz\",\n self_declared: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.Create(ctx, didit.WalletAddressEntryCreate{\n\tAddress: \"0xBeneficiaryWallet01\",\n\tChain: didit.String(\"ETH\"),\n\tHolderVendorData: didit.String(\"user-042\"),\n\tHolderName: didit.String(\"Ana Diaz\"),\n\tSelfDeclared: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.WalletAddressEntryCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().create(WalletAddressEntryCreate.builder()\n .address(\"0xBeneficiaryWallet01\")\n .chain(\"ETH\")\n .holderVendorData(\"user-042\")\n .holderName(\"Ana Diaz\")\n .selfDeclared(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletAddresses->create([\n 'address' => '0xBeneficiaryWallet01',\n 'chain' => 'ETH',\n 'holder_vendor_data' => 'user-042',\n 'holder_name' => 'Ana Diaz',\n 'self_declared' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.create(\n address: \"0xBeneficiaryWallet01\",\n chain: \"ETH\",\n holder_vendor_data: \"user-042\",\n holder_name: \"Ana Diaz\",\n self_declared: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.CreateAsync(new WalletAddressEntryCreate\n{\n Address = \"0xBeneficiaryWallet01\",\n Chain = \"ETH\",\n HolderVendorData = \"user-042\",\n HolderName = \"Ana Diaz\",\n SelfDeclared = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -31838,6 +34690,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PATCH https://verification.didit.me/v3/travel-rule/wallet-addresses/{entry_uuid}/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"holder_name\": \"Ana Updated\", \"travel_address\": \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.update(\n \"11111111-2222-3333-4444-555555555555\",\n holder_name=\"Ana Updated\",\n travel_address=\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.update(\"11111111-2222-3333-4444-555555555555\", {\n holder_name: \"Ana Updated\",\n travel_address: \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WalletAddressEntryUpdateParam{\n\tHolderName: didit.String(\"Ana Updated\"),\n\tTravelAddress: didit.String(\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.WalletAddressEntryUpdate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().update(\"11111111-2222-3333-4444-555555555555\", WalletAddressEntryUpdate.builder()\n .holderName(\"Ana Updated\")\n .travelAddress(\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletAddresses->update('11111111-2222-3333-4444-555555555555', [\n 'holder_name' => 'Ana Updated',\n 'travel_address' => 'ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.update(\n \"11111111-2222-3333-4444-555555555555\",\n holder_name: \"Ana Updated\",\n travel_address: \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new WalletAddressEntryUpdate\n{\n HolderName = \"Ana Updated\",\n TravelAddress = \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -31906,6 +34793,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/wallet-addresses/{entry_uuid}/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.travel_rule.wallet_addresses.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.travelRule.walletAddresses.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.TravelRule.WalletAddresses.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.travelRule().walletAddresses().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletAddresses->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_addresses.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.TravelRule.WalletAddresses.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ], "responses": { @@ -32045,6 +34967,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/vasps/?search=counterparty&reachable=true' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.list_vasps():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.listVasps()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.ListVASPsAutoPaging(ctx, didit.TravelRuleListVASPsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().listVasps()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->listVasps() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.list_vasps.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.ListVaspsAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -32146,6 +35103,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVasp(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASP(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVasp(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->retrieveVasp('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32216,6 +35208,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp_decision(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->retrieveVaspDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32330,6 +35357,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"decision\": \"BLOCKED\", \"reason\": \"Unlicensed in its home jurisdiction\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.update_vasp_decision(\n \"11111111-2222-3333-4444-555555555555\",\n decision=\"BLOCKED\",\n reason=\"Unlicensed in its home jurisdiction\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.updateVaspDecision(\"11111111-2222-3333-4444-555555555555\", {\n decision: \"BLOCKED\",\n reason: \"Unlicensed in its home jurisdiction\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UpdateVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyDecisionRequest{\n\tDecision: \"BLOCKED\",\n\tReason: didit.String(\"Unlicensed in its home jurisdiction\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyDecisionRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().updateVaspDecision(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyDecisionRequest.builder()\n .decision(TravelRuleCounterpartyDecisionRequest.Decision.of(\"BLOCKED\"))\n .reason(\"Unlicensed in its home jurisdiction\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->updateVaspDecision('11111111-2222-3333-4444-555555555555', [\n 'decision' => 'BLOCKED',\n 'reason' => 'Unlicensed in its home jurisdiction',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.update_vasp_decision(\n \"11111111-2222-3333-4444-555555555555\",\n decision: \"BLOCKED\",\n reason: \"Unlicensed in its home jurisdiction\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UpdateVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyDecisionRequest\n{\n Decision = \"BLOCKED\",\n Reason = \"Unlicensed in its home jurisdiction\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32428,6 +35490,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.clear_vasp_decision(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.clearVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ClearVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().clearVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->clearVaspDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.clear_vasp_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ClearVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32510,6 +35607,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/screening/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp_screening(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVaspScreening(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASPScreening(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVaspScreening(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->retrieveVaspScreening('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp_screening(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspScreeningAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32623,6 +35755,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/screening/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"refresh\": false}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.screen_vasp(\n \"11111111-2222-3333-4444-555555555555\",\n refresh=False,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.screenVasp(\"11111111-2222-3333-4444-555555555555\", {\n refresh: false,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ScreenVASP(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyScreeningRequest{\n\tRefresh: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyScreeningRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().screenVasp(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyScreeningRequest.builder()\n .refresh(false)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->screenVasp('11111111-2222-3333-4444-555555555555', [\n 'refresh' => false,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.screen_vasp(\n \"11111111-2222-3333-4444-555555555555\",\n refresh: false\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ScreenVaspAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyScreeningRequest\n{\n Refresh = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32820,6 +35987,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/questionnaires/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.list_vasp_questionnaires(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.listVaspQuestionnaires(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ListVASPQuestionnaires(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().listVaspQuestionnaires(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->listVaspQuestionnaires('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.list_vasp_questionnaires(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ListVaspQuestionnairesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -32942,6 +36144,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/questionnaires/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"sent_to\": \"travelrule@counterparty.example\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.send_vasp_questionnaire(\n \"11111111-2222-3333-4444-555555555555\",\n sent_to=\"travelrule@counterparty.example\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.sendVaspQuestionnaire(\"11111111-2222-3333-4444-555555555555\", {\n sent_to: \"travelrule@counterparty.example\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.SendVASPQuestionnaire(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyQuestionnaireRequest{\n\tSentTo: didit.String(\"travelrule@counterparty.example\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyQuestionnaireRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().sendVaspQuestionnaire(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyQuestionnaireRequest.builder()\n .sentTo(\"travelrule@counterparty.example\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->sendVaspQuestionnaire('11111111-2222-3333-4444-555555555555', [\n 'sent_to' => 'travelrule@counterparty.example',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.send_vasp_questionnaire(\n \"11111111-2222-3333-4444-555555555555\",\n sent_to: \"travelrule@counterparty.example\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.SendVaspQuestionnaireAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyQuestionnaireRequest\n{\n SentTo = \"travelrule@counterparty.example\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -33107,6 +36344,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PATCH https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"payment_txn_id\": \"0xchainhash\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.update_transfer(\n \"11111111-2222-3333-4444-555555555555\",\n payment_txn_id=\"0xchainhash\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.updateTransfer(\"11111111-2222-3333-4444-555555555555\", {\n payment_txn_id: \"0xchainhash\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.UpdateTransfer(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleTransferPatchRequest{\n\tPaymentTxnID: didit.String(\"0xchainhash\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleTransferPatchRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().updateTransfer(\"11111111-2222-3333-4444-555555555555\", TravelRuleTransferPatchRequest.builder()\n .paymentTxnId(\"0xchainhash\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->travelRule->updateTransfer('11111111-2222-3333-4444-555555555555', [\n 'payment_txn_id' => '0xchainhash',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.update_transfer(\n \"11111111-2222-3333-4444-555555555555\",\n payment_txn_id: \"0xchainhash\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.UpdateTransferAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleTransferPatchRequest\n{\n PaymentTxnId = \"0xchainhash\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -33227,6 +36499,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ownership/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"confirmed\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.confirm_ownership(\n \"11111111-2222-3333-4444-555555555555\",\n confirmed=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.confirmOwnership(\"11111111-2222-3333-4444-555555555555\", {\n confirmed: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ConfirmOwnership(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleOwnershipConfirmRequest{\n\tConfirmed: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleOwnershipConfirmRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().confirmOwnership(\"11111111-2222-3333-4444-555555555555\", TravelRuleOwnershipConfirmRequest.builder()\n .confirmed(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->travelRule->confirmOwnership('11111111-2222-3333-4444-555555555555', [\n 'confirmed' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.confirm_ownership(\n \"11111111-2222-3333-4444-555555555555\",\n confirmed: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.ConfirmOwnershipAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleOwnershipConfirmRequest\n{\n Confirmed = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -33331,6 +36638,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/messages/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.list_messages(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.listMessages(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ListMessages(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().listMessages(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->travelRule->listMessages('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.travel_rule.list_messages(\"11111111-2222-3333-4444-555555555555\").each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.ListMessagesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -33409,6 +36751,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/messages/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"kind\": \"DOCUMENT_REQUEST\", \"body\": \"Please confirm the date of birth of the beneficiary.\", \"requested_documents\": [\"Proof of address\"]}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.create_message(\n \"11111111-2222-3333-4444-555555555555\",\n kind=\"DOCUMENT_REQUEST\",\n body=\"Please confirm the date of birth of the beneficiary.\",\n requested_documents=[\"Proof of address\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.createMessage(\"11111111-2222-3333-4444-555555555555\", {\n kind: \"DOCUMENT_REQUEST\",\n body: \"Please confirm the date of birth of the beneficiary.\",\n requested_documents: [\"Proof of address\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.CreateMessage(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleMessageCreateRequest{\n\tKind: didit.Some(didit.TravelRuleMessageCreateRequestKind(\"DOCUMENT_REQUEST\")),\n\tBody: didit.String(\"Please confirm the date of birth of the beneficiary.\"),\n\tRequestedDocuments: didit.Some([]string{\"Proof of address\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleMessageCreateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().createMessage(\"11111111-2222-3333-4444-555555555555\", TravelRuleMessageCreateRequest.builder()\n .kind(TravelRuleMessageCreateRequest.Kind.of(\"DOCUMENT_REQUEST\"))\n .body(\"Please confirm the date of birth of the beneficiary.\")\n .requestedDocuments(List.of(\"Proof of address\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->travelRule->createMessage('11111111-2222-3333-4444-555555555555', [\n 'kind' => 'DOCUMENT_REQUEST',\n 'body' => 'Please confirm the date of birth of the beneficiary.',\n 'requested_documents' => ['Proof of address'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.create_message(\n \"11111111-2222-3333-4444-555555555555\",\n kind: \"DOCUMENT_REQUEST\",\n body: \"Please confirm the date of birth of the beneficiary.\",\n requested_documents: [\"Proof of address\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.CreateMessageAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleMessageCreateRequest\n{\n Kind = new TravelRuleMessageCreateRequestKind(\"DOCUMENT_REQUEST\"),\n Body = \"Please confirm the date of birth of the beneficiary.\",\n RequestedDocuments = new string[] { \"Proof of address\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -33911,6 +37288,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/inbound/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"chain\":\"ETH\",\"txid\":\"0xdeposit-hash\",\"wallet_address\":\"0xYourDepositWallet\",\"amount\":\"500.00\",\"currency\":\"USDC\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.register_inbound(\n chain=\"ETH\",\n txid=\"0xdeposit-hash\",\n wallet_address=\"0xYourDepositWallet\",\n amount=\"500.00\",\n currency=\"USDC\",\n originator_data={\"name\": \"Origin CASP SL\"},\n beneficiary_data={\"name\": \"Ana Diaz\"},\n originating_vasp={\n \"name\": \"Origin CASP SL\",\n \"lei\": \"\",\n \"travel_address\": \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.registerInbound({\n chain: \"ETH\",\n txid: \"0xdeposit-hash\",\n wallet_address: \"0xYourDepositWallet\",\n amount: \"500.00\",\n currency: \"USDC\",\n originator_data: { name: \"Origin CASP SL\" },\n beneficiary_data: { name: \"Ana Diaz\" },\n originating_vasp: {\n name: \"Origin CASP SL\",\n lei: \"\",\n travel_address: \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RegisterInbound(ctx, didit.TravelRuleInboundRequest{\n\tChain: \"ETH\",\n\tTxid: \"0xdeposit-hash\",\n\tWalletAddress: \"0xYourDepositWallet\",\n\tAmount: \"500.00\",\n\tCurrency: \"USDC\",\n\tOriginatorData: didit.Some(map[string]any{\"name\": \"Origin CASP SL\"}),\n\tBeneficiaryData: didit.Some(map[string]any{\"name\": \"Ana Diaz\"}),\n\tOriginatingVASP: didit.Some(didit.TravelRuleInboundRequestOriginatingVASP{\n\t\tName: didit.String(\"Origin CASP SL\"),\n\t\tLei: didit.String(\"\"),\n\t\tTravelAddress: didit.String(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleInboundRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().registerInbound(TravelRuleInboundRequest.builder()\n .chain(\"ETH\")\n .txid(\"0xdeposit-hash\")\n .walletAddress(\"0xYourDepositWallet\")\n .amount(\"500.00\")\n .currency(\"USDC\")\n .originatorData(Map.of(\"name\", \"Origin CASP SL\"))\n .beneficiaryData(Map.of(\"name\", \"Ana Diaz\"))\n .originatingVasp(TravelRuleInboundRequest.OriginatingVasp.builder()\n .name(\"Origin CASP SL\")\n .lei(\"\")\n .travelAddress(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\")\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->registerInbound([\n 'chain' => 'ETH',\n 'txid' => '0xdeposit-hash',\n 'wallet_address' => '0xYourDepositWallet',\n 'amount' => '500.00',\n 'currency' => 'USDC',\n 'originator_data' => ['name' => 'Origin CASP SL'],\n 'beneficiary_data' => ['name' => 'Ana Diaz'],\n 'originating_vasp' => [\n 'name' => 'Origin CASP SL',\n 'lei' => '',\n 'travel_address' => 'ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC',\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.register_inbound(\n chain: \"ETH\",\n txid: \"0xdeposit-hash\",\n wallet_address: \"0xYourDepositWallet\",\n amount: \"500.00\",\n currency: \"USDC\",\n originator_data: { name: \"Origin CASP SL\" },\n beneficiary_data: { name: \"Ana Diaz\" },\n originating_vasp: {\n name: \"Origin CASP SL\",\n lei: \"\",\n travel_address: \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RegisterInboundAsync(new TravelRuleInboundRequest\n{\n Chain = \"ETH\",\n Txid = \"0xdeposit-hash\",\n WalletAddress = \"0xYourDepositWallet\",\n Amount = \"500.00\",\n Currency = \"USDC\",\n OriginatorData = new Dictionary { [\"name\"] = \"Origin CASP SL\" },\n BeneficiaryData = new Dictionary { [\"name\"] = \"Ana Diaz\" },\n OriginatingVasp = new TravelRuleInboundRequestOriginatingVasp\n {\n Name = \"Origin CASP SL\",\n Lei = \"\",\n TravelAddress = \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -34002,6 +37414,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \\\n -H 'x-api-key: YOUR_SANDBOX_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"beneficiary_wallet_address\":\"0xYourSandboxWallet\",\"scenario\":\"accept\",\"reference\":\"demo-001\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.trigger_test_vasp_inbound(\n beneficiary_wallet_address=\"0xYourSandboxWallet\",\n scenario=\"accept\",\n amount=\"1\",\n reference=\"demo-001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.triggerTestVaspInbound({\n beneficiary_wallet_address: \"0xYourSandboxWallet\",\n scenario: \"accept\",\n amount: \"1\",\n reference: \"demo-001\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.TriggerTestVASPInbound(ctx, didit.TravelRuleTestVASPInboundRequest{\n\tBeneficiaryWalletAddress: \"0xYourSandboxWallet\",\n\tScenario: didit.Some(didit.TravelRuleTestVASPInboundRequestScenario(\"accept\")),\n\tAmount: didit.String(\"1\"),\n\tReference: didit.String(\"demo-001\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleTestVaspInboundRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().triggerTestVaspInbound(TravelRuleTestVaspInboundRequest.builder()\n .beneficiaryWalletAddress(\"0xYourSandboxWallet\")\n .scenario(TravelRuleTestVaspInboundRequest.Scenario.of(\"accept\"))\n .amount(\"1\")\n .reference(\"demo-001\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->travelRule->triggerTestVaspInbound([\n 'beneficiary_wallet_address' => '0xYourSandboxWallet',\n 'scenario' => 'accept',\n 'amount' => '1',\n 'reference' => 'demo-001',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.trigger_test_vasp_inbound(\n beneficiary_wallet_address: \"0xYourSandboxWallet\",\n scenario: \"accept\",\n amount: \"1\",\n reference: \"demo-001\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.TriggerTestVaspInboundAsync(new TravelRuleTestVaspInboundRequest\n{\n BeneficiaryWalletAddress = \"0xYourSandboxWallet\",\n Scenario = new TravelRuleTestVaspInboundRequestScenario(\"accept\"),\n Amount = \"1\",\n Reference = \"demo-001\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -34085,6 +37532,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget-session/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"wallet_address\":\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\"chain\":\"ETH\",\"holder_name\":\"Jane Doe\",\"transaction_id\":\"99999999-aaaa-bbbb-cccc-dddddddddddd\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.create_widget_session(\n wallet_address=\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n chain=\"ETH\",\n holder_name=\"Jane Doe\",\n vendor_data=\"user-042\",\n transaction_id=\"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n expires_in_minutes=60,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.createWidgetSession({\n wallet_address: \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n chain: \"ETH\",\n holder_name: \"Jane Doe\",\n vendor_data: \"user-042\",\n transaction_id: \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n expires_in_minutes: 60,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.CreateWidgetSession(ctx, didit.TravelRuleWidgetSessionCreate{\n\tWalletAddress: didit.String(\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\"),\n\tChain: didit.String(\"ETH\"),\n\tHolderName: didit.String(\"Jane Doe\"),\n\tVendorData: didit.String(\"user-042\"),\n\tTransactionID: didit.String(\"99999999-aaaa-bbbb-cccc-dddddddddddd\"),\n\tExpiresInMinutes: didit.Int(60),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWidgetSessionCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().createWidgetSession(TravelRuleWidgetSessionCreate.builder()\n .walletAddress(\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\")\n .chain(\"ETH\")\n .holderName(\"Jane Doe\")\n .vendorData(\"user-042\")\n .transactionId(\"99999999-aaaa-bbbb-cccc-dddddddddddd\")\n .expiresInMinutes(60L)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->createWidgetSession([\n 'wallet_address' => '0xd3b62acb76fb27a7f8961ec40fa11746b113aca9',\n 'chain' => 'ETH',\n 'holder_name' => 'Jane Doe',\n 'vendor_data' => 'user-042',\n 'transaction_id' => '99999999-aaaa-bbbb-cccc-dddddddddddd',\n 'expires_in_minutes' => 60,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.create_widget_session(\n wallet_address: \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n chain: \"ETH\",\n holder_name: \"Jane Doe\",\n vendor_data: \"user-042\",\n transaction_id: \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n expires_in_minutes: 60\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.CreateWidgetSessionAsync(new TravelRuleWidgetSessionCreate\n{\n WalletAddress = \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n Chain = \"ETH\",\n HolderName = \"Jane Doe\",\n VendorData = \"user-042\",\n TransactionId = \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n ExpiresInMinutes = 60,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -34504,6 +37986,12 @@ "application/json": { "schema": { "$ref": "#/components/schemas/OngoingMonitoringToggleRequest" + }, + "example": { + "is_enabled": true, + "didit_internal_id_list": [ + "5b9a0000-0000-4000-8000-00000000f00d" + ] } } } @@ -34537,6 +38025,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.set_ongoing_monitoring(\n is_enabled=True,\n didit_internal_id_list=[\"5b9a0000-0000-4000-8000-00000000f00d\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.setOngoingMonitoring({\n is_enabled: true,\n didit_internal_id_list: [\"5b9a0000-0000-4000-8000-00000000f00d\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.SetOngoingMonitoring(ctx, didit.OngoingMonitoringToggleRequest{\n\tIsEnabled: true,\n\tDiditInternalIDList: didit.Some([]string{\"5b9a0000-0000-4000-8000-00000000f00d\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.OngoingMonitoringToggleRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().setOngoingMonitoring(OngoingMonitoringToggleRequest.builder()\n .isEnabled(true)\n .diditInternalIdList(List.of(\"5b9a0000-0000-4000-8000-00000000f00d\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->setOngoingMonitoring([\n 'is_enabled' => true,\n 'didit_internal_id_list' => ['5b9a0000-0000-4000-8000-00000000f00d'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.set_ongoing_monitoring(\n is_enabled: true,\n didit_internal_id_list: [\"5b9a0000-0000-4000-8000-00000000f00d\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.SetOngoingMonitoringAsync(new OngoingMonitoringToggleRequest\n{\n IsEnabled = true,\n DiditInternalIdList = new string[] { \"5b9a0000-0000-4000-8000-00000000f00d\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -34606,6 +38131,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.retrieve_ongoing_monitoring_job(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.RetrieveOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->retrieveOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.retrieve_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.RetrieveOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -34652,6 +38214,12 @@ "application/json": { "schema": { "$ref": "#/components/schemas/OngoingMonitoringToggleRequest" + }, + "example": { + "is_enabled": true, + "didit_internal_id_list": [ + "b0000000-0000-4000-8000-0000000000b1" + ] } } } @@ -34685,6 +38253,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.set_ongoing_monitoring(\n is_enabled=True,\n didit_internal_id_list=[\"b0000000-0000-4000-8000-0000000000b1\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setOngoingMonitoring({\n is_enabled: true,\n didit_internal_id_list: [\"b0000000-0000-4000-8000-0000000000b1\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetOngoingMonitoring(ctx, didit.OngoingMonitoringToggleRequest{\n\tIsEnabled: true,\n\tDiditInternalIDList: didit.Some([]string{\"b0000000-0000-4000-8000-0000000000b1\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.OngoingMonitoringToggleRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().setOngoingMonitoring(OngoingMonitoringToggleRequest.builder()\n .isEnabled(true)\n .diditInternalIdList(List.of(\"b0000000-0000-4000-8000-0000000000b1\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->setOngoingMonitoring([\n 'is_enabled' => true,\n 'didit_internal_id_list' => ['b0000000-0000-4000-8000-0000000000b1'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_ongoing_monitoring(\n is_enabled: true,\n didit_internal_id_list: [\"b0000000-0000-4000-8000-0000000000b1\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetOngoingMonitoringAsync(new OngoingMonitoringToggleRequest\n{\n IsEnabled = true,\n DiditInternalIdList = new string[] { \"b0000000-0000-4000-8000-0000000000b1\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -34754,6 +38359,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.retrieve_ongoing_monitoring_job(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.RetrieveOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->retrieveOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -34854,6 +38496,13 @@ "type": "string" } } + }, + "example": { + "is_enabled": true, + "session_numbers": [ + "1001", + "1002" + ] } } } @@ -34887,6 +38536,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.set_session_ongoing_monitoring(\n is_enabled=True,\n session_numbers=[\"1001\", \"1002\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setSessionOngoingMonitoring({\n is_enabled: true,\n session_numbers: [\"1001\", \"1002\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetSessionOngoingMonitoring(ctx, didit.BusinessesSetSessionOngoingMonitoringParams{\n\tIsEnabled: true,\n\tSessionNumbers: didit.Some([]string{\"1001\", \"1002\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesSetSessionOngoingMonitoringParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().setSessionOngoingMonitoring(BusinessesSetSessionOngoingMonitoringParams.builder()\n .isEnabled(true)\n .sessionNumbers(List.of(\"1001\", \"1002\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->setSessionOngoingMonitoring([\n 'is_enabled' => true,\n 'session_numbers' => ['1001', '1002'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_session_ongoing_monitoring(\n is_enabled: true,\n session_numbers: [\"1001\", \"1002\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetSessionOngoingMonitoringAsync(new BusinessesSetSessionOngoingMonitoringParams\n{\n IsEnabled = true,\n SessionNumbers = new string[] { \"1001\", \"1002\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -34956,6 +38642,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.retrieve_session_ongoing_monitoring_job(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieveSessionOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.RetrieveSessionOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieveSessionOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->retrieveSessionOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve_session_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveSessionOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -35141,7 +38864,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'status__in': 'OPEN,AWAITING_USER', 'ordering': '-due_at'},\n timeout=10,\n)\nresp.raise_for_status()\nfor case in resp.json()['results']:\n print(case['case_number'], case['title'], case['priority'], case['due_at'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.ListAutoPaging(ctx, didit.CasesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -35303,6 +39056,18 @@ "$ref": "#/components/schemas/CaseDuplicateCaseFraudSourceContextRequest" } } + }, + "example": { + "title": "Manual - Jane Doe", + "blueprint": "b1de0000-0000-4000-8000-000000000002", + "priority": "HIGH", + "subject": { + "type": "user", + "uuid": "5b9a0000-0000-4000-8000-00000000f00d" + }, + "tags": [ + "review" + ] } } } @@ -35316,7 +39081,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'title': 'Manual - Jane Doe',\n 'blueprint': 'b1de0000-0000-4000-8000-000000000002',\n 'priority': 'HIGH',\n 'subject': {'type': 'user', 'uuid': '5b9a0000-0000-4000-8000-00000000f00d'},\n },\n timeout=10,\n)\nresp.raise_for_status()\ncase = resp.json()\nprint(case['case_number'], case['uuid'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.create(\n title=\"Manual - Jane Doe\",\n blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n priority=\"HIGH\",\n tags=[\"review\"],\n subject={\n \"type\": \"user\",\n \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\",\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.create({\n title: \"Manual - Jane Doe\",\n blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n priority: \"HIGH\",\n tags: [\"review\"],\n subject: {\n type: \"user\",\n uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Create(ctx, didit.CasesCreateParams{\n\tTitle: \"Manual - Jane Doe\",\n\tBlueprint: didit.String(\"b1de0000-0000-4000-8000-000000000002\"),\n\tPriority: didit.Some(didit.CasesCreateParamsPriority(\"HIGH\")),\n\tTags: didit.Some([]string{\"review\"}),\n\tSubject: didit.Some(didit.CasesCreateParamsSubject{\n\t\tType: didit.Some(didit.CasesCreateParamsSubjectType(\"user\")),\n\t\tUUID: didit.String(\"5b9a0000-0000-4000-8000-00000000f00d\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().create(CasesCreateParams.builder()\n .title(\"Manual - Jane Doe\")\n .blueprint(\"b1de0000-0000-4000-8000-000000000002\")\n .priority(CasesCreateParams.Priority.of(\"HIGH\"))\n .tags(List.of(\"review\"))\n .subject(CasesCreateParams.Subject.builder()\n .type(CasesCreateParams.Subject.Type.of(\"user\"))\n .uuid(\"5b9a0000-0000-4000-8000-00000000f00d\")\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->create([\n 'title' => 'Manual - Jane Doe',\n 'blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n 'priority' => 'HIGH',\n 'tags' => ['review'],\n 'subject' => [\n 'type' => 'user',\n 'uuid' => '5b9a0000-0000-4000-8000-00000000f00d',\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.create(\n title: \"Manual - Jane Doe\",\n blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n priority: \"HIGH\",\n tags: [\"review\"],\n subject: {\n type: \"user\",\n uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.CreateAsync(new CasesCreateParams\n{\n Title = \"Manual - Jane Doe\",\n Blueprint = \"b1de0000-0000-4000-8000-000000000002\",\n Priority = new CasesCreateParamsPriority(\"HIGH\"),\n Tags = new string[] { \"review\" },\n Subject = new CasesCreateParamsSubject\n {\n Type = new CasesCreateParamsSubjectType(\"user\"),\n Uuid = \"5b9a0000-0000-4000-8000-00000000f00d\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -35404,6 +39199,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retrieve(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retrieve(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Retrieve(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retrieve(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->retrieve('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retrieve(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetrieveAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -35558,6 +39388,41 @@ "lang": "curl", "label": "curl (change team)", "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"team\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.update(\n \"c1a5e000-0000-4000-8000-000000000001\",\n priority=\"HIGH\",\n due_at=\"2026-11-01T00:00:00Z\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.update(\"c1a5e000-0000-4000-8000-000000000001\", {\n priority: \"HIGH\",\n due_at: \"2026-11-01T00:00:00Z\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Update(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesUpdateParams{\n\tPriority: didit.Some(didit.CasesUpdateParamsPriority(\"HIGH\")),\n\tDueAt: didit.Time(time.Date(2026, 11, 1, 0, 0, 0, 0, time.UTC)),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.OffsetDateTime;\nimport me.didit.Didit;\nimport me.didit.types.CasesUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().update(\"c1a5e000-0000-4000-8000-000000000001\", CasesUpdateParams.builder()\n .priority(CasesUpdateParams.Priority.of(\"HIGH\"))\n .dueAt(OffsetDateTime.parse(\"2026-11-01T00:00:00Z\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->update('c1a5e000-0000-4000-8000-000000000001', [\n 'priority' => 'HIGH',\n 'due_at' => '2026-11-01T00:00:00Z',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.update(\n \"c1a5e000-0000-4000-8000-000000000001\",\n priority: \"HIGH\",\n due_at: \"2026-11-01T00:00:00Z\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.UpdateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesUpdateParams\n{\n Priority = new CasesUpdateParamsPriority(\"HIGH\"),\n DueAt = DateTimeOffset.Parse(\"2026-11-01T00:00:00Z\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -35701,6 +39566,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.delete(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.delete(\"c1a5e000-0000-4000-8000-000000000001\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Delete(ctx, \"c1a5e000-0000-4000-8000-000000000001\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().delete(\"c1a5e000-0000-4000-8000-000000000001\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->delete('c1a5e000-0000-4000-8000-000000000001');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.delete(\"c1a5e000-0000-4000-8000-000000000001\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.DeleteAsync(\"c1a5e000-0000-4000-8000-000000000001\");" } ], "responses": { @@ -35829,6 +39729,9 @@ "nullable": true } } + }, + "example": { + "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa" } } } @@ -35838,6 +39741,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/assign/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"assignee_user_id\": \"9a000000-0000-4000-8000-0000000000aa\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.assign(\n \"c1a5e000-0000-4000-8000-000000000001\",\n assignee_user_id=\"9a000000-0000-4000-8000-0000000000aa\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.assign(\"c1a5e000-0000-4000-8000-000000000001\", {\n assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Assign(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesAssignParams{\n\tAssigneeUserID: didit.String(\"9a000000-0000-4000-8000-0000000000aa\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesAssignParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().assign(\"c1a5e000-0000-4000-8000-000000000001\", CasesAssignParams.builder()\n .assigneeUserId(\"9a000000-0000-4000-8000-0000000000aa\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->assign('c1a5e000-0000-4000-8000-000000000001', [\n 'assignee_user_id' => '9a000000-0000-4000-8000-0000000000aa',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.assign(\n \"c1a5e000-0000-4000-8000-000000000001\",\n assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.AssignAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesAssignParams\n{\n AssigneeUserId = \"9a000000-0000-4000-8000-0000000000aa\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -35967,7 +39905,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/resolve/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'resolution': 'FALSE_POSITIVE', 'note': 'Confirmed legitimate activity.'},\n timeout=10,\n)\nresp.raise_for_status()\ncase = resp.json()\nprint(case['status'], case['resolution'], case.get('pending_resolution'))" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.resolve(\n \"c1a5e000-0000-4000-8000-000000000001\",\n resolution=\"FALSE_POSITIVE\",\n note=\"Confirmed legitimate activity after reviewing documents.\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.resolve(\"c1a5e000-0000-4000-8000-000000000001\", {\n resolution: \"FALSE_POSITIVE\",\n note: \"Confirmed legitimate activity after reviewing documents.\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Resolve(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesResolveParams{\n\tResolution: \"FALSE_POSITIVE\",\n\tNote: didit.String(\"Confirmed legitimate activity after reviewing documents.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesResolveParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().resolve(\"c1a5e000-0000-4000-8000-000000000001\", CasesResolveParams.builder()\n .resolution(CasesResolveParams.Resolution.of(\"FALSE_POSITIVE\"))\n .note(\"Confirmed legitimate activity after reviewing documents.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->resolve('c1a5e000-0000-4000-8000-000000000001', [\n 'resolution' => 'FALSE_POSITIVE',\n 'note' => 'Confirmed legitimate activity after reviewing documents.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.resolve(\n \"c1a5e000-0000-4000-8000-000000000001\",\n resolution: \"FALSE_POSITIVE\",\n note: \"Confirmed legitimate activity after reviewing documents.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ResolveAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesResolveParams\n{\n Resolution = \"FALSE_POSITIVE\",\n Note = \"Confirmed legitimate activity after reviewing documents.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36104,6 +40072,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/reopen/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.reopen(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.reopen(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Reopen(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().reopen(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->reopen('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.reopen(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ReopenAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36178,6 +40181,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/request-info/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.request_info(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requestInfo(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RequestInfo(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requestInfo(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requestInfo('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.request_info(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RequestInfoAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36252,6 +40290,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/escalate/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.escalate(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.escalate(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Escalate(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().escalate(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->escalate('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.escalate(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.EscalateAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36336,6 +40409,9 @@ "format": "uuid" } } + }, + "example": { + "target_blueprint": "b1de0000-0000-4000-8000-000000000002" } } } @@ -36345,6 +40421,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/transfer/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"target_blueprint\": \"b1de0000-0000-4000-8000-000000000002\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.transfer(\n \"c1a5e000-0000-4000-8000-000000000001\",\n target_blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.transfer(\"c1a5e000-0000-4000-8000-000000000001\", {\n target_blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Transfer(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesTransferParams{\n\tTargetBlueprint: \"b1de0000-0000-4000-8000-000000000002\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesTransferParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().transfer(\"c1a5e000-0000-4000-8000-000000000001\", CasesTransferParams.builder()\n .targetBlueprint(\"b1de0000-0000-4000-8000-000000000002\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->transfer('c1a5e000-0000-4000-8000-000000000001', [\n 'target_blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.transfer(\n \"c1a5e000-0000-4000-8000-000000000001\",\n target_blueprint: \"b1de0000-0000-4000-8000-000000000002\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.TransferAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesTransferParams\n{\n TargetBlueprint = \"b1de0000-0000-4000-8000-000000000002\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36419,6 +40530,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/approve/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.approve_resolution(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.approveResolution(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ApproveResolution(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().approveResolution(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->approveResolution('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.approve_resolution(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ApproveResolutionAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36547,6 +40693,9 @@ "nullable": true } } + }, + "example": { + "notes": "Needs a clearer rationale before this can be approved." } } } @@ -36556,6 +40705,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/reject-approval/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"notes\": \"Needs a clearer rationale before this can be approved.\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.reject_resolution(\n \"c1a5e000-0000-4000-8000-000000000001\",\n notes=\"Needs a clearer rationale before this can be approved.\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.rejectResolution(\"c1a5e000-0000-4000-8000-000000000001\", {\n notes: \"Needs a clearer rationale before this can be approved.\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RejectResolution(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRejectResolutionParams{\n\tNotes: didit.String(\"Needs a clearer rationale before this can be approved.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesRejectResolutionParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().rejectResolution(\"c1a5e000-0000-4000-8000-000000000001\", CasesRejectResolutionParams.builder()\n .notes(\"Needs a clearer rationale before this can be approved.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->rejectResolution('c1a5e000-0000-4000-8000-000000000001', [\n 'notes' => 'Needs a clearer rationale before this can be approved.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.reject_resolution(\n \"c1a5e000-0000-4000-8000-000000000001\",\n notes: \"Needs a clearer rationale before this can be approved.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RejectResolutionAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesRejectResolutionParams\n{\n Notes = \"Needs a clearer rationale before this can be approved.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36676,6 +40860,13 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest" + }, + "example": { + "client_reference": "e1a00000-0000-4000-8000-000000000001", + "action": "add_tags", + "tags": [ + "source-of-funds-reviewed" + ] } }, "multipart/form-data": { @@ -36706,7 +40897,44 @@ "ApiKeyAuth": [] } ], - "description": "Apply one explicit action to the case subject. Supply a unique client_reference to obtain an action receipt and make retries idempotent. Reusing that reference with a different payload returns 409. With a reference, inspect receipt.status even when HTTP status is 200: FAILED means no action was applied. Repeating a failed request does not execute it again unless retry is true. Omitting client_reference preserves the legacy response." + "description": "Apply one explicit action to the case subject. Supply a unique client_reference to obtain an action receipt and make retries idempotent. Reusing that reference with a different payload returns 409. With a reference, inspect receipt.status even when HTTP status is 200: FAILED means no action was applied. Repeating a failed request does not execute it again unless retry is true. Omitting client_reference preserves the legacy response.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.apply_entity_action(\n \"11111111-2222-3333-4444-555555555555\",\n client_reference=\"e1a00000-0000-4000-8000-000000000001\",\n action=\"add_tags\",\n tags=[\"source-of-funds-reviewed\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.applyEntityAction(\"11111111-2222-3333-4444-555555555555\", {\n client_reference: \"e1a00000-0000-4000-8000-000000000001\",\n action: \"add_tags\",\n tags: [\"source-of-funds-reviewed\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ApplyEntityAction(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseActionCaseEntityActionRequest{\n\tClientReference: didit.String(\"e1a00000-0000-4000-8000-000000000001\"),\n\tAction: didit.CaseActionActionEnum(\"add_tags\"),\n\tTags: didit.Some([]string{\"source-of-funds-reviewed\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseActionActionEnum;\nimport me.didit.types.CaseActionCaseEntityActionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().applyEntityAction(\"11111111-2222-3333-4444-555555555555\", CaseActionCaseEntityActionRequest.builder()\n .clientReference(\"e1a00000-0000-4000-8000-000000000001\")\n .action(CaseActionActionEnum.of(\"add_tags\"))\n .tags(List.of(\"source-of-funds-reviewed\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->applyEntityAction('11111111-2222-3333-4444-555555555555', [\n 'client_reference' => 'e1a00000-0000-4000-8000-000000000001',\n 'action' => 'add_tags',\n 'tags' => ['source-of-funds-reviewed'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.apply_entity_action(\n \"11111111-2222-3333-4444-555555555555\",\n client_reference: \"e1a00000-0000-4000-8000-000000000001\",\n action: \"add_tags\",\n tags: [\"source-of-funds-reviewed\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ApplyEntityActionAsync(\"11111111-2222-3333-4444-555555555555\", new CaseActionCaseEntityActionRequest\n{\n ClientReference = \"e1a00000-0000-4000-8000-000000000001\",\n Action = \"add_tags\",\n Tags = new string[] { \"source-of-funds-reviewed\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/print/": { @@ -36762,6 +40990,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/print/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.print(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.print(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Print(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().print(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->print('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.print(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.PrintAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -36880,6 +41143,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.notes.list(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.notes.list(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Notes.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesNotesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().notes().list(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->notes->list('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.notes.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Notes.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] }, "post": { @@ -36930,6 +41230,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest" + }, + "example": { + "comment": "Proof of address matches the ID document." } }, "multipart/form-data": { @@ -36979,7 +41282,44 @@ "ApiKeyAuth": [] } ], - "description": "Add a case-scoped note. An optional client_reference makes an unchanged retry return the same note without duplicate activity or notifications. reply_to must identify a live note in this case. The response includes a bounded parent excerpt without copying that excerpt into the saved reply." + "description": "Add a case-scoped note. An optional client_reference makes an unchanged retry return the same note without duplicate activity or notifications. reply_to must identify a live note in this case. The response includes a bounded parent excerpt without copying that excerpt into the saved reply.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.create(\n \"11111111-2222-3333-4444-555555555555\",\n comment=\"Proof of address matches the ID document.\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.create(\"11111111-2222-3333-4444-555555555555\", {\n comment: \"Proof of address matches the ID document.\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseCollaborationCaseNoteCreateRequest{\n\tComment: \"Proof of address matches the ID document.\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CaseCollaborationCaseNoteCreateRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().create(\"11111111-2222-3333-4444-555555555555\", CaseCollaborationCaseNoteCreateRequest.builder()\n .comment(\"Proof of address matches the ID document.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->notes->create('11111111-2222-3333-4444-555555555555', [\n 'comment' => 'Proof of address matches the ID document.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.create(\n \"11111111-2222-3333-4444-555555555555\",\n comment: \"Proof of address matches the ID document.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseCollaborationCaseNoteCreateRequest\n{\n Comment = \"Proof of address matches the ID document.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/{note_uuid}/": { @@ -37040,6 +41380,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest" + }, + "example": { + "is_pinned": true } }, "multipart/form-data": { @@ -37075,7 +41418,44 @@ "ApiKeyAuth": [] } ], - "description": "Pin or unpin an existing note. Pinned notes appear first. Pin changes are recorded in case activity and do not change evidence or source decisions." + "description": "Pin or unpin an existing note. Pinned notes appear first. Pin changes are recorded in case activity and do not change evidence or source decisions.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.update(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n is_pinned=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.update(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n {\n is_pinned: true,\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.Update(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", didit.CaseCollaborationPatchedCaseNoteUpdateRequest{\n\tIsPinned: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CaseCollaborationPatchedCaseNoteUpdateRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().update(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", CaseCollaborationPatchedCaseNoteUpdateRequest.builder()\n .isPinned(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->notes->update('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555', [\n 'is_pinned' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.update(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n is_pinned: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", new CaseCollaborationPatchedCaseNoteUpdateRequest\n{\n IsPinned = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] }, "delete": { "operationId": "delete_case_note", @@ -37142,6 +41522,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.notes.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.notes.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Notes.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().notes().delete(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->notes->delete('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.notes.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\"\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Notes.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");" + } ] } }, @@ -37217,6 +41634,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/notes/presign/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -F 'file=@evidence.pdf'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.create_attachment_upload(\n \"c1a5e000-0000-4000-8000-000000000001\",\n file=open(\"document.pdf\", \"rb\"),\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.createAttachmentUpload(\"c1a5e000-0000-4000-8000-000000000001\", {\n file: await fileFromPath(\"document.pdf\"),\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.CreateAttachmentUpload(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesNotesCreateAttachmentUploadParams{\n\tFile: didit.FileFromPath(\"document.pdf\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.CasesNotesCreateAttachmentUploadParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().createAttachmentUpload(\"c1a5e000-0000-4000-8000-000000000001\", CasesNotesCreateAttachmentUploadParams.builder()\n .file(Path.of(\"document.pdf\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->notes->createAttachmentUpload('c1a5e000-0000-4000-8000-000000000001', [\n 'file' => File::fromPath('document.pdf'),\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.create_attachment_upload(\n \"c1a5e000-0000-4000-8000-000000000001\",\n file: Pathname(\"document.pdf\")\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.CreateAttachmentUploadAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesNotesCreateAttachmentUploadParams\n{\n File = FileUpload.FromPath(\"document.pdf\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -37323,6 +41775,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/notes/presign/?s3_key=case-notes/c1a5e000-0000-4000-8000-000000000001/evidence.pdf' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.retrieve_attachment_url(\n \"c1a5e000-0000-4000-8000-000000000001\",\n s3_key=\"your-s3-key\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.retrieveAttachmentUrl(\"c1a5e000-0000-4000-8000-000000000001\", {\n s3_key: \"your-s3-key\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.RetrieveAttachmentURL(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesNotesRetrieveAttachmentURLParams{\n\tS3Key: \"your-s3-key\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesNotesRetrieveAttachmentUrlParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().retrieveAttachmentUrl(\"c1a5e000-0000-4000-8000-000000000001\", CasesNotesRetrieveAttachmentUrlParams.builder()\n .s3Key(\"your-s3-key\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->notes->retrieveAttachmentUrl('c1a5e000-0000-4000-8000-000000000001', [\n 's3_key' => 'your-s3-key',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.retrieve_attachment_url(\n \"c1a5e000-0000-4000-8000-000000000001\",\n s3_key: \"your-s3-key\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.RetrieveAttachmentUrlAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesNotesRetrieveAttachmentUrlParams\n{\n S3Key = \"your-s3-key\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -37419,6 +41906,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.links.list(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.links.list(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Links.List(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().links().list(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->links->list('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.links.list(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Links.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -37513,6 +42035,10 @@ "format": "uuid" } } + }, + "example": { + "entity_type": "transaction", + "entity_uuid": "77000000-0000-4000-8000-000000000077" } } } @@ -37522,6 +42048,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"entity_type\": \"transaction\", \"entity_uuid\": \"77000000-0000-4000-8000-000000000077\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.links.create(\n \"c1a5e000-0000-4000-8000-000000000001\",\n entity_type=\"transaction\",\n entity_uuid=\"77000000-0000-4000-8000-000000000077\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.links.create(\"c1a5e000-0000-4000-8000-000000000001\", {\n entity_type: \"transaction\",\n entity_uuid: \"77000000-0000-4000-8000-000000000077\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Links.Create(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesLinksCreateParams{\n\tEntityType: \"transaction\",\n\tEntityUUID: \"77000000-0000-4000-8000-000000000077\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesLinksCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().links().create(\"c1a5e000-0000-4000-8000-000000000001\", CasesLinksCreateParams.builder()\n .entityType(CasesLinksCreateParams.EntityType.of(\"transaction\"))\n .entityUuid(\"77000000-0000-4000-8000-000000000077\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->links->create('c1a5e000-0000-4000-8000-000000000001', [\n 'entity_type' => 'transaction',\n 'entity_uuid' => '77000000-0000-4000-8000-000000000077',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.links.create(\n \"c1a5e000-0000-4000-8000-000000000001\",\n entity_type: \"transaction\",\n entity_uuid: \"77000000-0000-4000-8000-000000000077\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Links.CreateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesLinksCreateParams\n{\n EntityType = \"transaction\",\n EntityUuid = \"77000000-0000-4000-8000-000000000077\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -37622,6 +42183,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/11000000-0000-4000-8000-000000000004/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.links.delete(\n \"c1a5e000-0000-4000-8000-000000000001\",\n \"11000000-0000-4000-8000-000000000004\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.links.delete(\n \"c1a5e000-0000-4000-8000-000000000001\",\n \"11000000-0000-4000-8000-000000000004\",\n);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Links.Delete(ctx, \"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().links().delete(\"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->links->delete('c1a5e000-0000-4000-8000-000000000001', '11000000-0000-4000-8000-000000000004');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.links.delete(\n \"c1a5e000-0000-4000-8000-000000000001\",\n \"11000000-0000-4000-8000-000000000004\"\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Links.DeleteAsync(\"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\");" } ], "responses": { @@ -37709,6 +42305,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/events/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.list_events(\n \"c1a5e000-0000-4000-8000-000000000001\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.listEvents(\"c1a5e000-0000-4000-8000-000000000001\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.ListEventsAutoPaging(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesListEventsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().listEvents(\"c1a5e000-0000-4000-8000-000000000001\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->listEvents('c1a5e000-0000-4000-8000-000000000001') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list_events(\"c1a5e000-0000-4000-8000-000000000001\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.ListEventsAsync(\"c1a5e000-0000-4000-8000-000000000001\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -37805,6 +42436,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/checklist/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.checklist.list(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.checklist.list(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Checklist.List(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().checklist().list(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->checklist->list('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.checklist.list(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Checklist.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -37902,6 +42568,9 @@ "type": "boolean" } } + }, + "example": { + "is_completed": true } } } @@ -37911,6 +42580,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/checklist/c4ec0000-0000-4000-8000-000000000005/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"is_completed\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.checklist.toggle_item(\n \"c1a5e000-0000-4000-8000-000000000001\",\n \"c4ec0000-0000-4000-8000-000000000005\",\n is_completed=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.checklist.toggleItem(\n \"c1a5e000-0000-4000-8000-000000000001\",\n \"c4ec0000-0000-4000-8000-000000000005\",\n {\n is_completed: true,\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Checklist.ToggleItem(ctx, \"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", didit.CasesChecklistToggleItemParams{\n\tIsCompleted: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesChecklistToggleItemParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().checklist().toggleItem(\"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", CasesChecklistToggleItemParams.builder()\n .isCompleted(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->checklist->toggleItem('c1a5e000-0000-4000-8000-000000000001', 'c4ec0000-0000-4000-8000-000000000005', [\n 'is_completed' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.checklist.toggle_item(\n \"c1a5e000-0000-4000-8000-000000000001\",\n \"c4ec0000-0000-4000-8000-000000000005\",\n is_completed: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Checklist.ToggleItemAsync(\"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", new CasesChecklistToggleItemParams\n{\n IsCompleted = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -37985,6 +42689,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/aml/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_aml_hits(\n \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listAmlHits(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListAMLHits(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listAmlHits(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->listAmlHits('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list_aml_hits(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListAmlHitsAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -38132,6 +42871,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/statistics/?date_from=2026-06-01&date_to=2026-06-30' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retrieve_statistics()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retrieveStatistics();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RetrieveStatistics(ctx, didit.CasesRetrieveStatisticsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retrieveStatistics();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->retrieveStatistics();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retrieve_statistics\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetrieveStatisticsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -38523,6 +43297,13 @@ "nullable": true } } + }, + "example": { + "case_uuids": [ + "c1a5e000-0000-4000-8000-000000000001" + ], + "status": "RESOLVED", + "resolution": "FALSE_POSITIVE" } } } @@ -38532,6 +43313,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/bulk/status/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"case_uuids\": [\"c1a5e000-0000-4000-8000-000000000001\"], \"status\": \"RESOLVED\", \"resolution\": \"FALSE_POSITIVE\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.bulk_update_status(\n case_uuids=[\"c1a5e000-0000-4000-8000-000000000001\"],\n status=\"RESOLVED\",\n resolution=\"FALSE_POSITIVE\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.bulkUpdateStatus({\n case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n status: \"RESOLVED\",\n resolution: \"FALSE_POSITIVE\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.BulkUpdateStatus(ctx, didit.CasesBulkUpdateStatusParams{\n\tCaseUUIDs: []string{\"c1a5e000-0000-4000-8000-000000000001\"},\n\tStatus: \"RESOLVED\",\n\tResolution: didit.Some(didit.CasesBulkUpdateStatusParamsResolution(\"FALSE_POSITIVE\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBulkUpdateStatusParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().bulkUpdateStatus(CasesBulkUpdateStatusParams.builder()\n .caseUuids(List.of(\"c1a5e000-0000-4000-8000-000000000001\"))\n .status(CasesBulkUpdateStatusParams.Status.of(\"RESOLVED\"))\n .resolution(CasesBulkUpdateStatusParams.Resolution.of(\"FALSE_POSITIVE\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->bulkUpdateStatus([\n 'case_uuids' => ['c1a5e000-0000-4000-8000-000000000001'],\n 'status' => 'RESOLVED',\n 'resolution' => 'FALSE_POSITIVE',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.bulk_update_status(\n case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n status: \"RESOLVED\",\n resolution: \"FALSE_POSITIVE\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.BulkUpdateStatusAsync(new CasesBulkUpdateStatusParams\n{\n CaseUuids = new string[] { \"c1a5e000-0000-4000-8000-000000000001\" },\n Status = \"RESOLVED\",\n Resolution = new CasesBulkUpdateStatusParamsResolution(\"FALSE_POSITIVE\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -38624,6 +43440,12 @@ "nullable": true } } + }, + "example": { + "case_uuids": [ + "c1a5e000-0000-4000-8000-000000000001" + ], + "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa" } } } @@ -38633,6 +43455,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/bulk/assign/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"case_uuids\": [\"c1a5e000-0000-4000-8000-000000000001\"], \"assignee_user_id\": \"9a000000-0000-4000-8000-0000000000aa\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.bulk_assign(\n case_uuids=[\"c1a5e000-0000-4000-8000-000000000001\"],\n assignee_user_id=\"9a000000-0000-4000-8000-0000000000aa\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.bulkAssign({\n case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.BulkAssign(ctx, didit.CasesBulkAssignParams{\n\tCaseUUIDs: []string{\"c1a5e000-0000-4000-8000-000000000001\"},\n\tAssigneeUserID: didit.String(\"9a000000-0000-4000-8000-0000000000aa\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBulkAssignParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().bulkAssign(CasesBulkAssignParams.builder()\n .caseUuids(List.of(\"c1a5e000-0000-4000-8000-000000000001\"))\n .assigneeUserId(\"9a000000-0000-4000-8000-0000000000aa\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->bulkAssign([\n 'case_uuids' => ['c1a5e000-0000-4000-8000-000000000001'],\n 'assignee_user_id' => '9a000000-0000-4000-8000-0000000000aa',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.bulk_assign(\n case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.BulkAssignAsync(new CasesBulkAssignParams\n{\n CaseUuids = new string[] { \"c1a5e000-0000-4000-8000-000000000001\" },\n AssigneeUserId = \"9a000000-0000-4000-8000-0000000000aa\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -38716,6 +43573,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.blueprints.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.blueprints.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Blueprints.ListAutoPaging(ctx, didit.CasesBlueprintsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().blueprints().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Blueprints.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -38880,6 +43772,22 @@ "description": "Set false to save a never-published draft. The record remains inactive at version 0 until the draft is explicitly published. Omitting this field preserves immediate creation for existing integrations." } } + }, + "example": { + "name": "AML investigation", + "assignee_pool": [ + "9a000000-0000-4000-8000-0000000000aa" + ], + "assignment_method": "AUTOMATIC", + "max_active_cases": 15, + "require_resolution_note": true, + "content_config": { + "aml_control": { + "enabled": true, + "financial": true, + "identity": false + } + } } } } @@ -38889,6 +43797,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\": \"AML investigation\", \"assignee_pool\": [\"9a000000-0000-4000-8000-0000000000aa\"], \"assignment_method\": \"AUTOMATIC\", \"max_active_cases\": 15, \"require_resolution_note\": true, \"content_config\": {\"aml_control\": {\"enabled\": true, \"financial\": true, \"identity\": false}}}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.create(\n name=\"AML investigation\",\n assignee_pool=[\"9a000000-0000-4000-8000-0000000000aa\"],\n assignment_method=\"AUTOMATIC\",\n max_active_cases=15,\n require_resolution_note=True,\n content_config={\n \"aml_control\": {\n \"enabled\": True,\n \"financial\": True,\n \"identity\": False,\n },\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.create({\n name: \"AML investigation\",\n assignee_pool: [\"9a000000-0000-4000-8000-0000000000aa\"],\n assignment_method: \"AUTOMATIC\",\n max_active_cases: 15,\n require_resolution_note: true,\n content_config: {\n aml_control: {\n enabled: true,\n financial: true,\n identity: false,\n },\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Create(ctx, didit.CasesBlueprintsCreateParams{\n\tName: \"AML investigation\",\n\tAssigneePool: []string{\"9a000000-0000-4000-8000-0000000000aa\"},\n\tAssignmentMethod: didit.Some(didit.CasesBlueprintsCreateParamsAssignmentMethod(\"AUTOMATIC\")),\n\tMaxActiveCases: didit.Int(15),\n\tRequireResolutionNote: didit.Bool(true),\n\tContentConfig: didit.Some(didit.CaseContentConfigParam{\n\t\tAMLControl: didit.Some(didit.CaseContentConfigParamAMLControl{\n\t\t\tEnabled: didit.Bool(true),\n\t\t\tFinancial: didit.Bool(true),\n\t\t\tIdentity: didit.Bool(false),\n\t\t}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseContentConfig;\nimport me.didit.types.CasesBlueprintsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().create(CasesBlueprintsCreateParams.builder()\n .name(\"AML investigation\")\n .assigneePool(List.of(\"9a000000-0000-4000-8000-0000000000aa\"))\n .assignmentMethod(CasesBlueprintsCreateParams.AssignmentMethod.of(\"AUTOMATIC\"))\n .maxActiveCases(15L)\n .requireResolutionNote(true)\n .contentConfig(CaseContentConfig.builder()\n .amlControl(CaseContentConfig.AmlControl.builder()\n .enabled(true)\n .financial(true)\n .identity(false)\n .build())\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->create([\n 'name' => 'AML investigation',\n 'assignee_pool' => ['9a000000-0000-4000-8000-0000000000aa'],\n 'assignment_method' => 'AUTOMATIC',\n 'max_active_cases' => 15,\n 'require_resolution_note' => true,\n 'content_config' => [\n 'aml_control' => [\n 'enabled' => true,\n 'financial' => true,\n 'identity' => false,\n ],\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.create(\n name: \"AML investigation\",\n assignee_pool: [\"9a000000-0000-4000-8000-0000000000aa\"],\n assignment_method: \"AUTOMATIC\",\n max_active_cases: 15,\n require_resolution_note: true,\n content_config: {\n aml_control: {\n enabled: true,\n financial: true,\n identity: false,\n },\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.CreateAsync(new CasesBlueprintsCreateParams\n{\n Name = \"AML investigation\",\n AssigneePool = new string[] { \"9a000000-0000-4000-8000-0000000000aa\" },\n AssignmentMethod = new CasesBlueprintsCreateParamsAssignmentMethod(\"AUTOMATIC\"),\n MaxActiveCases = 15,\n RequireResolutionNote = true,\n ContentConfig = new CaseContentConfig\n {\n AmlControl = new CaseContentConfigAmlControl\n {\n Enabled = true,\n Financial = true,\n Identity = false,\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -38973,6 +43916,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.retrieve(\n \"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.retrieve(\"b1de0000-0000-4000-8000-000000000002\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Retrieve(ctx, \"b1de0000-0000-4000-8000-000000000002\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().retrieve(\"b1de0000-0000-4000-8000-000000000002\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->retrieve('b1de0000-0000-4000-8000-000000000002');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.retrieve(\"b1de0000-0000-4000-8000-000000000002\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.RetrieveAsync(\"b1de0000-0000-4000-8000-000000000002\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39118,6 +44096,9 @@ "description": "The version opened by the editor. A stale version returns 409 without changing the review policy." } } + }, + "example": { + "transfer_enabled": true } } } @@ -39127,6 +44108,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"transfer_enabled\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.update(\n \"b1de0000-0000-4000-8000-000000000002\",\n transfer_enabled=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.update(\"b1de0000-0000-4000-8000-000000000002\", {\n transfer_enabled: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Update(ctx, \"b1de0000-0000-4000-8000-000000000002\", didit.CasesBlueprintsUpdateParams{\n\tTransferEnabled: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesBlueprintsUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().update(\"b1de0000-0000-4000-8000-000000000002\", CasesBlueprintsUpdateParams.builder()\n .transferEnabled(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->update('b1de0000-0000-4000-8000-000000000002', [\n 'transfer_enabled' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.update(\n \"b1de0000-0000-4000-8000-000000000002\",\n transfer_enabled: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.UpdateAsync(\"b1de0000-0000-4000-8000-000000000002\", new CasesBlueprintsUpdateParams\n{\n TransferEnabled = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39202,6 +44218,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.blueprints.delete(\n \"b1de0000-0000-4000-8000-000000000002\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.blueprints.delete(\"b1de0000-0000-4000-8000-000000000002\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Blueprints.Delete(ctx, \"b1de0000-0000-4000-8000-000000000002\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().blueprints().delete(\"b1de0000-0000-4000-8000-000000000002\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->delete('b1de0000-0000-4000-8000-000000000002');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.delete(\"b1de0000-0000-4000-8000-000000000002\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Blueprints.DeleteAsync(\"b1de0000-0000-4000-8000-000000000002\");" } ], "responses": { @@ -39258,6 +44309,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/presets/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.list_presets()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.listPresets();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.ListPresets(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().listPresets();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->listPresets();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.list_presets\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.ListPresetsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39363,6 +44449,12 @@ "description": "Subset of screening_hit, aml_investigation, suspicious_activity, kyc. Omit to install all." } } + }, + "example": { + "preset_keys": [ + "aml_investigation", + "kyc" + ] } } } @@ -39372,6 +44464,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/presets/install/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"preset_keys\": [\"aml_investigation\", \"kyc\"]}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.install_presets(\n preset_keys=[\"aml_investigation\", \"kyc\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.installPresets({\n preset_keys: [\"aml_investigation\", \"kyc\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.InstallPresets(ctx, didit.CasesBlueprintsInstallPresetsParams{\n\tPresetKeys: didit.Some([]string{\"aml_investigation\", \"kyc\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBlueprintsInstallPresetsParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().installPresets(CasesBlueprintsInstallPresetsParams.builder()\n .presetKeys(List.of(\"aml_investigation\", \"kyc\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->installPresets([\n 'preset_keys' => ['aml_investigation', 'kyc'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.install_presets(preset_keys: [\"aml_investigation\", \"kyc\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.InstallPresetsAsync(new CasesBlueprintsInstallPresetsParams\n{\n PresetKeys = new string[] { \"aml_investigation\", \"kyc\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39465,6 +44592,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.report_templates.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.reportTemplates.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.ReportTemplates.ListAutoPaging(ctx, didit.ReportTemplatesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.reportTemplates().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "reportTemplates->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.report_templates.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.ReportTemplates.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -39580,6 +44742,16 @@ "description": "Reusable goAML header defaults. Template-level obligatory fields: rentity_id, submission_code, and currency_code_local (3-letter). Optional: enabled_fields (which optional report blocks to include) plus reporting_person, location, reason, and action defaults. Per-filing header fields (action, submission_date, transactions, jurisdiction) are enforced when the report is validated or finalized, not on the template." } } + }, + "example": { + "name": "US SAR default", + "jurisdiction": "US", + "report_type": "SAR", + "field_config": { + "rentity_id": "FIU-US-00123", + "submission_code": "E", + "currency_code_local": "USD" + } } } } @@ -39593,7 +44765,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'name': 'US SAR default',\n 'jurisdiction': 'US',\n 'report_type': 'SAR',\n 'field_config': {'rentity_id': 'FIU-US-00123', 'submission_code': 'E', 'currency_code_local': 'USD'},\n },\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json()['uuid'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.create(\n name=\"US SAR default\",\n jurisdiction=\"US\",\n report_type=\"SAR\",\n field_config={\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.create({\n name: \"US SAR default\",\n jurisdiction: \"US\",\n report_type: \"SAR\",\n field_config: { rentity_id: \"FIU-US-00123\", submission_code: \"E\", currency_code_local: \"USD\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Create(ctx, didit.ReportTemplatesCreateParams{\n\tName: \"US SAR default\",\n\tJurisdiction: \"US\",\n\tReportType: \"SAR\",\n\tFieldConfig: didit.Some(map[string]any{\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.ReportTemplatesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().create(ReportTemplatesCreateParams.builder()\n .name(\"US SAR default\")\n .jurisdiction(\"US\")\n .reportType(ReportTemplatesCreateParams.ReportType.of(\"SAR\"))\n .fieldConfig(Map.of(\"rentity_id\", \"FIU-US-00123\", \"submission_code\", \"E\", \"currency_code_local\", \"USD\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "reportTemplates->create([\n 'name' => 'US SAR default',\n 'jurisdiction' => 'US',\n 'report_type' => 'SAR',\n 'field_config' => ['rentity_id' => 'FIU-US-00123', 'submission_code' => 'E', 'currency_code_local' => 'USD'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.create(\n name: \"US SAR default\",\n jurisdiction: \"US\",\n report_type: \"SAR\",\n field_config: { rentity_id: \"FIU-US-00123\", submission_code: \"E\", currency_code_local: \"USD\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.CreateAsync(new ReportTemplatesCreateParams\n{\n Name = \"US SAR default\",\n Jurisdiction = \"US\",\n ReportType = \"SAR\",\n FieldConfig = new Dictionary { [\"rentity_id\"] = \"FIU-US-00123\", [\"submission_code\"] = \"E\", [\"currency_code_local\"] = \"USD\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39686,6 +44888,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.retrieve(\n \"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.retrieve(\"7ec00000-0000-4000-8000-000000000006\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Retrieve(ctx, \"7ec00000-0000-4000-8000-000000000006\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().retrieve(\"7ec00000-0000-4000-8000-000000000006\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "reportTemplates->retrieve('7ec00000-0000-4000-8000-000000000006');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.retrieve(\"7ec00000-0000-4000-8000-000000000006\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.RetrieveAsync(\"7ec00000-0000-4000-8000-000000000006\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39787,6 +45024,11 @@ "description": "Reusable goAML header defaults. Template-level obligatory fields: rentity_id, submission_code, and currency_code_local (3-letter). Optional: enabled_fields (which optional report blocks to include) plus reporting_person, location, reason, and action defaults. Per-filing header fields (action, submission_date, transactions, jurisdiction) are enforced when the report is validated or finalized, not on the template." } } + }, + "example": { + "field_config": { + "rentity_id": "FIU-US-00124" + } } } } @@ -39796,6 +45038,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"field_config\": {\"rentity_id\": \"FIU-US-00124\"}}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.update(\n \"7ec00000-0000-4000-8000-000000000006\",\n field_config={\"rentity_id\": \"FIU-US-00124\"},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.update(\"7ec00000-0000-4000-8000-000000000006\", {\n field_config: { rentity_id: \"FIU-US-00124\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Update(ctx, \"7ec00000-0000-4000-8000-000000000006\", didit.ReportTemplatesUpdateParams{\n\tFieldConfig: didit.Some(map[string]any{\"rentity_id\": \"FIU-US-00124\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.ReportTemplatesUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().update(\"7ec00000-0000-4000-8000-000000000006\", ReportTemplatesUpdateParams.builder()\n .fieldConfig(Map.of(\"rentity_id\", \"FIU-US-00124\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "reportTemplates->update('7ec00000-0000-4000-8000-000000000006', [\n 'field_config' => ['rentity_id' => 'FIU-US-00124'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.update(\n \"7ec00000-0000-4000-8000-000000000006\",\n field_config: { rentity_id: \"FIU-US-00124\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.UpdateAsync(\"7ec00000-0000-4000-8000-000000000006\", new ReportTemplatesUpdateParams\n{\n FieldConfig = new Dictionary { [\"rentity_id\"] = \"FIU-US-00124\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -39868,6 +45145,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.report_templates.delete(\n \"7ec00000-0000-4000-8000-000000000006\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.reportTemplates.delete(\"7ec00000-0000-4000-8000-000000000006\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.ReportTemplates.Delete(ctx, \"7ec00000-0000-4000-8000-000000000006\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.reportTemplates().delete(\"7ec00000-0000-4000-8000-000000000006\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "reportTemplates->delete('7ec00000-0000-4000-8000-000000000006');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.report_templates.delete(\"7ec00000-0000-4000-8000-000000000006\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.ReportTemplates.DeleteAsync(\"7ec00000-0000-4000-8000-000000000006\");" } ], "responses": { @@ -39955,6 +45267,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.regulatory_reports.list(\n \"c1a5e000-0000-4000-8000-000000000001\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.regulatoryReports.list(\"c1a5e000-0000-4000-8000-000000000001\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RegulatoryReports.ListAutoPaging(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRegulatoryReportsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().regulatoryReports().list(\"c1a5e000-0000-4000-8000-000000000001\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->regulatoryReports->list('c1a5e000-0000-4000-8000-000000000001') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.regulatory_reports.list(\"c1a5e000-0000-4000-8000-000000000001\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RegulatoryReports.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -40153,6 +45500,9 @@ } } } + }, + "example": { + "template": "7ec00000-0000-4000-8000-000000000006" } } } @@ -40162,6 +45512,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"template\": \"7ec00000-0000-4000-8000-000000000006\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.regulatory_reports.create(\n \"c1a5e000-0000-4000-8000-000000000001\",\n template=\"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.regulatoryReports.create(\"c1a5e000-0000-4000-8000-000000000001\", {\n template: \"7ec00000-0000-4000-8000-000000000006\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RegulatoryReports.Create(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRegulatoryReportsCreateParams{\n\tTemplate: didit.String(\"7ec00000-0000-4000-8000-000000000006\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasesRegulatoryReportsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().regulatoryReports().create(\"c1a5e000-0000-4000-8000-000000000001\", CasesRegulatoryReportsCreateParams.builder()\n .template(\"7ec00000-0000-4000-8000-000000000006\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->regulatoryReports->create('c1a5e000-0000-4000-8000-000000000001', [\n 'template' => '7ec00000-0000-4000-8000-000000000006',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.regulatory_reports.create(\n \"c1a5e000-0000-4000-8000-000000000001\",\n template: \"7ec00000-0000-4000-8000-000000000006\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RegulatoryReports.CreateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesRegulatoryReportsCreateParams\n{\n Template = \"7ec00000-0000-4000-8000-000000000006\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -40300,6 +45685,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.regulatory_reports.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.regulatoryReports.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.RegulatoryReports.ListAutoPaging(ctx, didit.RegulatoryReportsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.regulatoryReports().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.regulatory_reports.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.RegulatoryReports.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -40493,6 +45913,10 @@ } } } + }, + "example": { + "case": "c1a5e000-0000-4000-8000-000000000001", + "template": "7ec00000-0000-4000-8000-000000000006" } } } @@ -40502,6 +45926,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"case\": \"c1a5e000-0000-4000-8000-000000000001\", \"template\": \"7ec00000-0000-4000-8000-000000000006\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.create(\n case=\"c1a5e000-0000-4000-8000-000000000001\",\n template=\"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.create({\n case: \"c1a5e000-0000-4000-8000-000000000001\",\n template: \"7ec00000-0000-4000-8000-000000000006\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Create(ctx, didit.RegulatoryReportsCreateParams{\n\tCase: \"c1a5e000-0000-4000-8000-000000000001\",\n\tTemplate: \"7ec00000-0000-4000-8000-000000000006\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().create(RegulatoryReportsCreateParams.builder()\n .case_(\"c1a5e000-0000-4000-8000-000000000001\")\n .template(\"7ec00000-0000-4000-8000-000000000006\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->create([\n 'case' => 'c1a5e000-0000-4000-8000-000000000001',\n 'template' => '7ec00000-0000-4000-8000-000000000006',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.create(\n case: \"c1a5e000-0000-4000-8000-000000000001\",\n template: \"7ec00000-0000-4000-8000-000000000006\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.CreateAsync(new RegulatoryReportsCreateParams\n{\n Case = \"c1a5e000-0000-4000-8000-000000000001\",\n Template = \"7ec00000-0000-4000-8000-000000000006\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -40591,6 +46050,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.retrieve(\n \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.retrieve(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Retrieve(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().retrieve(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->retrieve('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.retrieve(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.RetrieveAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -40759,6 +46253,10 @@ } } } + }, + "example": { + "rentity_id": "FIU-US-00123", + "currency_code_local": "USD" } } } @@ -40768,6 +46266,41 @@ "lang": "curl", "label": "curl", "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"rentity_id\": \"FIU-US-00123\", \"currency_code_local\": \"USD\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.update(\n \"5ec00000-0000-4000-8000-000000000007\",\n rentity_id=\"FIU-US-00123\",\n currency_code_local=\"USD\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.update(\"5ec00000-0000-4000-8000-000000000007\", {\n rentity_id: \"FIU-US-00123\",\n currency_code_local: \"USD\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Update(ctx, \"5ec00000-0000-4000-8000-000000000007\", didit.RegulatoryReportsUpdateParams{\n\tRentityID: didit.String(\"FIU-US-00123\"),\n\tCurrencyCodeLocal: didit.String(\"USD\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().update(\"5ec00000-0000-4000-8000-000000000007\", RegulatoryReportsUpdateParams.builder()\n .rentityId(\"FIU-US-00123\")\n .currencyCodeLocal(\"USD\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->update('5ec00000-0000-4000-8000-000000000007', [\n 'rentity_id' => 'FIU-US-00123',\n 'currency_code_local' => 'USD',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.update(\n \"5ec00000-0000-4000-8000-000000000007\",\n rentity_id: \"FIU-US-00123\",\n currency_code_local: \"USD\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.UpdateAsync(\"5ec00000-0000-4000-8000-000000000007\", new RegulatoryReportsUpdateParams\n{\n RentityId = \"FIU-US-00123\",\n CurrencyCodeLocal = \"USD\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -40860,6 +46393,36 @@ "lang": "curl", "label": "curl (finalized report)", "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"confirm_delete\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.regulatory_reports.delete(\n \"5ec00000-0000-4000-8000-000000000007\",\n confirm_delete=True,\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.regulatoryReports.delete(\"5ec00000-0000-4000-8000-000000000007\", {\n confirm_delete: true,\n});" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsDeleteParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.regulatoryReports().delete(\"5ec00000-0000-4000-8000-000000000007\", RegulatoryReportsDeleteParams.builder()\n .confirmDelete(true)\n .build());" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->delete('5ec00000-0000-4000-8000-000000000007', [\n 'confirm_delete' => true,\n]);" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.regulatory_reports.delete(\n \"5ec00000-0000-4000-8000-000000000007\",\n confirm_delete: true\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.RegulatoryReports.DeleteAsync(\"5ec00000-0000-4000-8000-000000000007\", new RegulatoryReportsDeleteParams\n{\n ConfirmDelete = true,\n});" } ], "responses": { @@ -40985,6 +46548,9 @@ "example": { "confirm_delete": true } + }, + "example": { + "confirm_delete": true } } } @@ -41044,6 +46610,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/validate/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.validate(\n \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.validate(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Validate(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().validate(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->validate('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.validate(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.ValidateAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -41150,7 +46751,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/finalize/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=30,\n)\nif resp.status_code == 400:\n print('Validation failed:', resp.json()['errors'])\nelse:\n resp.raise_for_status()\n report = resp.json()\n print(report['status'], report['report_number'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.finalize(\n \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.finalize(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Finalize(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().finalize_(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->finalize('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.finalize(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.FinalizeAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -41282,6 +46913,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/download-url/?file=xml' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.retrieve_download_url(\n \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.retrieveDownloadUrl(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.RetrieveDownloadURL(ctx, \"5ec00000-0000-4000-8000-000000000007\", didit.RegulatoryReportsRetrieveDownloadURLParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().retrieveDownloadUrl(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "regulatoryReports->retrieveDownloadUrl('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.retrieve_download_url(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.RetrieveDownloadUrlAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -41472,6 +47138,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/?source=CUSTOM&ordering=-run_count' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.rules.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.rules.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Rules.ListAutoPaging(ctx, didit.TransactionsRulesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().rules().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Rules.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] }, @@ -41599,12 +47300,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nrule = {\n \"title\": \"Structuring - inbound (custom)\",\n \"description\": \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n \"category\": \"finance\",\n \"mode\": \"TEST\",\n \"evaluation_mode\": \"ALL\",\n \"scope\": {\n \"transaction_types\": [\n \"finance\"\n ],\n \"directions\": [\n \"INBOUND\"\n ]\n },\n \"conditions\": [\n {\n \"field\": \"currency\",\n \"operator\": \"eq\",\n \"value\": \"EUR\"\n },\n {\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000\n }\n ],\n \"aggregation\": [\n {\n \"metric\": \"count\",\n \"operator\": \"gte\",\n \"value\": 20,\n \"window\": \"30d\",\n \"filters\": {\n \"direction\": \"INBOUND\",\n \"transaction_type\": \"finance\",\n \"subject_vendor_data\": \"__current__\",\n \"currency\": \"EUR\"\n }\n },\n {\n \"metric\": \"max\",\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000,\n \"window\": \"30d\",\n \"filters\": {\n \"direction\": \"INBOUND\",\n \"transaction_type\": \"finance\",\n \"subject_vendor_data\": \"__current__\",\n \"currency\": \"EUR\"\n }\n }\n ],\n \"actions\": [\n {\n \"type\": \"add_score\",\n \"value\": 35\n }\n ]\n}\n\nresp = requests.post(\n 'https://verification.didit.me/v3/transactions/rules/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json=rule,\n timeout=15,\n)\nresp.raise_for_status()\nprint(resp.json()['uuid'], resp.json()['mode'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.create(\n title=\"Structuring - inbound (custom)\",\n description=\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n category=\"finance\",\n mode=\"TEST\",\n evaluation_mode=\"ALL\",\n scope={\n \"transaction_types\": [\"finance\"],\n \"directions\": [\"INBOUND\"],\n },\n conditions=[{\n \"field\": \"currency\",\n \"operator\": \"eq\",\n \"value\": \"EUR\",\n }, {\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000,\n }],\n aggregation=[{\n \"metric\": \"count\",\n \"operator\": \"gte\",\n \"value\": 20.0,\n \"window\": \"30d\",\n \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n }, {\n \"metric\": \"max\",\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000.0,\n \"window\": \"30d\",\n \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n }],\n actions=[{\n \"type\": \"add_score\",\n \"value\": 35,\n }],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const rule = {\n \"title\": \"Structuring - inbound (custom)\",\n \"description\": \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n \"category\": \"finance\",\n \"mode\": \"TEST\",\n \"evaluation_mode\": \"ALL\",\n \"scope\": {\n \"transaction_types\": [\n \"finance\"\n ],\n \"directions\": [\n \"INBOUND\"\n ]\n },\n \"conditions\": [\n {\n \"field\": \"currency\",\n \"operator\": \"eq\",\n \"value\": \"EUR\"\n },\n {\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000\n }\n ],\n \"aggregation\": [\n {\n \"metric\": \"count\",\n \"operator\": \"gte\",\n \"value\": 20,\n \"window\": \"30d\",\n \"filters\": {\n \"direction\": \"INBOUND\",\n \"transaction_type\": \"finance\",\n \"subject_vendor_data\": \"__current__\",\n \"currency\": \"EUR\"\n }\n },\n {\n \"metric\": \"max\",\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000,\n \"window\": \"30d\",\n \"filters\": {\n \"direction\": \"INBOUND\",\n \"transaction_type\": \"finance\",\n \"subject_vendor_data\": \"__current__\",\n \"currency\": \"EUR\"\n }\n }\n ],\n \"actions\": [\n {\n \"type\": \"add_score\",\n \"value\": 35\n }\n ]\n};\n\nconst resp = await fetch('https://verification.didit.me/v3/transactions/rules/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(rule),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst created = await resp.json();\nconsole.log(created.uuid, created.mode);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.create({\n title: \"Structuring - inbound (custom)\",\n description: \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n category: \"finance\",\n mode: \"TEST\",\n evaluation_mode: \"ALL\",\n scope: {\n transaction_types: [\"finance\"],\n directions: [\"INBOUND\"],\n },\n conditions: [{\n field: \"currency\",\n operator: \"eq\",\n value: \"EUR\",\n }, {\n field: \"amount\",\n operator: \"lt\",\n value: 10000,\n }],\n aggregation: [{\n metric: \"count\",\n operator: \"gte\",\n value: 20.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }, {\n metric: \"max\",\n field: \"amount\",\n operator: \"lt\",\n value: 10000.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }],\n actions: [{\n type: \"add_score\",\n value: 35,\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Create(ctx, didit.TransactionRuleCreateRequest{\n\tTitle: \"Structuring - inbound (custom)\",\n\tDescription: didit.String(\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\"),\n\tCategory: \"finance\",\n\tMode: \"TEST\",\n\tEvaluationMode: didit.Some(didit.TransactionRuleCreateRequestEvaluationMode(\"ALL\")),\n\tScope: didit.Some(didit.TransactionRuleScopeParam{\n\t\tTransactionTypes: didit.Some([]string{\"finance\"}),\n\t\tDirections: didit.Some([]didit.TransactionRuleScopeDirections{\"INBOUND\"}),\n\t}),\n\tConditions: didit.Some([]didit.TransactionRuleConditionParam{{\n\t\tField: \"currency\",\n\t\tOperator: \"eq\",\n\t\tValue: didit.Some[any](\"EUR\"),\n\t}, {\n\t\tField: \"amount\",\n\t\tOperator: \"lt\",\n\t\tValue: didit.Some[any](10000),\n\t}}),\n\tAggregation: didit.Some([]didit.TransactionRuleAggregationParam{{\n\t\tMetric: didit.Some(didit.TransactionRuleAggregationMetric(\"count\")),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"gte\")),\n\t\tValue: 20.0,\n\t\tWindow: didit.String(\"30d\"),\n\t\tFilters: didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}, {\n\t\tMetric: didit.Some(didit.TransactionRuleAggregationMetric(\"max\")),\n\t\tField: didit.String(\"amount\"),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"lt\")),\n\t\tValue: 10000.0,\n\t\tWindow: didit.String(\"30d\"),\n\t\tFilters: didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}}),\n\tActions: didit.Some([]didit.TransactionRuleActionParam{{\n\t\tType: \"add_score\",\n\t\tValue: didit.Some[any](35),\n\t}}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleAction;\nimport me.didit.types.TransactionRuleActionAddScore;\nimport me.didit.types.TransactionRuleAggregation;\nimport me.didit.types.TransactionRuleCondition;\nimport me.didit.types.TransactionRuleCreateRequest;\nimport me.didit.types.TransactionRuleScope;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().create(TransactionRuleCreateRequest.builder()\n .title(\"Structuring - inbound (custom)\")\n .description(\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\")\n .category(\"finance\")\n .mode(TransactionRuleCreateRequest.Mode.of(\"TEST\"))\n .evaluationMode(TransactionRuleCreateRequest.EvaluationMode.of(\"ALL\"))\n .scope(TransactionRuleScope.builder()\n .transactionTypes(List.of(\"finance\"))\n .directions(List.of(TransactionRuleScope.Directions.of(\"INBOUND\")))\n .build())\n .conditions(List.of(\n TransactionRuleCondition.builder()\n .field(\"currency\")\n .operator(TransactionRuleCondition.Operator.of(\"eq\"))\n .value(\"EUR\")\n .build(),\n TransactionRuleCondition.builder()\n .field(\"amount\")\n .operator(TransactionRuleCondition.Operator.of(\"lt\"))\n .value(10000)\n .build()))\n .aggregation(List.of(\n TransactionRuleAggregation.builder()\n .metric(TransactionRuleAggregation.Metric.of(\"count\"))\n .operator(TransactionRuleAggregation.Operator.of(\"gte\"))\n .value(20.0)\n .window(\"30d\")\n .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n .build(),\n TransactionRuleAggregation.builder()\n .metric(TransactionRuleAggregation.Metric.of(\"max\"))\n .field(\"amount\")\n .operator(TransactionRuleAggregation.Operator.of(\"lt\"))\n .value(10000.0)\n .window(\"30d\")\n .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n .build()))\n .actions(List.of(TransactionRuleAction.ofAddScore(TransactionRuleActionAddScore.builder()\n .type(TransactionRuleActionAddScore.Type.of(\"add_score\"))\n .value(35L)\n .build())))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->create([\n 'title' => 'Structuring - inbound (custom)',\n 'description' => '20+ inbound EUR transfers, all under 10,000 EUR, 30 days',\n 'category' => 'finance',\n 'mode' => 'TEST',\n 'evaluation_mode' => 'ALL',\n 'scope' => [\n 'transaction_types' => ['finance'],\n 'directions' => ['INBOUND'],\n ],\n 'conditions' => [[\n 'field' => 'currency',\n 'operator' => 'eq',\n 'value' => 'EUR',\n ], [\n 'field' => 'amount',\n 'operator' => 'lt',\n 'value' => 10000,\n ]],\n 'aggregation' => [[\n 'metric' => 'count',\n 'operator' => 'gte',\n 'value' => 20.0,\n 'window' => '30d',\n 'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n ], [\n 'metric' => 'max',\n 'field' => 'amount',\n 'operator' => 'lt',\n 'value' => 10000.0,\n 'window' => '30d',\n 'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n ]],\n 'actions' => [[\n 'type' => 'add_score',\n 'value' => 35,\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.create(\n title: \"Structuring - inbound (custom)\",\n description: \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n category: \"finance\",\n mode: \"TEST\",\n evaluation_mode: \"ALL\",\n scope: {\n transaction_types: [\"finance\"],\n directions: [\"INBOUND\"],\n },\n conditions: [{\n field: \"currency\",\n operator: \"eq\",\n value: \"EUR\",\n }, {\n field: \"amount\",\n operator: \"lt\",\n value: 10000,\n }],\n aggregation: [{\n metric: \"count\",\n operator: \"gte\",\n value: 20.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }, {\n metric: \"max\",\n field: \"amount\",\n operator: \"lt\",\n value: 10000.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }],\n actions: [{\n type: \"add_score\",\n value: 35,\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.CreateAsync(new TransactionRuleCreateRequest\n{\n Title = \"Structuring - inbound (custom)\",\n Description = \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n Category = \"finance\",\n Mode = \"TEST\",\n EvaluationMode = new TransactionRuleCreateRequestEvaluationMode(\"ALL\"),\n Scope = new TransactionRuleScope\n {\n TransactionTypes = new string[] { \"finance\" },\n Directions = new TransactionRuleScopeDirections[] { \"INBOUND\" },\n },\n Conditions = new TransactionRuleCondition[]\n {\n new()\n {\n Field = \"currency\",\n Operator = \"eq\",\n Value = \"EUR\",\n },\n new()\n {\n Field = \"amount\",\n Operator = \"lt\",\n Value = 10000,\n },\n },\n Aggregation = new TransactionRuleAggregation[]\n {\n new()\n {\n Metric = new TransactionRuleAggregationMetric(\"count\"),\n Operator = new TransactionRuleAggregationOperator(\"gte\"),\n Value = 20.0,\n Window = \"30d\",\n Filters = new Dictionary { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n },\n new()\n {\n Metric = new TransactionRuleAggregationMetric(\"max\"),\n Field = \"amount\",\n Operator = new TransactionRuleAggregationOperator(\"lt\"),\n Value = 10000.0,\n Window = \"30d\",\n Filters = new Dictionary { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n },\n },\n Actions = new TransactionRuleAction[]\n {\n new()\n {\n Type = new TransactionRuleActionType(\"add_score\"),\n Value = 35,\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -41667,6 +47393,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -41732,7 +47493,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'mode': 'ACTIVE'},\n timeout=15,\n)\nresp.raise_for_status()\nprint(resp.json()['mode'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.update(\n \"11111111-2222-3333-4444-555555555555\",\n mode=\"ACTIVE\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.update(\"11111111-2222-3333-4444-555555555555\", {\n mode: \"ACTIVE\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TransactionRuleUpdateRequest{\n\tMode: didit.Some(didit.TransactionRuleUpdateRequestMode(\"ACTIVE\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TransactionRuleUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().update(\"11111111-2222-3333-4444-555555555555\", TransactionRuleUpdateRequest.builder()\n .mode(TransactionRuleUpdateRequest.Mode.of(\"ACTIVE\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->update('11111111-2222-3333-4444-555555555555', [\n 'mode' => 'ACTIVE',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.update(\n \"11111111-2222-3333-4444-555555555555\",\n mode: \"ACTIVE\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new TransactionRuleUpdateRequest\n{\n Mode = new TransactionRuleUpdateRequestMode(\"ACTIVE\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -41787,6 +47578,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.transactions.rules.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.transactions.rules.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Transactions.Rules.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.transactions().rules().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Transactions.Rules.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ] } @@ -41898,7 +47724,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/transactions/rules/backtest/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n \"conditions\": [\n {\n \"field\": \"currency\",\n \"operator\": \"eq\",\n \"value\": \"EUR\"\n },\n {\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000\n }\n ],\n \"aggregation\": [\n {\n \"metric\": \"count\",\n \"operator\": \"gte\",\n \"value\": 20,\n \"window\": \"30d\",\n \"filters\": {\n \"direction\": \"INBOUND\",\n \"transaction_type\": \"finance\",\n \"subject_vendor_data\": \"__current__\",\n \"currency\": \"EUR\"\n }\n },\n {\n \"metric\": \"max\",\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000,\n \"window\": \"30d\",\n \"filters\": {\n \"direction\": \"INBOUND\",\n \"transaction_type\": \"finance\",\n \"subject_vendor_data\": \"__current__\",\n \"currency\": \"EUR\"\n }\n }\n ],\n \"evaluation_mode\": \"ALL\",\n \"scope\": {\n \"transaction_types\": [\n \"finance\"\n ],\n \"directions\": [\n \"INBOUND\"\n ]\n },\n \"period_days\": 90\n},\n timeout=30,\n)\nresp.raise_for_status()\nstats = resp.json()\nprint(stats['matched'], 'matches across', stats['affected_entities'], 'subjects')" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.backtest(\n conditions=[{\n \"field\": \"currency\",\n \"operator\": \"eq\",\n \"value\": \"EUR\",\n }, {\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000,\n }],\n aggregation=[{\n \"metric\": \"count\",\n \"operator\": \"gte\",\n \"value\": 20.0,\n \"window\": \"30d\",\n \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n }, {\n \"metric\": \"max\",\n \"field\": \"amount\",\n \"operator\": \"lt\",\n \"value\": 10000.0,\n \"window\": \"30d\",\n \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n }],\n evaluation_mode=\"ALL\",\n scope={\n \"transaction_types\": [\"finance\"],\n \"directions\": [\"INBOUND\"],\n },\n period_days=90,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.backtest({\n conditions: [{\n field: \"currency\",\n operator: \"eq\",\n value: \"EUR\",\n }, {\n field: \"amount\",\n operator: \"lt\",\n value: 10000,\n }],\n aggregation: [{\n metric: \"count\",\n operator: \"gte\",\n value: 20.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }, {\n metric: \"max\",\n field: \"amount\",\n operator: \"lt\",\n value: 10000.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }],\n evaluation_mode: \"ALL\",\n scope: {\n transaction_types: [\"finance\"],\n directions: [\"INBOUND\"],\n },\n period_days: 90,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Backtest(ctx, didit.TransactionRuleBacktestRequest{\n\tConditions: didit.Some([]didit.TransactionRuleConditionParam{{\n\t\tField: \"currency\",\n\t\tOperator: \"eq\",\n\t\tValue: didit.Some[any](\"EUR\"),\n\t}, {\n\t\tField: \"amount\",\n\t\tOperator: \"lt\",\n\t\tValue: didit.Some[any](10000),\n\t}}),\n\tAggregation: didit.Some([]didit.TransactionRuleAggregationParam{{\n\t\tMetric: didit.Some(didit.TransactionRuleAggregationMetric(\"count\")),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"gte\")),\n\t\tValue: 20.0,\n\t\tWindow: didit.String(\"30d\"),\n\t\tFilters: didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}, {\n\t\tMetric: didit.Some(didit.TransactionRuleAggregationMetric(\"max\")),\n\t\tField: didit.String(\"amount\"),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"lt\")),\n\t\tValue: 10000.0,\n\t\tWindow: didit.String(\"30d\"),\n\t\tFilters: didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}}),\n\tEvaluationMode: didit.Some(didit.TransactionRuleBacktestRequestEvaluationMode(\"ALL\")),\n\tScope: didit.Some(didit.TransactionRuleScopeParam{\n\t\tTransactionTypes: didit.Some([]string{\"finance\"}),\n\t\tDirections: didit.Some([]didit.TransactionRuleScopeDirections{\"INBOUND\"}),\n\t}),\n\tPeriodDays: didit.Int(90),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleAggregation;\nimport me.didit.types.TransactionRuleBacktestRequest;\nimport me.didit.types.TransactionRuleCondition;\nimport me.didit.types.TransactionRuleScope;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().backtest(TransactionRuleBacktestRequest.builder()\n .conditions(List.of(\n TransactionRuleCondition.builder()\n .field(\"currency\")\n .operator(TransactionRuleCondition.Operator.of(\"eq\"))\n .value(\"EUR\")\n .build(),\n TransactionRuleCondition.builder()\n .field(\"amount\")\n .operator(TransactionRuleCondition.Operator.of(\"lt\"))\n .value(10000)\n .build()))\n .aggregation(List.of(\n TransactionRuleAggregation.builder()\n .metric(TransactionRuleAggregation.Metric.of(\"count\"))\n .operator(TransactionRuleAggregation.Operator.of(\"gte\"))\n .value(20.0)\n .window(\"30d\")\n .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n .build(),\n TransactionRuleAggregation.builder()\n .metric(TransactionRuleAggregation.Metric.of(\"max\"))\n .field(\"amount\")\n .operator(TransactionRuleAggregation.Operator.of(\"lt\"))\n .value(10000.0)\n .window(\"30d\")\n .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n .build()))\n .evaluationMode(TransactionRuleBacktestRequest.EvaluationMode.of(\"ALL\"))\n .scope(TransactionRuleScope.builder()\n .transactionTypes(List.of(\"finance\"))\n .directions(List.of(TransactionRuleScope.Directions.of(\"INBOUND\")))\n .build())\n .periodDays(90L)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->backtest([\n 'conditions' => [[\n 'field' => 'currency',\n 'operator' => 'eq',\n 'value' => 'EUR',\n ], [\n 'field' => 'amount',\n 'operator' => 'lt',\n 'value' => 10000,\n ]],\n 'aggregation' => [[\n 'metric' => 'count',\n 'operator' => 'gte',\n 'value' => 20.0,\n 'window' => '30d',\n 'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n ], [\n 'metric' => 'max',\n 'field' => 'amount',\n 'operator' => 'lt',\n 'value' => 10000.0,\n 'window' => '30d',\n 'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n ]],\n 'evaluation_mode' => 'ALL',\n 'scope' => [\n 'transaction_types' => ['finance'],\n 'directions' => ['INBOUND'],\n ],\n 'period_days' => 90,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.backtest(\n conditions: [{\n field: \"currency\",\n operator: \"eq\",\n value: \"EUR\",\n }, {\n field: \"amount\",\n operator: \"lt\",\n value: 10000,\n }],\n aggregation: [{\n metric: \"count\",\n operator: \"gte\",\n value: 20.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }, {\n metric: \"max\",\n field: \"amount\",\n operator: \"lt\",\n value: 10000.0,\n window: \"30d\",\n filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n }],\n evaluation_mode: \"ALL\",\n scope: {\n transaction_types: [\"finance\"],\n directions: [\"INBOUND\"],\n },\n period_days: 90\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.BacktestAsync(new TransactionRuleBacktestRequest\n{\n Conditions = new TransactionRuleCondition[]\n {\n new()\n {\n Field = \"currency\",\n Operator = \"eq\",\n Value = \"EUR\",\n },\n new()\n {\n Field = \"amount\",\n Operator = \"lt\",\n Value = 10000,\n },\n },\n Aggregation = new TransactionRuleAggregation[]\n {\n new()\n {\n Metric = new TransactionRuleAggregationMetric(\"count\"),\n Operator = new TransactionRuleAggregationOperator(\"gte\"),\n Value = 20.0,\n Window = \"30d\",\n Filters = new Dictionary { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n },\n new()\n {\n Metric = new TransactionRuleAggregationMetric(\"max\"),\n Field = \"amount\",\n Operator = new TransactionRuleAggregationOperator(\"lt\"),\n Value = 10000.0,\n Window = \"30d\",\n Filters = new Dictionary { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n },\n },\n EvaluationMode = new TransactionRuleBacktestRequestEvaluationMode(\"ALL\"),\n Scope = new TransactionRuleScope\n {\n TransactionTypes = new string[] { \"finance\" },\n Directions = new TransactionRuleScopeDirections[] { \"INBOUND\" },\n },\n PeriodDays = 90,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -42005,6 +47861,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/library/?bundle=finance' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.rules.list_library():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.rules.listLibrary()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Rules.ListLibraryAutoPaging(ctx, didit.TransactionsRulesListLibraryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().rules().listLibrary()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->listLibrary() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.list_library.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Rules.ListLibraryAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] } @@ -42078,6 +47969,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/install/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"library_keys\": [\"structuring-inbound\", \"structuring-outbound\"]}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.install_library(\n library_keys=[\"structuring-inbound\", \"structuring-outbound\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.installLibrary({\n library_keys: [\"structuring-inbound\", \"structuring-outbound\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.InstallLibrary(ctx, didit.TransactionRuleInstallRequest{\n\tLibraryKeys: didit.Some([]string{\"structuring-inbound\", \"structuring-outbound\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleInstallRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().installLibrary(TransactionRuleInstallRequest.builder()\n .libraryKeys(List.of(\"structuring-inbound\", \"structuring-outbound\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->installLibrary([\n 'library_keys' => ['structuring-inbound', 'structuring-outbound'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.install_library(library_keys: [\"structuring-inbound\", \"structuring-outbound\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.InstallLibraryAsync(new TransactionRuleInstallRequest\n{\n LibraryKeys = new string[] { \"structuring-inbound\", \"structuring-outbound\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -42142,6 +48068,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE 'https://verification.didit.me/v3/transactions/rules/install/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"bundle\": \"responsible_gaming\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.uninstall_library(\n bundle=\"responsible_gaming\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.uninstallLibrary({\n bundle: \"responsible_gaming\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.UninstallLibrary(ctx, didit.TransactionRuleInstallRequest{\n\tBundle: didit.String(\"responsible_gaming\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TransactionRuleInstallRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().uninstallLibrary(TransactionRuleInstallRequest.builder()\n .bundle(\"responsible_gaming\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->rules->uninstallLibrary([\n 'bundle' => 'responsible_gaming',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.uninstall_library(bundle: \"responsible_gaming\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.UninstallLibraryAsync(new TransactionRuleInstallRequest\n{\n Bundle = \"responsible_gaming\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -42346,6 +48307,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/?status=active,in_review&ordering=-risk_score' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.networks.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.networks.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Networks.ListAutoPaging(ctx, didit.NetworksListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.networks().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.networks.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Networks.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -42596,6 +48592,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve(\n \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieve(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.Retrieve(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieve(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->retrieve('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -42911,6 +48942,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/graph/?depth=2' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_graph(\n \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveGraph(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveGraph(ctx, \"n3a5e000-0000-4000-8000-000000000001\", didit.NetworksRetrieveGraphParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveGraph(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->retrieveGraph('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_graph(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveGraphAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43000,6 +49066,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/members/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.list_members(\n \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.listMembers(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.ListMembers(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().listMembers(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->listMembers('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.list_members(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.ListMembersAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43097,6 +49198,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/signals/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.list_signals(\n \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.listSignals(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.ListSignals(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().listSignals(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->listSignals('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.list_signals(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.ListSignalsAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43261,6 +49397,41 @@ "lang": "curl", "label": "curl (typed timeline)", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/timeline/?contract=2&limit=50&event_type=verification_attempt,login' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_timeline(\n \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveTimeline(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveTimeline(ctx, \"n3a5e000-0000-4000-8000-000000000001\", didit.NetworksRetrieveTimelineParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveTimeline(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->retrieveTimeline('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_timeline(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveTimelineAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43625,6 +49796,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/map/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_map(\n \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveMap(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveMap(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveMap(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->retrieveMap('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_map(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveMapAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43713,6 +49919,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/sessions/aaaaaaaa-0000-4000-8000-000000000001/networks/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.sessions.list_networks(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.sessions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43801,6 +50042,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/business-sessions/aaaaaaaa-0000-4000-8000-000000000002/networks/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.business_sessions.list_networks(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businessSessions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.BusinessSessions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businessSessions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businessSessions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.business_sessions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.BusinessSessions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43889,6 +50165,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/users/aaaaaaaa-0000-4000-8000-000000000003/networks/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.list_networks(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "users->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -43977,6 +50288,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/businesses/aaaaaaaa-0000-4000-8000-000000000004/networks/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.list_networks(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -44065,6 +50411,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/aaaaaaaa-0000-4000-8000-000000000005/networks/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.transactions.list_networks(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.transactions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.transactions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.transactions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -44163,6 +50544,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/aaaaaaaa-0000-4000-8000-000000000005/parties/bbbbbbbb-0000-4000-8000-000000000006/networks/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.transactions.list_party_networks(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.transactions.listPartyNetworks(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.ListPartyNetworks(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.transactions().listPartyNetworks(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->listPartyNetworks('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.transactions.list_party_networks(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.ListPartyNetworksAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -44535,6 +50951,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/biometric-templates/?vendor_data=user-42&status=active' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.biometric_templates.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.biometricTemplates.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.BiometricTemplates.ListAutoPaging(ctx, didit.BiometricTemplatesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.biometricTemplates().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "biometricTemplates->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.biometric_templates.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.BiometricTemplates.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ] } @@ -44690,6 +51141,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/biometric-templates/count/?status=active' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.count()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.count();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Count(ctx, didit.BiometricTemplatesCountParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().count();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "biometricTemplates->count();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.count\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.CountAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -44909,6 +51395,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/biometric-templates/9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.retrieve(\n \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Retrieve(ctx, \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "biometricTemplates->retrieve('9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.RetrieveAsync(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] }, @@ -45037,6 +51558,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE https://verification.didit.me/v3/biometric-templates/9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.delete(\n \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Delete(ctx, \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "biometricTemplates->delete('9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.DeleteAsync(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -45260,6 +51816,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/biometric-templates/delete/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"delete_all\": true, \"vendor_user_uuid\": \"2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.batch_delete(\n template_uuids=[\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.batchDelete({\n template_uuids: [\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.BatchDelete(ctx, didit.BiometricTemplatesBatchDeleteParams{\n\tTemplateUUIDs: didit.Some([]string{\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BiometricTemplatesBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().batchDelete(BiometricTemplatesBatchDeleteParams.builder()\n .templateUuids(List.of(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "biometricTemplates->batchDelete([\n 'template_uuids' => ['9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b', '1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.batch_delete(template_uuids: [\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.BatchDeleteAsync(new BiometricTemplatesBatchDeleteParams\n{\n TemplateUuids = new string[] { \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -45283,13 +51874,17 @@ } ], "parameters": [], - "description": "Retrieve the Lite profile **plus the direct shareholders** (natural persons and corporate entities, with their ownership bands) of one candidate returned by `POST /v3/kyb/search/`.\n\n**Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. The search runs on the Lite registry chain; when the country's ownership data lives at another registry Didit re-finds the company there by registration number, at no extra cost.\n\n**Billing.** Billed at the country's Shareholders price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). When the registry holds no shareholder record for the company (or the country offers no ownership data at all) the Lite profile is delivered and billed instead: read `registry_tier_delivered` and `registry_ownership_status`. The balance is checked against the Shareholders price before any registry call (`403` when short).\n\n**Availability.** v3 only. Every call creates a business session (its id is the `request_id`).\n\n**Pending reports.** When a report is still being prepared, or the ownership section has not been retrieved from the registry yet, the endpoint returns 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, and registry_tier_delivered=null. Keep request_id and retrieve GET /v3/session/{request_id}/decision/ until registry_checks[0].company.fetch_status is resolved. Didit completes the report automatically and charges the delivered tier once it is ready. Do not repeat the purchase while it is pending; every new POST creates a separate request.", + "description": "Retrieve the Lite profile **plus the direct shareholders** (natural persons and corporate entities, with their ownership bands) of one candidate returned by `POST /v3/kyb/search/`.\n\n**Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. Search at the tier you intend to buy (`tier` on `POST /v3/kyb/search/`), because the search runs on the registry chain that serves that tier and an empty Lite search is not proof that the registry does not hold the company. When the country's ownership data lives at another registry, Didit re-finds the company there by registration number, at no extra cost.\n\n**Billing.** Billed at the country's Shareholders price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). When the registry holds no shareholder record for the company (or the country offers no ownership data at all) the Lite profile is delivered and billed instead: read `registry_tier_delivered` and `registry_ownership_status`. The balance is checked against the Shareholders price before any registry call (`403` when short).\n\n**Availability.** v3 only. Every call creates a business session (its id is the `request_id`).\n\n**Pending reports.** When a report is still being prepared, or the ownership section has not been retrieved from the registry yet, the endpoint returns 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, and registry_tier_delivered=null. Keep request_id and retrieve GET /v3/session/{request_id}/decision/ until registry_checks[0].company.fetch_status is resolved. Didit completes the report automatically and charges the delivered tier once it is ready. Do not repeat the purchase while it is pending; every new POST creates a separate request.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KYBRegistryCandidateRequest" + }, + "example": { + "kyb_response_id": "69aeeb95febb0f1704042259", + "vendor_data": "company-1234" } } } @@ -45303,12 +51898,37 @@ { "lang": "python", "label": "Python", - "source": "import os, time, requests\n\nsearch = requests.post(\n \"https://verification.didit.me/v3/kyb/search/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"country_code\": \"GB\", \"name\": \"Tesco\"},\n timeout=60,\n).json()\nkyb_response_id = search[\"kyb_registry\"][\"companies\"][0][\"kyb_response_id\"]\n\nresp = requests.post(\n \"https://verification.didit.me/v3/kyb/shareholders/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"kyb_response_id\": kyb_response_id, \"vendor_data\": \"company-1234\"},\n timeout=90,\n)\nresp.raise_for_status()\ndata = resp.json()\nrequest_id = data[\"request_id\"]\nprint(\"Keep this request ID:\", request_id)\ncompany = data[\"kyb_registry\"]\nif resp.status_code == 202 or company.get(\"fetch_status\") == \"pending\":\n # This client wait limit does not cancel the report or create a new purchase.\n deadline = time.monotonic() + 300\n while company.get(\"fetch_status\") != \"resolved\" and time.monotonic() < deadline:\n time.sleep(5)\n decision = requests.get(\n f\"https://verification.didit.me/v3/session/{request_id}/decision/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n timeout=30,\n )\n decision.raise_for_status()\n checks = decision.json().get(\"registry_checks\") or []\n if checks:\n company = checks[0].get(\"company\") or company\nif company.get(\"fetch_status\") == \"resolved\":\n print(company[\"company_name\"], company[\"registry_tier_delivered\"])\nelse:\n print(\"Still processing; retrieve this request later:\", request_id)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.list_shareholders(\n kyb_response_id=\"69aeeb95febb0f1704042259\",\n vendor_data=\"company-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/kyb/shareholders/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n kyb_response_id: '69aeeb95febb0f1704042259',\n vendor_data: 'company-1234',\n }),\n});\nif (!res.ok) throw new Error(`Request failed: ${res.status}`);\nconst data = await res.json();\nconst requestId = data.request_id;\nconsole.log('Keep this request ID:', requestId);\nlet company = data.kyb_registry;\nif (res.status === 202 || company.fetch_status === 'pending') {\n // This client wait limit does not cancel the report or create a new purchase.\n const deadline = Date.now() + 300000;\n while (company.fetch_status !== 'resolved' && Date.now() < deadline) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n const decisionResponse = await fetch(\n `https://verification.didit.me/v3/session/${requestId}/decision/`,\n { headers: { 'x-api-key': 'YOUR_API_KEY' }, signal: AbortSignal.timeout(30000) },\n );\n if (!decisionResponse.ok) throw new Error(`Retrieval failed: ${decisionResponse.status}`);\n const decision = await decisionResponse.json();\n company = decision.registry_checks?.[0]?.company ?? company;\n }\n}\nif (company.fetch_status === 'resolved') {\n console.log(company.company_name, company.registry_tier_delivered);\n} else {\n console.log('Still processing; retrieve this request later:', requestId);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.listShareholders({\n kyb_response_id: \"69aeeb95febb0f1704042259\",\n vendor_data: \"company-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.ListShareholders(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData: didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().listShareholders(KYBRegistryCandidateRequest.builder()\n .kybResponseId(\"69aeeb95febb0f1704042259\")\n .vendorData(\"company-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "kyb->listShareholders([\n 'kyb_response_id' => '69aeeb95febb0f1704042259',\n 'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.list_shareholders(\n kyb_response_id: \"69aeeb95febb0f1704042259\",\n vendor_data: \"company-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.ListShareholdersAsync(new KYBRegistryCandidateRequest\n{\n KybResponseId = \"69aeeb95febb0f1704042259\",\n VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -45819,8 +52439,7 @@ "description": "Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts." }, "registry_data": { - "type": "object", - "description": "Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead." + "$ref": "#/components/schemas/KYBRegistryData" }, "user_provided_data": { "type": "object", @@ -45874,6 +52493,55 @@ "type": "string", "nullable": true, "description": "The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`." + }, + "registry_monitoring": { + "type": "object", + "nullable": true, + "description": "The latest registry monitor for the company, or `null` when none exists.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string" + }, + "unavailable_reason": { + "type": "string", + "nullable": true + }, + "enrolled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "cancelled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "last_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "next_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "last_event_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "events_count": { + "type": "integer" + }, + "watched_fields": { + "description": "The company fields the monitor watches." + } + } } } }, @@ -45969,24 +52637,7 @@ "next_account": "26 February 2026", "due_by_date": "26 August 2026" }, - "registry_data": { - "name": "Tesco PLC", - "registration_number": "00445790", - "status": "active", - "type": "Public Limited Company", - "incorporation_date": "1947-11-27", - "tax_number": "GB412 8925 93", - "country_code": "GB", - "fetch_status": "resolved", - "industries_detail": [ - { - "code": "47110", - "name": "Retail Sale In Non-specialised Stores With Food, Beverages Or Tobacco Predominating", - "description": null, - "meta_detail": [] - } - ] - }, + "registry_data": {}, "user_provided_data": null, "confirmed_by_user_at": null, "last_console_edit_at": null, @@ -46027,7 +52678,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", "content": { "application/json": { "examples": { @@ -46157,13 +52808,17 @@ } ], "parameters": [], - "description": "Retrieve the Lite profile, the direct shareholders **and the ultimate beneficial owners** resolved through the ownership chain (`registry_data.ubo_resolution` carries the corporate parent chain) of one candidate returned by `POST /v3/kyb/search/`.\n\n**Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. The search runs on the Lite registry chain; when the country's ownership data lives at another registry Didit re-finds the company there by registration number, at no extra cost.\n\n**Billing.** Billed at the country's UBO price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). The tier delivered is the highest the country and the registry can serve: Shareholders when the resolved report names no natural person as a beneficial owner, Lite when there is no ownership record at all; `registry_tier_delivered` names what was billed. The balance is checked against the UBO price before any registry call (`403` when short).\n\n**Availability.** v3 only. Every call creates a business session (its id is the `request_id`).\n\n**Pending reports.** When a report is still being prepared, or the ownership section has not been retrieved from the registry yet, the endpoint returns 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, and registry_tier_delivered=null. Keep request_id and retrieve GET /v3/session/{request_id}/decision/ until registry_checks[0].company.fetch_status is resolved. Didit completes the report automatically and charges the delivered tier once it is ready. Do not repeat the purchase while it is pending; every new POST creates a separate request.", + "description": "Retrieve the Lite profile, the direct shareholders **and the ultimate beneficial owners** resolved through the ownership chain (`registry_data.ubo_resolution` carries the corporate parent chain) of one candidate returned by `POST /v3/kyb/search/`.\n\n**Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. Search at the tier you intend to buy (`tier` on `POST /v3/kyb/search/`), because the search runs on the registry chain that serves that tier and an empty Lite search is not proof that the registry does not hold the company. When the country's ownership data lives at another registry, Didit re-finds the company there by registration number, at no extra cost.\n\n**Billing.** Billed at the country's UBO price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). The tier delivered is the highest the country and the registry can serve: Shareholders when the resolved report names no natural person as a beneficial owner, Lite when there is no ownership record at all; `registry_tier_delivered` names what was billed. The balance is checked against the UBO price before any registry call (`403` when short).\n\n**Availability.** v3 only. Every call creates a business session (its id is the `request_id`).\n\n**Pending reports.** When a report is still being prepared, or the ownership section has not been retrieved from the registry yet, the endpoint returns 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, and registry_tier_delivered=null. Keep request_id and retrieve GET /v3/session/{request_id}/decision/ until registry_checks[0].company.fetch_status is resolved. Didit completes the report automatically and charges the delivered tier once it is ready. Do not repeat the purchase while it is pending; every new POST creates a separate request.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KYBRegistryCandidateRequest" + }, + "example": { + "kyb_response_id": "69aeeb95febb0f1704042259", + "vendor_data": "company-1234" } } } @@ -46177,12 +52832,37 @@ { "lang": "python", "label": "Python", - "source": "import os, time, requests\n\nsearch = requests.post(\n \"https://verification.didit.me/v3/kyb/search/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"country_code\": \"GB\", \"name\": \"Tesco\"},\n timeout=60,\n).json()\nkyb_response_id = search[\"kyb_registry\"][\"companies\"][0][\"kyb_response_id\"]\n\nresp = requests.post(\n \"https://verification.didit.me/v3/kyb/ubo/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\"kyb_response_id\": kyb_response_id, \"vendor_data\": \"company-1234\"},\n timeout=90,\n)\nresp.raise_for_status()\ndata = resp.json()\nrequest_id = data[\"request_id\"]\nprint(\"Keep this request ID:\", request_id)\ncompany = data[\"kyb_registry\"]\nif resp.status_code == 202 or company.get(\"fetch_status\") == \"pending\":\n # This client wait limit does not cancel the report or create a new purchase.\n deadline = time.monotonic() + 300\n while company.get(\"fetch_status\") != \"resolved\" and time.monotonic() < deadline:\n time.sleep(5)\n decision = requests.get(\n f\"https://verification.didit.me/v3/session/{request_id}/decision/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n timeout=30,\n )\n decision.raise_for_status()\n checks = decision.json().get(\"registry_checks\") or []\n if checks:\n company = checks[0].get(\"company\") or company\nif company.get(\"fetch_status\") == \"resolved\":\n print(company[\"company_name\"], company[\"registry_tier_delivered\"])\nelse:\n print(\"Still processing; retrieve this request later:\", request_id)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.list_ubos(\n kyb_response_id=\"69aeeb95febb0f1704042259\",\n vendor_data=\"company-1234\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/kyb/ubo/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n kyb_response_id: '69aeeb95febb0f1704042259',\n vendor_data: 'company-1234',\n }),\n});\nif (!res.ok) throw new Error(`Request failed: ${res.status}`);\nconst data = await res.json();\nconst requestId = data.request_id;\nconsole.log('Keep this request ID:', requestId);\nlet company = data.kyb_registry;\nif (res.status === 202 || company.fetch_status === 'pending') {\n // This client wait limit does not cancel the report or create a new purchase.\n const deadline = Date.now() + 300000;\n while (company.fetch_status !== 'resolved' && Date.now() < deadline) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n const decisionResponse = await fetch(\n `https://verification.didit.me/v3/session/${requestId}/decision/`,\n { headers: { 'x-api-key': 'YOUR_API_KEY' }, signal: AbortSignal.timeout(30000) },\n );\n if (!decisionResponse.ok) throw new Error(`Retrieval failed: ${decisionResponse.status}`);\n const decision = await decisionResponse.json();\n company = decision.registry_checks?.[0]?.company ?? company;\n }\n}\nif (company.fetch_status === 'resolved') {\n console.log(company.company_name, company.registry_tier_delivered);\n} else {\n console.log('Still processing; retrieve this request later:', requestId);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.listUbos({\n kyb_response_id: \"69aeeb95febb0f1704042259\",\n vendor_data: \"company-1234\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.ListUBOs(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData: didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().listUbos(KYBRegistryCandidateRequest.builder()\n .kybResponseId(\"69aeeb95febb0f1704042259\")\n .vendorData(\"company-1234\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "kyb->listUbos([\n 'kyb_response_id' => '69aeeb95febb0f1704042259',\n 'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.list_ubos(\n kyb_response_id: \"69aeeb95febb0f1704042259\",\n vendor_data: \"company-1234\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.ListUbosAsync(new KYBRegistryCandidateRequest\n{\n KybResponseId = \"69aeeb95febb0f1704042259\",\n VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -46693,8 +53373,7 @@ "description": "Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts." }, "registry_data": { - "type": "object", - "description": "Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead." + "$ref": "#/components/schemas/KYBRegistryData" }, "user_provided_data": { "type": "object", @@ -46748,6 +53427,55 @@ "type": "string", "nullable": true, "description": "The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`." + }, + "registry_monitoring": { + "type": "object", + "nullable": true, + "description": "The latest registry monitor for the company, or `null` when none exists.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string" + }, + "unavailable_reason": { + "type": "string", + "nullable": true + }, + "enrolled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "cancelled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "last_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "next_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "last_event_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "events_count": { + "type": "integer" + }, + "watched_fields": { + "description": "The company fields the monitor watches." + } + } } } }, @@ -46844,22 +53572,11 @@ "due_by_date": "26 August 2026" }, "registry_data": { - "name": "Tesco PLC", - "registration_number": "00445790", - "status": "active", - "type": "Public Limited Company", - "incorporation_date": "1947-11-27", - "tax_number": "GB412 8925 93", - "country_code": "GB", - "fetch_status": "resolved", - "industries_detail": [ - { - "code": "47110", - "name": "Retail Sale In Non-specialised Stores With Food, Beverages Or Tobacco Predominating", - "description": null, - "meta_detail": [] - } - ] + "ubo_resolution": { + "parent_chain": [], + "subsidiaries": [], + "unresolved": [] + } }, "user_provided_data": null, "confirmed_by_user_at": null, @@ -46901,7 +53618,7 @@ } }, "403": { - "description": "Permission denied. Returned when the `x-api-key` header is missing, malformed, revoked, or belongs to another environment — and also when the calling organization's balance cannot cover the call. Authentication failures return `403` with `{\"detail\": ...}`; this API never returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", + "description": "Permission denied. Returned when the `x-api-key` header is missing, and also when the calling organization's balance cannot cover the call; a wrong, revoked or expired key returns `401`. A missing key returns `403` with `{\"detail\": ...}`; a wrong, revoked or expired key returns `401`. Credit shortfalls return `403` with `{\"error\": ...}` before any screening or provider call happens.", "content": { "application/json": { "examples": { @@ -47053,7 +53770,7 @@ } } }, - "description": "Missing or invalid credentials (x-api-key or Authorization: Bearer)." + "description": "Missing credentials (x-api-key or Authorization: Bearer)." } }, "x-codeSamples": [ @@ -47065,7 +53782,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"]\n}\n\nresponse = requests.get(\n \"https://verification.didit.me/v3/id-verification/wallets/\",\n headers=headers,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.list()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.list();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().list();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->list();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.list\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.ListAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -47155,7 +53902,7 @@ } } }, - "description": "Missing or invalid credentials (x-api-key or Authorization: Bearer)." + "description": "Missing credentials (x-api-key or Authorization: Bearer)." }, "404": { "content": { @@ -47177,7 +53924,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"]\n}\n\nresponse = requests.get(\n \"https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/\",\n headers=headers,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.retrieve_verification(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.retrieveVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.RetrieveVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().retrieveVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->retrieveVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.retrieve_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.RetrieveVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -47268,7 +54045,7 @@ } } }, - "description": "Missing or invalid credentials (x-api-key or Authorization: Bearer)." + "description": "Missing credentials (x-api-key or Authorization: Bearer)." }, "404": { "content": { @@ -47300,7 +54077,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"]\n}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/poll/\",\n headers=headers,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.poll_verification(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.pollVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.PollVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().pollVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->pollVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.poll_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.PollVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -47387,7 +54194,7 @@ } } }, - "description": "Missing or invalid credentials (x-api-key or Authorization: Bearer)." + "description": "Missing credentials (x-api-key or Authorization: Bearer)." }, "404": { "content": { @@ -47419,7 +54226,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"]\n}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/cancel/\",\n headers=headers,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.cancel_verification(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.cancelVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.CancelVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().cancelVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->cancelVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.cancel_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.CancelVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ] } @@ -47545,7 +54382,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -47587,7 +54424,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'DNK',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/mitid/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mitid(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"DNK\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMitid({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"DNK\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMitid(ctx, didit.IDWalletsStartMitidParams{\n\tBody: didit.DigitalIDWalletAPIMitidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIMitidWalletVerificationStartCountryEnum(\"DNK\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiMitidWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiMitidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMitid(DigitalIdWalletApiMitidWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiMitidWalletVerificationStartCountryEnum.of(\"DNK\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startMitid([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'DNK',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mitid(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"DNK\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMitidAsync(new DigitalIdWalletApiMitidWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiMitidWalletVerificationStartCountryEnum(\"DNK\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "mitid" @@ -47714,7 +54581,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -47756,7 +54623,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'SWE',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/bankid-se/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_se(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"SWE\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidSe({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"SWE\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidSe(ctx, didit.IDWalletsStartBankidSeParams{\n\tBody: didit.DigitalIDWalletAPIBankidSeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryEe9enum(\"SWE\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidSeWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryEe9Enum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidSe(DigitalIdWalletApiBankidSeWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryEe9Enum.of(\"SWE\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startBankidSe([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'SWE',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_se(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"SWE\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidSeAsync(new DigitalIdWalletApiBankidSeWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryEe9Enum(\"SWE\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "bankid_se" @@ -47883,7 +54780,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -47925,192 +54822,53 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'NOR',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/bankid-no/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" - } - ], - "x-didit-wallet-id": "bankid_no" - } - }, - "/v3/id-verification/wallets/vipps/": { - "post": { - "operationId": "start_vipps_wallet_verification", - "x-didit-sdk": { - "resource": "id_wallets", - "method": "start_vipps", - "auth": "api_key", - "server": true - }, - "description": "Start a Vipps sign-in (Vipps MobilePay / BankID NO; NOR) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=redirect with the URL to send the user's browser to; the user returns to return_url with request_id and result appended. Read the outcome with GET /v3/id-verification/wallets/verifications/{request_id}/ or from the webhook, never from the URL. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider.", - "summary": "Start Vipps verification", - "parameters": [ - { - "in": "header", - "name": "Idempotency-Key", - "schema": { - "type": "string" - }, - "description": "Optional retry-safety key (max 255 characters). Retrying with the same key, wallet and body returns the original verification without starting a second sign-in; the same key with another wallet or body returns 409 idempotency_key_reused." - } - ], - "tags": [ - "Digital ID wallets" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest" - }, - "example": { - "country": "NOR", - "vendor_data": "your-customer-reference", - "metadata": { - "reference": "example" - }, - "return_url": "https://app.example.com/identity/complete" - } - }, - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest" - } - }, - "multipart/form-data": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest" - } - } + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_no(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"NOR\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" }, - "required": true - }, - "security": [ { - "ApiKeyAuth": [] + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidNo({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NOR\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" }, { - "BearerAuth": [] - } - ], - "responses": { - "201": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse" - }, - "example": { - "request_id": "00000000-0000-4000-8000-000000000001", - "wallet_verification": { - "wallet": { - "id": "vipps", - "name": "Vipps", - "issuing_authority": "Vipps MobilePay / BankID NO" - }, - "country": "NOR", - "status": "Not Finished", - "outcome": "pending", - "error": null, - "interaction": "redirect", - "simulated": false, - "expires_at": "2026-01-01T10:10:00Z", - "next_action": { - "type": "redirect", - "url": "https://wallet.example.com/authorize" - }, - "identity": null, - "attributes": null, - "level_of_assurance": null, - "verified_at": null, - "signature_valid": null, - "credential_type": "person_identification" - }, - "vendor_data": "your-customer-reference", - "metadata": { - "reference": "example" - }, - "created_at": "2026-01-01T10:00:00Z" - } - } - }, - "description": "" + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidNo(ctx, didit.IDWalletsStartBankidNoParams{\n\tBody: didit.DigitalIDWalletAPIBankidNoWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "400": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest" - } - } - }, - "description": "Field validation errors ({field: [messages]}), or error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number or idempotency_key_invalid." - }, - "403": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden" - } - } - }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." - }, - "409": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" - } - } - }, - "description": "error idempotency_key_reused or idempotency_key_in_progress (with Retry-After)." + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidNoWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidNo(DigitalIdWalletApiBankidNoWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" }, - "502": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" - } - } - }, - "description": "error wallet_provider_unavailable: the provider could not start; nothing was created." + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startBankidNo([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'NOR',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" }, - "503": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" - } - } - }, - "description": "error wallet_not_configured: this environment cannot reach the wallet." - } - }, - "x-codeSamples": [ { - "lang": "curl", - "label": "cURL", - "source": "curl --request POST \\\n --url https://verification.didit.me/v3/id-verification/wallets/vipps/ \\\n --header 'x-api-key: YOUR_API_KEY' \\\n --header 'Idempotency-Key: your-unique-attempt-key' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"country\": \"NOR\",\n \"vendor_data\": \"your-customer-reference\",\n \"metadata\": {\n \"reference\": \"example\"\n },\n \"return_url\": \"https://app.example.com/identity/complete\"\n}'" + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_no(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NOR\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" }, { - "lang": "python", - "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'NOR',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/vipps/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidNoAsync(new DigitalIdWalletApiBankidNoWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], - "x-didit-wallet-id": "vipps" + "x-didit-wallet-id": "bankid_no" } }, - "/v3/id-verification/wallets/buypass/": { + "/v3/id-verification/wallets/vipps/": { "post": { - "operationId": "start_buypass_wallet_verification", + "operationId": "start_vipps_wallet_verification", "x-didit-sdk": { "resource": "id_wallets", - "method": "start_buypass", + "method": "start_vipps", "auth": "api_key", "server": true }, - "description": "Start a Buypass ID sign-in (Buypass AS; NOR) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=redirect with the URL to send the user's browser to; the user returns to return_url with request_id and result appended. Read the outcome with GET /v3/id-verification/wallets/verifications/{request_id}/ or from the webhook, never from the URL. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider.", - "summary": "Start Buypass ID verification", + "description": "Start a Vipps sign-in (Vipps MobilePay / BankID NO; NOR) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=redirect with the URL to send the user's browser to; the user returns to return_url with request_id and result appended. Read the outcome with GET /v3/id-verification/wallets/verifications/{request_id}/ or from the webhook, never from the URL. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider.", + "summary": "Start Vipps verification", "parameters": [ { "in": "header", @@ -48128,7 +54886,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest" + "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest" }, "example": { "country": "NOR", @@ -48141,12 +54899,211 @@ }, "application/x-www-form-urlencoded": { "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest" + "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest" } }, "multipart/form-data": { "schema": { - "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest" + "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest" + } + } + }, + "required": true + }, + "security": [ + { + "ApiKeyAuth": [] + }, + { + "BearerAuth": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse" + }, + "example": { + "request_id": "00000000-0000-4000-8000-000000000001", + "wallet_verification": { + "wallet": { + "id": "vipps", + "name": "Vipps", + "issuing_authority": "Vipps MobilePay / BankID NO" + }, + "country": "NOR", + "status": "Not Finished", + "outcome": "pending", + "error": null, + "interaction": "redirect", + "simulated": false, + "expires_at": "2026-01-01T10:10:00Z", + "next_action": { + "type": "redirect", + "url": "https://wallet.example.com/authorize" + }, + "identity": null, + "attributes": null, + "level_of_assurance": null, + "verified_at": null, + "signature_valid": null, + "credential_type": "person_identification" + }, + "vendor_data": "your-customer-reference", + "metadata": { + "reference": "example" + }, + "created_at": "2026-01-01T10:00:00Z" + } + } + }, + "description": "" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest" + } + } + }, + "description": "Field validation errors ({field: [messages]}), or error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number or idempotency_key_invalid." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden" + } + } + }, + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error idempotency_key_reused or idempotency_key_in_progress (with Retry-After)." + }, + "502": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error wallet_provider_unavailable: the provider could not start; nothing was created." + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error wallet_not_configured: this environment cannot reach the wallet." + } + }, + "x-codeSamples": [ + { + "lang": "curl", + "label": "cURL", + "source": "curl --request POST \\\n --url https://verification.didit.me/v3/id-verification/wallets/vipps/ \\\n --header 'x-api-key: YOUR_API_KEY' \\\n --header 'Idempotency-Key: your-unique-attempt-key' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"country\": \"NOR\",\n \"vendor_data\": \"your-customer-reference\",\n \"metadata\": {\n \"reference\": \"example\"\n },\n \"return_url\": \"https://app.example.com/identity/complete\"\n}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_vipps(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"NOR\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startVipps({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NOR\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartVipps(ctx, didit.IDWalletsStartVippsParams{\n\tBody: didit.DigitalIDWalletAPIVippsWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\nimport me.didit.types.DigitalIdWalletApiVippsWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startVipps(DigitalIdWalletApiVippsWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startVipps([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'NOR',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_vipps(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NOR\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartVippsAsync(new DigitalIdWalletApiVippsWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ], + "x-didit-wallet-id": "vipps" + } + }, + "/v3/id-verification/wallets/buypass/": { + "post": { + "operationId": "start_buypass_wallet_verification", + "x-didit-sdk": { + "resource": "id_wallets", + "method": "start_buypass", + "auth": "api_key", + "server": true + }, + "description": "Start a Buypass ID sign-in (Buypass AS; NOR) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=redirect with the URL to send the user's browser to; the user returns to return_url with request_id and result appended. Read the outcome with GET /v3/id-verification/wallets/verifications/{request_id}/ or from the webhook, never from the URL. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider.", + "summary": "Start Buypass ID verification", + "parameters": [ + { + "in": "header", + "name": "Idempotency-Key", + "schema": { + "type": "string" + }, + "description": "Optional retry-safety key (max 255 characters). Retrying with the same key, wallet and body returns the original verification without starting a second sign-in; the same key with another wallet or body returns 409 idempotency_key_reused." + } + ], + "tags": [ + "Digital ID wallets" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest" + }, + "example": { + "country": "NOR", + "vendor_data": "your-customer-reference", + "metadata": { + "reference": "example" + }, + "return_url": "https://app.example.com/identity/complete" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest" } } }, @@ -48221,7 +55178,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -48263,7 +55220,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'NOR',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/buypass/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_buypass(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"NOR\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBuypass({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NOR\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBuypass(ctx, didit.IDWalletsStartBuypassParams{\n\tBody: didit.DigitalIDWalletAPIBuypassWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBuypassWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBuypass(DigitalIdWalletApiBuypassWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startBuypass([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'NOR',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_buypass(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NOR\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBuypassAsync(new DigitalIdWalletApiBuypassWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "buypass" @@ -48390,7 +55377,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -48432,7 +55419,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'BEL',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/itsme/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_itsme(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"BEL\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startItsme({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"BEL\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartItsme(ctx, didit.IDWalletsStartItsmeParams{\n\tBody: didit.DigitalIDWalletAPIItsmeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.DigitalIDWalletAPIItsmeWalletVerificationStartCountryEnum(\"BEL\"),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiItsmeWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startItsme(DigitalIdWalletApiItsmeWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum.of(\"BEL\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startItsme([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'BEL',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_itsme(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"BEL\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartItsmeAsync(new DigitalIdWalletApiItsmeWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = \"BEL\",\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "itsme" @@ -48559,7 +55576,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -48601,7 +55618,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'NLD',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/idin/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_idin(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"NLD\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startIdin({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NLD\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartIdin(ctx, didit.IDWalletsStartIdinParams{\n\tBody: didit.DigitalIDWalletAPIIdinWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIIdinWalletVerificationStartCountryEnum(\"NLD\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiIdinWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiIdinWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startIdin(DigitalIdWalletApiIdinWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiIdinWalletVerificationStartCountryEnum.of(\"NLD\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startIdin([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'NLD',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_idin(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"NLD\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartIdinAsync(new DigitalIdWalletApiIdinWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiIdinWalletVerificationStartCountryEnum(\"NLD\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "idin" @@ -48728,7 +55775,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -48770,7 +55817,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'FIN',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/ftn/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_ftn(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"FIN\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFtn({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"FIN\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFtn(ctx, didit.IDWalletsStartFtnParams{\n\tBody: didit.DigitalIDWalletAPIFtnWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIFtnWalletVerificationStartCountryEnum(\"FIN\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiFtnWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiFtnWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFtn(DigitalIdWalletApiFtnWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiFtnWalletVerificationStartCountryEnum.of(\"FIN\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startFtn([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'FIN',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_ftn(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"FIN\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFtnAsync(new DigitalIdWalletApiFtnWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiFtnWalletVerificationStartCountryEnum(\"FIN\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "ftn" @@ -48897,7 +55974,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -48939,7 +56016,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'DEU',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/personalausweis/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_personalausweis(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"DEU\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startPersonalausweis({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"DEU\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartPersonalausweis(ctx, didit.IDWalletsStartPersonalausweisParams{\n\tBody: didit.DigitalIDWalletAPIPersonalausweisWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIPersonalausweisWalletVerificationStartCountryEnum(\"DEU\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startPersonalausweis(DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum.of(\"DEU\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startPersonalausweis([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'DEU',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_personalausweis(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"DEU\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartPersonalausweisAsync(new DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum(\"DEU\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "personalausweis" @@ -49066,7 +56173,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -49108,7 +56215,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'SWE',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/frejaid/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_frejaid(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"SWE\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFrejaid({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"SWE\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFrejaid(ctx, didit.IDWalletsStartFrejaidParams{\n\tBody: didit.DigitalIDWalletAPIFrejaidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryEe9enum(\"SWE\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryEe9Enum;\nimport me.didit.types.DigitalIdWalletApiFrejaidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFrejaid(DigitalIdWalletApiFrejaidWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryEe9Enum.of(\"SWE\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startFrejaid([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'SWE',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_frejaid(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"SWE\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFrejaidAsync(new DigitalIdWalletApiFrejaidWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryEe9Enum(\"SWE\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "frejaid" @@ -49235,7 +56372,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -49277,7 +56414,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'ARE',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/uae-pass/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_uae_pass(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"ARE\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startUaePass({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"ARE\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartUaePass(ctx, didit.IDWalletsStartUaePassParams{\n\tBody: didit.DigitalIDWalletAPIUaePassWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIUaePassWalletVerificationStartCountryEnum(\"ARE\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiUaePassWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startUaePass(DigitalIdWalletApiUaePassWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum.of(\"ARE\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startUaePass([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'ARE',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_uae_pass(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"ARE\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartUaePassAsync(new DigitalIdWalletApiUaePassWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum(\"ARE\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "uae_pass" @@ -49404,7 +56571,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -49446,7 +56613,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'BRA',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/govbr/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_govbr(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"BRA\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startGovbr({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"BRA\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartGovbr(ctx, didit.IDWalletsStartGovbrParams{\n\tBody: didit.DigitalIDWalletAPIGovbrWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIGovbrWalletVerificationStartCountryEnum(\"BRA\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiGovbrWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startGovbr(DigitalIdWalletApiGovbrWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum.of(\"BRA\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startGovbr([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'BRA',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_govbr(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"BRA\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartGovbrAsync(new DigitalIdWalletApiGovbrWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum(\"BRA\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "govbr" @@ -49573,7 +56770,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -49615,7 +56812,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'GBR',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/oneid/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_oneid(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"GBR\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startOneid({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"GBR\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartOneid(ctx, didit.IDWalletsStartOneidParams{\n\tBody: didit.DigitalIDWalletAPIOneidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountry520enum(\"GBR\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountry520Enum;\nimport me.didit.types.DigitalIdWalletApiOneidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startOneid(DigitalIdWalletApiOneidWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountry520Enum.of(\"GBR\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startOneid([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'GBR',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_oneid(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"GBR\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartOneidAsync(new DigitalIdWalletApiOneidWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountry520Enum(\"GBR\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "oneid" @@ -49742,7 +56969,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -49784,7 +57011,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'GBR',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/govuk-wallet/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_govuk_wallet(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"GBR\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startGovukWallet({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"GBR\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartGovukWallet(ctx, didit.IDWalletsStartGovukWalletParams{\n\tBody: didit.DigitalIDWalletAPIGovukWalletWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountry520enum(\"GBR\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountry520Enum;\nimport me.didit.types.DigitalIdWalletApiGovukWalletWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startGovukWallet(DigitalIdWalletApiGovukWalletWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountry520Enum.of(\"GBR\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startGovukWallet([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'GBR',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_govuk_wallet(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"GBR\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartGovukWalletAsync(new DigitalIdWalletApiGovukWalletWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountry520Enum(\"GBR\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "govuk_wallet" @@ -49912,7 +57169,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -49954,7 +57211,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'EST',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'personal_code': '00000000000'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/smart-id/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_smart_id(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"EST\",\n personal_code=\"00000000000\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startSmartId({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"EST\",\n personal_code: \"00000000000\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartSmartID(ctx, didit.IDWalletsStartSmartIDParams{\n\tBody: didit.DigitalIDWalletAPISmartIDWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.DigitalIDWalletAPISmartIDWalletVerificationStartCountryEnum(\"EST\"),\n\t\tPersonalCode: \"00000000000\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiSmartIdWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startSmartId(DigitalIdWalletApiSmartIdWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum.of(\"EST\"))\n .personalCode(\"00000000000\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startSmartId([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'EST',\n 'personal_code' => '00000000000',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_smart_id(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"EST\",\n personal_code: \"00000000000\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartSmartIdAsync(new DigitalIdWalletApiSmartIdWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = \"EST\",\n PersonalCode = \"00000000000\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "smart_id" @@ -50083,7 +57370,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -50125,7 +57412,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'EST',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'personal_code': '00000000000',\n 'phone_number': '+37200000000'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/mobile-id/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mobile_id(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"EST\",\n personal_code=\"00000000000\",\n phone_number=\"+37200000000\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMobileId({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"EST\",\n personal_code: \"00000000000\",\n phone_number: \"+37200000000\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMobileID(ctx, didit.IDWalletsStartMobileIDParams{\n\tBody: didit.DigitalIDWalletAPIMobileIDWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.DigitalIDWalletAPIMobileIDWalletVerificationStartCountryEnum(\"EST\"),\n\t\tPersonalCode: \"00000000000\",\n\t\tPhoneNumber: \"+37200000000\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiMobileIdWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMobileId(DigitalIdWalletApiMobileIdWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum.of(\"EST\"))\n .personalCode(\"00000000000\")\n .phoneNumber(\"+37200000000\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startMobileId([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'EST',\n 'personal_code' => '00000000000',\n 'phone_number' => '+37200000000',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mobile_id(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"EST\",\n personal_code: \"00000000000\",\n phone_number: \"+37200000000\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMobileIdAsync(new DigitalIdWalletApiMobileIdWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = \"EST\",\n PersonalCode = \"00000000000\",\n PhoneNumber = \"+37200000000\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "mobile_id" @@ -50252,7 +57569,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -50294,7 +57611,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'EST',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/idcard-ee/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_idcard_ee(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"EST\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startIdcardEe({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"EST\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartIdcardEe(ctx, didit.IDWalletsStartIdcardEeParams{\n\tBody: didit.DigitalIDWalletAPIIdcardEeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIIdcardEeWalletVerificationStartCountryEnum(\"EST\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiIdcardEeWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startIdcardEe(DigitalIdWalletApiIdcardEeWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum.of(\"EST\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startIdcardEe([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'EST',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_idcard_ee(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"EST\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartIdcardEeAsync(new DigitalIdWalletApiIdcardEeWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum(\"EST\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "idcard_ee" @@ -50421,7 +57768,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -50463,7 +57810,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'LVA',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/eparaksts-mobile/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_eparaksts_mobile(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"LVA\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startEparakstsMobile({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"LVA\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartEparakstsMobile(ctx, didit.IDWalletsStartEparakstsMobileParams{\n\tBody: didit.DigitalIDWalletAPIEparakstsMobileWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIEparakstsMobileWalletVerificationStartCountryEnum(\"LVA\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startEparakstsMobile(DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum.of(\"LVA\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startEparakstsMobile([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'LVA',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_eparaksts_mobile(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"LVA\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartEparakstsMobileAsync(new DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum(\"LVA\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "eparaksts_mobile" @@ -50590,7 +57967,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -50632,7 +58009,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'CZE',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/bankid-cz/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_cz(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"CZE\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidCz({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"CZE\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidCz(ctx, didit.IDWalletsStartBankidCzParams{\n\tBody: didit.DigitalIDWalletAPIBankidCzWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryE2dEnum(\"CZE\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidCzWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryE2dEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidCz(DigitalIdWalletApiBankidCzWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryE2dEnum.of(\"CZE\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startBankidCz([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'CZE',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_cz(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"CZE\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidCzAsync(new DigitalIdWalletApiBankidCzWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryE2dEnum(\"CZE\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "bankid_cz" @@ -50759,7 +58166,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -50801,7 +58208,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'CZE',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/mojeid/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mojeid(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"CZE\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMojeid({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"CZE\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMojeid(ctx, didit.IDWalletsStartMojeidParams{\n\tBody: didit.DigitalIDWalletAPIMojeidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPICountryE2dEnum(\"CZE\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryE2dEnum;\nimport me.didit.types.DigitalIdWalletApiMojeidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMojeid(DigitalIdWalletApiMojeidWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiCountryE2dEnum.of(\"CZE\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startMojeid([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'CZE',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mojeid(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"CZE\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMojeidAsync(new DigitalIdWalletApiMojeidWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiCountryE2dEnum(\"CZE\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "mojeid" @@ -50928,7 +58365,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -50970,7 +58407,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'UKR',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/diia/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_diia(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"UKR\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startDiia({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"UKR\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartDiia(ctx, didit.IDWalletsStartDiiaParams{\n\tBody: didit.DigitalIDWalletAPIDiiaWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIDiiaWalletVerificationStartCountryEnum(\"UKR\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiDiiaWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startDiia(DigitalIdWalletApiDiiaWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum.of(\"UKR\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startDiia([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'UKR',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_diia(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"UKR\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartDiiaAsync(new DigitalIdWalletApiDiiaWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum(\"UKR\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "diia" @@ -51097,7 +58564,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -51139,7 +58606,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'FRA',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/franceconnect/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_franceconnect(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"FRA\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFranceconnect({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"FRA\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFranceconnect(ctx, didit.IDWalletsStartFranceconnectParams{\n\tBody: didit.DigitalIDWalletAPIFranceconnectWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIFranceconnectWalletVerificationStartCountryEnum(\"FRA\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiFranceconnectWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFranceconnect(DigitalIdWalletApiFranceconnectWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum.of(\"FRA\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startFranceconnect([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'FRA',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_franceconnect(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"FRA\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFranceconnectAsync(new DigitalIdWalletApiFranceconnectWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum(\"FRA\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "franceconnect" @@ -51266,7 +58763,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -51308,7 +58805,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'ISL',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/audkenni/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_audkenni(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"ISL\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startAudkenni({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"ISL\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartAudkenni(ctx, didit.IDWalletsStartAudkenniParams{\n\tBody: didit.DigitalIDWalletAPIAudkenniWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIAudkenniWalletVerificationStartCountryEnum(\"ISL\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiAudkenniWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startAudkenni(DigitalIdWalletApiAudkenniWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum.of(\"ISL\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startAudkenni([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'ISL',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_audkenni(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"ISL\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartAudkenniAsync(new DigitalIdWalletApiAudkenniWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum(\"ISL\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "audkenni" @@ -51435,7 +58962,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -51477,7 +59004,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'AUS',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/connectid/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_connectid(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"AUS\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startConnectid({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"AUS\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartConnectid(ctx, didit.IDWalletsStartConnectidParams{\n\tBody: didit.DigitalIDWalletAPIConnectidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.Some(didit.DigitalIDWalletAPIConnectidWalletVerificationStartCountryEnum(\"AUS\")),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiConnectidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startConnectid(DigitalIdWalletApiConnectidWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum.of(\"AUS\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startConnectid([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'AUS',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_connectid(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"AUS\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartConnectidAsync(new DigitalIdWalletApiConnectidWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = new DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum(\"AUS\"),\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "connectid" @@ -51604,7 +59161,7 @@ } } }, - "description": "Missing or invalid credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, "409": { "content": { @@ -51646,7 +59203,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nimport requests\n\nheaders = {\n \"x-api-key\": os.environ[\"DIDIT_API_KEY\"],\n \"Idempotency-Key\": \"your-unique-attempt-key\"\n}\npayload = {'country': 'AUT',\n 'vendor_data': 'your-customer-reference',\n 'metadata': {'reference': 'example'},\n 'return_url': 'https://app.example.com/identity/complete'}\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/id-verification/wallets/eudi/\",\n headers=headers,\n json=payload,\n timeout=30,\n)\nresponse.raise_for_status()\nprint(response.json())\n" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_eudi(\n vendor_data=\"your-customer-reference\",\n metadata={\"reference\": \"example\"},\n country=\"AUT\",\n return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startEudi({\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"AUT\",\n return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartEudi(ctx, didit.IDWalletsStartEudiParams{\n\tBody: didit.DigitalIDWalletAPIEudiWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata: didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry: didit.DigitalIDWalletAPIEudiWalletVerificationStartCountryEnum(\"AUT\"),\n\t\tReturnURL: \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiEudiWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiEudiWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startEudi(DigitalIdWalletApiEudiWalletVerificationStartRequest.builder()\n .vendorData(\"your-customer-reference\")\n .metadata(Map.of(\"reference\", \"example\"))\n .country(DigitalIdWalletApiEudiWalletVerificationStartCountryEnum.of(\"AUT\"))\n .returnUrl(\"https://app.example.com/identity/complete\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "idWallets->startEudi([\n 'vendor_data' => 'your-customer-reference',\n 'metadata' => ['reference' => 'example'],\n 'country' => 'AUT',\n 'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_eudi(\n vendor_data: \"your-customer-reference\",\n metadata: { reference: \"example\" },\n country: \"AUT\",\n return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartEudiAsync(new DigitalIdWalletApiEudiWalletVerificationStartRequest\n{\n VendorData = \"your-customer-reference\",\n Metadata = new Dictionary { [\"reference\"] = \"example\" },\n Country = \"AUT\",\n ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-wallet-id": "eudi" @@ -51751,6 +59338,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.teams.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.teams.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Teams.ListAutoPaging(ctx, didit.CasesTeamsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().teams().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->teams->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.teams.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Teams.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] }, "post": { @@ -51813,6 +59437,15 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CaseReviewTeamCreate" + }, + "example": { + "name": "AML analysts", + "members": [ + { + "user_id": "9a000000-0000-4000-8000-0000000000aa", + "capacity": 10 + } + ] } } } @@ -51821,6 +59454,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.create(\n name=\"AML analysts\",\n members=[{\n \"user_id\": \"9a000000-0000-4000-8000-0000000000aa\",\n \"capacity\": 10,\n }],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.create({\n name: \"AML analysts\",\n members: [{\n user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n capacity: 10,\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Create(ctx, didit.CaseReviewTeamCreate{\n\tName: \"AML analysts\",\n\tMembers: []didit.CaseReviewTeamMemberParam{{\n\t\tUserID: \"9a000000-0000-4000-8000-0000000000aa\",\n\t\tCapacity: didit.Int(10),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseReviewTeamCreate;\nimport me.didit.types.CaseReviewTeamMember;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().create(CaseReviewTeamCreate.builder()\n .name(\"AML analysts\")\n .members(List.of(CaseReviewTeamMember.builder()\n .userId(\"9a000000-0000-4000-8000-0000000000aa\")\n .capacity(10L)\n .build()))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->teams->create([\n 'name' => 'AML analysts',\n 'members' => [[\n 'user_id' => '9a000000-0000-4000-8000-0000000000aa',\n 'capacity' => 10,\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.create(\n name: \"AML analysts\",\n members: [{\n user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n capacity: 10,\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.CreateAsync(new CaseReviewTeamCreate\n{\n Name = \"AML analysts\",\n Members = new CaseReviewTeamMember[]\n {\n new()\n {\n UserId = \"9a000000-0000-4000-8000-0000000000aa\",\n Capacity = 10,\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -51888,6 +59558,43 @@ ], "tags": [ "Fraud Check" + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "fraudChecks->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -51982,6 +59689,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.requests.list(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.requests.list(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Requests.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesRequestsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().requests().list(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->list('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.requests.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Requests.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] }, "post": { @@ -52074,7 +59818,44 @@ "ApiKeyAuth": [] } ], - "description": "Confirm the exact signed preview within 15 minutes. Only fixed templates and an OTP-verified contact belonging to the case subject are accepted. The request ID makes retries idempotent. Delivery is queued; SENT, SIMULATED and UNKNOWN are distinct outcomes. An actionable request sets the case to Awaiting user. A review update leaves its status unchanged." + "description": "Confirm the exact signed preview within 15 minutes. Only fixed templates and an OTP-verified contact belonging to the case subject are accepted. The request ID makes retries idempotent. Delivery is queued; SENT, SIMULATED and UNKNOWN are distinct outcomes. An actionable request sets the case to Awaiting user. A review update leaves its status unchanged.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.create(\n \"11111111-2222-3333-4444-555555555555\",\n contact_id=\"11111111-2222-3333-4444-555555555555\",\n purpose=\"identity_document\",\n request_id=\"11111111-2222-3333-4444-555555555555\",\n expires_at=\"2026-01-15T10:00:00Z\",\n preview_token=\"your-preview-token\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.create(\"11111111-2222-3333-4444-555555555555\", {\n contact_id: \"11111111-2222-3333-4444-555555555555\",\n purpose: \"identity_document\",\n request_id: \"11111111-2222-3333-4444-555555555555\",\n expires_at: \"2026-01-15T10:00:00Z\",\n preview_token: \"your-preview-token\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CustomerMessagingCaseRequestConfirmRequest{\n\tContactID: \"11111111-2222-3333-4444-555555555555\",\n\tPurpose: didit.CustomerMessagingPurposeEnum(\"identity_document\"),\n\tRequestID: \"11111111-2222-3333-4444-555555555555\",\n\tExpiresAt: time.Date(2026, 1, 15, 10, 0, 0, 0, time.UTC),\n\tPreviewToken: \"your-preview-token\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.OffsetDateTime;\nimport me.didit.Didit;\nimport me.didit.types.CustomerMessagingCaseRequestConfirmRequest;\nimport me.didit.types.CustomerMessagingPurposeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().create(\"11111111-2222-3333-4444-555555555555\", CustomerMessagingCaseRequestConfirmRequest.builder()\n .contactId(\"11111111-2222-3333-4444-555555555555\")\n .purpose(CustomerMessagingPurposeEnum.of(\"identity_document\"))\n .requestId(\"11111111-2222-3333-4444-555555555555\")\n .expiresAt(OffsetDateTime.parse(\"2026-01-15T10:00:00Z\"))\n .previewToken(\"your-preview-token\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->create('11111111-2222-3333-4444-555555555555', [\n 'contact_id' => '11111111-2222-3333-4444-555555555555',\n 'purpose' => 'identity_document',\n 'request_id' => '11111111-2222-3333-4444-555555555555',\n 'expires_at' => '2026-01-15T10:00:00Z',\n 'preview_token' => 'your-preview-token',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.create(\n \"11111111-2222-3333-4444-555555555555\",\n contact_id: \"11111111-2222-3333-4444-555555555555\",\n purpose: \"identity_document\",\n request_id: \"11111111-2222-3333-4444-555555555555\",\n expires_at: \"2026-01-15T10:00:00Z\",\n preview_token: \"your-preview-token\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new CustomerMessagingCaseRequestConfirmRequest\n{\n ContactId = \"11111111-2222-3333-4444-555555555555\",\n Purpose = \"identity_document\",\n RequestId = \"11111111-2222-3333-4444-555555555555\",\n ExpiresAt = DateTimeOffset.Parse(\"2026-01-15T10:00:00Z\"),\n PreviewToken = \"your-preview-token\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/fraud/checks/": { @@ -52098,6 +59879,28 @@ "application/json": { "schema": { "$ref": "#/components/schemas/FraudCheckRequestRequest" + }, + "example": { + "client_reference": "review-attempt-001", + "subject": { + "identifiers": [ + { + "type": "email", + "value": "applicant@example.com" + } + ], + "attributes": { + "first_name": "Alex", + "last_name": "Example" + } + }, + "checks": { + "include": [ + "networks_same_org", + "networks_cross_org", + "email_risk" + ] + } } }, "multipart/form-data": { @@ -52196,6 +59999,43 @@ ], "tags": [ "Fraud Check" + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.create(\n client_reference=\"review-attempt-001\",\n subject={\n \"identifiers\": [{\n \"type\": \"email\",\n \"value\": \"applicant@example.com\",\n }],\n \"attributes\": {\n \"first_name\": \"Alex\",\n \"last_name\": \"Example\",\n },\n },\n checks={\n \"include\": [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.create({\n client_reference: \"review-attempt-001\",\n subject: {\n identifiers: [{\n type: \"email\",\n value: \"applicant@example.com\",\n }],\n attributes: {\n first_name: \"Alex\",\n last_name: \"Example\",\n },\n },\n checks: {\n include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Create(ctx, didit.FraudCheckRequestRequest{\n\tClientReference: didit.String(\"review-attempt-001\"),\n\tSubject: didit.FraudCheckSubjectRequest{\n\t\tIdentifiers: []didit.FraudCheckIdentifierRequest{{\n\t\t\tType: didit.FraudTypeEnum(\"email\"),\n\t\t\tValue: \"applicant@example.com\",\n\t\t}},\n\t\tAttributes: didit.Some(didit.FraudCheckAttributesRequest{\n\t\t\tFirstName: didit.String(\"Alex\"),\n\t\t\tLastName: didit.String(\"Example\"),\n\t\t}),\n\t},\n\tChecks: didit.Some(didit.FraudCheckModuleSelectionRequest{\n\t\tInclude: didit.Some([]didit.FraudExcludeEnum{didit.FraudExcludeEnum(\"networks_same_org\"), didit.FraudExcludeEnum(\"networks_cross_org\"), didit.FraudExcludeEnum(\"email_risk\")}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.FraudCheckAttributesRequest;\nimport me.didit.types.FraudCheckIdentifierRequest;\nimport me.didit.types.FraudCheckModuleSelectionRequest;\nimport me.didit.types.FraudCheckRequestRequest;\nimport me.didit.types.FraudCheckSubjectRequest;\nimport me.didit.types.FraudExcludeEnum;\nimport me.didit.types.FraudTypeEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().create(FraudCheckRequestRequest.builder()\n .clientReference(\"review-attempt-001\")\n .subject(FraudCheckSubjectRequest.builder()\n .identifiers(List.of(FraudCheckIdentifierRequest.builder()\n .type(FraudTypeEnum.of(\"email\"))\n .value(\"applicant@example.com\")\n .build()))\n .attributes(FraudCheckAttributesRequest.builder()\n .firstName(\"Alex\")\n .lastName(\"Example\")\n .build())\n .build())\n .checks(FraudCheckModuleSelectionRequest.builder()\n .include(List.of(FraudExcludeEnum.of(\"networks_same_org\"), FraudExcludeEnum.of(\"networks_cross_org\"), FraudExcludeEnum.of(\"email_risk\")))\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "fraudChecks->create([\n 'client_reference' => 'review-attempt-001',\n 'subject' => [\n 'identifiers' => [[\n 'type' => 'email',\n 'value' => 'applicant@example.com',\n ]],\n 'attributes' => [\n 'first_name' => 'Alex',\n 'last_name' => 'Example',\n ],\n ],\n 'checks' => [\n 'include' => ['networks_same_org', 'networks_cross_org', 'email_risk'],\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.create(\n client_reference: \"review-attempt-001\",\n subject: {\n identifiers: [{\n type: \"email\",\n value: \"applicant@example.com\",\n }],\n attributes: {\n first_name: \"Alex\",\n last_name: \"Example\",\n },\n },\n checks: {\n include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.CreateAsync(new FraudCheckRequestRequest\n{\n ClientReference = \"review-attempt-001\",\n Subject = new()\n {\n Identifiers = new FraudCheckIdentifierRequest[]\n {\n new()\n {\n Type = \"email\",\n Value = \"applicant@example.com\",\n },\n },\n Attributes = new FraudCheckAttributesRequest\n {\n FirstName = \"Alex\",\n LastName = \"Example\",\n },\n },\n Checks = new FraudCheckModuleSelectionRequest\n {\n Include = new FraudExcludeEnum[] { \"networks_same_org\", \"networks_cross_org\", \"email_risk\" },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -52278,6 +60118,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.cancel(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.cancel(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Cancel(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().cancel(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->cancel('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.cancel(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.CancelAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -52345,6 +60222,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.retrieve_options(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.retrieveOptions(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.RetrieveOptions(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().retrieveOptions(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->retrieveOptions('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.retrieve_options(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.RetrieveOptionsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -52422,6 +60336,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.cases.requests.retrieve_attachment(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.png\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.cases.requests.retrieveAttachment(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.png\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Cases.Requests.RetrieveAttachment(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.png\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().requests().retrieveAttachment(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\n .writeTo(Path.of(\"download.png\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->retrieveAttachment('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.png');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.cases.requests.retrieve_attachment(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.png\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Cases.Requests.RetrieveAttachmentAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.png\");" + } ] } }, @@ -52513,6 +60464,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.routing_rules.list_history(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.routingRules.listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RoutingRules.ListHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesRoutingRulesListHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().routingRules().listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->listHistory('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.list_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RoutingRules.ListHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] } }, @@ -52597,7 +60585,8 @@ "EMAIL", "KYB_REGISTRY", "KYB_KEY_PEOPLE", - "KYB" + "KYB", + "GEOLOCATION" ], "example": "OCR" } @@ -52664,6 +60653,7 @@ "sender_kind", "subject", "html", + "text", "language", "will_be_sent", "not_sent_reason", @@ -52723,6 +60713,11 @@ "description": "The email's HTML exactly as it is sent, with its logo embedded as a data URL. Render it in a sandboxed frame, never directly in your application DOM.", "example": "..." }, + "text": { + "type": "string", + "description": "The email's words as plain text, as the person's Messages thread keeps them, for a compact preview (the HTML stays the email the person receives).", + "example": "Almost there\n\nSome steps need to be completed again.\nHere’s what to fix:\n\nhttps://verify.didit.me/session/abc123" + }, "language": { "type": "string", "description": "The language the email is written in. English (`en`) when the `email_language` you asked for is not offered.", @@ -52786,7 +60781,8 @@ "EMAIL", "KYB_REGISTRY", "KYB_KEY_PEOPLE", - "KYB" + "KYB", + "GEOLOCATION" ], "example": "OCR" } @@ -52917,7 +60913,7 @@ } }, "403": { - "description": "Missing or invalid credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", + "description": "Missing credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", "content": { "application/json": { "examples": { @@ -52972,7 +60968,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.preview_resubmission(\n \"11111111-2222-3333-4444-555555555555\",\n nodes_to_resubmit=[{\n \"node_id\": \"feature_poa_1\",\n \"feature\": \"POA\",\n }],\n email_language=\"en\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.previewResubmission(\"11111111-2222-3333-4444-555555555555\", {\n nodes_to_resubmit: [{\n node_id: \"feature_poa_1\",\n feature: \"POA\",\n }],\n email_language: \"en\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.PreviewResubmission(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsPreviewResubmissionParams{\n\tNodesToResubmit: didit.Some([]didit.SessionsPreviewResubmissionParamsNodesToResubmit{{\n\t\tNodeID: \"feature_poa_1\",\n\t\tFeature: \"POA\",\n\t}}),\n\tEmailLanguage: didit.String(\"en\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsPreviewResubmissionParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().previewResubmission(\"11111111-2222-3333-4444-555555555555\", SessionsPreviewResubmissionParams.builder()\n .nodesToResubmit(List.of(SessionsPreviewResubmissionParams.NodesToResubmit.builder()\n .nodeId(\"feature_poa_1\")\n .feature(SessionsPreviewResubmissionParams.NodesToResubmit.Feature.of(\"POA\"))\n .build()))\n .emailLanguage(\"en\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->previewResubmission('11111111-2222-3333-4444-555555555555', [\n 'nodes_to_resubmit' => [[\n 'node_id' => 'feature_poa_1',\n 'feature' => 'POA',\n ]],\n 'email_language' => 'en',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.preview_resubmission(\n \"11111111-2222-3333-4444-555555555555\",\n nodes_to_resubmit: [{\n node_id: \"feature_poa_1\",\n feature: \"POA\",\n }],\n email_language: \"en\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.PreviewResubmissionAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsPreviewResubmissionParams\n{\n NodesToResubmit = new SessionsPreviewResubmissionParamsNodesToResubmit[]\n {\n new()\n {\n NodeId = \"feature_poa_1\",\n Feature = \"POA\",\n },\n },\n EmailLanguage = \"en\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/": { @@ -53046,6 +61079,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] }, "patch": { @@ -53131,6 +61201,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.update(\n \"11111111-2222-3333-4444-555555555555\",\n name=\"your-name\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.update(\"11111111-2222-3333-4444-555555555555\", {\n name: \"your-name\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseRoutingRuleUpdate{\n\tName: didit.String(\"your-name\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CaseRoutingRuleUpdate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().update(\"11111111-2222-3333-4444-555555555555\", CaseRoutingRuleUpdate.builder()\n .name(\"your-name\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->update('11111111-2222-3333-4444-555555555555', [\n 'name' => 'your-name',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.update(\n \"11111111-2222-3333-4444-555555555555\",\n name: \"your-name\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseRoutingRuleUpdate\n{\n Name = \"your-name\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -53268,6 +61375,28 @@ "application/json": { "schema": { "$ref": "#/components/schemas/FraudCheckRequestRequest" + }, + "example": { + "client_reference": "review-attempt-001", + "subject": { + "identifiers": [ + { + "type": "email", + "value": "applicant@example.com" + } + ], + "attributes": { + "first_name": "Alex", + "last_name": "Example" + } + }, + "checks": { + "include": [ + "networks_same_org", + "networks_cross_org", + "email_risk" + ] + } } }, "multipart/form-data": { @@ -53307,6 +61436,43 @@ { "BearerAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.plan(\n client_reference=\"review-attempt-001\",\n subject={\n \"identifiers\": [{\n \"type\": \"email\",\n \"value\": \"applicant@example.com\",\n }],\n \"attributes\": {\n \"first_name\": \"Alex\",\n \"last_name\": \"Example\",\n },\n },\n checks={\n \"include\": [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.plan({\n client_reference: \"review-attempt-001\",\n subject: {\n identifiers: [{\n type: \"email\",\n value: \"applicant@example.com\",\n }],\n attributes: {\n first_name: \"Alex\",\n last_name: \"Example\",\n },\n },\n checks: {\n include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Plan(ctx, didit.FraudCheckRequestRequest{\n\tClientReference: didit.String(\"review-attempt-001\"),\n\tSubject: didit.FraudCheckSubjectRequest{\n\t\tIdentifiers: []didit.FraudCheckIdentifierRequest{{\n\t\t\tType: didit.FraudTypeEnum(\"email\"),\n\t\t\tValue: \"applicant@example.com\",\n\t\t}},\n\t\tAttributes: didit.Some(didit.FraudCheckAttributesRequest{\n\t\t\tFirstName: didit.String(\"Alex\"),\n\t\t\tLastName: didit.String(\"Example\"),\n\t\t}),\n\t},\n\tChecks: didit.Some(didit.FraudCheckModuleSelectionRequest{\n\t\tInclude: didit.Some([]didit.FraudExcludeEnum{didit.FraudExcludeEnum(\"networks_same_org\"), didit.FraudExcludeEnum(\"networks_cross_org\"), didit.FraudExcludeEnum(\"email_risk\")}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.FraudCheckAttributesRequest;\nimport me.didit.types.FraudCheckIdentifierRequest;\nimport me.didit.types.FraudCheckModuleSelectionRequest;\nimport me.didit.types.FraudCheckRequestRequest;\nimport me.didit.types.FraudCheckSubjectRequest;\nimport me.didit.types.FraudExcludeEnum;\nimport me.didit.types.FraudTypeEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().plan(FraudCheckRequestRequest.builder()\n .clientReference(\"review-attempt-001\")\n .subject(FraudCheckSubjectRequest.builder()\n .identifiers(List.of(FraudCheckIdentifierRequest.builder()\n .type(FraudTypeEnum.of(\"email\"))\n .value(\"applicant@example.com\")\n .build()))\n .attributes(FraudCheckAttributesRequest.builder()\n .firstName(\"Alex\")\n .lastName(\"Example\")\n .build())\n .build())\n .checks(FraudCheckModuleSelectionRequest.builder()\n .include(List.of(FraudExcludeEnum.of(\"networks_same_org\"), FraudExcludeEnum.of(\"networks_cross_org\"), FraudExcludeEnum.of(\"email_risk\")))\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "fraudChecks->plan([\n 'client_reference' => 'review-attempt-001',\n 'subject' => [\n 'identifiers' => [[\n 'type' => 'email',\n 'value' => 'applicant@example.com',\n ]],\n 'attributes' => [\n 'first_name' => 'Alex',\n 'last_name' => 'Example',\n ],\n ],\n 'checks' => [\n 'include' => ['networks_same_org', 'networks_cross_org', 'email_risk'],\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.plan(\n client_reference: \"review-attempt-001\",\n subject: {\n identifiers: [{\n type: \"email\",\n value: \"applicant@example.com\",\n }],\n attributes: {\n first_name: \"Alex\",\n last_name: \"Example\",\n },\n },\n checks: {\n include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.PlanAsync(new FraudCheckRequestRequest\n{\n ClientReference = \"review-attempt-001\",\n Subject = new()\n {\n Identifiers = new FraudCheckIdentifierRequest[]\n {\n new()\n {\n Type = \"email\",\n Value = \"applicant@example.com\",\n },\n },\n Attributes = new FraudCheckAttributesRequest\n {\n FirstName = \"Alex\",\n LastName = \"Example\",\n },\n },\n Checks = new FraudCheckModuleSelectionRequest\n {\n Include = new FraudExcludeEnum[] { \"networks_same_org\", \"networks_cross_org\", \"email_risk\" },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -53409,6 +61575,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.routing_rules.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.routingRules.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RoutingRules.ListAutoPaging(ctx, didit.CasesRoutingRulesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().routingRules().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RoutingRules.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] }, "post": { @@ -53471,6 +61674,17 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CaseRoutingRuleCreate" + }, + "example": { + "name": "AML screening alerts", + "conditions": [ + { + "field": "source", + "operator": "equals", + "value": "AML_SCREENING" + } + ], + "blueprint": "b1de0000-0000-4000-8000-000000000002" } } } @@ -53479,6 +61693,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.create(\n name=\"AML screening alerts\",\n conditions=[{\n \"field\": \"source\",\n \"operator\": \"equals\",\n \"value\": \"AML_SCREENING\",\n }],\n blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.create({\n name: \"AML screening alerts\",\n conditions: [{\n field: \"source\",\n operator: \"equals\",\n value: \"AML_SCREENING\",\n }],\n blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Create(ctx, didit.CaseRoutingRuleCreate{\n\tName: \"AML screening alerts\",\n\tConditions: []didit.CaseRoutingConditionParam{{\n\t\tField: \"source\",\n\t\tOperator: \"equals\",\n\t\tValue: \"AML_SCREENING\",\n\t}},\n\tBlueprint: \"b1de0000-0000-4000-8000-000000000002\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseRoutingCondition;\nimport me.didit.types.CaseRoutingRuleCreate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().create(CaseRoutingRuleCreate.builder()\n .name(\"AML screening alerts\")\n .conditions(List.of(CaseRoutingCondition.builder()\n .field(CaseRoutingCondition.Field.of(\"source\"))\n .operator(CaseRoutingCondition.Operator.of(\"equals\"))\n .value(CaseRoutingCondition.Value.ofString(\"AML_SCREENING\"))\n .build()))\n .blueprint(\"b1de0000-0000-4000-8000-000000000002\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->create([\n 'name' => 'AML screening alerts',\n 'conditions' => [[\n 'field' => 'source',\n 'operator' => 'equals',\n 'value' => 'AML_SCREENING',\n ]],\n 'blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.create(\n name: \"AML screening alerts\",\n conditions: [{\n field: \"source\",\n operator: \"equals\",\n value: \"AML_SCREENING\",\n }],\n blueprint: \"b1de0000-0000-4000-8000-000000000002\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.CreateAsync(new CaseRoutingRuleCreate\n{\n Name = \"AML screening alerts\",\n Conditions = new CaseRoutingCondition[]\n {\n new()\n {\n Field = \"source\",\n Operator = \"equals\",\n Value = \"AML_SCREENING\",\n },\n },\n Blueprint = \"b1de0000-0000-4000-8000-000000000002\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -53566,6 +61817,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.publish(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version=0,\n expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.publish(\"11111111-2222-3333-4444-555555555555\", {\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Publish(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion: 0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().publish(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftPreconditionRequest.builder()\n .expectedVersion(0L)\n .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->publish('11111111-2222-3333-4444-555555555555', [\n 'expected_version' => 0,\n 'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.publish(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.PublishAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftPreconditionRequest\n{\n ExpectedVersion = 0,\n ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -53653,6 +61941,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.publish(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version=0,\n expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.publish(\"11111111-2222-3333-4444-555555555555\", {\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Publish(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion: 0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().publish(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftPreconditionRequest.builder()\n .expectedVersion(0L)\n .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->publish('11111111-2222-3333-4444-555555555555', [\n 'expected_version' => 0,\n 'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.publish(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.PublishAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftPreconditionRequest\n{\n ExpectedVersion = 0,\n ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -53747,7 +62072,44 @@ "ApiKeyAuth": [] } ], - "description": "Render the production email without sending or changing the case. Returns the exact recipient, sender, subject, body and a signed preview_token. Send the same contact_id, purpose, language, request_id, expires_at and preview_token to confirm within 15 minutes." + "description": "Render the production email without sending or changing the case. Returns the exact recipient, sender, subject, body and a signed preview_token. Send the same contact_id, purpose, language, request_id, expires_at and preview_token to confirm within 15 minutes.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.preview(\n \"11111111-2222-3333-4444-555555555555\",\n contact_id=\"11111111-2222-3333-4444-555555555555\",\n purpose=\"identity_document\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.preview(\"11111111-2222-3333-4444-555555555555\", {\n contact_id: \"11111111-2222-3333-4444-555555555555\",\n purpose: \"identity_document\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Preview(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CustomerMessagingCaseRequestPreviewRequest{\n\tContactID: \"11111111-2222-3333-4444-555555555555\",\n\tPurpose: didit.CustomerMessagingPurposeEnum(\"identity_document\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CustomerMessagingCaseRequestPreviewRequest;\nimport me.didit.types.CustomerMessagingPurposeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().preview(\"11111111-2222-3333-4444-555555555555\", CustomerMessagingCaseRequestPreviewRequest.builder()\n .contactId(\"11111111-2222-3333-4444-555555555555\")\n .purpose(CustomerMessagingPurposeEnum.of(\"identity_document\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->preview('11111111-2222-3333-4444-555555555555', [\n 'contact_id' => '11111111-2222-3333-4444-555555555555',\n 'purpose' => 'identity_document',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.preview(\n \"11111111-2222-3333-4444-555555555555\",\n contact_id: \"11111111-2222-3333-4444-555555555555\",\n purpose: \"identity_document\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.PreviewAsync(\"11111111-2222-3333-4444-555555555555\", new CustomerMessagingCaseRequestPreviewRequest\n{\n ContactId = \"11111111-2222-3333-4444-555555555555\",\n Purpose = \"identity_document\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/action-receipts/": { @@ -53819,7 +62181,44 @@ "ApiKeyAuth": [] } ], - "description": "List subject-action receipts, newest first, with at most 20 results per page. Use next_offset for the next page. Input note text is not exposed in the history." + "description": "List subject-action receipts, newest first, with at most 20 results per page. Use next_offset for the next page. Input note text is not exposed in the history.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_action_receipts(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listActionReceipts(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListActionReceipts(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesListActionReceiptsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listActionReceipts(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->listActionReceipts('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.list_action_receipts(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListActionReceiptsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/notes/{note_uuid}/": { @@ -53905,6 +62304,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nclient.networks.notes.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n fetch: (url, init) => {\n const headers = new Headers(init?.headers);\n headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n return fetch(url, { ...init, headers });\n },\n});\n\nawait didit.networks.notes.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nif err := client.Networks.Notes.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesDeleteParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n}); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nclient.networks().notes().delete(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n .build());" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->notes->delete('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555', [\n 'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ndidit.networks.notes.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nawait client.Networks.Notes.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n Headers = new Dictionary\n {\n [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n },\n});" + } ] } }, @@ -53976,7 +62412,44 @@ "ApiKeyAuth": [] } ], - "description": "Retry only this failed subject action using its saved inputs. Current write permission is checked. Applied actions return their receipt without executing again. Case closure is independent." + "description": "Retry only this failed subject action using its saved inputs. Current write permission is checked. Applied actions return their receipt without executing again. Case closure is independent.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retry_action_receipt(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retryActionReceipt(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RetryActionReceipt(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retryActionReceipt(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->retryActionReceipt('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retry_action_receipt(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetryActionReceiptAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/draft/": { @@ -54040,6 +62513,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.retrieve_draft(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.RetrieveDraft(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->retrieveDraft('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.retrieve_draft(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.RetrieveDraftAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] }, "put": { @@ -54093,6 +62603,13 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest" + }, + "example": { + "expected_version": 1, + "expected_revision": "4e5f0000-0000-4000-8000-000000000003", + "changes": { + "max_active_cases": 20 + } } }, "multipart/form-data": { @@ -54125,6 +62642,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.save_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version=1,\n expected_revision=\"4e5f0000-0000-4000-8000-000000000003\",\n changes={\"max_active_cases\": 20},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.saveDraft(\"11111111-2222-3333-4444-555555555555\", {\n expected_version: 1,\n expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n changes: { max_active_cases: 20 },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.SaveDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftWriteRequest{\n\tExpectedVersion: 1,\n\tExpectedRevision: didit.String(\"4e5f0000-0000-4000-8000-000000000003\"),\n\tChanges: map[string]any{\"max_active_cases\": 20},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftWriteRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().saveDraft(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftWriteRequest.builder()\n .expectedVersion(1L)\n .expectedRevision(\"4e5f0000-0000-4000-8000-000000000003\")\n .changes(Map.of(\"max_active_cases\", 20))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->saveDraft('11111111-2222-3333-4444-555555555555', [\n 'expected_version' => 1,\n 'expected_revision' => '4e5f0000-0000-4000-8000-000000000003',\n 'changes' => ['max_active_cases' => 20],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.save_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version: 1,\n expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n changes: { max_active_cases: 20 }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.SaveDraftAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftWriteRequest\n{\n ExpectedVersion = 1,\n ExpectedRevision = \"4e5f0000-0000-4000-8000-000000000003\",\n Changes = new Dictionary { [\"max_active_cases\"] = 20 },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] }, "delete": { @@ -54193,7 +62747,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.blueprints.discard_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version=0,\n expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.blueprints.discardDraft(\"11111111-2222-3333-4444-555555555555\", {\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Blueprints.DiscardDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion: 0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n}); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().blueprints().discardDraft(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftPreconditionRequest.builder()\n .expectedVersion(0L)\n .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n .build());" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->discardDraft('11111111-2222-3333-4444-555555555555', [\n 'expected_version' => 0,\n 'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.discard_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Blueprints.DiscardDraftAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftPreconditionRequest\n{\n ExpectedVersion = 0,\n ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/teams/{record_uuid}/": { @@ -54267,6 +62858,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->teams->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] }, "patch": { @@ -54349,6 +62977,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.update(\n \"11111111-2222-3333-4444-555555555555\",\n name=\"your-name\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.update(\"11111111-2222-3333-4444-555555555555\", {\n name: \"your-name\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseReviewTeamUpdate{\n\tName: didit.String(\"your-name\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CaseReviewTeamUpdate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().update(\"11111111-2222-3333-4444-555555555555\", CaseReviewTeamUpdate.builder()\n .name(\"your-name\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->teams->update('11111111-2222-3333-4444-555555555555', [\n 'name' => 'your-name',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.update(\n \"11111111-2222-3333-4444-555555555555\",\n name: \"your-name\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseReviewTeamUpdate\n{\n Name = \"your-name\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -54434,6 +63099,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\ncontent = client.networks.download_report(\n \"11111111-2222-3333-4444-555555555555\",\n extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n fetch: (url, init) => {\n const headers = new Headers(init?.headers);\n headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n return fetch(url, { ...init, headers });\n },\n});\n\nconst content = await didit.networks.downloadReport(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nresp, err := client.Networks.DownloadReport(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksDownloadReportParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nclient.networks().downloadReport(\"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n .build())\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->downloadReport('11111111-2222-3333-4444-555555555555', [\n 'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ncontent = didit.networks.download_report(\n \"11111111-2222-3333-4444-555555555555\",\n request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nvar content = await client.Networks.DownloadReportAsync(\"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n Headers = new Dictionary\n {\n [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n },\n});\nawait content.SaveToAsync(\"download.pdf\");" + } ] } }, @@ -54557,6 +63259,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nfor item in client.networks.notes.list(\n \"11111111-2222-3333-4444-555555555555\",\n extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n fetch: (url, init) => {\n const headers = new Headers(init?.headers);\n headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n return fetch(url, { ...init, headers });\n },\n});\n\nfor await (const item of didit.networks.notes.list(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\niter := client.Networks.Notes.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesListParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nfor (var item : client.networks().notes().list(\"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n .build())) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->notes->list('11111111-2222-3333-4444-555555555555', [\n 'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]) as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ndidit.networks.notes.list(\n \"11111111-2222-3333-4444-555555555555\",\n request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n).auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Networks.Notes.ListAsync(\"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n Headers = new Dictionary\n {\n [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n },\n}))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] }, "post": { @@ -54680,6 +63419,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nresult = client.networks.notes.create(\n \"11111111-2222-3333-4444-555555555555\",\n comment=\"your-comment\",\n client_reference=\"11111111-2222-3333-4444-555555555555\",\n extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n fetch: (url, init) => {\n const headers = new Headers(init?.headers);\n headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n return fetch(url, { ...init, headers });\n },\n});\n\nconst result = await didit.networks.notes.create(\"11111111-2222-3333-4444-555555555555\", {\n comment: \"your-comment\",\n client_reference: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nresult, err := client.Networks.Notes.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesCreateParams{\n\tComment: \"your-comment\",\n\tClientReference: \"11111111-2222-3333-4444-555555555555\",\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\nimport me.didit.types.NetworksNotesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nvar result = client.networks().notes().create(\"11111111-2222-3333-4444-555555555555\", NetworksNotesCreateParams.builder()\n .comment(\"your-comment\")\n .clientReference(\"11111111-2222-3333-4444-555555555555\")\n .build(), RequestOptions.builder()\n .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->notes->create('11111111-2222-3333-4444-555555555555', [\n 'comment' => 'your-comment',\n 'client_reference' => '11111111-2222-3333-4444-555555555555',\n 'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\nresult = didit.networks.notes.create(\n \"11111111-2222-3333-4444-555555555555\",\n comment: \"your-comment\",\n client_reference: \"11111111-2222-3333-4444-555555555555\",\n request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.Notes.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new NetworksNotesCreateParams\n{\n Comment = \"your-comment\",\n ClientReference = \"11111111-2222-3333-4444-555555555555\",\n}, requestOptions: new RequestOptions\n{\n Headers = new Dictionary\n {\n [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -54744,6 +63520,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.retrieve_draft(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.RetrieveDraft(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->retrieveDraft('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.retrieve_draft(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.RetrieveDraftAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] }, "put": { @@ -54797,6 +63610,13 @@ "application/json": { "schema": { "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest" + }, + "example": { + "expected_version": 1, + "expected_revision": "4e5f0000-0000-4000-8000-000000000003", + "changes": { + "priority": 10 + } } }, "multipart/form-data": { @@ -54829,6 +63649,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.save_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version=1,\n expected_revision=\"4e5f0000-0000-4000-8000-000000000003\",\n changes={\"priority\": 10},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.saveDraft(\"11111111-2222-3333-4444-555555555555\", {\n expected_version: 1,\n expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n changes: { priority: 10 },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.SaveDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftWriteRequest{\n\tExpectedVersion: 1,\n\tExpectedRevision: didit.String(\"4e5f0000-0000-4000-8000-000000000003\"),\n\tChanges: map[string]any{\"priority\": 10},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftWriteRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().saveDraft(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftWriteRequest.builder()\n .expectedVersion(1L)\n .expectedRevision(\"4e5f0000-0000-4000-8000-000000000003\")\n .changes(Map.of(\"priority\", 10))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->saveDraft('11111111-2222-3333-4444-555555555555', [\n 'expected_version' => 1,\n 'expected_revision' => '4e5f0000-0000-4000-8000-000000000003',\n 'changes' => ['priority' => 10],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.save_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version: 1,\n expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n changes: { priority: 10 }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.SaveDraftAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftWriteRequest\n{\n ExpectedVersion = 1,\n ExpectedRevision = \"4e5f0000-0000-4000-8000-000000000003\",\n Changes = new Dictionary { [\"priority\"] = 10 },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] }, "delete": { @@ -54897,7 +63754,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.routing_rules.discard_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version=0,\n expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.routingRules.discardDraft(\"11111111-2222-3333-4444-555555555555\", {\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.RoutingRules.DiscardDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion: 0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n}); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().routingRules().discardDraft(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftPreconditionRequest.builder()\n .expectedVersion(0L)\n .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n .build());" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->discardDraft('11111111-2222-3333-4444-555555555555', [\n 'expected_version' => 0,\n 'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.discard_draft(\n \"11111111-2222-3333-4444-555555555555\",\n expected_version: 0,\n expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.RoutingRules.DiscardDraftAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftPreconditionRequest\n{\n ExpectedVersion = 0,\n ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/duplicates/": { @@ -54943,6 +63837,12 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest" + }, + "example": { + "subject": { + "type": "user", + "uuid": "5b9a0000-0000-4000-8000-00000000f00d" + } } }, "multipart/form-data": { @@ -54969,7 +63869,44 @@ "ApiKeyAuth": [] } ], - "description": "Review existing cases for a subject or owned source record before manual case creation. Both open and resolved investigations are returned. Each page contains at most 20 cases; use next_offset to request another page." + "description": "Review existing cases for a subject or owned source record before manual case creation. Both open and resolved investigations are returned. Each page contains at most 20 cases; use next_offset to request another page.", + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.find_duplicates(\n subject={\n \"type\": \"user\",\n \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\",\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.findDuplicates({\n subject: {\n type: \"user\",\n uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.FindDuplicates(ctx, didit.CaseDuplicateCaseDuplicateQueryRequest{\n\tSubject: didit.Some(didit.CaseDuplicateCaseSubjectInputRequest{\n\t\tType: didit.CaseDuplicateTypeEnum(\"user\"),\n\t\tUUID: \"5b9a0000-0000-4000-8000-00000000f00d\",\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CaseDuplicateCaseDuplicateQueryRequest;\nimport me.didit.types.CaseDuplicateCaseSubjectInputRequest;\nimport me.didit.types.CaseDuplicateTypeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().findDuplicates(CaseDuplicateCaseDuplicateQueryRequest.builder()\n .subject(CaseDuplicateCaseSubjectInputRequest.builder()\n .type(CaseDuplicateTypeEnum.of(\"user\"))\n .uuid(\"5b9a0000-0000-4000-8000-00000000f00d\")\n .build())\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->findDuplicates([\n 'subject' => [\n 'type' => 'user',\n 'uuid' => '5b9a0000-0000-4000-8000-00000000f00d',\n ],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.find_duplicates(\n subject: {\n type: \"user\",\n uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.FindDuplicatesAsync(new CaseDuplicateCaseDuplicateQueryRequest\n{\n Subject = new CaseDuplicateCaseSubjectInputRequest\n {\n Type = \"user\",\n Uuid = \"5b9a0000-0000-4000-8000-00000000f00d\",\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/preview/": { @@ -55041,6 +63978,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.preview(\n source=\"MANUAL\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.preview({\n source: \"MANUAL\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Preview(ctx, didit.CaseRoutingPreviewRequest{\n\tSource: \"MANUAL\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.CaseRoutingPreviewRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().preview(CaseRoutingPreviewRequest.builder()\n .source(CaseRoutingPreviewRequest.Source.of(\"MANUAL\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->routingRules->preview([\n 'source' => 'MANUAL',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.preview(source: \"MANUAL\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.PreviewAsync(new CaseRoutingPreviewRequest\n{\n Source = \"MANUAL\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -55127,6 +64101,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_reviewers()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listReviewers();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListReviewers(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listReviewers();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->listReviewers();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.list_reviewers\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListReviewersAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -55218,13 +64229,50 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.blueprints.list_history(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.blueprints.listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Blueprints.ListHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesBlueprintsListHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().blueprints().listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->blueprints->listHistory('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.list_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Blueprints.ListHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } ] } }, "/v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/": { "get": { "summary": "Download a signed document", - "description": "Download the signed PDF of one document of an Electronic Signature step. Use the `signed_file` path of `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field values stamped, the evidence page (unless `signature_evidence_page` is off) and the PAdES signature with its timestamp. Didit checks the file against `sha256_signed` before returning it.\n\nWorks for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API key works. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents).", + "description": "Download the signed PDF of one document of an E-signature step. Use the `signed_file` path of `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field values stamped and the evidence page (unless `signature_evidence_page` is off). An Advanced (AES) PDF also carries the PAdES signature with its timestamp; a Simple PDF has no digital signature, seal or timestamp. Didit checks the file against `sha256_signed` before returning it.\n\nWorks for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API key works. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents).", "operationId": "get_v3_session_signature_document_file", "x-didit-sdk": { "resource": "sessions.signatures", @@ -55251,7 +64299,7 @@ "name": "nodeId", "in": "path", "required": true, - "description": "The Electronic Signature step: `node_id` of the item in `signatures[]`.", + "description": "The E-signature step: `node_id` of the item in `signatures[]`.", "schema": { "type": "string", "example": "feature_signature" @@ -55295,7 +64343,7 @@ } }, "403": { - "description": "Missing or invalid credentials, or a credential that can't read this session. Didit's API-key authentication answers `403`, never `401`.", + "description": "Missing credentials, or a credential that can't read this session. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "schema": { @@ -55373,13 +64421,50 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_document(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadDocument(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadDocument(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadDocument(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->signatures->downloadDocument('11111111-2222-3333-4444-555555555555', 'feature_signature', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_document(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadDocumentAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.pdf\");" + } + ] } }, "/v3/session/{sessionId}/signatures/{nodeId}/evidence/": { "get": { "summary": "Download the signature evidence", - "description": "Download a signer's evidence PDF: the level and format, the signer and their verified identity session, the code confirmation, the IP address, each document with its original SHA-256 and field values, the certificate, the timestamp and the SHA-256 of every signed file. Use the `evidence_file` path of the signer's item in `signatures[]`.\n\nAlways pass `signature_id` when a Business Verification step has several signers: without it, the route picks one of the step's signers. Needs `read:sessions`; your API key works.", + "description": "Download a signer's evidence PDF: the level and format, the signer, the IP address, each document with its original SHA-256 and field values and the SHA-256 of every signed file, plus, for an Advanced (AES) signature, the verified identity session, the code confirmation, the certificate and the timestamp. Use the `evidence_file` path of the signer's item in `signatures[]`.\n\nAlways pass `signature_id` when a Business Verification step has several signers: without it, the route picks one of the step's signers. Needs `read:sessions`; your API key works.", "operationId": "get_v3_session_signature_evidence", "x-didit-sdk": { "resource": "sessions.signatures", @@ -55406,7 +64491,7 @@ "name": "nodeId", "in": "path", "required": true, - "description": "The Electronic Signature step: `node_id` of the item in `signatures[]`.", + "description": "The E-signature step: `node_id` of the item in `signatures[]`.", "schema": { "type": "string", "example": "feature_signature" @@ -55450,7 +64535,7 @@ } }, "403": { - "description": "Missing or invalid credentials, or a credential that can't read this session. Didit's API-key authentication answers `403`, never `401`.", + "description": "Missing credentials, or a credential that can't read this session. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "schema": { @@ -55528,7 +64613,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_evidence(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadEvidence(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n);\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadEvidence(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", didit.SessionsSignaturesDownloadEvidenceParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadEvidence(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\")\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->signatures->downloadEvidence('11111111-2222-3333-4444-555555555555', 'feature_signature');\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_evidence(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\"\n)\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadEvidenceAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\");\nawait content.SaveToAsync(\"download.pdf\");" + } + ] } }, "/v3/session/{sessionId}/signatures/{nodeId}/fields/{fieldId}/image/": { @@ -55561,7 +64683,7 @@ "name": "nodeId", "in": "path", "required": true, - "description": "The Electronic Signature step: `node_id` of the item in `signatures[]`.", + "description": "The E-signature step: `node_id` of the item in `signatures[]`.", "schema": { "type": "string", "example": "feature_signature" @@ -55618,7 +64740,7 @@ } }, "403": { - "description": "Missing or invalid credentials, or a credential that can't read this session. Didit's API-key authentication answers `403`, never `401`.", + "description": "Missing credentials, or a credential that can't read this session. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "schema": { @@ -55662,13 +64784,50 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_field_image(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.png\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadFieldImage(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.png\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadFieldImage(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.png\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadFieldImage(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\n .writeTo(Path.of(\"download.png\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->signatures->downloadFieldImage('11111111-2222-3333-4444-555555555555', 'feature_signature', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.png');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_field_image(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.png\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadFieldImageAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.png\");" + } + ] } }, "/v3/session/{sessionId}/signatures/{nodeId}/validate/": { "post": { "summary": "Validate signatures again", - "description": "Re-check the signed documents of an Electronic Signature step. Didit re-reads every signed PDF, checks its SHA-256 and validates the PAdES signature, the certificate, the revocation data and the timestamp, then saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if any of them hasn't signed.\n\nNeeds `write:sessions`; your API key works. In the console it's the **Validate again** button.", + "description": "Re-check the signed documents of an E-signature step. Didit re-reads every signed PDF, checks its SHA-256 and, for an Advanced (AES) signature, validates the PAdES signature, the certificate, the revocation data and the timestamp (a Simple signature has no digital signature, so only the file integrity is checked), then saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if any of them hasn't signed.\n\nNeeds `write:sessions`; your API key works. In the console it's the **Validate again** button.", "operationId": "post_v3_session_signature_validate", "x-didit-sdk": { "resource": "sessions.signatures", @@ -55695,7 +64854,7 @@ "name": "nodeId", "in": "path", "required": true, - "description": "The Electronic Signature step: `node_id` of the item in `signatures[]`.", + "description": "The E-signature step: `node_id` of the item in `signatures[]`.", "schema": { "type": "string", "example": "feature_signature" @@ -55774,7 +64933,7 @@ } }, "403": { - "description": "Missing or invalid credentials, or a credential that can't read this session. Didit's API-key authentication answers `403`, never `401`.", + "description": "Missing credentials, or a credential that can't read this session. A missing key returns `403`; a wrong, revoked or expired key returns `401`.", "content": { "application/json": { "schema": { @@ -55845,7 +65004,44 @@ } } } - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.signatures.validate(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n signature_id=\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.signatures.validate(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n {\n signature_id: \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Signatures.Validate(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", didit.SessionsSignaturesValidateParams{\n\tSignatureID: didit.String(\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsSignaturesValidateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().signatures().validate(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", SessionsSignaturesValidateParams.builder()\n .signatureId(\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->signatures->validate('11111111-2222-3333-4444-555555555555', 'feature_signature', [\n 'signature_id' => '0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.signatures.validate(\n \"11111111-2222-3333-4444-555555555555\",\n \"feature_signature\",\n signature_id: \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Signatures.ValidateAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", new SessionsSignaturesValidateParams\n{\n SignatureId = \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/document-ai/{sessionId}/documents/{documentUuid}/": { @@ -55932,12 +65128,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '11111111-2222-3333-4444-555555555555'\ndocument_uuid = '44444444-5555-6666-7777-888888888888'\nresp = requests.patch(\n f'https://verification.didit.me/v3/document-ai/{session_id}/documents/{document_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'extracted_data': {'invoice_number': 'INV-2026-0042'}, 'status': 'Approved'},\n timeout=10,\n)\nresp.raise_for_status()\ndocument = resp.json()\nprint(document['status'], document['extracted_data'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_document_ai_data(\n \"11111111-2222-3333-4444-555555555555\",\n \"44444444-5555-6666-7777-888888888888\",\n extracted_data={\"invoice_number\": \"INV-2026-0042\"},\n status=\"Approved\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '11111111-2222-3333-4444-555555555555';\nconst documentUuid = '44444444-5555-6666-7777-888888888888';\nconst resp = await fetch(`https://verification.didit.me/v3/document-ai/${sessionId}/documents/${documentUuid}/`, {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ extracted_data: { invoice_number: 'INV-2026-0042' }, status: 'Approved' }),\n});\nif (!resp.ok) throw new Error(`Update failed: ${resp.status}`);\nconst document = await resp.json();\nconsole.log(document.status, document.extracted_data);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateDocumentAiData(\n \"11111111-2222-3333-4444-555555555555\",\n \"44444444-5555-6666-7777-888888888888\",\n {\n extracted_data: { invoice_number: \"INV-2026-0042\" },\n status: \"Approved\",\n },\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateDocumentAiData(ctx, \"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", didit.SessionsUpdateDocumentAiDataParams{\n\tExtractedData: didit.Some(map[string]any{\"invoice_number\": \"INV-2026-0042\"}),\n\tStatus: didit.Some(didit.SessionsUpdateDocumentAiDataParamsStatus(\"Approved\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateDocumentAiDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateDocumentAiData(\"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", SessionsUpdateDocumentAiDataParams.builder()\n .extractedData(Map.of(\"invoice_number\", \"INV-2026-0042\"))\n .status(SessionsUpdateDocumentAiDataParams.Status.of(\"Approved\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateDocumentAiData('11111111-2222-3333-4444-555555555555', '44444444-5555-6666-7777-888888888888', [\n 'extracted_data' => ['invoice_number' => 'INV-2026-0042'],\n 'status' => 'Approved',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_document_ai_data(\n \"11111111-2222-3333-4444-555555555555\",\n \"44444444-5555-6666-7777-888888888888\",\n extracted_data: { invoice_number: \"INV-2026-0042\" },\n status: \"Approved\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateDocumentAiDataAsync(\"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", new SessionsUpdateDocumentAiDataParams\n{\n ExtractedData = new Dictionary { [\"invoice_number\"] = \"INV-2026-0042\" },\n Status = new SessionsUpdateDocumentAiDataParamsStatus(\"Approved\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -56059,7 +65280,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -56202,12 +65423,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/aml/dataset-freshness/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nbody = resp.json()\nif body['availability'] == 'available':\n for family, info in body['dataset_freshness']['sources'].items():\n print(family, info['last_updated_at'], info['oldest_updated_at'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml.retrieve_dataset_freshness()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/aml/dataset-freshness/', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Freshness lookup failed: ${resp.status}`);\nconst body = await resp.json();\nif (body.availability === 'available') {\n for (const [family, info] of Object.entries(body.dataset_freshness.sources)) {\n console.log(family, info.last_updated_at, info.oldest_updated_at);\n }\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.aml.retrieveDatasetFreshness();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AML.RetrieveDatasetFreshness(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.aml().retrieveDatasetFreshness();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "aml->retrieveDatasetFreshness();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml.retrieve_dataset_freshness\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Aml.RetrieveDatasetFreshnessAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -56300,7 +65546,7 @@ } }, "403": { - "description": "The request is not allowed. A missing or invalid API key gets the generic message (never `401`).", + "description": "The request is not allowed. A missing key gets the generic message; a wrong, revoked or expired key gets `401`.", "content": { "application/json": { "schema": { @@ -56493,12 +65739,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/lists/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'list_type': 'blocklist'},\n timeout=10,\n)\nresp.raise_for_status()\nfor item in resp.json()['results']:\n print(item['uuid'], item['entry_type'], item['name'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.lists.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/lists/?list_type=blocklist', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst page = await resp.json();\nconsole.log(page.results.map((list) => [list.uuid, list.entry_type, list.name]));" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.lists.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Lists.ListAutoPaging(ctx, didit.ListsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.lists().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Lists.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -56621,7 +65892,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -56753,12 +66024,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/lists/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'name': 'Trusted office IPs',\n 'description': 'Office egress ranges',\n 'list_type': 'allowlist',\n 'entry_type': 'ip_address',\n },\n timeout=10,\n)\nresp.raise_for_status()\nprint('Created list', resp.json()['uuid'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.create(\n name=\"Trusted office IPs\",\n description=\"Office egress ranges\",\n list_type=\"allowlist\",\n entry_type=\"ip_address\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/lists/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name: 'Trusted office IPs',\n description: 'Office egress ranges',\n list_type: 'allowlist',\n entry_type: 'ip_address',\n }),\n});\nif (!resp.ok) throw new Error(`Create failed: ${resp.status}`);\nconst list = await resp.json();\nconsole.log('Created list', list.uuid);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.create({\n name: \"Trusted office IPs\",\n description: \"Office egress ranges\",\n list_type: \"allowlist\",\n entry_type: \"ip_address\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Create(ctx, didit.ListsCreateParams{\n\tName: \"Trusted office IPs\",\n\tDescription: didit.String(\"Office egress ranges\"),\n\tListType: \"allowlist\",\n\tEntryType: \"ip_address\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.ListsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().create(ListsCreateParams.builder()\n .name(\"Trusted office IPs\")\n .description(\"Office egress ranges\")\n .listType(ListsCreateParams.ListType.of(\"allowlist\"))\n .entryType(ListsCreateParams.EntryType.of(\"ip_address\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->create([\n 'name' => 'Trusted office IPs',\n 'description' => 'Office egress ranges',\n 'list_type' => 'allowlist',\n 'entry_type' => 'ip_address',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.create(\n name: \"Trusted office IPs\",\n description: \"Office egress ranges\",\n list_type: \"allowlist\",\n entry_type: \"ip_address\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.CreateAsync(new ListsCreateParams\n{\n Name = \"Trusted office IPs\",\n Description = \"Office egress ranges\",\n ListType = \"allowlist\",\n EntryType = \"ip_address\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -56853,7 +66149,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -56918,12 +66214,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/lists/{list_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const listUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/lists/${listUuid}/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Lookup failed: ${resp.status}`);\nconst list = await resp.json();\nconsole.log(list.name, list.entry_count);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -56968,7 +66289,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -57091,12 +66412,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.patch(\n f'https://verification.didit.me/v3/lists/{list_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'name': 'Trusted office and VPN IPs'},\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.update(\n \"11111111-2222-3333-4444-555555555555\",\n name=\"Trusted office and VPN IPs\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const listUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/lists/${listUuid}/`, {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name: 'Trusted office and VPN IPs' }),\n});\nif (!resp.ok) throw new Error(`Update failed: ${resp.status}`);\nconsole.log(await resp.json());" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.update(\"11111111-2222-3333-4444-555555555555\", {\n name: \"Trusted office and VPN IPs\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsUpdateParams{\n\tName: didit.String(\"Trusted office and VPN IPs\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.ListsUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().update(\"11111111-2222-3333-4444-555555555555\", ListsUpdateParams.builder()\n .name(\"Trusted office and VPN IPs\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->update('11111111-2222-3333-4444-555555555555', [\n 'name' => 'Trusted office and VPN IPs',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.update(\n \"11111111-2222-3333-4444-555555555555\",\n name: \"Trusted office and VPN IPs\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new ListsUpdateParams\n{\n Name = \"Trusted office and VPN IPs\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -57177,7 +66523,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -57254,12 +66600,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.delete(\n f'https://verification.didit.me/v3/lists/{list_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nprint('Deleted:', resp.status_code == 204)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.lists.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const listUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/lists/${listUuid}/`, {\n method: 'DELETE',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (resp.status !== 204) throw new Error(`Delete failed: ${resp.status}`);\nconsole.log('List deleted');" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.lists.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Lists.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.lists().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Lists.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ], "responses": { @@ -57295,7 +66666,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -57417,12 +66788,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/lists/{list_uuid}/entries/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'search': 'example.com', 'limit': 100},\n timeout=10,\n)\nresp.raise_for_status()\nfor entry in resp.json()['results']:\n print(entry['uuid'], entry['value'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.lists.entries.list(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const listUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(\n `https://verification.didit.me/v3/lists/${listUuid}/entries/?search=example.com`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst page = await resp.json();\nconsole.log(page.count, page.results.map((entry) => entry.value));" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.lists.entries.list(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Lists.Entries.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.lists().entries().list(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->entries->list('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.entries.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Lists.Entries.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -57546,7 +66942,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -57742,12 +67138,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.post(\n f'https://verification.didit.me/v3/lists/{list_uuid}/entries/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'reference_session_id': '33333333-4444-5555-6666-777777777777'},\n timeout=10,\n)\nresp.raise_for_status()\nentry = resp.json()\nprint('Listed', entry['value'], 'as', entry['uuid'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.entries.create(\n \"11111111-2222-3333-4444-555555555555\",\n value=\"+14155552671\",\n comment=\"Reported fraud\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const listUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/lists/${listUuid}/entries/`, {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ value: '+14155552671', comment: 'Reported fraud' }),\n});\nif (!resp.ok) throw new Error(`Create failed: ${resp.status} ${await resp.text()}`);\nconst entry = await resp.json();\nconsole.log('Listed', entry.value, 'as', entry.uuid);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.entries.create(\"11111111-2222-3333-4444-555555555555\", {\n value: \"+14155552671\",\n comment: \"Reported fraud\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Entries.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesCreateParams{\n\tValue: didit.String(\"+14155552671\"),\n\tComment: didit.String(\"Reported fraud\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.ListsEntriesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().entries().create(\"11111111-2222-3333-4444-555555555555\", ListsEntriesCreateParams.builder()\n .value(\"+14155552671\")\n .comment(\"Reported fraud\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->entries->create('11111111-2222-3333-4444-555555555555', [\n 'value' => '+14155552671',\n 'comment' => 'Reported fraud',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.entries.create(\n \"11111111-2222-3333-4444-555555555555\",\n value: \"+14155552671\",\n comment: \"Reported fraud\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.Entries.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new ListsEntriesCreateParams\n{\n Value = \"+14155552671\",\n Comment = \"Reported fraud\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -57918,7 +67339,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -58022,12 +67443,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nentry_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'\nresp = requests.delete(\n f'https://verification.didit.me/v3/lists/{list_uuid}/entries/{entry_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nprint('Deleted:', resp.status_code == 204)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.lists.entries.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const listUuid = '11111111-2222-3333-4444-555555555555';\nconst entryUuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\nconst resp = await fetch(\n `https://verification.didit.me/v3/lists/${listUuid}/entries/${entryUuid}/`,\n { method: 'DELETE', headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (resp.status !== 204) throw new Error(`Delete failed: ${resp.status}`);\nconsole.log('Entry deleted');" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.lists.entries.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Lists.Entries.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.lists().entries().delete(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->entries->delete('11111111-2222-3333-4444-555555555555', 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.entries.delete(\n \"11111111-2222-3333-4444-555555555555\",\n \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Lists.Entries.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");" } ], "responses": { @@ -58049,7 +67495,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -58161,12 +67607,37 @@ { "lang": "python", "label": "Python", - "source": "import base64\nimport os\n\nimport requests\n\nlist_uuid = '11111111-2222-3333-4444-555555555555'\nwith open('face.jpg', 'rb') as image_file:\n image_b64 = base64.b64encode(image_file.read()).decode('ascii')\n\nresp = requests.post(\n f'https://verification.didit.me/v3/lists/{list_uuid}/entries/face-upload/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'image': image_b64, 'comment': 'Known fraud attempt'},\n timeout=10,\n)\nresp.raise_for_status()\nprint('Face entry', resp.json()['uuid'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.entries.upload_face(\n \"11111111-2222-3333-4444-555555555555\",\n image=\"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n comment=\"Known fraud attempt\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { readFile } from 'node:fs/promises';\n\nconst listUuid = '11111111-2222-3333-4444-555555555555';\nconst image = (await readFile('face.jpg')).toString('base64');\nconst resp = await fetch(`https://verification.didit.me/v3/lists/${listUuid}/entries/face-upload/`, {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ image, comment: 'Known fraud attempt' }),\n});\nif (!resp.ok) throw new Error(`Upload failed: ${resp.status} ${await resp.text()}`);\nconst entry = await resp.json();\nconsole.log('Face entry', entry.uuid);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.entries.uploadFace(\"11111111-2222-3333-4444-555555555555\", {\n image: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n comment: \"Known fraud attempt\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Entries.UploadFace(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesUploadFaceParams{\n\tImage: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n\tComment: didit.String(\"Known fraud attempt\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.ListsEntriesUploadFaceParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().entries().uploadFace(\"11111111-2222-3333-4444-555555555555\", ListsEntriesUploadFaceParams.builder()\n .image(\"/9j/4AAQSkZJRgABAQAAAQABAAD...\")\n .comment(\"Known fraud attempt\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "lists->entries->uploadFace('11111111-2222-3333-4444-555555555555', [\n 'image' => '/9j/4AAQSkZJRgABAQAAAQABAAD...',\n 'comment' => 'Known fraud attempt',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.entries.upload_face(\n \"11111111-2222-3333-4444-555555555555\",\n image: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n comment: \"Known fraud attempt\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.Entries.UploadFaceAsync(\"11111111-2222-3333-4444-555555555555\", new ListsEntriesUploadFaceParams\n{\n Image = \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n Comment = \"Known fraud attempt\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -58286,7 +67757,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -58407,12 +67878,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/blocklist/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'item_type': 'document'},\n timeout=10,\n)\nresp.raise_for_status()\nfor item in resp.json()['results']:\n print(item['session_id'], item['document_type'], item['document_number'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.blocklist.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/blocklist/?item_type=document', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst page = await resp.json();\nconsole.log(page.count, page.results);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.blocklist.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Blocklist.ListAutoPaging(ctx, didit.BlocklistListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.blocklist().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "blocklist->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.blocklist.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Blocklist.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -58530,7 +68026,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: read` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -58649,12 +68145,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/blocklist/add/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'session_id': '33333333-4444-5555-6666-777777777777',\n 'blocklist_face': True,\n 'blocklist_document': True,\n },\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json()['message'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.blocklist.add(\n session_id=\"33333333-4444-5555-6666-777777777777\",\n blocklist_face=True,\n blocklist_document=True,\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/blocklist/add/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n session_id: '33333333-4444-5555-6666-777777777777',\n blocklist_face: true,\n blocklist_document: true,\n }),\n});\nif (!resp.ok) throw new Error(`Blocklist failed: ${resp.status} ${await resp.text()}`);\nconsole.log((await resp.json()).message);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.blocklist.add({\n session_id: \"33333333-4444-5555-6666-777777777777\",\n blocklist_face: true,\n blocklist_document: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Blocklist.Add(ctx, didit.BlocklistAddParams{\n\tSessionID: \"33333333-4444-5555-6666-777777777777\",\n\tBlocklistFace: didit.Bool(true),\n\tBlocklistDocument: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BlocklistAddParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.blocklist().add(BlocklistAddParams.builder()\n .sessionId(\"33333333-4444-5555-6666-777777777777\")\n .blocklistFace(true)\n .blocklistDocument(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "blocklist->add([\n 'session_id' => '33333333-4444-5555-6666-777777777777',\n 'blocklist_face' => true,\n 'blocklist_document' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.blocklist.add(\n session_id: \"33333333-4444-5555-6666-777777777777\",\n blocklist_face: true,\n blocklist_document: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Blocklist.AddAsync(new BlocklistAddParams\n{\n SessionId = \"33333333-4444-5555-6666-777777777777\",\n BlocklistFace = true,\n BlocklistDocument = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -58750,7 +68271,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -58852,12 +68373,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/blocklist/remove/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'session_id': '33333333-4444-5555-6666-777777777777',\n 'unblock_face': True,\n 'unblock_document': True,\n },\n timeout=10,\n)\nresp.raise_for_status()\nprint(resp.json()['message'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.blocklist.remove(\n session_id=\"33333333-4444-5555-6666-777777777777\",\n unblock_face=True,\n unblock_document=True,\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/blocklist/remove/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n session_id: '33333333-4444-5555-6666-777777777777',\n unblock_face: true,\n unblock_document: true,\n }),\n});\nif (!resp.ok) throw new Error(`Unblock failed: ${resp.status} ${await resp.text()}`);\nconsole.log((await resp.json()).message);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.blocklist.remove({\n session_id: \"33333333-4444-5555-6666-777777777777\",\n unblock_face: true,\n unblock_document: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Blocklist.Remove(ctx, didit.BlocklistRemoveParams{\n\tSessionID: \"33333333-4444-5555-6666-777777777777\",\n\tUnblockFace: didit.Bool(true),\n\tUnblockDocument: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.BlocklistRemoveParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.blocklist().remove(BlocklistRemoveParams.builder()\n .sessionId(\"33333333-4444-5555-6666-777777777777\")\n .unblockFace(true)\n .unblockDocument(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "blocklist->remove([\n 'session_id' => '33333333-4444-5555-6666-777777777777',\n 'unblock_face' => true,\n 'unblock_document' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.blocklist.remove(\n session_id: \"33333333-4444-5555-6666-777777777777\",\n unblock_face: true,\n unblock_document: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Blocklist.RemoveAsync(new BlocklistRemoveParams\n{\n SessionId = \"33333333-4444-5555-6666-777777777777\",\n UnblockFace = true,\n UnblockDocument = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -58946,7 +68492,7 @@ } }, "403": { - "description": "The `x-api-key` header is missing or invalid, or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", + "description": "The `x-api-key` header is missing (a wrong, revoked or expired key gets `401`), or a scoped API key lacks `workflows: write` or is used from an IP address outside its allowlist.", "content": { "application/json": { "examples": { @@ -58999,12 +68545,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/webhook/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nconfig = resp.json()\nfor destination in config['endpoints']:\n print(destination['label'], destination['url'], destination['subscribed_events'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.retrieve_config()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/webhook/', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst config = await resp.json();\nfor (const destination of config.endpoints) {\n console.log(destination.label, destination.url, destination.subscribed_events);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.retrieveConfig();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.RetrieveConfig(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().retrieveConfig();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->retrieveConfig();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.retrieve_config\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.RetrieveConfigAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -59098,7 +68669,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -59311,6 +68882,18 @@ "type": "string", "maxLength": 253 } + }, + "allowed_domains": { + "type": "array", + "maxItems": 50, + "items": { + "type": "string", + "maxLength": 300 + }, + "description": "Replaces the whole list of allowed origins. Origins (for example `https://app.example.com`; `http` only for `localhost`) the hosted verification flow may be embedded in and may send the user back to with a session callback. Server-to-server calls are not affected. An empty list means no restriction. Didit stores each origin in lower case without a default port. An invalid entry fails with `400` on `allowed_domains`. Send `[]` to remove the restriction.", + "example": [ + "https://app.example.com" + ] } } }, @@ -59353,12 +68936,32 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.patch(\n 'https://verification.didit.me/v3/webhook/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'face_retention_policy': 'retain_until_user_deleted', 'face_retention_days': 365},\n timeout=10,\n)\nresp.raise_for_status()\nconfig = resp.json()\nprint(config['face_retention_policy'], config['face_retention_days'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.update_config(\n face_retention_policy=\"retain_until_user_deleted\",\n face_retention_days=365,\n biometric_consent_mode=\"auto\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/webhook/', {\n method: 'PATCH',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ face_retention_policy: 'retain_until_user_deleted', face_retention_days: 365 }),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst config = await resp.json();\nconsole.log(config.face_retention_policy, config.face_retention_days);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.updateConfig({\n face_retention_policy: \"retain_until_user_deleted\",\n face_retention_days: 365,\n biometric_consent_mode: \"auto\",\n});\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.WebhooksUpdateConfigParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().updateConfig(WebhooksUpdateConfigParams.builder()\n .faceRetentionPolicy(WebhooksUpdateConfigParams.FaceRetentionPolicy.of(\"retain_until_user_deleted\"))\n .faceRetentionDays(365L)\n .biometricConsentMode(WebhooksUpdateConfigParams.BiometricConsentMode.of(\"auto\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->updateConfig([\n 'face_retention_policy' => 'retain_until_user_deleted',\n 'face_retention_days' => 365,\n 'biometric_consent_mode' => 'auto',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.update_config(\n face_retention_policy: \"retain_until_user_deleted\",\n face_retention_days: 365,\n biometric_consent_mode: \"auto\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.UpdateConfigAsync(new WebhooksUpdateConfigParams\n{\n FaceRetentionPolicy = new WebhooksUpdateConfigParamsFaceRetentionPolicy(\"retain_until_user_deleted\"),\n FaceRetentionDays = 365,\n BiometricConsentMode = new WebhooksUpdateConfigParamsBiometricConsentMode(\"auto\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -59500,7 +69103,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -59682,12 +69285,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\ndestination_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/analytics/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'date_from': '2026-10-01', 'date_to': '2026-10-16'},\n timeout=10,\n)\nresp.raise_for_status()\nsummary = resp.json()['summary']\nprint(f\"{summary['failed_deliveries']} of {summary['total_deliveries']} failed ({summary['error_rate_percentage']}%)\")" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve_analytics(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const destinationUuid = '11111111-2222-3333-4444-555555555555';\nconst params = new URLSearchParams({ date_from: '2026-10-01', date_to: '2026-10-16' });\nconst resp = await fetch(`https://verification.didit.me/v3/webhook/destinations/${destinationUuid}/analytics/?${params}`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst { summary, points } = await resp.json();\nconsole.log(summary.error_rate_percentage, points.length);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieveAnalytics(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.RetrieveAnalytics(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsRetrieveAnalyticsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieveAnalytics(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->retrieveAnalytics('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve_analytics(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveAnalyticsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -59886,7 +69514,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -60117,12 +69745,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\ndestination_uuid = '11111111-2222-3333-4444-555555555555'\nurl = f'https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/deliveries/'\nparams = {'limit': 50, 'date_from': '2026-10-01'}\n\nwhile url:\n resp = requests.get(\n url,\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params=params,\n timeout=10,\n )\n resp.raise_for_status()\n page = resp.json()\n for delivery in page['results']:\n if delivery['response_status'] is None or delivery['response_status'] >= 400:\n print(delivery['uuid'], delivery['webhook_type'], delivery['response_status'])\n url, params = page['next'], None # next already carries the query string" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.webhooks.destinations.list_deliveries(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const destinationUuid = '11111111-2222-3333-4444-555555555555';\nlet url = `https://verification.didit.me/v3/webhook/destinations/${destinationUuid}/deliveries/?limit=50&date_from=2026-10-01`;\nwhile (url) {\n const resp = await fetch(url, { headers: { 'x-api-key': process.env.DIDIT_API_KEY } });\n if (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\n const page = await resp.json();\n for (const delivery of page.results) {\n if (delivery.response_status === null || delivery.response_status >= 400) {\n console.log(delivery.uuid, delivery.webhook_type, delivery.response_status);\n }\n }\n url = page.next;\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.webhooks.destinations.listDeliveries(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Webhooks.Destinations.ListDeliveriesAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsListDeliveriesParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.webhooks().destinations().listDeliveries(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->listDeliveries('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.list_deliveries(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Webhooks.Destinations.ListDeliveriesAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -60237,7 +69890,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -60441,12 +70094,37 @@ { "lang": "python", "label": "Python", - "source": "import json\nimport os\n\nimport requests\n\ndestination_uuid = '11111111-2222-3333-4444-555555555555'\ndelivery_uuid = '66666666-7777-8888-9999-000000000001'\nresp = requests.get(\n f'https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\ndelivery = resp.json()\nheaders = json.loads(delivery['request_header'])\npayload = json.loads(delivery['request_body'])\nprint(delivery['response_status'], headers['X-Signature-V2'], payload['event_id'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve_delivery(\n \"11111111-2222-3333-4444-555555555555\",\n \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const destinationUuid = '11111111-2222-3333-4444-555555555555';\nconst deliveryUuid = '66666666-7777-8888-9999-000000000001';\nconst resp = await fetch(\n `https://verification.didit.me/v3/webhook/destinations/${destinationUuid}/deliveries/${deliveryUuid}/`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst delivery = await resp.json();\nconst headers = JSON.parse(delivery.request_header);\nconst payload = JSON.parse(delivery.request_body);\nconsole.log(delivery.response_status, headers['X-Signature-V2'], payload.event_id);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieveDelivery(\n \"11111111-2222-3333-4444-555555555555\",\n \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.RetrieveDelivery(ctx, \"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieveDelivery(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->retrieveDelivery('11111111-2222-3333-4444-555555555555', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve_delivery(\n \"11111111-2222-3333-4444-555555555555\",\n \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveDeliveryAsync(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -60477,7 +70155,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -60686,12 +70364,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\ndestination_uuid = '11111111-2222-3333-4444-555555555555'\ndelivery_uuid = '66666666-7777-8888-9999-000000000001'\nresp = requests.post(\n f'https://verification.didit.me/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nresent = resp.json()\nif resent['response_status'] is None or resent['response_status'] >= 400:\n print('Your endpoint still rejects it:', resent['response_status'])\nelse:\n print('Delivered as', resent['uuid'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.resend_delivery(\n \"11111111-2222-3333-4444-555555555555\",\n \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const destinationUuid = '11111111-2222-3333-4444-555555555555';\nconst deliveryUuid = '66666666-7777-8888-9999-000000000001';\nconst resp = await fetch(\n `https://verification.didit.me/v3/webhook/destinations/${destinationUuid}/deliveries/${deliveryUuid}/resend/`,\n { method: 'POST', headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(await resp.text());\nconst resent = await resp.json();\nconsole.log(resent.uuid, resent.response_status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.resendDelivery(\n \"11111111-2222-3333-4444-555555555555\",\n \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.ResendDelivery(ctx, \"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().resendDelivery(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "webhooks->destinations->resendDelivery('11111111-2222-3333-4444-555555555555', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.resend_delivery(\n \"11111111-2222-3333-4444-555555555555\",\n \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.ResendDeliveryAsync(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -60750,7 +70453,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -61215,12 +70918,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nurl = 'https://verification.didit.me/v3/events/'\nparams = {\n 'event_category': ['payment', 'dispute'],\n 'matched_only': 'true',\n 'occurred_from': '2026-10-01T00:00:00Z',\n 'limit': 50,\n}\nwhile url:\n resp = requests.get(\n url,\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params=params,\n timeout=10,\n )\n resp.raise_for_status()\n page = resp.json()\n for event in page['results']:\n print(event['event_uuid'], event['action_type'], event['status'])\n url, params = page['next'], None" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.monitoring_events.list():\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const params = new URLSearchParams([\n ['event_category', 'payment'],\n ['event_category', 'dispute'],\n ['matched_only', 'true'],\n ['occurred_from', '2026-10-01T00:00:00Z'],\n ['limit', '50'],\n]);\nlet url = `https://verification.didit.me/v3/events/?${params}`;\nwhile (url) {\n const resp = await fetch(url, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n });\n if (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\n const page = await resp.json();\n for (const event of page.results) console.log(event.event_uuid, event.action_type, event.status);\n url = page.next;\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.monitoringEvents.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.MonitoringEvents.ListAutoPaging(ctx, didit.MonitoringEventsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.monitoringEvents().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.MonitoringEvents.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -61339,7 +71067,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", "content": { "application/json": { "examples": { @@ -61500,12 +71228,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/events/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'event_id': 'login-2026-10-17-000001',\n 'event_category': 'auth',\n 'action_type': 'login',\n 'occurred_at': '2026-10-17T09:15:02.481Z',\n 'subject': {'vendor_data': 'user-42', 'entity_type': 'individual'},\n 'session': {'session_id': 'web-session-abc', 'sequence': 142},\n 'device_context': {\n 'fingerprint': 'fp-a8c1',\n 'network_context': {'ip_address': '203.0.113.42'},\n },\n 'payload': {'method': 'password'},\n },\n timeout=10,\n)\nresp.raise_for_status()\nresult = resp.json()\nprint(result['event_uuid'], result['status'], result['idempotent_replay'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create(\n event_id=\"login-2026-10-17-000001\",\n event_category=\"auth\",\n action_type=\"login\",\n occurred_at=\"2026-10-17T09:15:02.481Z\",\n time_zone=\"Europe/Madrid\",\n subject={\n \"vendor_data\": \"user-42\",\n \"entity_type\": \"individual\",\n },\n session={\n \"session_id\": \"web-session-abc\",\n \"sequence\": 142,\n },\n device_context={\n \"fingerprint\": \"fp-a8c1\",\n \"network_context\": {\n \"ip_address\": \"203.0.113.42\",\n },\n },\n payload={\"method\": \"password\"},\n custom_values={\"vip_tier\": \"gold\"},\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/events/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n event_id: 'login-2026-10-17-000001',\n event_category: 'auth',\n action_type: 'login',\n occurred_at: '2026-10-17T09:15:02.481Z',\n subject: { vendor_data: 'user-42', entity_type: 'individual' },\n session: { session_id: 'web-session-abc', sequence: 142 },\n device_context: {\n fingerprint: 'fp-a8c1',\n network_context: { ip_address: '203.0.113.42' },\n },\n payload: { method: 'password' },\n }),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst result = await resp.json();\nconsole.log(result.event_uuid, result.status, result.idempotent_replay);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.create({\n event_id: \"login-2026-10-17-000001\",\n event_category: \"auth\",\n action_type: \"login\",\n occurred_at: \"2026-10-17T09:15:02.481Z\",\n time_zone: \"Europe/Madrid\",\n subject: {\n vendor_data: \"user-42\",\n entity_type: \"individual\",\n },\n session: {\n session_id: \"web-session-abc\",\n sequence: 142,\n },\n device_context: {\n fingerprint: \"fp-a8c1\",\n network_context: {\n ip_address: \"203.0.113.42\",\n },\n },\n payload: { method: \"password\" },\n custom_values: { vip_tier: \"gold\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.Create(ctx, didit.MonitoringEventCreateRequest{\n\tEventID: \"login-2026-10-17-000001\",\n\tEventCategory: \"auth\",\n\tActionType: \"login\",\n\tOccurredAt: time.Date(2026, 10, 17, 9, 15, 2, 0, time.UTC),\n\tTimeZone: didit.String(\"Europe/Madrid\"),\n\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\tVendorData: \"user-42\",\n\t\tEntityType: didit.String(\"individual\"),\n\t},\n\tSession: didit.Some(didit.MonitoringEventCreateRequestSession{\n\t\tSessionID: didit.String(\"web-session-abc\"),\n\t\tSequence: didit.Int(142),\n\t}),\n\tDeviceContext: didit.Some(didit.MonitoringEventCreateRequestDeviceContext{\n\t\tFingerprint: didit.String(\"fp-a8c1\"),\n\t\tNetworkContext: didit.Some(didit.MonitoringEventCreateRequestDeviceContextNetworkContext{\n\t\t\tIPAddress: didit.String(\"203.0.113.42\"),\n\t\t}),\n\t}),\n\tPayload: didit.Some(map[string]any{\"method\": \"password\"}),\n\tCustomValues: didit.Some(map[string]any{\"vip_tier\": \"gold\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.OffsetDateTime;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventCreateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().create(MonitoringEventCreateRequest.builder()\n .eventId(\"login-2026-10-17-000001\")\n .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"auth\"))\n .actionType(\"login\")\n .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:15:02.481Z\"))\n .timeZone(\"Europe/Madrid\")\n .subject(MonitoringEventCreateRequest.Subject.builder()\n .vendorData(\"user-42\")\n .entityType(\"individual\")\n .build())\n .session(MonitoringEventCreateRequest.Session.builder()\n .sessionId(\"web-session-abc\")\n .sequence(142L)\n .build())\n .deviceContext(MonitoringEventCreateRequest.DeviceContext.builder()\n .fingerprint(\"fp-a8c1\")\n .networkContext(MonitoringEventCreateRequest.DeviceContext.NetworkContext.builder()\n .ipAddress(\"203.0.113.42\")\n .build())\n .build())\n .payload(Map.of(\"method\", \"password\"))\n .customValues(Map.of(\"vip_tier\", MonitoringEventCreateRequest.CustomValuesValue.ofString(\"gold\")))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->create([\n 'event_id' => 'login-2026-10-17-000001',\n 'event_category' => 'auth',\n 'action_type' => 'login',\n 'occurred_at' => '2026-10-17T09:15:02.481Z',\n 'time_zone' => 'Europe/Madrid',\n 'subject' => [\n 'vendor_data' => 'user-42',\n 'entity_type' => 'individual',\n ],\n 'session' => [\n 'session_id' => 'web-session-abc',\n 'sequence' => 142,\n ],\n 'device_context' => [\n 'fingerprint' => 'fp-a8c1',\n 'network_context' => [\n 'ip_address' => '203.0.113.42',\n ],\n ],\n 'payload' => ['method' => 'password'],\n 'custom_values' => ['vip_tier' => 'gold'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create(\n event_id: \"login-2026-10-17-000001\",\n event_category: \"auth\",\n action_type: \"login\",\n occurred_at: \"2026-10-17T09:15:02.481Z\",\n time_zone: \"Europe/Madrid\",\n subject: {\n vendor_data: \"user-42\",\n entity_type: \"individual\",\n },\n session: {\n session_id: \"web-session-abc\",\n sequence: 142,\n },\n device_context: {\n fingerprint: \"fp-a8c1\",\n network_context: {\n ip_address: \"203.0.113.42\",\n },\n },\n payload: { method: \"password\" },\n custom_values: { vip_tier: \"gold\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateAsync(new MonitoringEventCreateRequest\n{\n EventId = \"login-2026-10-17-000001\",\n EventCategory = \"auth\",\n ActionType = \"login\",\n OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:15:02.481Z\"),\n TimeZone = \"Europe/Madrid\",\n Subject = new()\n {\n VendorData = \"user-42\",\n EntityType = \"individual\",\n },\n Session = new MonitoringEventCreateRequestSession\n {\n SessionId = \"web-session-abc\",\n Sequence = 142,\n },\n DeviceContext = new MonitoringEventCreateRequestDeviceContext\n {\n Fingerprint = \"fp-a8c1\",\n NetworkContext = new MonitoringEventCreateRequestDeviceContextNetworkContext\n {\n IpAddress = \"203.0.113.42\",\n },\n },\n Payload = new Dictionary { [\"method\"] = \"password\" },\n CustomValues = new Dictionary { [\"vip_tier\"] = \"gold\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -61691,7 +71444,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist. Also returned with `code: event_monitoring_disabled` while event ingestion is switched off for the application; nothing is stored in that case, and the check runs before the body is validated.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist. Also returned with `code: event_monitoring_disabled` while event ingestion is switched off for the application; nothing is stored in that case, and the check runs before the body is validated.", "content": { "application/json": { "examples": { @@ -61849,12 +71602,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nevents = [\n {\n 'event_id': 'login-2026-10-17-000001',\n 'event_category': 'auth',\n 'action_type': 'login',\n 'occurred_at': '2026-10-17T09:15:02.481Z',\n 'subject': {'vendor_data': 'user-42'},\n },\n {\n 'event_id': 'deposit-2026-10-17-000002',\n 'event_category': 'payment',\n 'action_type': 'deposit_completed',\n 'occurred_at': '2026-10-17T09:16:40.000Z',\n 'subject': {'vendor_data': 'user-42'},\n 'transaction_context': {'amount': '100.00', 'currency': 'EUR', 'payment_reference_id': 'dep_736'},\n 'payload': {'payment_method': 'card', 'status': 'completed'},\n },\n]\nresp = requests.post(\n 'https://verification.didit.me/v3/events/batch/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'events': events},\n timeout=10,\n)\nresp.raise_for_status() # 201 and 207 are both success\nbatch = resp.json()\nfor item in batch['results']:\n if item['outcome'] == 'rejected':\n print('fix and resend', events[item['index']]['event_id'], item['errors'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create_batch(\n events=[{\n \"event_id\": \"login-2026-10-17-000001\",\n \"event_category\": \"auth\",\n \"action_type\": \"login\",\n \"occurred_at\": \"2026-10-17T09:15:02.481Z\",\n \"subject\": {\n \"vendor_data\": \"user-42\",\n },\n }, {\n \"event_id\": \"deposit-2026-10-17-000002\",\n \"event_category\": \"payment\",\n \"action_type\": \"deposit_completed\",\n \"occurred_at\": \"2026-10-17T09:16:40Z\",\n \"subject\": {\n \"vendor_data\": \"user-42\",\n },\n \"transaction_context\": {\n \"amount\": \"100.00\",\n \"currency\": \"EUR\",\n \"payment_reference_id\": \"dep_736\",\n },\n \"payload\": {\"payment_method\": \"card\", \"status\": \"completed\"},\n }],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const events = [\n {\n event_id: 'login-2026-10-17-000001',\n event_category: 'auth',\n action_type: 'login',\n occurred_at: '2026-10-17T09:15:02.481Z',\n subject: { vendor_data: 'user-42' },\n },\n {\n event_id: 'deposit-2026-10-17-000002',\n event_category: 'payment',\n action_type: 'deposit_completed',\n occurred_at: '2026-10-17T09:16:40.000Z',\n subject: { vendor_data: 'user-42' },\n transaction_context: { amount: '100.00', currency: 'EUR', payment_reference_id: 'dep_736' },\n payload: { payment_method: 'card', status: 'completed' },\n },\n];\nconst resp = await fetch('https://verification.didit.me/v3/events/batch/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ events }),\n});\nif (!resp.ok) throw new Error(await resp.text()); // 201 and 207 are both ok\nconst batch = await resp.json();\nfor (const item of batch.results) {\n if (item.outcome === 'rejected') console.log('fix and resend', events[item.index].event_id, item.errors);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.createBatch({\n events: [{\n event_id: \"login-2026-10-17-000001\",\n event_category: \"auth\",\n action_type: \"login\",\n occurred_at: \"2026-10-17T09:15:02.481Z\",\n subject: {\n vendor_data: \"user-42\",\n },\n }, {\n event_id: \"deposit-2026-10-17-000002\",\n event_category: \"payment\",\n action_type: \"deposit_completed\",\n occurred_at: \"2026-10-17T09:16:40Z\",\n subject: {\n vendor_data: \"user-42\",\n },\n transaction_context: {\n amount: \"100.00\",\n currency: \"EUR\",\n payment_reference_id: \"dep_736\",\n },\n payload: { payment_method: \"card\", status: \"completed\" },\n }],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.CreateBatch(ctx, didit.MonitoringEventsCreateBatchParams{\n\tEvents: []didit.MonitoringEventCreateRequest{{\n\t\tEventID: \"login-2026-10-17-000001\",\n\t\tEventCategory: \"auth\",\n\t\tActionType: \"login\",\n\t\tOccurredAt: time.Date(2026, 10, 17, 9, 15, 2, 0, time.UTC),\n\t\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\t\tVendorData: \"user-42\",\n\t\t},\n\t}, {\n\t\tEventID: \"deposit-2026-10-17-000002\",\n\t\tEventCategory: \"payment\",\n\t\tActionType: \"deposit_completed\",\n\t\tOccurredAt: time.Date(2026, 10, 17, 9, 16, 40, 0, time.UTC),\n\t\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\t\tVendorData: \"user-42\",\n\t\t},\n\t\tTransactionContext: didit.Some(didit.MonitoringEventCreateRequestTransactionContext{\n\t\t\tAmount: didit.String(\"100.00\"),\n\t\t\tCurrency: didit.String(\"EUR\"),\n\t\t\tPaymentReferenceID: didit.String(\"dep_736\"),\n\t\t}),\n\t\tPayload: didit.Some(map[string]any{\"payment_method\": \"card\", \"status\": \"completed\"}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.time.OffsetDateTime;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventCreateRequest;\nimport me.didit.types.MonitoringEventsCreateBatchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().createBatch(MonitoringEventsCreateBatchParams.builder()\n .events(List.of(\n MonitoringEventCreateRequest.builder()\n .eventId(\"login-2026-10-17-000001\")\n .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"auth\"))\n .actionType(\"login\")\n .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:15:02.481Z\"))\n .subject(MonitoringEventCreateRequest.Subject.builder()\n .vendorData(\"user-42\")\n .build())\n .build(),\n MonitoringEventCreateRequest.builder()\n .eventId(\"deposit-2026-10-17-000002\")\n .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"payment\"))\n .actionType(\"deposit_completed\")\n .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:16:40Z\"))\n .subject(MonitoringEventCreateRequest.Subject.builder()\n .vendorData(\"user-42\")\n .build())\n .transactionContext(MonitoringEventCreateRequest.TransactionContext.builder()\n .amount(\"100.00\")\n .currency(\"EUR\")\n .paymentReferenceId(\"dep_736\")\n .build())\n .payload(Map.of(\"payment_method\", \"card\", \"status\", \"completed\"))\n .build()))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->createBatch([\n 'events' => [[\n 'event_id' => 'login-2026-10-17-000001',\n 'event_category' => 'auth',\n 'action_type' => 'login',\n 'occurred_at' => '2026-10-17T09:15:02.481Z',\n 'subject' => [\n 'vendor_data' => 'user-42',\n ],\n ], [\n 'event_id' => 'deposit-2026-10-17-000002',\n 'event_category' => 'payment',\n 'action_type' => 'deposit_completed',\n 'occurred_at' => '2026-10-17T09:16:40Z',\n 'subject' => [\n 'vendor_data' => 'user-42',\n ],\n 'transaction_context' => [\n 'amount' => '100.00',\n 'currency' => 'EUR',\n 'payment_reference_id' => 'dep_736',\n ],\n 'payload' => ['payment_method' => 'card', 'status' => 'completed'],\n ]],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create_batch(\n events: [{\n event_id: \"login-2026-10-17-000001\",\n event_category: \"auth\",\n action_type: \"login\",\n occurred_at: \"2026-10-17T09:15:02.481Z\",\n subject: {\n vendor_data: \"user-42\",\n },\n }, {\n event_id: \"deposit-2026-10-17-000002\",\n event_category: \"payment\",\n action_type: \"deposit_completed\",\n occurred_at: \"2026-10-17T09:16:40Z\",\n subject: {\n vendor_data: \"user-42\",\n },\n transaction_context: {\n amount: \"100.00\",\n currency: \"EUR\",\n payment_reference_id: \"dep_736\",\n },\n payload: { payment_method: \"card\", status: \"completed\" },\n }]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateBatchAsync(new MonitoringEventsCreateBatchParams\n{\n Events = new MonitoringEventCreateRequest[]\n {\n new()\n {\n EventId = \"login-2026-10-17-000001\",\n EventCategory = \"auth\",\n ActionType = \"login\",\n OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:15:02.481Z\"),\n Subject = new()\n {\n VendorData = \"user-42\",\n },\n },\n new()\n {\n EventId = \"deposit-2026-10-17-000002\",\n EventCategory = \"payment\",\n ActionType = \"deposit_completed\",\n OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:16:40Z\"),\n Subject = new()\n {\n VendorData = \"user-42\",\n },\n TransactionContext = new MonitoringEventCreateRequestTransactionContext\n {\n Amount = \"100.00\",\n Currency = \"EUR\",\n PaymentReferenceId = \"dep_736\",\n },\n Payload = new Dictionary { [\"payment_method\"] = \"card\", [\"status\"] = \"completed\" },\n },\n },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -62300,7 +72078,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist. Also returned with `code: event_monitoring_disabled` while event ingestion is switched off for the application; nothing is stored in that case, and the check runs before the body is validated.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist. Also returned with `code: event_monitoring_disabled` while event ingestion is switched off for the application; nothing is stored in that case, and the check runs before the body is validated.", "content": { "application/json": { "examples": { @@ -62467,12 +72245,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.post(\n 'https://verification.didit.me/v3/events/sdk-token/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'vendor_data': 'user-42',\n 'allowed_event_categories': ['auth', 'session', 'gameplay'],\n 'ttl_seconds': 900,\n 'max_uses': 1000,\n 'bind_to_origin': 'https://app.example.com',\n },\n timeout=10,\n)\nresp.raise_for_status()\ncredential = resp.json()\n# Hand only monitoring_token to the app, never the API key.\nprint(credential['monitoring_token'], credential['expires_at'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create_sdk_token(\n vendor_data=\"user-42\",\n allowed_event_categories=[\"auth\", \"session\", \"gameplay\"],\n ttl_seconds=900,\n max_uses=1000,\n bind_to_origin=\"https://app.example.com\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/events/sdk-token/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n vendor_data: 'user-42',\n allowed_event_categories: ['auth', 'session', 'gameplay'],\n ttl_seconds: 900,\n max_uses: 1000,\n bind_to_origin: 'https://app.example.com',\n }),\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst { monitoring_token, expires_at } = await resp.json();\n// Hand only monitoring_token to the app, never the API key.\nconsole.log(monitoring_token, expires_at);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.createSdkToken({\n vendor_data: \"user-42\",\n allowed_event_categories: [\"auth\", \"session\", \"gameplay\"],\n ttl_seconds: 900,\n max_uses: 1000,\n bind_to_origin: \"https://app.example.com\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.CreateSDKToken(ctx, didit.MonitoringEventsCreateSDKTokenParams{\n\tVendorData: \"user-42\",\n\tAllowedEventCategories: didit.Some([]didit.MonitoringEventsCreateSDKTokenParamsAllowedEventCategories{\"auth\", \"session\", \"gameplay\"}),\n\tTTLSeconds: didit.Int(900),\n\tMaxUses: didit.Int(1000),\n\tBindToOrigin: didit.String(\"https://app.example.com\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventsCreateSdkTokenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().createSdkToken(MonitoringEventsCreateSdkTokenParams.builder()\n .vendorData(\"user-42\")\n .allowedEventCategories(List.of(MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"auth\"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"session\"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"gameplay\")))\n .ttlSeconds(900L)\n .maxUses(1000L)\n .bindToOrigin(\"https://app.example.com\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->createSdkToken([\n 'vendor_data' => 'user-42',\n 'allowed_event_categories' => ['auth', 'session', 'gameplay'],\n 'ttl_seconds' => 900,\n 'max_uses' => 1000,\n 'bind_to_origin' => 'https://app.example.com',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create_sdk_token(\n vendor_data: \"user-42\",\n allowed_event_categories: [\"auth\", \"session\", \"gameplay\"],\n ttl_seconds: 900,\n max_uses: 1000,\n bind_to_origin: \"https://app.example.com\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateSdkTokenAsync(new MonitoringEventsCreateSdkTokenParams\n{\n VendorData = \"user-42\",\n AllowedEventCategories = new MonitoringEventsCreateSdkTokenParamsAllowedEventCategories[] { \"auth\", \"session\", \"gameplay\" },\n TtlSeconds = 900,\n MaxUses = 1000,\n BindToOrigin = \"https://app.example.com\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -62591,7 +72394,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist. Also returned with `code: event_monitoring_disabled` while event ingestion is switched off for the application; nothing is stored in that case, and the check runs before the body is validated.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist. Also returned with `code: event_monitoring_disabled` while event ingestion is switched off for the application; nothing is stored in that case, and the check runs before the body is validated.", "content": { "application/json": { "examples": { @@ -62693,12 +72496,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nevent_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/events/{event_uuid}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nevent = resp.json()\nprint(event['status'], event['score'])\nfor run in event['rule_runs']:\n print(run['rule_title'], run['score_delta'], run['action_summary'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.retrieve(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const eventUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/events/${eventUuid}/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst event = await resp.json();\nconsole.log(event.status, event.score, event.rule_runs.length, 'rule runs');" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -62857,7 +72685,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", "content": { "application/json": { "examples": { @@ -63237,12 +73065,37 @@ { "lang": "python", "label": "Python", - "source": "import os\nfrom urllib.parse import quote\n\nimport requests\n\nvendor_data = 'user-42'\nresp = requests.get(\n f'https://verification.didit.me/v3/events/subjects/{quote(vendor_data, safe=\"\")}/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'entity_type': 'individual', 'limit': 50},\n timeout=10,\n)\nresp.raise_for_status()\nfor event in resp.json()['results']:\n print(event['occurred_at'], event['event_category'], event['action_type'], event['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.monitoring_events.retrieve_subject_timeline(\n \"user-42\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const vendorData = 'user-42';\nconst url = `https://verification.didit.me/v3/events/subjects/${encodeURIComponent(vendorData)}/?entity_type=individual&limit=50`;\nconst resp = await fetch(url, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst page = await resp.json();\nfor (const event of page.results) console.log(event.occurred_at, event.event_category, event.action_type, event.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.monitoringEvents.retrieveSubjectTimeline(\"user-42\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.MonitoringEvents.RetrieveSubjectTimelineAutoPaging(ctx, \"user-42\", didit.MonitoringEventsRetrieveSubjectTimelineParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.monitoringEvents().retrieveSubjectTimeline(\"user-42\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->retrieveSubjectTimeline('user-42') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.retrieve_subject_timeline(\"user-42\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.MonitoringEvents.RetrieveSubjectTimelineAsync(\"user-42\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -63369,7 +73222,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", "content": { "application/json": { "examples": { @@ -63467,12 +73320,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nresp = requests.get(\n 'https://verification.didit.me/v3/events/enrichment-metrics/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'days': 30},\n timeout=10,\n)\nresp.raise_for_status()\nmetrics = resp.json()\nprint(metrics['events_ingested'], metrics['cache_hit_rate'], metrics['provider_calls_per_1k_events'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.retrieve_enrichment_metrics()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const resp = await fetch('https://verification.didit.me/v3/events/enrichment-metrics/?days=30', {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst metrics = await resp.json();\nconsole.log(metrics.events_ingested, metrics.cache_hit_rate, metrics.provider_calls_per_1k_events);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.retrieveEnrichmentMetrics();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.RetrieveEnrichmentMetrics(ctx, didit.MonitoringEventsRetrieveEnrichmentMetricsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().retrieveEnrichmentMetrics();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->retrieveEnrichmentMetrics();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.retrieve_enrichment_metrics\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.RetrieveEnrichmentMetricsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -63595,7 +73473,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: read`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", "content": { "application/json": { "examples": { @@ -63691,12 +73569,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nevent_uuid = '11111111-2222-3333-4444-555555555555'\nresp = requests.delete(\n f'https://verification.didit.me/v3/events/{event_uuid}/delete/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status() # 204 No Content\nprint('deleted', event_uuid)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.monitoring_events.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const eventUuid = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/events/${eventUuid}/delete/`, {\n method: 'DELETE',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (resp.status !== 204) throw new Error(`Delete failed: ${resp.status}`);\nconsole.log('deleted', eventUuid);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.monitoringEvents.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.MonitoringEvents.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.monitoringEvents().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "monitoringEvents->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.MonitoringEvents.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ], "responses": { @@ -63718,7 +73621,7 @@ } }, "403": { - "description": "Missing or invalid `x-api-key` (this endpoint answers `403`, never `401`, for a missing or invalid key), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", + "description": "A missing `x-api-key` (a wrong, revoked or expired key gets `401`), a scoped key without `transactions: write`, a key limited to some workflows or to approved sessions (such a key never reaches transaction monitoring data), or a request from outside the key's IP allowlist.", "content": { "application/json": { "examples": { @@ -63839,12 +73742,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '33333333-4444-5555-6666-777777777777'\nparty_uuid = '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41'\nresp = requests.post(\n f'https://verification.didit.me/v3/session/{session_id}/kyb/parties/{party_uuid}/regenerate/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nparty = resp.json()\nprint(party['kyc_session_id'], party['kyc_session_status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.regenerate_kyb_party(\n \"33333333-4444-5555-6666-777777777777\",\n \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '33333333-4444-5555-6666-777777777777';\nconst partyUuid = '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41';\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/kyb/parties/${partyUuid}/regenerate/`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Regenerate failed: ${resp.status}`);\nconst party = await resp.json();\nconsole.log(party.kyc_session_id, party.kyc_session_status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.regenerateKybParty(\n \"33333333-4444-5555-6666-777777777777\",\n \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RegenerateKYBParty(ctx, \"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().regenerateKybParty(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->regenerateKybParty('33333333-4444-5555-6666-777777777777', '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.regenerate_kyb_party(\n \"33333333-4444-5555-6666-777777777777\",\n \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RegenerateKybPartyAsync(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -63935,7 +73863,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -64151,12 +74079,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\ntransaction_id = 'abcdef12-3456-7890-abcd-ef1234567890'\nurl = f'https://verification.didit.me/v3/transactions/{transaction_id}/notes/'\nparams = {'limit': 50}\nwhile url:\n resp = requests.get(\n url,\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params=params,\n timeout=10,\n )\n resp.raise_for_status()\n page = resp.json()\n for note in page['results']:\n print(note['created_at'], note['actor_name'], note['note'])\n url, params = page['next'], None" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.notes.list(\n \"abcdef12-3456-7890-abcd-ef1234567890\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const transactionId = 'abcdef12-3456-7890-abcd-ef1234567890';\nlet url = `https://verification.didit.me/v3/transactions/${transactionId}/notes/?limit=50`;\nwhile (url) {\n const resp = await fetch(url, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n });\n if (!resp.ok) throw new Error(`List notes failed: ${resp.status}`);\n const page = await resp.json();\n for (const note of page.results) console.log(note.created_at, note.actor_name, note.note);\n url = page.next;\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.notes.list(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Notes.ListAutoPaging(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsNotesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().notes().list(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->notes->list('abcdef12-3456-7890-abcd-ef1234567890') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.notes.list(\"abcdef12-3456-7890-abcd-ef1234567890\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Notes.ListAsync(\"abcdef12-3456-7890-abcd-ef1234567890\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -64304,7 +74257,7 @@ } }, "403": { - "description": "The request is not allowed. A missing or invalid API key gets the generic message (never `401`).", + "description": "The request is not allowed. A missing key gets the generic message; a wrong, revoked or expired key gets `401`.", "content": { "application/json": { "schema": { @@ -64497,12 +74450,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\ntransaction_id = 'abcdef12-3456-7890-abcd-ef1234567890'\nresp = requests.post(\n f'https://verification.didit.me/v3/transactions/{transaction_id}/notes/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={\n 'note': 'Customer confirmed the withdrawal by phone.',\n 'mentioned_emails': ['analyst@example.com'],\n },\n timeout=10,\n)\nresp.raise_for_status()\nnote = resp.json()\nprint(note['uuid'], note['created_at'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.notes.create(\n \"abcdef12-3456-7890-abcd-ef1234567890\",\n note=\"Customer confirmed the withdrawal by phone.\",\n mentioned_emails=[\"analyst@example.com\"],\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const transactionId = 'abcdef12-3456-7890-abcd-ef1234567890';\nconst resp = await fetch(`https://verification.didit.me/v3/transactions/${transactionId}/notes/`, {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n note: 'Customer confirmed the withdrawal by phone.',\n mentioned_emails: ['analyst@example.com'],\n }),\n});\nif (!resp.ok) throw new Error(`Create note failed: ${resp.status}`);\nconst note = await resp.json();\nconsole.log(note.uuid, note.created_at);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.notes.create(\"abcdef12-3456-7890-abcd-ef1234567890\", {\n note: \"Customer confirmed the withdrawal by phone.\",\n mentioned_emails: [\"analyst@example.com\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Notes.Create(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsNotesCreateParams{\n\tNote: \"Customer confirmed the withdrawal by phone.\",\n\tMentionedEmails: didit.Some([]string{\"analyst@example.com\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionsNotesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().notes().create(\"abcdef12-3456-7890-abcd-ef1234567890\", TransactionsNotesCreateParams.builder()\n .note(\"Customer confirmed the withdrawal by phone.\")\n .mentionedEmails(List.of(\"analyst@example.com\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->notes->create('abcdef12-3456-7890-abcd-ef1234567890', [\n 'note' => 'Customer confirmed the withdrawal by phone.',\n 'mentioned_emails' => ['analyst@example.com'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.notes.create(\n \"abcdef12-3456-7890-abcd-ef1234567890\",\n note: \"Customer confirmed the withdrawal by phone.\",\n mentioned_emails: [\"analyst@example.com\"]\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Notes.CreateAsync(\"abcdef12-3456-7890-abcd-ef1234567890\", new TransactionsNotesCreateParams\n{\n Note = \"Customer confirmed the withdrawal by phone.\",\n MentionedEmails = new string[] { \"analyst@example.com\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -64599,7 +74577,7 @@ } }, "403": { - "description": "The request is not allowed. A missing or invalid API key gets the generic message (never `401`).", + "description": "The request is not allowed. A missing key gets the generic message; a wrong, revoked or expired key gets `401`.", "content": { "application/json": { "schema": { @@ -64774,12 +74752,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\ntransaction_id = 'abcdef12-3456-7890-abcd-ef1234567890'\nresp = requests.get(\n f'https://verification.didit.me/v3/transactions/{transaction_id}/related/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'limit': 50},\n timeout=10,\n)\nresp.raise_for_status()\nfor tx in resp.json()['results']:\n print(tx['uuid'], tx['txn_date'], tx['status'], tx['amount'], tx['currency'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.list_related(\n \"abcdef12-3456-7890-abcd-ef1234567890\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const transactionId = 'abcdef12-3456-7890-abcd-ef1234567890';\nconst resp = await fetch(\n `https://verification.didit.me/v3/transactions/${transactionId}/related/?limit=50`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(`Related lookup failed: ${resp.status}`);\nconst page = await resp.json();\nfor (const tx of page.results) console.log(tx.uuid, tx.status, tx.amount, tx.currency);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.listRelated(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.ListRelatedAutoPaging(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsListRelatedParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().listRelated(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->listRelated('abcdef12-3456-7890-abcd-ef1234567890') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.list_related(\"abcdef12-3456-7890-abcd-ef1234567890\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.ListRelatedAsync(\"abcdef12-3456-7890-abcd-ef1234567890\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -64927,7 +74930,7 @@ } }, "403": { - "description": "The request is not allowed. A missing or invalid API key gets the generic message (never `401`).", + "description": "The request is not allowed. A missing key gets the generic message; a wrong, revoked or expired key gets `401`.", "content": { "application/json": { "schema": { @@ -65101,12 +75104,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\norg_id = '11111111-2222-3333-4444-555555555555'\napp_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'\nbusiness_session_id = '22222222-3333-4444-5555-666666666666'\nresp = requests.get(\n f'https://verification.didit.me/v3/organization/{org_id}/application/{app_id}'\n f'/businesses/{business_session_id}/pdf/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=60,\n)\nresp.raise_for_status()\nwith open(f'business_{business_session_id}.pdf', 'wb') as fh:\n fh.write(resp.content)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.businesses.generate_session_pdf(\n \"22222222-3333-4444-5555-666666666666\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { writeFile } from 'node:fs/promises';\n\nconst orgId = '11111111-2222-3333-4444-555555555555';\nconst appId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\nconst businessSessionId = '22222222-3333-4444-5555-666666666666';\nconst resp = await fetch(\n `https://verification.didit.me/v3/organization/${orgId}/application/${appId}/businesses/${businessSessionId}/pdf/`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(`PDF generation failed: ${resp.status}`);\nawait writeFile(`business_${businessSessionId}.pdf`, Buffer.from(await resp.arrayBuffer()));" + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.businesses.generateSessionPdf(\"22222222-3333-4444-5555-666666666666\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Businesses.GenerateSessionPDF(ctx, \"22222222-3333-4444-5555-666666666666\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.businesses().generateSessionPdf(\"22222222-3333-4444-5555-666666666666\")\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "businesses->generateSessionPdf('22222222-3333-4444-5555-666666666666');\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.businesses.generate_session_pdf(\"22222222-3333-4444-5555-666666666666\")\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Businesses.GenerateSessionPdfAsync(\"22222222-3333-4444-5555-666666666666\");\nawait content.SaveToAsync(\"download.pdf\");" } ], "responses": { @@ -65153,7 +75181,7 @@ } }, "403": { - "description": "The request is not allowed or the session is not finished. Read `detail`: a session that is not `Approved`, `Declined` or `In Review`, a missing or invalid API key (never `401`), an `application_id` that is not the key's application, a scoped key without `media: read` or `businesses: read`, a key limited to workflows or approved sessions, or a request from outside the key's IP list.", + "description": "The request is not allowed or the session is not finished. Read `detail`: a session that is not `Approved`, `Declined` or `In Review`, a missing API key (a wrong, revoked or expired key gets `401`), an `application_id` that is not the key's application, a scoped key without `media: read` or `businesses: read`, a key limited to workflows or approved sessions, or a request from outside the key's IP list.", "content": { "application/json": { "schema": { @@ -65342,12 +75370,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\norg_id = '11111111-2222-3333-4444-555555555555'\napp_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'\ntransaction_uuid = 'abcdef12-3456-7890-abcd-ef1234567890'\nresp = requests.get(\n f'https://verification.didit.me/v3/organization/{org_id}/application/{app_id}'\n f'/transactions/{transaction_uuid}/pdf/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=60,\n)\nresp.raise_for_status()\nwith open(f'transaction_{transaction_uuid}.pdf', 'wb') as fh:\n fh.write(resp.content)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.transactions.generate_pdf(\n \"abcdef12-3456-7890-abcd-ef1234567890\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n file.write(content)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { writeFile } from 'node:fs/promises';\n\nconst orgId = '11111111-2222-3333-4444-555555555555';\nconst appId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\nconst transactionUuid = 'abcdef12-3456-7890-abcd-ef1234567890';\nconst resp = await fetch(\n `https://verification.didit.me/v3/organization/${orgId}/application/${appId}/transactions/${transactionUuid}/pdf/`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(`PDF generation failed: ${resp.status}`);\nawait writeFile(`transaction_${transactionUuid}.pdf`, Buffer.from(await resp.arrayBuffer()));" + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.transactions.generatePdf(\"abcdef12-3456-7890-abcd-ef1234567890\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Transactions.GeneratePDF(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.transactions().generatePdf(\"abcdef12-3456-7890-abcd-ef1234567890\")\n .writeTo(Path.of(\"download.pdf\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->generatePdf('abcdef12-3456-7890-abcd-ef1234567890');\n$content->saveTo('download.pdf');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.transactions.generate_pdf(\"abcdef12-3456-7890-abcd-ef1234567890\")\nFile.binwrite(\"download.pdf\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Transactions.GeneratePdfAsync(\"abcdef12-3456-7890-abcd-ef1234567890\");\nawait content.SaveToAsync(\"download.pdf\");" } ], "responses": { @@ -65394,7 +75447,7 @@ } }, "403": { - "description": "The request is not allowed. Read `detail`: a missing or invalid API key (never `401`), an `application_id` that is not the key's application, a scoped key without `media: read` or `transactions: read`, a key limited to workflows or approved sessions, or a request from outside the key's IP list.", + "description": "The request is not allowed. Read `detail`: a missing API key (a wrong, revoked or expired key gets `401`), an `application_id` that is not the key's application, a scoped key without `media: read` or `transactions: read`, a key limited to workflows or approved sessions, or a request from outside the key's IP list.", "content": { "application/json": { "schema": { @@ -65673,12 +75726,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\norg_id = '11111111-2222-3333-4444-555555555555'\napp_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'\nresp = requests.get(\n f'https://verification.didit.me/v3/organization/{org_id}/application/{app_id}/analytics/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'start_date': '2026-10-01', 'end_date': '2026-10-15'},\n timeout=10,\n)\nresp.raise_for_status()\ndata = resp.json()\nprint(data['request_breakdown']['total_approved'], data['conversion_rate'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.analytics.retrieve()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const orgId = '11111111-2222-3333-4444-555555555555';\nconst appId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\nconst params = new URLSearchParams({ start_date: '2026-10-01', end_date: '2026-10-15' });\nconst resp = await fetch(\n `https://verification.didit.me/v3/organization/${orgId}/application/${appId}/analytics/?${params}`,\n { headers: { 'x-api-key': process.env.DIDIT_API_KEY } },\n);\nif (!resp.ok) throw new Error(`Analytics failed: ${resp.status}`);\nconst data = await resp.json();\nconsole.log(data.request_breakdown.total_approved, data.conversion_rate);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.analytics.retrieve();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Analytics.Retrieve(ctx, didit.AnalyticsRetrieveParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.analytics().retrieve();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "analytics->retrieve();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.analytics.retrieve\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Analytics.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -66185,6 +76263,277 @@ } } }, + "403": { + "description": "The request is not allowed. Read `detail`: a missing API key (a wrong, revoked or expired key gets `401`), a key of another application, any scoped key, or a request from outside the key's IP list.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string" + } + } + }, + "examples": { + "Missing or invalid key": { + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Another application": { + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key": { + "value": { + "detail": "This API key has no access to this endpoint." + } + }, + "Outside the key's IP list": { + "value": { + "detail": "This API key can't be used from this IP address." + } + } + } + } + } + }, + "429": { + "description": "More than 600 GET requests per minute with this API key. Wait the number of seconds in `Retry-After`, then retry.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string" + } + } + }, + "examples": { + "Throttled": { + "value": { + "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute." + } + } + } + } + }, + "headers": { + "Retry-After": { + "description": "Seconds until the current one-minute window resets.", + "schema": { + "type": "integer", + "example": 23 + } + }, + "X-RateLimit-Limit": { + "description": "Requests allowed per minute in this budget.", + "schema": { + "type": "integer" + } + }, + "X-RateLimit-Remaining": { + "description": "Requests left in the current window.", + "schema": { + "type": "integer" + } + }, + "X-RateLimit-Reset": { + "description": "Unix time when the window resets.", + "schema": { + "type": "integer" + } + } + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + } + }, + "/v3/organization/{organization_id}/application/{application_id}/analytics/today/": { + "get": { + "summary": "Get today's verifications by hour", + "operationId": "get_application_analytics_today", + "x-didit-sdk": { + "resource": "analytics", + "method": "retrieve_today", + "auth": "api_key", + "server": true, + "scope": "application" + }, + "tags": [ + "Analytics" + ], + "description": "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.\n\n`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.", + "parameters": [ + { + "name": "organization_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Organization UUID.", + "example": "11111111-2222-3333-4444-555555555555" + }, + { + "name": "application_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "Application UUID. Must be the application the API key belongs to: a key used on any other application gets `403`.", + "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + }, + { + "name": "tz", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "UTC", + "example": "Europe/Madrid" + }, + "description": "IANA time zone whose midnight starts today, for example `Europe/Madrid` or `America/Mexico_City`. Omit it for UTC." + } + ], + "responses": { + "200": { + "description": "Today's verifications by local hour, the comparison day's, and today's outcomes.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplicationAnalyticsToday" + }, + "examples": { + "Madrid, 14:00": { + "value": { + "time_zone": "Europe/Madrid", + "date": "2026-10-30", + "current_hour": 14, + "previous_date": "2026-10-23", + "hours": [ + 3, + 1, + 0, + 0, + 1, + 2, + 4, + 9, + 14, + 18, + 21, + 19, + 22, + 24, + 27, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "previous_hours": [ + 2, + 1, + 1, + 0, + 1, + 3, + 5, + 8, + 12, + 16, + 19, + 18, + 20, + 22, + 24, + 26, + 23, + 19, + 15, + 12, + 9, + 7, + 5, + 3 + ], + "total": 165, + "previous_total_so_far": 151, + "outcomes": { + "approved": 139, + "in_review": 6, + "declined": 18 + } + } + } + } + } + } + }, + "400": { + "description": "Unknown time zone. The body is keyed by the parameter, with a list of messages.", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "examples": { + "Unknown time zone": { + "value": { + "tz": [ + "Unknown time zone: Europe/Atlantis." + ] + } + } + } + } + } + }, + "401": { + "description": "The API key has expired. Only a key created with an expiry date can expire; after that date every request with it answers `401`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string" + } + } + }, + "examples": { + "Expired key": { + "value": { + "detail": "This API key has expired." + } + } + } + } + } + }, "403": { "description": "The request is not allowed. Read `detail`: a missing or invalid API key (never `401`), a key of another application, any scoped key, or a request from outside the key's IP list.", "content": { @@ -66272,6 +76621,13 @@ } } }, + "x-codeSamples": [ + { + "lang": "curl", + "label": "curl", + "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/analytics/today/?tz=Europe%2FMadrid' \\\n -H 'x-api-key: YOUR_API_KEY'" + } + ], "security": [ { "ApiKeyAuth": [] @@ -66315,12 +76671,37 @@ { "lang": "python", "label": "Python", - "source": "import json\nimport os\n\nimport requests\n\nsession_id = '22222222-3333-4444-5555-666666666666'\nresp = requests.get(\n f'https://verification.didit.me/v3/session/{session_id}/webhooks/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nfor delivery in resp.json():\n payload = json.loads(delivery['request_body'])\n print(delivery['created_at'], delivery['webhook_type'], delivery['response_status'], payload['event_id'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.list(\n \"22222222-3333-4444-5555-666666666666\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '22222222-3333-4444-5555-666666666666';\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/webhooks/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst deliveries = await resp.json();\nfor (const delivery of deliveries) {\n const payload = JSON.parse(delivery.request_body);\n console.log(delivery.created_at, delivery.webhook_type, delivery.response_status, payload.event_id);\n}" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.list(\"22222222-3333-4444-5555-666666666666\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.List(ctx, \"22222222-3333-4444-5555-666666666666\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().list(\"22222222-3333-4444-5555-666666666666\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->webhooks->list('22222222-3333-4444-5555-666666666666');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.webhooks.list(\"22222222-3333-4444-5555-666666666666\").each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.ListAsync(\"22222222-3333-4444-5555-666666666666\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -66369,7 +76750,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -66578,12 +76959,37 @@ { "lang": "python", "label": "Python", - "source": "import json\nimport os\n\nimport requests\n\nsession_id = '22222222-3333-4444-5555-666666666666'\nwebhook_uuid = '66666666-7777-8888-9999-000000000001'\nresp = requests.get(\n f'https://verification.didit.me/v3/session/{session_id}/webhook/{webhook_uuid}', # no trailing slash\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\ndelivery = resp.json()\nheaders = json.loads(delivery['request_header'])\npayload = json.loads(delivery['request_body'])\nprint(delivery['response_status'], headers['X-Signature-V2'], payload['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.retrieve(\n \"22222222-3333-4444-5555-666666666666\",\n \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '22222222-3333-4444-5555-666666666666';\nconst webhookUuid = '66666666-7777-8888-9999-000000000001';\n// No trailing slash on this path.\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/webhook/${webhookUuid}`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst delivery = await resp.json();\nconst payload = JSON.parse(delivery.request_body);\nconsole.log(delivery.response_status, payload.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.retrieve(\n \"22222222-3333-4444-5555-666666666666\",\n \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.Retrieve(ctx, \"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().retrieve(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->webhooks->retrieve('22222222-3333-4444-5555-666666666666', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.webhooks.retrieve(\n \"22222222-3333-4444-5555-666666666666\",\n \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.RetrieveAsync(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -66613,7 +77019,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -66827,12 +77233,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '22222222-3333-4444-5555-666666666666'\nwebhook_uuid = '66666666-7777-8888-9999-000000000001'\nresp = requests.post(\n f'https://verification.didit.me/v3/session/{session_id}/webhook/{webhook_uuid}/resend', # no trailing slash\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nresent = resp.json()\nprint(resent['uuid'], resent['response_status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.resend(\n \"22222222-3333-4444-5555-666666666666\",\n \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '22222222-3333-4444-5555-666666666666';\nconst webhookUuid = '66666666-7777-8888-9999-000000000001';\n// No trailing slash on this path.\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/webhook/${webhookUuid}/resend`, {\n method: 'POST',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(await resp.text());\nconst resent = await resp.json();\nconsole.log(resent.uuid, resent.response_status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.resend(\n \"22222222-3333-4444-5555-666666666666\",\n \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.Resend(ctx, \"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().resend(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->webhooks->resend('22222222-3333-4444-5555-666666666666', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.webhooks.resend(\n \"22222222-3333-4444-5555-666666666666\",\n \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.ResendAsync(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -66896,7 +77327,7 @@ } }, "401": { - "description": "The API key has expired: it was created with an expiry date that has passed. A missing, invalid or revoked key gets `403`, not `401`.", + "description": "The API key has expired: it was created with an expiry date that has passed. A wrong or revoked key also gets `401`; a missing key gets `403`.", "content": { "application/json": { "schema": { @@ -67135,12 +77566,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/session/{session_id}/events/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n params={'limit': 50},\n timeout=10,\n)\nresp.raise_for_status()\nfor event in resp.json()['results']:\n print(event['sent_at'], event['event_type'], event['step'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list_events(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/events/?limit=50`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst page = await resp.json();\nfor (const event of page.results) console.log(event.sent_at, event.event_type, event.step);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.listEvents(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListEventsAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsListEventsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().listEvents(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->listEvents('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list_events(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListEventsAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -67297,7 +77753,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -67419,7 +77875,7 @@ "/v3/session/{sessionId}/aml-screening-history/": { "get": { "summary": "List AML screening history", - "description": "List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`, including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves, so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed (the first screening is part of the session decision) and runs from before this history existed are not reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and capped at 100 above that, so follow `next` until it is `null`. A scoped API key needs `decisions: read`; see [Continuous AML monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening).", + "description": "List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`, including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves, so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed (the first screening is part of the session decision) and runs from before this history existed are not reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and capped at 100 above that, so follow `next` until it is `null`. Pass `month` to read one calendar month at a time. A scoped API key needs `decisions: read`; see [Continuous AML monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening).", "operationId": "get_v3_session_aml_screening_history", "x-didit-sdk": { "resource": "sessions", @@ -67452,6 +77908,17 @@ "example": "feature_aml_1" } }, + { + "name": "month", + "in": "query", + "required": false, + "description": "A UTC calendar month as `YYYY-MM`. Only screenings completed in that month are returned; without it every month is returned. A malformed month returns `400`.", + "schema": { + "type": "string", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])$", + "example": "2026-09" + } + }, { "name": "limit", "in": "query", @@ -67498,12 +77965,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/session/{session_id}/aml-screening-history/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nfor run in resp.json()['results']:\n print(run['completed_at'], run['outcome'], run['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list_aml_screening_history(\n \"11111111-2222-3333-4444-555555555555\",\n):\n print(item)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/aml-screening-history/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Request failed: ${resp.status}`);\nconst page = await resp.json();\nfor (const run of page.results) console.log(run.completed_at, run.outcome, run.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.listAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListAMLScreeningHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsListAMLScreeningHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().listAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->listAmlScreeningHistory('11111111-2222-3333-4444-555555555555') as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list_aml_screening_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListAmlScreeningHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -67554,6 +78046,7 @@ "results": [ { "uuid": "dddddddd-1111-2222-3333-444444444444", + "run_id": "aaaaaaaa-1111-2222-3333-444444444444", "completed_at": "2026-09-14T04:12:33.481207Z", "started_at": "2026-09-14T04:00:01.002311Z", "outcome": "NO_CHANGE", @@ -67562,6 +78055,8 @@ "status": "Approved", "score": 0.0, "total_hits": 0, + "new_hits": 0, + "entities_screened": 1, "dataset_freshness": { "captured_at": "2026-09-14T03:58:02.114820+00:00", "provider": "aml_data_source", @@ -67590,6 +78085,7 @@ }, { "uuid": "eeeeeeee-1111-2222-3333-444444444444", + "run_id": "bbbbbbbb-1111-2222-3333-444444444444", "completed_at": "2026-09-13T04:11:58.020914Z", "started_at": "2026-09-13T04:00:00.871022Z", "outcome": "FAILED", @@ -67598,6 +78094,8 @@ "status": "Approved", "score": 0.0, "total_hits": 0, + "new_hits": null, + "entities_screened": 0, "dataset_freshness": null } ] @@ -67608,7 +78106,7 @@ } }, "400": { - "description": "`limit` or `offset` is above 1,000,000. The body is a JSON array with one message.", + "description": "`limit` or `offset` is above 1,000,000 (a JSON array with one message), or `month` is not a `YYYY-MM` calendar month (an object keyed by `month`).", "content": { "application/json": { "examples": { @@ -67623,13 +78121,36 @@ "value": [ "offset must not exceed 1000000." ] + }, + "Malformed month": { + "summary": "month=2026-13", + "value": { + "month": [ + "Not a calendar month. Use YYYY-MM." + ] + } } }, "schema": { - "type": "array", - "items": { - "type": "string" - } + "oneOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "object", + "properties": { + "month": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + ] } } } @@ -67659,7 +78180,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -67787,7 +78308,7 @@ "/v3/session/{sessionId}/aml-screening-history/export/": { "get": { "summary": "Export AML screening history as CSV", - "description": "Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated, and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Errors are returned as JSON, not CSV. A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media: read` gets `403`.", + "description": "Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated, and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Pass `month` to export one calendar month. Errors are returned as JSON, not CSV. A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media: read` gets `403`.", "operationId": "get_v3_session_aml_screening_history_export", "x-didit-sdk": { "resource": "sessions", @@ -67819,6 +78340,17 @@ "type": "string", "example": "feature_aml_1" } + }, + { + "name": "month", + "in": "query", + "required": false, + "description": "A UTC calendar month as `YYYY-MM`. Only screenings completed in that month are returned; without it every month is returned. A malformed month returns `400`.", + "schema": { + "type": "string", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])$", + "example": "2026-09" + } } ], "x-codeSamples": [ @@ -67830,20 +78362,45 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '11111111-2222-3333-4444-555555555555'\nresp = requests.get(\n f'https://verification.didit.me/v3/session/{session_id}/aml-screening-history/export/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n timeout=10,\n)\nresp.raise_for_status()\nwith open('aml-screening-history.csv', 'wb') as fh:\n fh.write(resp.content)" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.export_aml_screening_history(\n \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.csv\", \"wb\") as file:\n file.write(content)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { writeFile } from 'node:fs/promises';\n\nconst sessionId = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/aml-screening-history/export/`, {\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n});\nif (!resp.ok) throw new Error(`Export failed: ${resp.status}`);\nawait writeFile('aml-screening-history.csv', await resp.text());" + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.exportAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.ExportAMLScreeningHistory(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsExportAMLScreeningHistoryParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().exportAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")\n .writeTo(Path.of(\"download.csv\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->exportAmlScreeningHistory('11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.csv');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.export_aml_screening_history(\"11111111-2222-3333-4444-555555555555\")\nFile.binwrite(\"download.csv\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.ExportAmlScreeningHistoryAsync(\"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.csv\");" } ], "responses": { "200": { - "description": "The CSV file, streamed as `text/csv` with CRLF line endings. Columns, in order: `screened_at` (when the re-screen finished), `outcome` (`NO_CHANGE`, `CHANGED` or `FAILED`), `provider` (opaque identifier of the AML data source; do not branch on it), `aml_status`, `aml_score`, `total_hits`, `datasets_captured_at`, `datasets_sanctions_last_updated_at`, `datasets_pep_last_updated_at`, `datasets_warnings_last_updated_at`, `datasets_adverse_media_last_updated_at` and `datasets_catalog_version`. Dates are ISO 8601 with a UTC offset. A session with no re-screens yet returns the header line only.", + "description": "The CSV file, streamed as `text/csv` with CRLF line endings. Columns, in order: `screened_at` (when the re-screen finished), `outcome` (`NO_CHANGE`, `CHANGED` or `FAILED`), `provider` (opaque identifier of the AML data source; do not branch on it), `aml_status`, `aml_score`, `total_hits`, `datasets_captured_at`, `datasets_sanctions_last_updated_at`, `datasets_pep_last_updated_at`, `datasets_warnings_last_updated_at`, `datasets_adverse_media_last_updated_at`, `datasets_catalog_version`, `run_id` (the monitoring run), `entities_screened` (`1`, or `0` for a failed run) and `new_hits` (empty when unknown). Dates are ISO 8601 with a UTC offset. A session with no re-screens yet returns the header line only.", "headers": { "Content-Disposition": { - "description": "`attachment; filename=\"aml-screening-history-{sessionId}.csv\"`.", + "description": "`attachment; filename=\"aml-screening-history-{sessionId}.csv\"`, or `aml-screening-history-{sessionId}-{month}.csv` when `month` is passed.", "schema": { "type": "string", "example": "attachment; filename=\"aml-screening-history-11111111-2222-3333-4444-555555555555.csv\"" @@ -67856,7 +78413,35 @@ "type": "string", "format": "binary" }, - "example": "screened_at,outcome,provider,aml_status,aml_score,total_hits,datasets_captured_at,datasets_sanctions_last_updated_at,datasets_pep_last_updated_at,datasets_warnings_last_updated_at,datasets_adverse_media_last_updated_at,datasets_catalog_version\r\n2026-09-14T04:12:33.481207+00:00,NO_CHANGE,aml_data_source,Approved,0.0,0,2026-09-14T03:58:02.114820+00:00,2026-09-13T21:10:00+00:00,2026-09-13T08:00:00+00:00,2026-09-12T18:45:00+00:00,,2026-09-13\r\n2026-09-13T04:11:58.020914+00:00,FAILED,aml_data_source,Approved,0.0,0,,,,,,\r\n" + "example": "screened_at,outcome,provider,aml_status,aml_score,total_hits,datasets_captured_at,datasets_sanctions_last_updated_at,datasets_pep_last_updated_at,datasets_warnings_last_updated_at,datasets_adverse_media_last_updated_at,datasets_catalog_version,run_id,entities_screened,new_hits\r\n2026-09-14T04:12:33.481207+00:00,NO_CHANGE,aml_data_source,Approved,0.0,0,2026-09-14T03:58:02.114820+00:00,2026-09-13T21:10:00+00:00,2026-09-13T08:00:00+00:00,2026-09-12T18:45:00+00:00,,2026-09-13,aaaaaaaa-1111-2222-3333-444444444444,1,0\r\n2026-09-13T04:11:58.020914+00:00,FAILED,aml_data_source,Approved,0.0,0,,,,,,,bbbbbbbb-1111-2222-3333-444444444444,0,\r\n" + } + } + }, + "400": { + "description": "`month` is not a `YYYY-MM` calendar month.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "month": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "examples": { + "Malformed month": { + "summary": "month=2026-13", + "value": { + "month": [ + "Not a calendar month. Use YYYY-MM." + ] + } + } + } } } }, @@ -67885,7 +78470,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -68090,12 +78675,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '11111111-2222-3333-4444-555555555555'\nwith open('back-of-id.jpg', 'rb') as fh:\n resp = requests.patch(\n f'https://verification.didit.me/v3/session/{session_id}/add-images/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n files={'file': ('back-of-id.jpg', fh, 'image/jpeg')},\n data={'model_type': 'kyc'},\n timeout=10,\n )\nresp.raise_for_status()\nprint(resp.json()['extra_files'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.add_images(\n \"11111111-2222-3333-4444-555555555555\",\n file=open(\"image.jpg\", \"rb\"),\n model_type=\"kyc\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "import { readFile } from 'node:fs/promises';\n\nconst sessionId = '11111111-2222-3333-4444-555555555555';\nconst form = new FormData();\nform.append('file', new Blob([await readFile('./back-of-id.jpg')], { type: 'image/jpeg' }), 'back-of-id.jpg');\nform.append('model_type', 'kyc');\n\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/add-images/`, {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY },\n body: form,\n});\nif (!resp.ok) throw new Error(`Upload failed: ${resp.status}`);\nconst { extra_files: extraFiles } = await resp.json();\nconsole.log(extraFiles);" + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.addImages(\"11111111-2222-3333-4444-555555555555\", {\n file: await fileFromPath(\"image.jpg\"),\n model_type: \"kyc\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.AddImages(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsAddImagesParams{\n\tFile: didit.FileFromPath(\"image.jpg\"),\n\tModelType: \"kyc\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.SessionsAddImagesParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().addImages(\"11111111-2222-3333-4444-555555555555\", SessionsAddImagesParams.builder()\n .file(Path.of(\"image.jpg\"))\n .modelType(SessionsAddImagesParams.ModelType.of(\"kyc\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->addImages('11111111-2222-3333-4444-555555555555', [\n 'file' => File::fromPath('image.jpg'),\n 'model_type' => 'kyc',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.add_images(\n \"11111111-2222-3333-4444-555555555555\",\n file: Pathname(\"image.jpg\"),\n model_type: \"kyc\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.AddImagesAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsAddImagesParams\n{\n File = FileUpload.FromPath(\"image.jpg\"),\n ModelType = \"kyc\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -68214,7 +78824,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -68426,12 +79036,37 @@ { "lang": "python", "label": "Python", - "source": "import os\n\nimport requests\n\nsession_id = '11111111-2222-3333-4444-555555555555'\nresp = requests.patch(\n f'https://verification.didit.me/v3/session/{session_id}/update-aml-status/',\n headers={'x-api-key': os.environ['DIDIT_API_KEY']},\n json={'status': 'Approved'},\n timeout=10,\n)\nresp.raise_for_status()\nbody = resp.json()\nprint(body['previous_status'], '->', body['status'])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_aml_status(\n \"11111111-2222-3333-4444-555555555555\",\n status=\"Approved\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const sessionId = '11111111-2222-3333-4444-555555555555';\nconst resp = await fetch(`https://verification.didit.me/v3/session/${sessionId}/update-aml-status/`, {\n method: 'PATCH',\n headers: { 'x-api-key': process.env.DIDIT_API_KEY, 'Content-Type': 'application/json' },\n body: JSON.stringify({ status: 'Approved' }),\n});\nif (!resp.ok) throw new Error(`Update failed: ${resp.status}`);\nconst body = await resp.json();\nconsole.log(body.previous_status, '->', body.status);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateAmlStatus(\"11111111-2222-3333-4444-555555555555\", {\n status: \"Approved\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateAMLStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateAMLStatusParams{\n\tStatus: \"Approved\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateAmlStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateAmlStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateAmlStatusParams.builder()\n .status(SessionsUpdateAmlStatusParams.Status.of(\"Approved\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateAmlStatus('11111111-2222-3333-4444-555555555555', [\n 'status' => 'Approved',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_aml_status(\n \"11111111-2222-3333-4444-555555555555\",\n status: \"Approved\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateAmlStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateAmlStatusParams\n{\n Status = \"Approved\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -68533,7 +79168,7 @@ } }, "403": { - "description": "Authentication or authorization failure. Missing, invalid and revoked keys return `403` (not `401`); so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist. Distinguish them by `detail`.", + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", "content": { "application/json": { "schema": { @@ -68862,7 +79497,7 @@ "/v3/organization/bank-verification-pricing/": { "get": { "summary": "Get bank verification prices (public, unauthenticated)", - "description": "Returns the list price of each Bank Verification method in every country: bank sign-in with its balance and transactions add-ons, and the account check. Use it to quote a bank step before you build a workflow, or to show bank prices in your own product.\n\nPublic: send no auth header. The response contains no organization data and is the same for every caller. It is cached publicly for one hour and carries an `ETag`, so send `If-None-Match` to get a `304 Not Modified` when nothing changed.\n\nA method is `available` only where Didit serves it in production today, and its `price_usd` is `null` everywhere else, so the feed never shows a price you cannot buy. `available: false` covers a country with no approved price, a method the country does not support, and a route that is not switched on yet.\n\nThese are list prices before your plan discount. Your plan discount applies to the whole bank price, and a negotiated or contract price replaces the list price for your organization.", + "description": "Returns the list price of each Bank Verification method in every country: bank sign-in with its balance and transactions add-ons, and the account check. Bank Verification is not enabled in production yet, so a bank step is refused on production workflows until it is; treat these prices as a list price, not as an offer you can buy today. Use it to quote a bank step before you build a workflow, or to show bank prices in your own product.\n\nPublic: send no auth header. The response contains no organization data and is the same for every caller. It is cached publicly for one hour and carries an `ETag`, so send `If-None-Match` to get a `304 Not Modified` when nothing changed.\n\nA method is `available` only where Didit serves it in production today, and its `price_usd` is `null` everywhere else, so the feed never shows a price you cannot buy. `available: false` covers a country with no approved price, a method the country does not support, and a route that is not switched on yet.\n\nThese are list prices before your plan discount. Your plan discount applies to the whole bank price, and a negotiated or contract price replaces the list price for your organization.", "operationId": "get_v3_bank_verification_pricing", "tags": [ "Pricing" @@ -68880,12 +79515,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresp = requests.get('https://verification.didit.me/v3/organization/bank-verification-pricing/', timeout=10)\nresp.raise_for_status()\nfeed = resp.json()\nfor iso3, country in feed['countries'].items():\n sign_in = country['methods']['open_banking']\n if sign_in['available']:\n print(iso3, country['name'], sign_in['price_usd'])" + "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.pricing.bank_verification()\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const feed = await fetch('https://verification.didit.me/v3/organization/bank-verification-pricing/').then((r) => r.json());\nconst gbr = feed.countries.GBR.methods;\nconsole.log(gbr.open_banking.available ? gbr.open_banking.price_usd : 'Not available');\nconsole.log(gbr.account_lookup.available ? gbr.account_lookup.price_usd : 'Not available');" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.pricing.bankVerification();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Pricing.BankVerification(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.pricing().bankVerification();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "pricing->bankVerification();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.pricing.bank_verification\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Pricing.BankVerificationAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-sdk": { @@ -69098,7 +79758,7 @@ } }, "403": { - "description": "Missing or invalid credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", + "description": "Missing credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", "content": { "application/json": { "examples": { @@ -69149,7 +79809,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/simulate/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json={\"scenario\": \"decline_aml_hit\", \"send_webhooks\": False},\n)\nresponse.raise_for_status()\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.simulate(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n scenario=\"decline_aml_hit\",\n send_webhooks=False,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.simulate(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n scenario: \"decline_aml_hit\",\n send_webhooks: false,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Simulate(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.SandboxSimulateRequest{\n\tScenario: didit.String(\"decline_aml_hit\"),\n\tSendWebhooks: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SandboxSimulateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().simulate(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", SandboxSimulateRequest.builder()\n .scenario(\"decline_aml_hit\")\n .sendWebhooks(false)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->simulate('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n 'scenario' => 'decline_aml_hit',\n 'send_webhooks' => false,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.simulate(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n scenario: \"decline_aml_hit\",\n send_webhooks: false\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.SimulateAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new SandboxSimulateRequest\n{\n Scenario = \"decline_aml_hit\",\n SendWebhooks = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-sdk": { @@ -69470,7 +80160,7 @@ } }, "403": { - "description": "Missing or invalid credentials, a caller without the `read:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", + "description": "Missing credentials, a caller without the `read:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", "content": { "application/json": { "examples": { @@ -69521,7 +80211,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.get(\n \"https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/features/overrides/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n)\nresponse.raise_for_status()\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_feature_overrides(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listFeatureOverrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListFeatureOverrides(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listFeatureOverrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->listFeatureOverrides('3fa85f64-5717-4562-b3fc-2c963f66afa6');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_feature_overrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListFeatureOverridesAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-sdk": { @@ -69621,7 +80341,7 @@ } }, "403": { - "description": "Missing or invalid credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", + "description": "Missing credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", "content": { "application/json": { "examples": { @@ -69694,7 +80414,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/features/overrides/9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3/cancel/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n)\nresponse.raise_for_status()\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.cancel_feature_override(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.cancelFeatureOverride(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.CancelFeatureOverride(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().cancelFeatureOverride(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->cancelFeatureOverride('3fa85f64-5717-4562-b3fc-2c963f66afa6', '9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.cancel_feature_override(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CancelFeatureOverrideAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-sdk": { @@ -69769,6 +80519,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/tags/add/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"tag_uuid\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.add_tag(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n tag_uuid=\"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.addTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.AddTag(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.NetworkTagRequest{\n\tTagUUID: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.NetworkTagRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().addTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", NetworkTagRequest.builder()\n .tagUuid(\"7c9e6679-7425-40de-944b-e07fc1f90ae7\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->addTag('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n 'tag_uuid' => '7c9e6679-7425-40de-944b-e07fc1f90ae7',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.add_tag(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.AddTagAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new NetworkTagRequest\n{\n TagUuid = \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -70248,6 +81033,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/tags/remove/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"tag_uuid\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.remove_tag(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n tag_uuid=\"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.removeTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RemoveTag(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.NetworkTagRequest{\n\tTagUUID: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.NetworkTagRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().removeTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", NetworkTagRequest.builder()\n .tagUuid(\"7c9e6679-7425-40de-944b-e07fc1f90ae7\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "networks->removeTag('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n 'tag_uuid' => '7c9e6679-7425-40de-944b-e07fc1f90ae7',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.remove_tag(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RemoveTagAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new NetworkTagRequest\n{\n TagUuid = \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -70582,6 +81402,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/requests/3fa85f64-5717-4562-b3fc-2c963f66afa6/remind/' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.remind(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.remind(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Remind(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().remind(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "cases->requests->remind('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.remind(\n \"11111111-2222-3333-4444-555555555555\",\n \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.RemindAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -70856,6 +81711,7 @@ "sender_kind", "subject", "html", + "text", "language", "will_be_sent", "not_sent_reason", @@ -70912,6 +81768,11 @@ "description": "The email's HTML exactly as it is sent, with its logo embedded as a data URL. Render it in a sandboxed frame, never directly in your application DOM.", "example": "..." }, + "text": { + "type": "string", + "description": "The email's words as plain text, as the person's Messages thread keeps them, for a compact preview (the HTML stays the email the person receives).", + "example": "Verification Approved\n\nYour identity has been successfully verified with Acme Pay. No further action is needed on your part." + }, "language": { "type": "string", "description": "The language the email is written in. English (`en`) when the `email_language` you asked for is not offered.", @@ -71028,7 +81889,7 @@ } }, "403": { - "description": "Missing or invalid credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", + "description": "Missing credentials, a caller without the `write:sessions` privilege, a scoped API key without the access this endpoint needs, or a `session_id` that belongs to another application.", "content": { "application/json": { "examples": { @@ -71079,7 +81940,37 @@ { "lang": "python", "label": "Python", - "source": "import requests\n\nresponse = requests.post(\n \"https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/decision-email-preview/\",\n headers={\"x-api-key\": \"YOUR_API_KEY\"},\n json={\"new_status\": \"Approved\", \"email_language\": \"en\"},\n)\nresponse.raise_for_status()\nprint(response.json())" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.preview_decision_email(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n new_status=\"Approved\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.previewDecisionEmail(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n new_status: \"Approved\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.PreviewDecisionEmail(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.SessionsPreviewDecisionEmailParams{\n\tNewStatus: \"Approved\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsPreviewDecisionEmailParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().previewDecisionEmail(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", SessionsPreviewDecisionEmailParams.builder()\n .newStatus(SessionsPreviewDecisionEmailParams.NewStatus.of(\"Approved\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->previewDecisionEmail('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n 'new_status' => 'Approved',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.preview_decision_email(\n \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n new_status: \"Approved\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.PreviewDecisionEmailAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new SessionsPreviewDecisionEmailParams\n{\n NewStatus = \"Approved\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "x-didit-sdk": { @@ -71328,6 +82219,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/workspace/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.get()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.get();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.Get(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().get();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->workspace->get();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.get\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.GetAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -71384,6 +82310,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/claim/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"vasp_id\": \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.claim(\n vasp_id=\"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.claim({\n vasp_id: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.Claim(ctx, didit.TravelRuleWorkspaceClaimRequest{\n\tVASPID: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceClaimRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().claim(TravelRuleWorkspaceClaimRequest.builder()\n .vaspId(\"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->workspace->claim([\n 'vasp_id' => '0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.claim(vasp_id: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.ClaimAsync(new TravelRuleWorkspaceClaimRequest\n{\n VaspId = \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -71430,6 +82391,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/code/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.send_domain_code()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.sendDomainCode();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.SendDomainCode(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().sendDomainCode();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->workspace->sendDomainCode();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.send_domain_code\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.SendDomainCodeAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -71486,6 +82482,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/confirm/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"code\": \"123456\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.confirm_domain(\n code=\"123456\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.confirmDomain({\n code: \"123456\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.ConfirmDomain(ctx, didit.TravelRuleWorkspaceDomainConfirmRequest{\n\tCode: \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceDomainConfirmRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().confirmDomain(TravelRuleWorkspaceDomainConfirmRequest.builder()\n .code(\"123456\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->workspace->confirmDomain([\n 'code' => '123456',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.confirm_domain(code: \"123456\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.ConfirmDomainAsync(new TravelRuleWorkspaceDomainConfirmRequest\n{\n Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -71532,6 +82563,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/dns/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.verify_domain_dns()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.verifyDomainDns();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.VerifyDomainDNS(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().verifyDomainDns();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->workspace->verifyDomainDns();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.verify_domain_dns\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.VerifyDomainDnsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -71591,6 +82657,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/billing/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"enabled\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.enable_billing(\n enabled=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.enableBilling({\n enabled: true,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.EnableBilling(ctx, didit.TravelRuleWorkspaceBillingRequest{\n\tEnabled: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceBillingRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().enableBilling(TravelRuleWorkspaceBillingRequest.builder()\n .enabled(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->workspace->enableBilling([\n 'enabled' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.enable_billing(enabled: true)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.EnableBillingAsync(new TravelRuleWorkspaceBillingRequest\n{\n Enabled = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -71703,7 +82804,44 @@ "method": "retrieve_summary", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_summary()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveSummary();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveSummary(ctx, didit.InvestigatorRetrieveSummaryParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveSummary();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->retrieveSummary();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_summary\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveSummaryAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/queue/": { @@ -71857,7 +82995,44 @@ "method": "list_queue", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.investigator.list_queue():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.investigator.listQueue()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Investigator.ListQueueAutoPaging(ctx, didit.InvestigatorListQueueParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.investigator().listQueue()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->listQueue() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.investigator.list_queue.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Investigator.ListQueueAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } + ] } }, "/v3/investigator/runs/{run_id}/": { @@ -71910,7 +83085,44 @@ "method": "retrieve_run", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_run(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveRun(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveRun(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveRun(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->retrieveRun('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_run(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveRunAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/runs/{run_id}/accept/": { @@ -71964,6 +83176,9 @@ "application/json": { "schema": { "$ref": "#/components/schemas/InvestigatorAcceptRequest" + }, + "example": { + "send_email": false } } } @@ -71973,7 +83188,44 @@ "method": "accept_run", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.accept_run(\n \"11111111-2222-3333-4444-555555555555\",\n send_email=False,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.acceptRun(\"11111111-2222-3333-4444-555555555555\", {\n send_email: false,\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.AcceptRun(ctx, \"11111111-2222-3333-4444-555555555555\", didit.InvestigatorAcceptRequest{\n\tSendEmail: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorAcceptRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().acceptRun(\"11111111-2222-3333-4444-555555555555\", InvestigatorAcceptRequest.builder()\n .sendEmail(false)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->acceptRun('11111111-2222-3333-4444-555555555555', [\n 'send_email' => false,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.accept_run(\n \"11111111-2222-3333-4444-555555555555\",\n send_email: false\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.AcceptRunAsync(\"11111111-2222-3333-4444-555555555555\", new InvestigatorAcceptRequest\n{\n SendEmail = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/runs/{run_id}/override/": { @@ -72027,6 +83279,11 @@ "application/json": { "schema": { "$ref": "#/components/schemas/InvestigatorOverrideRequest" + }, + "example": { + "action": "decline", + "category": "evidence_misread", + "reason": "The proof of address is older than three months." } } } @@ -72036,7 +83293,44 @@ "method": "override_run", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.override_run(\n \"11111111-2222-3333-4444-555555555555\",\n action=\"decline\",\n category=\"evidence_misread\",\n reason=\"The proof of address is older than three months.\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.overrideRun(\"11111111-2222-3333-4444-555555555555\", {\n action: \"decline\",\n category: \"evidence_misread\",\n reason: \"The proof of address is older than three months.\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.OverrideRun(ctx, \"11111111-2222-3333-4444-555555555555\", didit.InvestigatorOverrideRequest{\n\tAction: \"decline\",\n\tCategory: \"evidence_misread\",\n\tReason: \"The proof of address is older than three months.\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorOverrideRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().overrideRun(\"11111111-2222-3333-4444-555555555555\", InvestigatorOverrideRequest.builder()\n .action(InvestigatorOverrideRequest.Action.of(\"decline\"))\n .category(InvestigatorOverrideRequest.Category.of(\"evidence_misread\"))\n .reason(\"The proof of address is older than three months.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->overrideRun('11111111-2222-3333-4444-555555555555', [\n 'action' => 'decline',\n 'category' => 'evidence_misread',\n 'reason' => 'The proof of address is older than three months.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.override_run(\n \"11111111-2222-3333-4444-555555555555\",\n action: \"decline\",\n category: \"evidence_misread\",\n reason: \"The proof of address is older than three months.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.OverrideRunAsync(\"11111111-2222-3333-4444-555555555555\", new InvestigatorOverrideRequest\n{\n Action = \"decline\",\n Category = \"evidence_misread\",\n Reason = \"The proof of address is older than three months.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/runs/batch-accept/": { @@ -72085,7 +83379,44 @@ "method": "batch_accept_runs", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.batch_accept_runs(\n run_ids=[\"11111111-2222-3333-4444-555555555555\"],\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.batchAcceptRuns({\n run_ids: [\"11111111-2222-3333-4444-555555555555\"],\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.BatchAcceptRuns(ctx, didit.InvestigatorBatchAcceptRequest{\n\tRunIDs: []string{\"11111111-2222-3333-4444-555555555555\"},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.InvestigatorBatchAcceptRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().batchAcceptRuns(InvestigatorBatchAcceptRequest.builder()\n .runIds(List.of(\"11111111-2222-3333-4444-555555555555\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->batchAcceptRuns([\n 'run_ids' => ['11111111-2222-3333-4444-555555555555'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.batch_accept_runs(run_ids: [\"11111111-2222-3333-4444-555555555555\"])\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.BatchAcceptRunsAsync(new InvestigatorBatchAcceptRequest\n{\n RunIds = new string[] { \"11111111-2222-3333-4444-555555555555\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/transactions/{transaction_id}/": { @@ -72147,7 +83478,44 @@ "method": "retrieve_transaction", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_transaction(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveTransaction(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveTransaction(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveTransaction(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->retrieveTransaction('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_transaction(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveTransactionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/guardrails/": { @@ -72215,7 +83583,44 @@ "method": "list_guardrails", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.list_guardrails()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.listGuardrails();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.ListGuardrails(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().listGuardrails();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->listGuardrails();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.list_guardrails\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.ListGuardrailsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/dashboard/": { @@ -72296,7 +83701,44 @@ "method": "retrieve_dashboard", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_dashboard()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveDashboard();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveDashboard(ctx, didit.InvestigatorRetrieveDashboardParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveDashboard();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->retrieveDashboard();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_dashboard\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveDashboardAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/performance/": { @@ -72382,7 +83824,44 @@ "method": "retrieve_performance", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_performance()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrievePerformance();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrievePerformance(ctx, didit.InvestigatorRetrievePerformanceParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrievePerformance();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->retrievePerformance();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_performance\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrievePerformanceAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/investigator/activity/": { @@ -72517,7 +83996,44 @@ "method": "list_activity", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.investigator.list_activity():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.investigator.listActivity()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Investigator.ListActivityAutoPaging(ctx, didit.InvestigatorListActivityParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.investigator().listActivity()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->listActivity() as $item) {\n print_r($item);\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.investigator.list_activity.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Investigator.ListActivityAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } + ] } }, "/v3/investigator/activity/export/": { @@ -72609,7 +84125,44 @@ "method": "export_activity", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.investigator.export_activity()\nwith open(\"download.csv\", \"wb\") as file:\n file.write(content)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.investigator.exportActivity();\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Investigator.ExportActivity(ctx, didit.InvestigatorExportActivityParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.investigator().exportActivity()\n .writeTo(Path.of(\"download.csv\"));" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->exportActivity();\n$content->saveTo('download.csv');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.investigator.export_activity\nFile.binwrite(\"download.csv\", content)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Investigator.ExportActivityAsync();\nawait content.SaveToAsync(\"download.csv\");" + } + ] } }, "/v3/investigator/settings/": { @@ -72648,7 +84201,44 @@ "method": "retrieve_settings", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_settings()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveSettings();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveSettings(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveSettings();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->retrieveSettings();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_settings\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveSettingsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] }, "patch": { "operationId": "investigator_settings_update", @@ -72689,6 +84279,10 @@ "application/json": { "schema": { "$ref": "#/components/schemas/InvestigatorSettings" + }, + "example": { + "stage": "shadow", + "monthly_spend_limit": "500.00" } } } @@ -72698,7 +84292,44 @@ "method": "update_settings", "auth": "api_key", "server": true - } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.update_settings(\n stage=\"shadow\",\n monthly_spend_limit=\"500.00\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.updateSettings({\n stage: \"shadow\",\n monthly_spend_limit: \"500.00\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.UpdateSettings(ctx, didit.InvestigatorSettingsParam{\n\tStage: didit.Some(didit.InvestigatorSettingsStage(\"shadow\")),\n\tMonthlySpendLimit: didit.String(\"500.00\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorSettings;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().updateSettings(InvestigatorSettings.builder()\n .stage(InvestigatorSettings.Stage.of(\"shadow\"))\n .monthlySpendLimit(\"500.00\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "investigator->updateSettings([\n 'stage' => 'shadow',\n 'monthly_spend_limit' => '500.00',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.update_settings(\n stage: \"shadow\",\n monthly_spend_limit: \"500.00\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.UpdateSettingsAsync(new InvestigatorSettings\n{\n Stage = new InvestigatorSettingsStage(\"shadow\"),\n MonthlySpendLimit = \"500.00\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] } }, "/v3/travel-rule/wallet-addresses/import/": { @@ -72801,6 +84432,41 @@ "lang": "curl", "label": "curl (CSV)", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/import/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -F 'file=@wallets.csv;type=text/csv'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.bulk_import(\n body={\n \"entries\": [{\n \"address\": \"0xBeneficiaryWallet01\",\n \"chain\": \"ETH\",\n \"holder_name\": \"Ana Diaz\",\n \"holder_vendor_data\": \"user-042\",\n }, {\n \"address_hash\": \"4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e\",\n \"chain\": \"bitcoin\",\n \"holder_vendor_data\": \"user-043\",\n }, {\n \"address\": \"rExchangeSharedAddress01\",\n \"chain\": \"XRP\",\n \"memo\": \"104729\",\n \"holder_name\": \"Ana Diaz\",\n }],\n },\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.bulkImport({\n file: await fileFromPath(\"wallet-addresses.csv\"),\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.BulkImport(ctx, didit.TravelRuleWalletAddressesBulkImportParams{\n\tFile: didit.Some(didit.FileFromPath(\"wallet-addresses.csv\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleWalletAddressesBulkImportParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().bulkImport(TravelRuleWalletAddressesBulkImportParams.builder()\n .file(Path.of(\"wallet-addresses.csv\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletAddresses->bulkImport([\n 'file' => File::fromPath('wallet-addresses.csv'),\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.bulk_import(\n body: {\n entries: [{\n address: \"0xBeneficiaryWallet01\",\n chain: \"ETH\",\n holder_name: \"Ana Diaz\",\n holder_vendor_data: \"user-042\",\n }, {\n address_hash: \"4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e\",\n chain: \"bitcoin\",\n holder_vendor_data: \"user-043\",\n }, {\n address: \"rExchangeSharedAddress01\",\n chain: \"XRP\",\n memo: \"104729\",\n holder_name: \"Ana Diaz\",\n }],\n }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.BulkImportAsync(new TravelRuleWalletAddressesBulkImportParams\n{\n File = FileUpload.FromPath(\"wallet-addresses.csv\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -72954,6 +84620,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/counterparty-contacts/?counterparty={vasp_id}' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.counterparty_contacts.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.counterpartyContacts.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.CounterpartyContacts.ListAutoPaging(ctx, didit.TravelRuleCounterpartyContactsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().counterpartyContacts().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->counterpartyContacts->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.counterparty_contacts.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.CounterpartyContacts.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -73061,6 +84762,41 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/counterparty-contacts/ \\\n -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n -d '{\"counterparty\": \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\", \"email\": \"compliance@counterparty.example\", \"name\": \"Compliance desk\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.counterparty_contacts.create(\n counterparty=\"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n email=\"compliance@counterparty.example\",\n name=\"Compliance desk\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.counterpartyContacts.create({\n counterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n email: \"compliance@counterparty.example\",\n name: \"Compliance desk\",\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.CounterpartyContacts.Create(ctx, didit.TravelRuleCounterpartyContactCreate{\n\tCounterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n\tEmail: \"compliance@counterparty.example\",\n\tName: didit.String(\"Compliance desk\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyContactCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().counterpartyContacts().create(TravelRuleCounterpartyContactCreate.builder()\n .counterparty(\"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\")\n .email(\"compliance@counterparty.example\")\n .name(\"Compliance desk\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->counterpartyContacts->create([\n 'counterparty' => '0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91',\n 'email' => 'compliance@counterparty.example',\n 'name' => 'Compliance desk',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.counterparty_contacts.create(\n counterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n email: \"compliance@counterparty.example\",\n name: \"Compliance desk\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.CounterpartyContacts.CreateAsync(new TravelRuleCounterpartyContactCreate\n{\n Counterparty = \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n Email = \"compliance@counterparty.example\",\n Name = \"Compliance desk\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -73140,6 +84876,41 @@ "lang": "curl", "label": "curl", "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/counterparty-contacts/{contact_uuid}/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.travel_rule.counterparty_contacts.delete(\n \"11111111-2222-3333-4444-555555555555\",\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.travelRule.counterpartyContacts.delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.TravelRule.CounterpartyContacts.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.travelRule().counterpartyContacts().delete(\"11111111-2222-3333-4444-555555555555\");" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->counterpartyContacts->delete('11111111-2222-3333-4444-555555555555');" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.counterparty_contacts.delete(\"11111111-2222-3333-4444-555555555555\")" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.TravelRule.CounterpartyContacts.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");" } ], "responses": { @@ -73273,6 +85044,41 @@ "lang": "curl", "label": "curl", "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/transfers/?direction=OUTBOUND&status=AWAITING_COUNTERPARTY' \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.transfers.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.transfers.list()) {\n console.log(item);\n}" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.Transfers.ListAutoPaging(ctx, didit.TravelRuleTransfersListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().transfers().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->transfers->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.transfers.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.Transfers.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -73414,6 +85220,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_providers()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listProviders();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListProviders(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listProviders();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->listProviders();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_providers\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListProvidersAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -73487,6 +85330,13 @@ "provider", "credentials" ] + }, + "example": { + "provider": "sumsub", + "credentials": { + "app_token": "YOUR_PROVIDER_APP_TOKEN", + "secret_key": "YOUR_PROVIDER_SECRET_KEY" + } } } } @@ -73536,6 +85386,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.check_provider(\n provider=\"sumsub\",\n credentials={\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.checkProvider({\n provider: \"sumsub\",\n credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.CheckProvider(ctx, didit.SessionsImportsCheckProviderParams{\n\tProvider: \"sumsub\",\n\tCredentials: map[string]string{\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsImportsCheckProviderParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().checkProvider(SessionsImportsCheckProviderParams.builder()\n .provider(SessionsImportsCheckProviderParams.Provider.of(\"sumsub\"))\n .credentials(Map.of(\"app_token\", \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\", \"YOUR_PROVIDER_SECRET_KEY\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->checkProvider([\n 'provider' => 'sumsub',\n 'credentials' => ['app_token' => 'YOUR_PROVIDER_APP_TOKEN', 'secret_key' => 'YOUR_PROVIDER_SECRET_KEY'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.check_provider(\n provider: \"sumsub\",\n credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CheckProviderAsync(new SessionsImportsCheckProviderParams\n{\n Provider = \"sumsub\",\n Credentials = new Dictionary { [\"app_token\"] = \"YOUR_PROVIDER_APP_TOKEN\", [\"secret_key\"] = \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -73634,6 +85521,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.start(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.start(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Start(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsStartParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().start(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->start('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.start(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.StartAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -73695,6 +85619,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.pause(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.pause(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Pause(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().pause(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->pause('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.pause(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.PauseAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -73756,6 +85717,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.resume(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.resume(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Resume(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().resume(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->resume('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.resume(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ResumeAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -73817,6 +85815,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.cancel(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.cancel(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Cancel(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().cancel(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->cancel('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.cancel(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CancelAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -73865,6 +85900,12 @@ "description": "The record IDs or export file again, for `api_ids` and `export_file` providers." } } + }, + "example": { + "credentials": { + "app_token": "YOUR_PROVIDER_APP_TOKEN", + "secret_key": "YOUR_PROVIDER_SECRET_KEY" + } } } } @@ -73902,6 +85943,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.retry(\n \"11111111-2222-3333-4444-555555555555\",\n credentials={\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.retry(\"11111111-2222-3333-4444-555555555555\", {\n credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Retry(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsRetryParams{\n\tCredentials: didit.Some(map[string]string{\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsImportsRetryParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().retry(\"11111111-2222-3333-4444-555555555555\", SessionsImportsRetryParams.builder()\n .credentials(Map.of(\"app_token\", \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\", \"YOUR_PROVIDER_SECRET_KEY\"))\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->retry('11111111-2222-3333-4444-555555555555', [\n 'credentials' => ['app_token' => 'YOUR_PROVIDER_APP_TOKEN', 'secret_key' => 'YOUR_PROVIDER_SECRET_KEY'],\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.retry(\n \"11111111-2222-3333-4444-555555555555\",\n credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" }\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.RetryAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsImportsRetryParams\n{\n Credentials = new Dictionary { [\"app_token\"] = \"YOUR_PROVIDER_APP_TOKEN\", [\"secret_key\"] = \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -74000,6 +86078,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_jobs()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listJobs();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListJobs(ctx, didit.SessionsImportsListJobsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listJobs();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->listJobs();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_jobs\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListJobsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -74058,6 +86173,43 @@ { "ApiKeyAuth": [] } + ], + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_active_jobs()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listActiveJobs();\nconsole.log(result);" + }, + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListActiveJobs(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listActiveJobs();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "sessions->imports->listActiveJobs();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_active_jobs\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListActiveJobsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } ] } }, @@ -74178,6 +86330,36 @@ "lang": "curl", "label": "curl (selected transactions)", "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/delete/' \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"transaction_uuids\": [\"abcdef12-3456-7890-abcd-ef1234567890\"]}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.transactions.batch_delete(\n body={\n \"transaction_uuids\": [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n },\n)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.transactions.batchDelete({\n transaction_uuids: [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n});" + }, + { + "lang": "java", + "label": "Java", + "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionsBatchDeleteParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.transactions().batchDelete(TransactionsBatchDeleteParams.builder()\n .putAdditionalProperty(\"transaction_uuids\", List.of(\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"))\n .build());" + }, + { + "lang": "php", + "label": "PHP", + "source": "transactions->batchDelete([\n 'transaction_uuids' => ['abcdef12-3456-7890-abcd-ef1234567890', '12345678-90ab-cdef-1234-567890abcdef'],\n]);" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.transactions.batch_delete(\n body: {\n transaction_uuids: [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n }\n)" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Transactions.BatchDeleteAsync(new TransactionsBatchDeleteParams\n{\n TransactionUuids = new string[] { \"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\" },\n});" } ], "responses": { @@ -74264,6 +86446,36 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/networks/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.retrieve()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.retrieve();\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().retrieve();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->networks->retrieve();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.retrieve\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -74370,6 +86582,36 @@ "lang": "curl", "label": "curl", "source": "curl -X GET https://verification.didit.me/v3/travel-rule/networks/questionnaire/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.retrieve_questionnaire()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.retrieveQuestionnaire();\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().retrieveQuestionnaire();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->networks->retrieveQuestionnaire();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.retrieve_questionnaire\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RetrieveQuestionnaireAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -74411,6 +86653,36 @@ "lang": "curl", "label": "curl", "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/networks/questionnaire/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"legal_name\": \"Example VASP Ltd\", \"incorporation_country\": \"ES\", \"aml_ctf_policy_attested\": true}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.update_questionnaire(\n legal_name=\"Example VASP Ltd\",\n incorporation_country=\"ES\",\n aml_ctf_policy_attested=True,\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.updateQuestionnaire({\n legal_name: \"Example VASP Ltd\",\n incorporation_country: \"ES\",\n aml_ctf_policy_attested: true,\n});\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleNetworkQuestionnaireAnswers;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().updateQuestionnaire(TravelRuleNetworkQuestionnaireAnswers.builder()\n .legalName(\"Example VASP Ltd\")\n .incorporationCountry(\"ES\")\n .amlCtfPolicyAttested(true)\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->networks->updateQuestionnaire([\n 'legal_name' => 'Example VASP Ltd',\n 'incorporation_country' => 'ES',\n 'aml_ctf_policy_attested' => true,\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.update_questionnaire(\n legal_name: \"Example VASP Ltd\",\n incorporation_country: \"ES\",\n aml_ctf_policy_attested: true\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.UpdateQuestionnaireAsync(new TravelRuleNetworkQuestionnaireAnswers\n{\n LegalName = \"Example VASP Ltd\",\n IncorporationCountry = \"ES\",\n AmlCtfPolicyAttested = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -74419,6 +86691,11 @@ "application/json": { "schema": { "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers" + }, + "example": { + "legal_name": "Example VASP Ltd", + "incorporation_country": "ES", + "aml_ctf_policy_attested": true } } } @@ -74509,6 +86786,36 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/networks/questionnaire/submit/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.submit_questionnaire()\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.submitQuestionnaire();\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().submitQuestionnaire();\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->networks->submitQuestionnaire();\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.submit_questionnaire\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.SubmitQuestionnaireAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -74612,6 +86919,36 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/networks/gtr/request/ \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.request_access(\n \"your-network\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.requestAccess(\"your-network\");\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().requestAccess(\"your-network\");\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->networks->requestAccess('your-network');\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.request_access(\"your-network\")\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RequestAccessAsync(\"your-network\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -74702,12 +87039,32 @@ { "lang": "python", "label": "Python", - "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/address-validation/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"], \"Content-Type\": \"application/json\"},\n json={\n \"address_line_1\": \"1600 Amphitheatre Pkwy\",\n \"city\": \"Mountain View\",\n \"region\": \"CA\",\n \"postal_code\": \"94043\",\n \"country\": \"US\",\n },\n timeout=15,\n)\nresp.raise_for_status()\nresult = resp.json()[\"address_validation\"]\nprint(result[\"status\"], result[\"formatted_address\"])" + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.address_validation.validate(\n address_line_1=\"1600 Amphitheatre Pkwy\",\n city=\"Mountain View\",\n region=\"CA\",\n postal_code=\"94043\",\n country=\"US\",\n)\nprint(result)" }, { "lang": "javascript", - "label": "JavaScript", - "source": "const res = await fetch('https://verification.didit.me/v3/address-validation/', {\n method: 'POST',\n headers: {\n 'x-api-key': 'YOUR_API_KEY',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ address: 'Paseo de la Castellana 259, 28046 Madrid', country: 'ES' }),\n});\nconst { address_validation } = await res.json();\nconsole.log(address_validation.status, address_validation.formatted_address);" + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.addressValidation.validate({\n address_line_1: \"1600 Amphitheatre Pkwy\",\n city: \"Mountain View\",\n region: \"CA\",\n postal_code: \"94043\",\n country: \"US\",\n});\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.AddressValidationRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.addressValidation().validate(AddressValidationRequest.builder()\n .addressLine1(\"1600 Amphitheatre Pkwy\")\n .city(\"Mountain View\")\n .region(\"CA\")\n .postalCode(\"94043\")\n .country(\"US\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "addressValidation->validate([\n 'address_line_1' => '1600 Amphitheatre Pkwy',\n 'city' => 'Mountain View',\n 'region' => 'CA',\n 'postal_code' => '94043',\n 'country' => 'US',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.address_validation.validate(\n address_line_1: \"1600 Amphitheatre Pkwy\",\n city: \"Mountain View\",\n region: \"CA\",\n postal_code: \"94043\",\n country: \"US\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AddressValidation.ValidateAsync(new AddressValidationRequest\n{\n AddressLine1 = \"1600 Amphitheatre Pkwy\",\n City = \"Mountain View\",\n Region = \"CA\",\n PostalCode = \"94043\",\n Country = \"US\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "requestBody": { @@ -74882,6 +87239,36 @@ "lang": "curl", "label": "curl", "source": "curl https://verification.didit.me/v3/travel-rule/wallet-proofs/?status=PENDING \\\n -H 'x-api-key: YOUR_API_KEY'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.wallet_proofs.list():\n print(item)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.walletProofs.list()) {\n console.log(item);\n}" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().walletProofs().list()) {\n System.out.println(item);\n}" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletProofs->list() as $item) {\n print_r($item->toArray());\n}" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_proofs.list.auto_paging_each do |item|\n puts item.to_h\nend" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.WalletProofs.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" } ], "responses": { @@ -74963,6 +87350,10 @@ "application/json": { "schema": { "$ref": "#/components/schemas/TravelRuleWalletProofDecision" + }, + "example": { + "decision": "approve", + "note": "Address matches the wallet app." } } } @@ -74972,6 +87363,36 @@ "lang": "curl", "label": "curl", "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-proofs/{proof_uuid}/decision/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\"decision\": \"approve\", \"note\": \"Address matches the wallet app.\"}'" + }, + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_proofs.decide(\n \"11111111-2222-3333-4444-555555555555\",\n decision=\"approve\",\n note=\"Address matches the wallet app.\",\n)\nprint(result)" + }, + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletProofs.decide(\"11111111-2222-3333-4444-555555555555\", {\n decision: \"approve\",\n note: \"Address matches the wallet app.\",\n});\nconsole.log(result);" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWalletProofDecision;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletProofs().decide(\"11111111-2222-3333-4444-555555555555\", TravelRuleWalletProofDecision.builder()\n .decision(TravelRuleWalletProofDecision.Decision.of(\"approve\"))\n .note(\"Address matches the wallet app.\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->walletProofs->decide('11111111-2222-3333-4444-555555555555', [\n 'decision' => 'approve',\n 'note' => 'Address matches the wallet app.',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_proofs.decide(\n \"11111111-2222-3333-4444-555555555555\",\n decision: \"approve\",\n note: \"Address matches the wallet app.\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletProofs.DecideAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleWalletProofDecision\n{\n Decision = \"approve\",\n Note = \"Address matches the wallet app.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" } ], "responses": { @@ -75234,2626 +87655,6415 @@ } } } - } - }, - "components": { - "schemas": { - "DocumentAIDetectedCode": { - "type": "object", - "required": [ - "type", - "page_number", - "position", - "x", - "y", - "width", - "height", - "page_width", - "page_height", - "raw_payload", - "parsed_payload" + }, + "/v3/id-verification/wallets/verifications/{request_id}/response/": { + "post": { + "operationId": "submit_wallet_verification_response", + "x-didit-sdk": { + "resource": "id_wallets", + "method": "submit_verification_response", + "auth": "api_key", + "server": true + }, + "description": "Digital Credentials API wallets (Google Wallet): send what the wallet returned to your page or app for a verification whose next_action is request_digital_credential. Didit decrypts it, checks the issuer's signature against the trusted issuer roots, every returned value against its signed digest, and the device signature over your origin and this request, then decides the verification: verified (billed once) or declined with the error code. Single use: a second submit returns the decided verification.", + "summary": "Submit a wallet response", + "parameters": [ + { + "in": "path", + "name": "request_id", + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "The request_id the start endpoint returned.", + "required": true + } ], - "properties": { - "type": { - "type": "string", - "description": "Detected symbology, for example `QR_CODE`, `CODE_128`, `EAN_13`, `DATA_MATRIX`, or `PDF_417`." - }, - "page_number": { - "type": "integer", - "minimum": 1, - "description": "1-based page number." - }, - "position": { - "type": "array", - "nullable": true, - "description": "Detected polygon in rendered-page pixel coordinates. `null` when no reliable location is available.", - "items": { - "type": "array", - "minItems": 2, - "maxItems": 2, - "items": { - "type": "integer" + "tags": [ + "Digital ID wallets" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest" + }, + "example": { + "response": { + "protocol": "openid4vp-v1-signed", + "data": { + "response": "" + } + } + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest" + }, + "example": { + "response": { + "protocol": "openid4vp-v1-signed", + "data": { + "response": "" + } + } + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest" + }, + "example": { + "response": { + "protocol": "openid4vp-v1-signed", + "data": { + "response": "" + } + } } } }, - "x": { - "type": "integer", - "nullable": true, - "description": "Left edge of the bounding box in rendered-page pixels." - }, - "y": { - "type": "integer", - "nullable": true, - "description": "Top edge of the bounding box in rendered-page pixels." - }, - "width": { - "type": "integer", - "nullable": true, - "description": "Bounding-box width in rendered-page pixels." - }, - "height": { - "type": "integer", - "nullable": true, - "description": "Bounding-box height in rendered-page pixels." - }, - "page_width": { - "type": "integer", - "description": "Rendered page width in pixels." - }, - "page_height": { - "type": "integer", - "description": "Rendered page height in pixels." - }, - "raw_payload": { - "type": "string", - "description": "Raw decoder payload as a base64 string when available; otherwise an empty string." + "required": true + }, + "security": [ + { + "ApiKeyAuth": [] }, - "parsed_payload": { - "nullable": true, - "description": "Decoded string or structured value. `null` when the code was located but could not be decoded." + { + "BearerAuth": [] } - } - }, - "SessionImportJob": { - "type": "object", - "required": [ - "uuid", - "status", - "import_type", - "source_format", - "source_filename", - "total_rows", - "processed_rows", - "created_count", - "updated_count", - "skipped_count", - "failed_count" ], - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Import job id. Use this value to poll progress and fetch row errors." - }, - "status": { - "type": "string", - "enum": [ - "PENDING", - "PROCESSING", - "COMPLETED", - "FAILED", - "PAUSED", - "CANCELLED", - "READY" - ] - }, - "import_type": { - "type": "string", - "enum": [ - "user_verification", - "business_verification", - "status_rules", - "transactions" - ] - }, - "source_format": { - "type": "string", - "enum": [ - "csv", - "ndjson" - ] - }, - "source_filename": { - "type": "string" - }, - "total_rows": { - "type": "integer", - "format": "int64" - }, - "processed_rows": { - "type": "integer", - "format": "int64" - }, - "checkpoint_row": { - "type": "integer", - "format": "int64" - }, - "created_count": { - "type": "integer", - "format": "int64" - }, - "updated_count": { - "type": "integer", - "format": "int64" - }, - "skipped_count": { - "type": "integer", - "format": "int64" - }, - "failed_count": { - "type": "integer", - "format": "int64" - }, - "total_media_bytes": { - "type": "integer", - "format": "int64" - }, - "last_error": { - "type": "string", - "nullable": true - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "started_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "completed_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "state": { - "type": "string", - "enum": [ - "ready", - "queued", - "running", - "paused", - "completed", - "errors", - "failed", - "cancelled" - ], - "description": "The job's state as the console shows it; `errors` is a completed job with rejected rows." - }, - "source": { - "type": "string", - "enum": [ - "file", - "api", - "provider" - ] - }, - "provider": { - "type": "string", - "description": "Migration source; empty for a file or API import." + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse" + }, + "example": { + "request_id": "00000000-0000-4000-8000-000000000001", + "wallet_verification": { + "wallet": { + "id": "google_wallet", + "name": "Google Wallet", + "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)" + }, + "country": "USA", + "status": "Approved", + "outcome": "verified", + "error": null, + "interaction": "digital_credentials", + "simulated": false, + "expires_at": "2026-01-01T10:10:00Z", + "next_action": null, + "identity": { + "full_name": "Alex Example", + "first_name": "Alex", + "last_name": "Example", + "date_of_birth": "1990-01-31", + "nationality": "USA", + "issuing_state": "USA" + }, + "attributes": { + "document_number": "X0000000", + "document_expiry_date": "2030-01-31" + }, + "level_of_assurance": "substantial", + "verified_at": "2026-01-01T10:01:00Z", + "signature_valid": true, + "credential_type": "person_identification" + }, + "vendor_data": "your-customer-reference", + "metadata": { + "reference": "example" + }, + "created_at": "2026-01-01T10:00:00Z" + } + } + }, + "description": "" }, - "provider_options": { - "type": "object" + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage" + } + } + }, + "description": "Missing credentials (x-api-key or Authorization: Bearer)." }, - "credential_hint": { - "type": "string", - "description": "The first characters of the key the migration holds. The key itself is never returned." + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error not_found: no wallet verification of this application has this request_id." }, - "credentials_expires_at": { - "type": "string", - "format": "date-time", - "nullable": true + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest" + } + } + }, + "description": "Field validation errors ({field: [messages]})." }, - "resumes_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When a job paused by the provider's rate limit resumes by itself." + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error not_a_digital_credentials_wallet: this verification does not take a wallet response." }, - "status_mapping": { - "type": "object", - "additionalProperties": { + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error wallet_not_configured: this environment cannot verify the wallet." + } + }, + "x-codeSamples": [ + { + "lang": "curl", + "label": "cURL", + "source": "curl --request POST \\\n --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/response/ \\\n --header 'x-api-key: YOUR_API_KEY' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"response\": {\n \"protocol\": \"openid4vp-v1-signed\",\n \"data\": {\n \"response\": \"\"\n }\n }\n}'" + } + ] + } + }, + "/v3/id-verification/wallets/google-wallet/": { + "post": { + "operationId": "start_google_wallet_wallet_verification", + "x-didit-sdk": { + "resource": "id_wallets", + "method": "start_google_wallet", + "auth": "api_key", + "server": true + }, + "description": "Start a Google Wallet sign-in (Google Wallet (ID pass) and US state issuers (mobile driving licence); USA, GBR, BRA, SGP, TWN) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=request_digital_credential with a request Didit signed for your application, usable only from origin. In a user gesture there, pass next_action.digital_credentials.request to navigator.credentials.get({digital: ...}) (or to Android Credential Manager as GetDigitalCredentialOption requestJson), then POST what the wallet returns to /v3/id-verification/wallets/verifications/{request_id}/response/. The browser offers its own QR code when the wallet is on another device. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider.", + "summary": "Start Google Wallet verification", + "parameters": [ + { + "in": "header", + "name": "Idempotency-Key", + "schema": { "type": "string" + }, + "description": "Optional retry-safety key (max 255 characters). Retrying with the same key, wallet and body returns the original verification without starting a second sign-in; the same key with another wallet or body returns 409 idempotency_key_reused." + } + ], + "tags": [ + "Digital ID wallets" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest" + }, + "example": { + "country": "USA", + "vendor_data": "your-customer-reference", + "metadata": { + "reference": "example" + }, + "origin": "https://app.example.com" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest" + } + }, + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest" + } } }, - "is_dry_run": { - "type": "boolean" - }, - "dry_run_summary": { - "type": "object", - "description": "What a dry run found: `total`, `by_status`, `already_in_didit`, `same_person`, `not_finished`, `failed`, `unmapped_statuses`." - }, - "face_templates_enabled": { - "type": "boolean" - }, - "lawful_basis_confirmed_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "not_finished_count": { - "type": "integer", - "format": "int64" + "required": true + }, + "security": [ + { + "ApiKeyAuth": [] }, - "same_person_count": { - "type": "integer", - "format": "int64" + { + "BearerAuth": [] + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse" + }, + "example": { + "request_id": "00000000-0000-4000-8000-000000000001", + "wallet_verification": { + "wallet": { + "id": "google_wallet", + "name": "Google Wallet", + "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)" + }, + "country": "USA", + "status": "Not Finished", + "outcome": "pending", + "error": null, + "interaction": "digital_credentials", + "simulated": false, + "expires_at": "2026-01-01T10:10:00Z", + "next_action": { + "type": "request_digital_credential", + "digital_credentials": { + "protocol": "openid4vp-v1-signed", + "request": { + "requests": [ + { + "protocol": "openid4vp-v1-signed", + "data": { + "request": "" + } + } + ] + } + } + }, + "identity": null, + "attributes": null, + "level_of_assurance": null, + "verified_at": null, + "signature_valid": null, + "credential_type": "person_identification" + }, + "vendor_data": "your-customer-reference", + "metadata": { + "reference": "example" + }, + "created_at": "2026-01-01T10:00:00Z" + } + } + }, + "description": "" }, - "face_templates_count": { - "type": "integer", - "format": "int64" + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest" + } + } + }, + "description": "Field validation errors ({field: [messages]}), or error return_url_invalid, return_url_not_allowed, origin_invalid, origin_not_allowed, invalid_personal_code, invalid_phone_number or idempotency_key_invalid." }, - "face_duplicates_count": { - "type": "integer", - "format": "int64" + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden" + } + } + }, + "description": "Missing credentials ({detail}), or error wallet_unavailable, insufficient_credits or contract_rate_missing." }, - "face_blocklist_hits_count": { - "type": "integer", - "format": "int64" + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error idempotency_key_reused or idempotency_key_in_progress (with Retry-After)." }, - "created_by_name": { - "type": "string", - "nullable": true + "502": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error wallet_provider_unavailable: the provider could not start; nothing was created." }, - "created_by_email": { - "type": "string", - "nullable": true + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError" + } + } + }, + "description": "error wallet_not_configured: this environment cannot reach the wallet." + } + }, + "x-codeSamples": [ + { + "lang": "curl", + "label": "cURL", + "source": "curl --request POST \\\n --url https://verification.didit.me/v3/id-verification/wallets/google-wallet/ \\\n --header 'x-api-key: YOUR_API_KEY' \\\n --header 'Idempotency-Key: your-unique-attempt-key' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"country\": \"USA\",\n \"vendor_data\": \"your-customer-reference\",\n \"metadata\": {\n \"reference\": \"example\"\n },\n \"origin\": \"https://app.example.com\"\n}'" } - } - }, - "SessionImportError": { - "type": "object", - "required": [ - "uuid", - "row_number", - "error", - "raw_row" ], - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "row_number": { - "type": "integer", - "format": "int64" - }, - "external_id": { - "type": "string", - "nullable": true - }, - "error": { - "type": "string" - }, - "raw_row": { - "type": "object", - "additionalProperties": true - }, - "created_at": { - "type": "string", - "format": "date-time" + "x-didit-wallet-id": "google_wallet" + } + }, + "/v3/session/{sessionId}/kyb/documents/": { + "post": { + "summary": "Upload KYB documents to a session", + "description": "Upload one or more corporate documents (articles of incorporation, shareholder register, certificate of incorporation, ...) to the KYB Documents step of a Business Verification session, from your own server instead of the hosted page. Didit runs the hosted pipeline: compression, OCR, tampering and cross-document checks, document grouping, and advances the session when the required document groups are satisfied. The step costs one flat fee however many files you send. The session must be open and on the KYB Documents step, and the company chosen at the registry step must exist. Read the people the documents name with `GET /v3/session/{sessionId}/kyb/extracted-parties/`. Requires `write:businesses`.", + "operationId": "post_v3_session_kyb_documents", + "x-didit-sdk": { + "resource": "sessions", + "method": "upload_kyb_documents", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "ApiKeyAuth": [] } - } - }, - "BrandingCustomizationUpdate": { - "type": "object", - "description": "Partial branding update body. Provide only the fields you want to change. Hex colors accept `#RRGGBB` or `#RRGGBBAA`. Custom domain and white-label email are not accepted here.", - "properties": { - "color_primary": { - "type": "string", - "description": "Headers / primary text color." - }, - "color_secondary": { - "type": "string", - "description": "Paragraph / secondary text color." - }, - "color_background": { - "type": "string", - "description": "Page background color." - }, - "color_panel": { - "type": "string", - "description": "Panel / accent color." - }, - "color_panel_10": { - "type": "string", - "description": "Panel color at 10% opacity." - }, - "color_on_panel_1": { - "type": "string", - "description": "Support text color on panels." - }, - "color_on_panel_2": { - "type": "string", - "description": "Pill / badge color on panels." - }, - "color_on_background": { - "type": "string", - "description": "Text color on background." - }, - "color_button_1": { - "type": "string", - "description": "Primary button color." - }, - "color_button_2": { - "type": "string", - "description": "Secondary button color." - }, - "color_button_text_1": { - "type": "string", - "description": "Primary button text color." - }, - "color_button_text_2": { - "type": "string", - "description": "Secondary button text color." - }, - "color_pill_text": { - "type": "string", - "description": "Text color for pills, inputs and selectors." - }, - "border_radius_panel": { - "type": "integer", - "minimum": 0, - "description": "Panel corner radius in pixels." - }, - "border_radius_buttons": { - "type": "integer", - "minimum": 0, - "description": "Button corner radius in pixels." - }, - "font_family": { - "type": "string", - "description": "Google Font family name (e.g. `Inter`, `AR One Sans`)." - }, - "font_weight": { - "type": "string", - "description": "Font weight available for the selected family (e.g. `regular`, `500`, `700`)." - }, - "app_public_name": { - "type": "string", - "nullable": true, - "description": "Public name shown in the verification flow." - }, - "privacy_policy_url": { - "type": "string", - "nullable": true, - "description": "Privacy policy URL shown to the end user." - }, - "skip_welcome_screen": { - "type": "boolean", - "description": "Skip the initial welcome screen." - }, - "disable_login_with_didit": { - "type": "boolean", - "description": "Continue as guest instead of showing the login-with-Didit screen. Cannot be set back to `false` while a custom domain is configured (400)." - }, - "hide_progress_bar": { - "type": "boolean", - "description": "Hide the progress bar during the flow." - }, - "callback_seconds": { - "type": "integer", - "minimum": 0, - "description": "Delay (seconds) before redirecting to the callback URL." - }, - "delete_logo_square": { - "type": "boolean", - "description": "When `true`, removes the current square logo." - }, - "delete_logo_rectangular": { - "type": "boolean", - "description": "When `true`, removes the current rectangular logo." - }, - "delete_logo_rectangular_dark": { - "type": "boolean", - "description": "When `true`, removes the current dark-mode logo, and `logo_rectangular_dark` then reads `null`. If the same multipart request also uploads `image_rectangular_dark`, the upload wins." + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "delete_favicon": { - "type": "boolean", - "description": "When `true`, removes the current favicon." + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { + "type": "string" + } } - } - }, - "BrandingCustomization": { - "type": "object", - "description": "White-label branding for an application: colors, fonts, radii, logo URLs and UI/UX options. Logo URLs are read-only (set them by uploading images). Custom domain and white-label email are not included.", - "properties": { - "color_primary": { - "type": "string" - }, - "color_secondary": { - "type": "string" - }, - "color_background": { - "type": "string" - }, - "color_panel": { - "type": "string" - }, - "color_panel_10": { - "type": "string" + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": [ + "documents" + ], + "properties": { + "documents": { + "type": "array", + "items": { + "type": "string", + "format": "binary" + }, + "description": "Files to upload: JPG, JPEG, PNG, TIFF, WEBP, PDF or ZIP archives of them. PDFs up to 50 MB, photos up to 6 MB before compression." + }, + "document_passwords": { + "type": "array", + "items": { + "type": "string" + }, + "description": "One entry per file in `documents`, in the same order: the password of a protected PDF, empty for any other file." + }, + "document_group": { + "type": "string", + "enum": [ + "LEGAL_PRESENCE", + "COMPANY_DETAILS", + "OWNERSHIP_STRUCTURE", + "REPRESENTATIVES_AUTHORIZATION" + ], + "description": "Required document group this upload answers." + }, + "locale": { + "type": "string", + "maxLength": 10, + "description": "Locale used to translate the response of the next step." + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Documents processed. When every required group is satisfied the session advances and `next_step` names the next step; otherwise it stays on the Documents step and `document_groups` and `document_answer` say what is still missing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "valid": { + "type": "boolean" + }, + "next_step": { + "type": "string", + "nullable": true, + "description": "Step the session is on after the upload." + }, + "kyb_status": { + "type": "string", + "description": "Status of the company check." + }, + "document_answer": { + "type": "object", + "additionalProperties": true, + "description": "Result per uploaded document and the uploads left." + } + }, + "additionalProperties": true + }, + "example": { + "valid": true, + "next_step": "KYB_KEY_PEOPLE", + "kyb_status": "In Progress" + } + } + } }, - "color_on_panel_1": { - "type": "string" + "400": { + "description": "A document was rejected (tampering, unreadable or unsupported) or the session has no KYB company yet. Retry with another file while attempts remain.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "message": "No KYB company found. Submit company data first." + } + } + } }, - "color_on_panel_2": { - "type": "string" + "402": { + "description": "The organization has no credit left for the documents step.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "detail": "Insufficient credits." + } + } + } }, - "color_on_background": { - "type": "string" + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." + } + } + } + } + } }, - "color_button_1": { - "type": "string" + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." + } + } + } + } + } }, - "color_button_2": { - "type": "string" + "404": { + "description": "The session does not exist, was deleted, belongs to another application or is outside a scoped key's limits; no detail distinguishes them.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "detail": "Session not found." + } + } + } }, - "color_button_text_1": { - "type": "string" + "409": { + "description": "The session is finished (`kyb_session_not_writable`) or is not on the KYB Documents step (`kyb_step_mismatch`, with `next_step` naming the step it is on).", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + }, + "code": { + "type": "string" + }, + "next_step": { + "type": "string" + } + } + }, + "example": { + "detail": "The session is not on the step this operation completes.", + "code": "kyb_step_mismatch", + "next_step": "KYB_REGISTRY" + } + } + } }, - "color_button_text_2": { - "type": "string" + "429": { + "description": "Rate limit exceeded: 300 write (POST, PATCH, DELETE) requests per minute per API key. Wait `Retry-After` seconds before retrying; the `X-RateLimit-*` headers show the budget.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Rate limited": { + "summary": "Budget for the current minute exhausted", + "value": { + "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute." + } + } + } + } + }, + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer", + "minimum": 1, + "example": 30 + } + } + } + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.upload_kyb_documents(\n \"33333333-4444-5555-6666-777777777777\",\n documents=[open(\"document.pdf\", \"rb\")],\n)\nprint(result)" }, - "color_pill_text": { - "type": "string" + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.uploadKybDocuments(\"33333333-4444-5555-6666-777777777777\", {\n documents: [await fileFromPath(\"document.pdf\")],\n});\nconsole.log(result);" }, - "border_radius_panel": { - "type": "integer" + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UploadKYBDocuments(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsUploadKYBDocumentsParams{\n\tDocuments: []didit.File{didit.FileFromPath(\"document.pdf\")},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "border_radius_buttons": { - "type": "integer" + { + "lang": "java", + "label": "Java", + "source": "import java.nio.file.Path;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUploadKybDocumentsParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().uploadKybDocuments(\"33333333-4444-5555-6666-777777777777\", SessionsUploadKybDocumentsParams.builder()\n .documents(List.of(Path.of(\"document.pdf\")))\n .build());\nSystem.out.println(result);" }, - "font_family": { - "type": "string" + { + "lang": "php", + "label": "PHP", + "source": "sessions->uploadKybDocuments('33333333-4444-5555-6666-777777777777', [\n 'documents' => [File::fromPath('document.pdf')],\n]);\nprint_r($result->toArray());" }, - "font_weight": { - "type": "string" + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.upload_kyb_documents(\n \"33333333-4444-5555-6666-777777777777\",\n documents: [Pathname(\"document.pdf\")]\n)\nputs result.to_h" }, - "font_url": { - "type": "string", - "nullable": true, - "description": "Read-only. Resolved Google Fonts stylesheet URL for the selected family." + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UploadKybDocumentsAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsUploadKybDocumentsParams\n{\n Documents = new FileUpload[] { FileUpload.FromPath(\"document.pdf\") },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + } + }, + "/v3/session/{sessionId}/kyb/extracted-parties/": { + "get": { + "summary": "List the parties named by the uploaded documents", + "description": "Return the shareholders and directors that the documents uploaded to this KYB session name, merged per person and attributed to the documents that named them. Show them to your applicant to confirm, then declare them with the party draft endpoints. A range stays a range: `ownership_percent.text` keeps the verbatim figure and `min` / `max` the numbers read from it. Nobody is labelled a UBO here; that is decided when the parties are submitted, from the role settings and ownership thresholds of the workflow. The same list is in the session decision as `document_verifications[].extracted_parties`. Requires `read:businesses` or `read:sessions`.", + "operationId": "get_v3_session_kyb_extracted_parties", + "x-didit-sdk": { + "resource": "sessions", + "method": "list_kyb_extracted_parties", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "logo_square": { - "type": "string", - "nullable": true, - "description": "Read-only URL of the square logo. Upload via `image_square`." - }, - "logo_rectangular": { - "type": "string", - "nullable": true, - "description": "Read-only URL of the rectangular logo. Upload via `image_rectangular`." - }, - "logo_rectangular_dark": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "Read-only. Temporary signed URL of the rectangular logo for dark mode, shown on a dark background. `null` when no dark logo is set or rectangular logos are not shown for your account. Upload it with `image_rectangular_dark`." - }, - "favicon": { - "type": "string", - "nullable": true, - "description": "Read-only URL of the favicon. Upload via `image_favicon`." - }, - "app_public_name": { - "type": "string", - "nullable": true - }, - "privacy_policy_url": { - "type": "string", - "nullable": true - }, - "skip_welcome_screen": { - "type": "boolean" - }, - "disable_login_with_didit": { - "type": "boolean" - }, - "hide_progress_bar": { - "type": "boolean" - }, - "callback_seconds": { - "type": "integer" - } - } - }, - "WebhookEvent": { - "type": "string", - "description": "Supported webhook event name. Use these exact strings in `subscribed_events`; unsupported values are rejected.", - "enum": [ - "status.updated", - "data.updated", - "user.status.updated", - "user.data.updated", - "business.status.updated", - "business.data.updated", - "activity.created", - "transaction.created", - "transaction.status.updated", - "travel_rule.status.updated", - "workflow.compliance_changed", - "auth.signup", - "auth.login", - "auth.login_failed", - "auth.password_reset_requested", - "auth.password_reset_completed", - "auth.mfa_changed", - "auth.new_device", - "auth.account_locked", - "investigator.report.ready", - "investigator.decision.automated", - "investigator.decision.overridden", - "investigator.decision.contested", - "investigator.question.raised", - "investigator.automation.paused", - "investigator.rfi.answered", - "investigator.rfi.overdue", - "investigator.drift.detected", - "investigator.sla.breached", - "investigator.qa.failed", - "investigator.external.report.ready" - ] - }, - "WebhookSubscribedEvents": { - "type": "array", - "description": "Event filter for this webhook destination. Didit delivers only webhooks whose event type exactly matches one of these values — there is no wildcard subscription. When sent, the list must contain at least one valid event (an explicit `[]` is rejected with 400); a destination whose list is empty (field omitted at create) receives nothing. On update the list is replaced wholesale, never merged.", - "minItems": 1, - "uniqueItems": true, - "items": { - "$ref": "#/components/schemas/WebhookEvent" - }, - "example": [ - "status.updated", - "data.updated" - ] - }, - "PhoneVerificationSendResponse": { - "type": "object", - "properties": { - "request_id": { - "type": "string", - "format": "uuid", - "description": "Session id of the verification. A `Retry` send returns the same `request_id` as the original send. This id appears in the Business Console, is returned again by a finalized `POST /v3/phone/check/`, and can be passed to `GET /v3/session/{sessionId}/decision/`." - }, - "status": { - "type": "string", - "enum": [ - "Success", - "Retry", - "Blocked" - ], - "description": "`Success` — OTP sent to a new verification. `Retry` — OTP re-sent for the pending verification created by a previous send. `Blocked` — the anti-fraud layer refused to send; the verification is immediately finalized as `Declined` and nothing is billed." - }, - "reason": { - "type": "string", - "nullable": true, - "description": "Why a send was `Blocked` (e.g., `repeated_attempts`, `suspicious`, `spam`). `null` on `Success` and `Retry`." - }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "Echo of the `vendor_data` stored on the session (from the first send)." - }, - "metadata": { - "type": "object", - "nullable": true, - "description": "Echo of the `metadata` stored on the session (from the first send)." + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { + "type": "string" + } } - } - }, - "PhoneVerificationCheckResponse": { - "type": "object", - "properties": { - "request_id": { - "type": "string", - "format": "uuid", - "description": "On `Approved`/`Declined`: the session id of the matched verification — identical to the `request_id` returned by `POST /v3/phone/send/`. On `Failed` and `Expired or Not Found`: a random one-off UUID that cannot be looked up later." - }, - "status": { - "type": "string", - "enum": [ - "Approved", - "Declined", - "Failed", - "Expired or Not Found" - ], - "description": "`Approved` — correct code, no declining risk. `Declined` — terminal: a declining risk matched or the attempt budget (3) was exhausted. `Failed` — wrong code, attempts remaining. `Expired or Not Found` — no pending verification for this number in the last 5 minutes." - }, - "message": { - "type": "string", - "description": "Human-readable explanation of the outcome, including the number of attempts remaining after a wrong code." - }, - "phone": { - "type": "object", - "nullable": true, - "description": "Full phone report. Present (non-null) only on finalized outcomes (`Approved`/`Declined`); `null` on `Failed` and absent on `Expired or Not Found`.", - "properties": { - "status": { - "type": "string", - "enum": [ - "Approved", - "Declined", - "In Review", - "Not Finished", - "Expired" - ], - "description": "Final status of the phone verification. Matches the top-level `status` for finalized checks." - }, - "phone_number_prefix": { - "type": "string", - "description": "Country calling code with leading `+` (e.g., `+1`).", - "example": "+1" - }, - "phone_number": { - "type": "string", - "description": "National number without the country calling code.", - "example": "4155552671" - }, - "full_number": { - "type": "string", - "description": "Complete number in E.164 format.", - "example": "+14155552671" - }, - "country_code": { - "type": "string", - "nullable": true, - "description": "ISO 3166-1 alpha-2 country of the number.", - "example": "US" - }, - "country_name": { - "type": "string", - "description": "Full country name derived from `country_code`.", - "example": "United States" - }, - "carrier": { - "type": "object", - "description": "Current network serving the number, from the carrier lookup run at finalization.", - "properties": { - "name": { - "type": "string", - "description": "Carrier name. Empty string when the lookup could not identify it." - }, - "type": { - "type": "string", - "description": "Line type reported by the lookup: `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `pager`, `payphone`, `satellite`, `service`, `shared_cost`, `short_codes_commercial`, `calling_cards`, `local_rate`, `universal_access`, `voice_mail`, `other`, or `unknown`." - } - } - }, - "is_disposable": { - "type": "boolean", - "description": "`true` when the number belongs to a temporary/burner number service." - }, - "is_virtual": { - "type": "boolean", - "description": "`true` when the line type is virtual (`voip`, `isp`, or `vpn`)." - }, - "verification_method": { - "type": "string", - "description": "Channel that actually delivered the OTP once delivery is confirmed (e.g., `whatsapp`, `sms`); until then, the requested channel." - }, - "verification_attempts": { - "type": "integer", - "description": "Number of OTP sends for this verification (1, or 2 after a retry)." - }, - "verified_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the correct code was entered. `null` if the verification was never approved." - }, - "warnings": { - "type": "array", - "description": "Risk warnings recorded during the verification (duplicate, disposable, VoIP, attempts exceeded, blocklist, etc.). Empty array when there are none.", - "items": { + ], + "responses": { + "200": { + "description": "Parties named by the current documents.", + "content": { + "application/json": { + "schema": { "type": "object", + "required": [ + "parties", + "document_count" + ], "properties": { - "feature": { - "type": "string", - "description": "Feature that produced the warning. Always `PHONE` here." - }, - "risk": { - "type": "string", - "description": "Machine-readable risk code." + "parties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "entity_type": { + "type": "string", + "enum": [ + "person", + "company" + ] + }, + "first_name": { + "type": "string", + "nullable": true + }, + "last_name": { + "type": "string", + "nullable": true + }, + "appointment_date": { + "type": "string", + "nullable": true + }, + "designation": { + "type": "string", + "nullable": true + }, + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ] + }, + "ownership_percent": { + "type": "object", + "properties": { + "text": { + "type": "string", + "nullable": true, + "description": "The ownership figure exactly as the document states it, such as `25-50%`, `>50%` or `NO EXHIBE`." + }, + "min": { + "type": "number", + "nullable": true, + "description": "Lower number read out of `text`; null when it states none." + }, + "max": { + "type": "number", + "nullable": true, + "description": "Upper number read out of `text`; null when it states none." + } + } + } + } + } + }, + "documents": { + "type": "array", + "description": "The uploaded documents that named this party.", + "items": { + "type": "object", + "properties": { + "document_uuid": { + "type": "string", + "format": "uuid" + }, + "document_type": { + "type": "string", + "nullable": true + }, + "document_subtype": { + "type": "string", + "nullable": true + }, + "original_filename": { + "type": "string", + "nullable": true + }, + "status": { + "type": "string", + "nullable": true + } + } + } + } + } + }, + "description": "The shareholders and directors the uploaded documents name, merged per person. Nobody is labelled a UBO here: that is decided when the parties are submitted." }, - "additional_data": { - "type": "object", - "nullable": true, - "description": "Risk-specific context (e.g., the duplicated session id for duplicate risks). `null` when the risk carries no extra data." + "document_count": { + "type": "integer", + "description": "Number of uploaded documents the list was read from." }, - "log_type": { + "node_id": { "type": "string", - "enum": [ - "error", - "warning", - "information" + "nullable": true + } + } + }, + "example": { + "parties": [ + { + "name": "Ana Lopez", + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "appointment_date": null, + "designation": "Administrador unico", + "roles": [ + { + "role": "shareholder", + "ownership_percent": { + "text": "60%", + "min": 60, + "max": 60 + } + } ], - "description": "Severity. `error` risks decline the verification, `warning` flags it for review, `information` is recorded without affecting the status." - }, - "short_description": { - "type": "string", - "description": "Human-readable one-line summary of the risk." - }, - "long_description": { + "documents": [ + { + "document_uuid": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41", + "document_type": "OWNERSHIP_STRUCTURE", + "document_subtype": "ARTICLES_OF_INCORPORATION", + "original_filename": "acta_constitutiva.pdf", + "status": "Approved" + } + ] + } + ], + "document_count": 1, + "node_id": "node_kyb_documents" + } + } + } + }, + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { "type": "string", - "description": "Human-readable explanation of the risk." + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." } } } - }, - "lifecycle": { - "type": "array", - "description": "Chronological audit trail of the verification. Event `type` is one of `PHONE_VERIFICATION_MESSAGE_SENT`, `PHONE_VERIFICATION_RETRY_MESSAGE_SENT`, `PHONE_VERIFICATION_BLOCKED`, `PHONE_DELIVERY_DELIVERED`, `PHONE_DELIVERY_UNDELIVERABLE`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `PHONE_VERIFICATION_APPROVED`, `PHONE_VERIFICATION_DECLINED`, `PHONE_VERIFICATION_IN_REVIEW`, `PHONE_VERIFICATION_EXPIRED`.", - "items": { + } + } + }, + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "type": { - "type": "string", - "description": "Event type." - }, - "timestamp": { + "detail": { "type": "string", - "format": "date-time", - "description": "When the event happened." - }, - "details": { - "type": "object", - "nullable": true, - "description": "Event-specific payload. Send events: `{status, reason, channel, actual_channel}` (`actual_channel` is filled once delivery is confirmed). Delivery events: `{channel, status}`. Code-entry events: `{code_tried, status}`. Final-status events: `null`, or `{reason}` when declined or in review." - }, - "fee": { - "type": "number", - "description": "USD amount billed for this event. Non-zero only on send events (the delivery price); 0 for code entries, delivery confirmations, and status events." + "description": "Human-readable error message." + } + } + }, + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." } } } - }, - "matches": { - "type": "array", - "description": "Other sessions of your application (KYC, KYB, or API) where the same phone number was used by a different user (different `vendor_data`). Up to 5 entries, a synthetic list-entry blocklist match first when present (session-derived matches keep query order). Empty array when there are no matches.", - "items": { + } + } + }, + "404": { + "description": "The session does not exist, was deleted, belongs to another application or is outside a scoped key's limits; no detail distinguishes them.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "session_id": { - "type": "string", - "format": "uuid", - "description": "Session id of the other verification that used this phone number." - }, - "session_number": { - "type": "integer", - "description": "Human-friendly sequential number of that session." - }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "`vendor_data` of that session." - }, - "verification_date": { - "type": "string", - "description": "When that session was created (`YYYY-MM-DDTHH:MM:SSZ`)." - }, - "phone_number": { - "type": "string", - "description": "The matched phone number." - }, - "status": { - "type": "string", - "description": "Status of that session (e.g., `Approved`, `Declined`, `In Progress`)." - }, - "is_blocklisted": { - "type": "boolean", - "description": "Whether the phone number is on your application's blocklist." - }, - "api_service": { - "type": "string", - "nullable": true, - "description": "For API-type sessions, the standalone API that created it (e.g., `PHONE_VERIFICATION`); `null` for regular verification sessions." - }, - "source": { + "detail": { "type": "string", - "description": "Where the match was found. Usually `session`; a blocklist hit via an organization list entry prepends a synthetic match with `source: \"list_entry\"` and null `session_id`/`session_number`." + "description": "Human-readable error message." } } + }, + "example": { + "detail": "Session not found." } - }, - "phone_social": { - "$ref": "#/components/schemas/PhoneSocialFootprint" } } - }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "`vendor_data` of the matched verification's session. `null` on `Expired or Not Found`." - }, - "metadata": { - "type": "object", - "nullable": true, - "description": "`metadata` of the matched verification's session. `null` on `Expired or Not Found`." - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "Timestamp of this check response." } - } - }, - "EmailVerificationSendResponse": { - "type": "object", - "properties": { - "request_id": { - "type": "string", - "format": "uuid", - "description": "Session id of the verification. A `Retry` send returns the same `request_id` as the original send. This id appears in the Business Console, is returned again by a finalized `POST /v3/email/check/`, and can be passed to `GET /v3/session/{sessionId}/decision/`." + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_kyb_extracted_parties(\n \"33333333-4444-5555-6666-777777777777\",\n)\nprint(result)" }, - "status": { - "type": "string", - "enum": [ - "Success", - "Retry", - "Undeliverable" - ], - "description": "`Success` — OTP emailed to a new verification (billed). `Retry` — fresh OTP emailed for the pending verification created by a previous send (free). `Undeliverable` — the address failed deliverability validation or the message could not be sent; the verification is immediately finalized as `Declined` and nothing is billed." + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listKybExtractedParties(\"33333333-4444-5555-6666-777777777777\");\nconsole.log(result);" }, - "reason": { - "type": "string", - "nullable": true, - "enum": [ - "email_can_not_be_delivered", - null - ], - "description": "`email_can_not_be_delivered` when `status` is `Undeliverable`; `null` otherwise." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListKYBExtractedParties(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsListKYBExtractedPartiesParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "Echo of the `vendor_data` stored on the session (from the first send)." + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listKybExtractedParties(\"33333333-4444-5555-6666-777777777777\");\nSystem.out.println(result);" }, - "metadata": { - "type": "object", - "nullable": true, - "description": "Echo of the `metadata` stored on the session (from the first send)." - } - } - }, - "EmailVerificationCheckResponse": { - "type": "object", - "properties": { - "request_id": { - "type": "string", - "format": "uuid", - "description": "On `Approved`/`Declined`: the session id of the matched verification — identical to the `request_id` returned by `POST /v3/email/send/`. On `Failed` and `Expired or Not Found`: a random one-off UUID that cannot be looked up later." + { + "lang": "php", + "label": "PHP", + "source": "sessions->listKybExtractedParties('33333333-4444-5555-6666-777777777777');\nprint_r($result->toArray());" }, - "status": { - "type": "string", - "enum": [ - "Approved", - "Declined", - "Failed", - "Expired or Not Found" - ], - "description": "`Approved` — correct code, no declining risk. `Declined` — terminal: a declining risk matched or the attempt budget (3) was exhausted. `Failed` — wrong code, attempts remaining. `Expired or Not Found` — no pending verification for this address in the last 5 minutes." + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_kyb_extracted_parties(\"33333333-4444-5555-6666-777777777777\")\nputs result.to_h" }, - "message": { - "type": "string", - "description": "Human-readable explanation of the outcome, including the number of attempts remaining after a wrong code." + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListKybExtractedPartiesAsync(\"33333333-4444-5555-6666-777777777777\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + } + }, + "/v3/session/{sessionId}/kyb/parties/drafts/": { + "get": { + "summary": "List the KYB party drafts", + "description": "List the parties you are preparing for this KYB session, oldest first. A draft is not a declared party: it does not appear in the decision or the console and creates no verification session until you submit it with `POST /v3/session/{sessionId}/kyb/parties/submit/`. Requires `write:businesses`.", + "operationId": "get_v3_session_kyb_party_drafts", + "x-didit-sdk": { + "resource": "sessions", + "method": "list_kyb_party_drafts", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "email": { - "type": "object", - "nullable": true, - "description": "Full email report. Present (non-null) only on finalized outcomes (`Approved`/`Declined`); `null` on `Failed` and absent on `Expired or Not Found`.", - "properties": { - "status": { - "type": "string", - "enum": [ - "Approved", - "Declined", - "In Review", - "Not Finished", - "Expired" - ], - "description": "Final status of the email verification. Matches the top-level `status` for finalized checks." - }, - "email": { - "type": "string", - "format": "email", - "description": "The verified email address.", - "example": "alice@example.com" - }, - "is_breached": { - "type": "boolean", - "description": "`true` when the address appears in known data breaches (breach intelligence lookup run at finalization)." - }, - "breaches": { - "type": "array", - "description": "Up to 5 most recent known breaches containing this address. Empty array (or omitted) when `is_breached` is `false`.", - "items": { + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The stored drafts.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "name": { - "type": "string", - "description": "Breach identifier." - }, - "domain": { - "type": "string", - "description": "Domain of the breached service." - }, - "breach_date": { - "type": "string", - "format": "date", - "description": "Date the breach occurred." - }, - "breach_emails_count": { - "type": "integer", - "description": "Total number of accounts exposed in the breach." - }, - "description": { - "type": "string", - "description": "Human-readable description of the breach (may contain HTML markup)." - }, - "logo_path": { - "type": "string", - "description": "URL of the breached service's logo." - }, - "data_classes": { + "parties": { "type": "array", "items": { - "type": "string" - }, - "description": "Categories of data exposed, in snake_case (e.g., `email_addresses`, `passwords`)." + "type": "object", + "required": [ + "draft_id", + "created_at", + "updated_at", + "party" + ], + "properties": { + "draft_id": { + "type": "string", + "format": "uuid" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "party": { + "type": "object", + "required": [ + "entity_type", + "nationality" + ], + "properties": { + "entity_type": { + "type": "string", + "enum": [ + "person", + "company" + ], + "description": "Whether the party is an individual or a company." + }, + "full_name": { + "type": "string", + "maxLength": 255, + "description": "Full name of a person. Send it, or `first_name` and `last_name`." + }, + "first_name": { + "type": "string", + "maxLength": 128 + }, + "last_name": { + "type": "string", + "maxLength": 128 + }, + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ], + "description": "Role the party holds. Interchangeable with `roles`; when both are sent they are merged." + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ] + }, + "description": "Every role the party holds. A person needs at least one role (here or in `role`)." + }, + "position": { + "type": "string", + "maxLength": 128, + "description": "Job title of a person." + }, + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true + }, + "company_name": { + "type": "string", + "maxLength": 255, + "description": "Name of a company party. Required when `entity_type` is `company`." + }, + "registration_number": { + "type": "string", + "maxLength": 100, + "description": "Registration number of a company party." + }, + "email": { + "type": "string", + "format": "email", + "description": "Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow." + }, + "ownership_percent": { + "type": "number", + "nullable": true, + "description": "Share of the company the party owns." + }, + "nationality": { + "type": "string", + "maxLength": 100, + "description": "Nationality of a person, or country of incorporation of a company. Required for every party." + }, + "phone_number": { + "type": "string", + "maxLength": 32 + }, + "custom_fields": { + "type": "object", + "additionalProperties": true, + "description": "Workflow-defined extra fields." + }, + "skip_verification": { + "type": "boolean", + "default": false, + "description": "Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings." + } + } + } + } + } }, - "is_verified": { - "type": "boolean", - "description": "Whether the breach has been verified as legitimate." + "node_id": { + "type": "string", + "nullable": true } } + }, + "example": { + "parties": [ + { + "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + "created_at": "2026-10-31T10:00:00Z", + "updated_at": "2026-10-31T10:00:00Z", + "party": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": [ + "ubo", + "director" + ], + "ownership_percent": 60, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12" + } + } + ], + "node_id": "node_kyb_key_people" } - }, - "is_disposable": { - "type": "boolean", - "description": "`true` when the domain belongs to a known disposable/temporary-mail provider." - }, - "is_undeliverable": { - "type": "boolean", - "description": "`true` when the address cannot receive mail (failed syntax or DNS/MX validation, or the message bounced)." - }, - "verification_attempts": { - "type": "integer", - "description": "Number of OTP sends for this verification (1, or 2 after a retry)." - }, - "verified_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the correct code was entered. `null` if the verification was never approved." - }, - "warnings": { - "type": "array", - "description": "Risk warnings recorded during the verification (duplicate, breached, disposable, undeliverable, attempts exceeded, blocklist, etc.). Empty array when there are none.", - "items": { + } + } + }, + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "feature": { - "type": "string", - "description": "Feature that produced the warning. Always `EMAIL` here." - }, - "risk": { - "type": "string", - "description": "Machine-readable risk code." - }, - "additional_data": { - "type": "object", - "nullable": true, - "description": "Risk-specific context (e.g., the duplicated session id for duplicate risks). `null` when the risk carries no extra data." - }, - "log_type": { - "type": "string", - "enum": [ - "error", - "warning", - "information" - ], - "description": "Severity. `error` risks decline the verification, `warning` flags it for review, `information` is recorded without affecting the status." - }, - "short_description": { - "type": "string", - "description": "Human-readable one-line summary of the risk." - }, - "long_description": { + "detail": { "type": "string", - "description": "Human-readable explanation of the risk." + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." } } } - }, - "lifecycle": { - "type": "array", - "description": "Chronological audit trail of the verification. Event `type` is one of `EMAIL_VERIFICATION_MESSAGE_SENT`, `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `EMAIL_VERIFICATION_APPROVED`, `EMAIL_VERIFICATION_DECLINED`, `EMAIL_VERIFICATION_IN_REVIEW`, `EMAIL_VERIFICATION_EXPIRED`.", - "items": { + } + } + }, + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "type": { - "type": "string", - "description": "Event type." - }, - "timestamp": { + "detail": { "type": "string", - "format": "date-time", - "description": "When the event happened." - }, - "details": { - "type": "object", - "nullable": true, - "description": "Event-specific payload. Send events: `{status, reason}`. Code-entry events: `{code_tried, status}`. Final-status events: `null`, or `{reason}` when declined or in review." - }, - "fee": { - "type": "number", - "description": "USD amount billed for this event. Non-zero only on the first successful send; 0 for retries, code entries, and status events." + "description": "Human-readable error message." + } + } + }, + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." } } } - }, - "matches": { - "type": "array", - "description": "Other sessions of your application (KYC, KYB, or API) where the same email address was used by a different user (different `vendor_data`). Up to 5 entries; a synthetic list-entry blocklist match is prepended when present (and only when no session-derived blocklisted email exists) — session-derived matches keep created_at order. Empty array when there are no matches.", - "items": { + } + } + }, + "404": { + "description": "The session does not exist, was deleted, belongs to another application or is outside a scoped key's limits; no detail distinguishes them.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "session_id": { - "type": "string", - "format": "uuid", - "description": "Session id of the other verification that used this email address." - }, - "session_number": { - "type": "integer", - "description": "Human-friendly sequential number of that session." - }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "`vendor_data` of that session." - }, - "verification_date": { - "type": "string", - "description": "When that session was created (`YYYY-MM-DDTHH:MM:SSZ`)." - }, - "email": { - "type": "string", - "description": "The matched email address." - }, - "status": { - "type": "string", - "description": "Status of that session (e.g., `Approved`, `Declined`, `In Progress`)." - }, - "is_blocklisted": { - "type": "boolean", - "description": "Whether the email address is on your application's blocklist." - }, - "api_service": { - "type": "string", - "nullable": true, - "description": "For API-type sessions, the standalone API that created it (e.g., `PHONE_VERIFICATION`); `null` for regular verification sessions." - }, - "source": { + "detail": { "type": "string", - "description": "Where the match was found. Usually `session`; a blocklist hit via an organization list entry prepends a synthetic match with `source: \"list_entry\"` and null `session_id`/`session_number`." + "description": "Human-readable error message." } } + }, + "example": { + "detail": "Session not found." } - }, - "email_social": { - "$ref": "#/components/schemas/EmailSocialFootprint" } } + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_kyb_party_drafts(\n \"33333333-4444-5555-6666-777777777777\",\n)\nprint(result)" }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "`vendor_data` of the matched verification's session. `null` on `Expired or Not Found`." + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listKybPartyDrafts(\"33333333-4444-5555-6666-777777777777\");\nconsole.log(result);" }, - "metadata": { - "type": "object", - "nullable": true, - "description": "`metadata` of the matched verification's session. `null` on `Expired or Not Found`." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListKYBPartyDrafts(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsListKYBPartyDraftsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "Timestamp of this check response." - } - } - }, - "WorkflowListItem": { - "type": "object", - "description": "One workflow version in the list view.", - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Per-version UUID. Use as `{settings_uuid}` for get/update/delete, and as `workflow_id` when creating sessions." - }, - "workflow_id": { - "type": "string", - "format": "uuid", - "description": "Stable group ID shared by every version of the same workflow. Equals `uuid` for version 1." - }, - "workflow_label": { - "type": "string", - "description": "Display name for the workflow." + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listKybPartyDrafts(\"33333333-4444-5555-6666-777777777777\");\nSystem.out.println(result);" }, - "workflow_type": { - "type": "string", - "nullable": true, - "description": "Base type for simple workflows: `kyc`, `kyb`, `adaptive_age_verification`, `biometric_authentication`, etc. `null` for graph-based workflows without a KYB feature." + { + "lang": "php", + "label": "PHP", + "source": "sessions->listKybPartyDrafts('33333333-4444-5555-6666-777777777777');\nprint_r($result->toArray());" }, - "is_default": { - "type": "boolean", - "description": "Whether this is the default workflow for new sessions." + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_kyb_party_drafts(\"33333333-4444-5555-6666-777777777777\")\nputs result.to_h" }, - "is_archived": { - "type": "boolean" + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListKybPartyDraftsAsync(\"33333333-4444-5555-6666-777777777777\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + }, + "post": { + "summary": "Create a KYB party draft", + "description": "Add a party (a person or a company) to the list you are preparing for this KYB session. The same fields and rules as the hosted Key People screen apply: a person needs `full_name` or `first_name` and `last_name`, at least one role and a nationality; a company needs `company_name` and the country of incorporation in `nationality`. Nothing is declared or billed until `POST /v3/session/{sessionId}/kyb/parties/submit/`. Requires `write:businesses`.", + "operationId": "post_v3_session_kyb_party_drafts", + "x-didit-sdk": { + "resource": "sessions", + "method": "create_kyb_party_draft", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "is_white_label_enabled": { - "type": "boolean", - "description": "Whether white-label customization applies to sessions created with this workflow." + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "entity_type", + "nationality" + ], + "properties": { + "entity_type": { + "type": "string", + "enum": [ + "person", + "company" + ], + "description": "Whether the party is an individual or a company." + }, + "full_name": { + "type": "string", + "maxLength": 255, + "description": "Full name of a person. Send it, or `first_name` and `last_name`." + }, + "first_name": { + "type": "string", + "maxLength": 128 + }, + "last_name": { + "type": "string", + "maxLength": 128 + }, + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ], + "description": "Role the party holds. Interchangeable with `roles`; when both are sent they are merged." + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ] + }, + "description": "Every role the party holds. A person needs at least one role (here or in `role`)." + }, + "position": { + "type": "string", + "maxLength": 128, + "description": "Job title of a person." + }, + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true + }, + "company_name": { + "type": "string", + "maxLength": 255, + "description": "Name of a company party. Required when `entity_type` is `company`." + }, + "registration_number": { + "type": "string", + "maxLength": 100, + "description": "Registration number of a company party." + }, + "email": { + "type": "string", + "format": "email", + "description": "Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow." + }, + "ownership_percent": { + "type": "number", + "nullable": true, + "description": "Share of the company the party owns." + }, + "nationality": { + "type": "string", + "maxLength": 100, + "description": "Nationality of a person, or country of incorporation of a company. Required for every party." + }, + "phone_number": { + "type": "string", + "maxLength": 32 + }, + "custom_fields": { + "type": "object", + "additionalProperties": true, + "description": "Workflow-defined extra fields." + }, + "skip_verification": { + "type": "boolean", + "default": false, + "description": "Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings." + } + } + }, + "example": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": [ + "ubo", + "director" + ], + "ownership_percent": 60, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12" + } + } + } + }, + "responses": { + "201": { + "description": "Draft created.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "draft_id", + "created_at", + "updated_at", + "party" + ], + "properties": { + "draft_id": { + "type": "string", + "format": "uuid" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "party": { + "type": "object", + "required": [ + "entity_type", + "nationality" + ], + "properties": { + "entity_type": { + "type": "string", + "enum": [ + "person", + "company" + ], + "description": "Whether the party is an individual or a company." + }, + "full_name": { + "type": "string", + "maxLength": 255, + "description": "Full name of a person. Send it, or `first_name` and `last_name`." + }, + "first_name": { + "type": "string", + "maxLength": 128 + }, + "last_name": { + "type": "string", + "maxLength": 128 + }, + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ], + "description": "Role the party holds. Interchangeable with `roles`; when both are sent they are merged." + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ] + }, + "description": "Every role the party holds. A person needs at least one role (here or in `role`)." + }, + "position": { + "type": "string", + "maxLength": 128, + "description": "Job title of a person." + }, + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true + }, + "company_name": { + "type": "string", + "maxLength": 255, + "description": "Name of a company party. Required when `entity_type` is `company`." + }, + "registration_number": { + "type": "string", + "maxLength": 100, + "description": "Registration number of a company party." + }, + "email": { + "type": "string", + "format": "email", + "description": "Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow." + }, + "ownership_percent": { + "type": "number", + "nullable": true, + "description": "Share of the company the party owns." + }, + "nationality": { + "type": "string", + "maxLength": 100, + "description": "Nationality of a person, or country of incorporation of a company. Required for every party." + }, + "phone_number": { + "type": "string", + "maxLength": 32 + }, + "custom_fields": { + "type": "object", + "additionalProperties": true, + "description": "Workflow-defined extra fields." + }, + "skip_verification": { + "type": "boolean", + "default": false, + "description": "Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings." + } + } + } + } + }, + "example": { + "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + "created_at": "2026-10-31T10:00:00Z", + "updated_at": "2026-10-31T10:00:00Z", + "party": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": [ + "ubo", + "director" + ], + "ownership_percent": 60, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12" + } + } + } + } }, - "total_price": { - "type": "number", - "description": "Fixed price per verification in USD (JSON number, excludes variable-priced features such as DATABASE_VALIDATION and PHONE_VERIFICATION)." + "400": { + "description": "A party field is invalid or a required one is missing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "non_field_errors": [ + "Person parties require at least one role." + ] + } + } + } }, - "min_price": { - "type": "number", - "description": "Cheapest fixed price across workflow-graph paths, in USD." + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." + } + } + } + } + } }, - "max_price": { - "type": "number", - "description": "Most expensive fixed price across workflow-graph paths, in USD." + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." + } + } + } + } + } }, - "features": { - "type": "string", - "description": "Enabled features as a single `\" + \"`-joined string, e.g. `\"OCR + LIVENESS + FACE_MATCH\"`. Split on `\" + \"` to get a list." + "404": { + "description": "The session does not exist, was deleted, belongs to another application or is outside a scoped key's limits; no detail distinguishes them.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "detail": "Session not found." + } + } + } }, - "is_simple_workflow": { - "type": "boolean", - "description": "True when the workflow has no custom workflow graph." + "409": { + "description": "The session is finished (`kyb_session_not_writable`).", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + }, + "code": { + "type": "string" + } + } + }, + "example": { + "detail": "This verification session is no longer accepting changes.", + "code": "kyb_session_not_writable" + } + } + } }, - "is_editable": { - "type": "boolean", - "description": "True when this version is a `draft` (drafts are editable in place; published versions are immutable in the Console)." + "429": { + "description": "Rate limit exceeded: 300 write (POST, PATCH, DELETE) requests per minute per API key. Wait `Retry-After` seconds before retrying; the `X-RateLimit-*` headers show the budget.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Rate limited": { + "summary": "Budget for the current minute exhausted", + "value": { + "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute." + } + } + } + } + }, + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer", + "minimum": 1, + "example": 30 + } + } + } + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.create_kyb_party_draft(\n \"33333333-4444-5555-6666-777777777777\",\n entity_type=\"person\",\n first_name=\"Ana\",\n last_name=\"Lopez\",\n roles=[\"ubo\", \"director\"],\n date_of_birth=\"1984-06-12\",\n email=\"ana.lopez@example.com\",\n ownership_percent=60.0,\n nationality=\"MEX\",\n)\nprint(result)" }, - "workflow_url": { - "type": "string", - "format": "uri", - "description": "Public shareable verification URL for this workflow (`https://verify.didit.me/u/`)." + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.createKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", {\n entity_type: \"person\",\n first_name: \"Ana\",\n last_name: \"Lopez\",\n roles: [\"ubo\", \"director\"],\n date_of_birth: \"1984-06-12\",\n email: \"ana.lopez@example.com\",\n ownership_percent: 60.0,\n nationality: \"MEX\",\n});\nconsole.log(result);" }, - "max_retry_attempts": { - "type": "integer", - "description": "Maximum retry attempts allowed after a declined verification (0-10)." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.CreateKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsCreateKYBPartyDraftParams{\n\tEntityType: \"person\",\n\tFirstName: didit.String(\"Ana\"),\n\tLastName: didit.String(\"Lopez\"),\n\tRoles: didit.Some([]didit.SessionsCreateKYBPartyDraftParamsRoles{\"ubo\", \"director\"}),\n\tDateOfBirth: didit.String(\"1984-06-12\"),\n\tEmail: didit.String(\"ana.lopez@example.com\"),\n\tOwnershipPercent: didit.Float(60.0),\n\tNationality: \"MEX\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "retry_window_days": { - "type": "integer", - "nullable": true, - "description": "Rolling window in days used to count retries (1-365). `null` = all-time limit." + { + "lang": "java", + "label": "Java", + "source": "import java.time.LocalDate;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsCreateKybPartyDraftParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().createKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", SessionsCreateKybPartyDraftParams.builder()\n .entityType(SessionsCreateKybPartyDraftParams.EntityType.of(\"person\"))\n .firstName(\"Ana\")\n .lastName(\"Lopez\")\n .roles(List.of(SessionsCreateKybPartyDraftParams.Roles.of(\"ubo\"), SessionsCreateKybPartyDraftParams.Roles.of(\"director\")))\n .dateOfBirth(LocalDate.parse(\"1984-06-12\"))\n .email(\"ana.lopez@example.com\")\n .ownershipPercent(60.0)\n .nationality(\"MEX\")\n .build());\nSystem.out.println(result);" }, - "session_expiration_time": { - "type": "integer", - "description": "Seconds before an unfinished session expires (3600-2419200)." + { + "lang": "php", + "label": "PHP", + "source": "sessions->createKybPartyDraft('33333333-4444-5555-6666-777777777777', [\n 'entity_type' => 'person',\n 'first_name' => 'Ana',\n 'last_name' => 'Lopez',\n 'roles' => ['ubo', 'director'],\n 'date_of_birth' => '1984-06-12',\n 'email' => 'ana.lopez@example.com',\n 'ownership_percent' => 60.0,\n 'nationality' => 'MEX',\n]);\nprint_r($result->toArray());" }, - "version": { - "type": "integer", - "description": "Version number within the `workflow_id` group, starting at 1." + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.create_kyb_party_draft(\n \"33333333-4444-5555-6666-777777777777\",\n entity_type: \"person\",\n first_name: \"Ana\",\n last_name: \"Lopez\",\n roles: [\"ubo\", \"director\"],\n date_of_birth: \"1984-06-12\",\n email: \"ana.lopez@example.com\",\n ownership_percent: 60.0,\n nationality: \"MEX\"\n)\nputs result.to_h" }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ], - "description": "Version status. New sessions use the latest `published` version of a group." + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CreateKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsCreateKybPartyDraftParams\n{\n EntityType = \"person\",\n FirstName = \"Ana\",\n LastName = \"Lopez\",\n Roles = new SessionsCreateKybPartyDraftParamsRoles[] { \"ubo\", \"director\" },\n DateOfBirth = \"1984-06-12\",\n Email = \"ana.lopez@example.com\",\n OwnershipPercent = 60.0,\n Nationality = \"MEX\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + } + }, + "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/": { + "patch": { + "summary": "Edit a KYB party draft", + "description": "Change fields of one party draft. The edit is merged into the stored draft and the merged party is validated as a whole, so an edit that would leave the party incomplete is rejected. Changing `first_name` or `last_name` replaces the stored full name. Requires `write:businesses`.", + "operationId": "patch_v3_session_kyb_party_draft", + "x-didit-sdk": { + "resource": "sessions", + "method": "update_kyb_party_draft", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "has_draft": { - "type": "boolean", - "description": "True when any version in this `workflow_id` group is currently a draft." + { + "name": "draftId", + "in": "path", + "required": true, + "description": "UUID of the party draft (`draft_id` returned when it was created).", + "schema": { + "type": "string", + "format": "uuid", + "example": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d" + } }, - "created_by": { - "type": "object", - "nullable": true, - "description": "Who created this version: `{name, email, type}` where `type` is `user` (Console user, `email` set) or `api_key` (`name` is the client id, `email` is null). `null` when no creator was recorded.", - "properties": { - "name": { - "type": "string" - }, - "email": { - "type": "string", - "nullable": true + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Any subset of the party fields. The edit is merged into the stored draft and the merged party is validated as a whole, so a draft that could be submitted before an edit can still be submitted after it.", + "properties": { + "entity_type": { + "type": "string", + "enum": [ + "person", + "company" + ], + "description": "Whether the party is an individual or a company." + }, + "full_name": { + "type": "string", + "maxLength": 255, + "description": "Full name of a person. Send it, or `first_name` and `last_name`." + }, + "first_name": { + "type": "string", + "maxLength": 128 + }, + "last_name": { + "type": "string", + "maxLength": 128 + }, + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ], + "description": "Role the party holds. Interchangeable with `roles`; when both are sent they are merged." + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ] + }, + "description": "Every role the party holds. A person needs at least one role (here or in `role`)." + }, + "position": { + "type": "string", + "maxLength": 128, + "description": "Job title of a person." + }, + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true + }, + "company_name": { + "type": "string", + "maxLength": 255, + "description": "Name of a company party. Required when `entity_type` is `company`." + }, + "registration_number": { + "type": "string", + "maxLength": 100, + "description": "Registration number of a company party." + }, + "email": { + "type": "string", + "format": "email", + "description": "Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow." + }, + "ownership_percent": { + "type": "number", + "nullable": true, + "description": "Share of the company the party owns." + }, + "nationality": { + "type": "string", + "maxLength": 100, + "description": "Nationality of a person, or country of incorporation of a company. Required for every party." + }, + "phone_number": { + "type": "string", + "maxLength": 32 + }, + "custom_fields": { + "type": "object", + "additionalProperties": true, + "description": "Workflow-defined extra fields." + }, + "skip_verification": { + "type": "boolean", + "default": false, + "description": "Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings." + } + } }, - "type": { - "type": "string", - "enum": [ - "user", - "api_key" - ] + "example": { + "ownership_percent": 55 } } - }, - "updated_at": { - "type": "string", - "format": "date-time" } - } - }, - "SimpleWorkflowRequest": { - "type": "object", - "description": "Create a simple linear workflow. The API converts this feature list into a node-based workflow graph internally. STRICT field whitelist: any key not listed here (including `workflow_type`) is rejected with a 400.", - "required": [ - "features" - ], - "properties": { - "workflow_label": { - "type": "string", - "maxLength": 50, - "default": "ID Verification", - "description": "Display name for the workflow (max 50 characters). Defaults to `\"ID Verification\"` when omitted — always set it so workflows stay distinguishable.", - "example": "Standard KYC" + }, + "responses": { + "200": { + "description": "Draft updated.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "draft_id", + "created_at", + "updated_at", + "party" + ], + "properties": { + "draft_id": { + "type": "string", + "format": "uuid" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "party": { + "type": "object", + "required": [ + "entity_type", + "nationality" + ], + "properties": { + "entity_type": { + "type": "string", + "enum": [ + "person", + "company" + ], + "description": "Whether the party is an individual or a company." + }, + "full_name": { + "type": "string", + "maxLength": 255, + "description": "Full name of a person. Send it, or `first_name` and `last_name`." + }, + "first_name": { + "type": "string", + "maxLength": 128 + }, + "last_name": { + "type": "string", + "maxLength": 128 + }, + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ], + "description": "Role the party holds. Interchangeable with `roles`; when both are sent they are merged." + }, + "roles": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ] + }, + "description": "Every role the party holds. A person needs at least one role (here or in `role`)." + }, + "position": { + "type": "string", + "maxLength": 128, + "description": "Job title of a person." + }, + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true + }, + "company_name": { + "type": "string", + "maxLength": 255, + "description": "Name of a company party. Required when `entity_type` is `company`." + }, + "registration_number": { + "type": "string", + "maxLength": 100, + "description": "Registration number of a company party." + }, + "email": { + "type": "string", + "format": "email", + "description": "Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow." + }, + "ownership_percent": { + "type": "number", + "nullable": true, + "description": "Share of the company the party owns." + }, + "nationality": { + "type": "string", + "maxLength": 100, + "description": "Nationality of a person, or country of incorporation of a company. Required for every party." + }, + "phone_number": { + "type": "string", + "maxLength": 32 + }, + "custom_fields": { + "type": "object", + "additionalProperties": true, + "description": "Workflow-defined extra fields." + }, + "skip_verification": { + "type": "boolean", + "default": false, + "description": "Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings." + } + } + } + } + }, + "example": { + "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + "created_at": "2026-10-31T10:00:00Z", + "updated_at": "2026-10-31T10:00:00Z", + "party": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": [ + "ubo", + "director" + ], + "ownership_percent": 55, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12" + } + } + } + } }, - "is_default": { - "type": "boolean", - "description": "Set this workflow as the default for new sessions." + "400": { + "description": "The merged party is invalid.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "non_field_errors": [ + "Person parties require at least one role." + ] + } + } + } }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ], - "description": "Omit this field to create a published workflow ready for sessions. Use `draft` only when you want to save without publishing." + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." + } + } + } + } + } }, - "features": { - "type": "array", - "minItems": 1, - "description": "Verification features in execution order. The API links each item to the next one and adds one final status node automatically.", - "items": { - "$ref": "#/components/schemas/SimpleWorkflowFeature" + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." + } + } + } + } } }, - "is_white_label_enabled": { - "type": "boolean", - "description": "Enable white-label customization for sessions created with this workflow.", - "default": false + "404": { + "description": "The session or the draft does not exist, or the session is outside the key's application or a scoped key's limits.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "detail": "Session not found." + } + } + } }, - "is_desktop_allowed": { - "type": "boolean", - "description": "Allow the verification flow to run on desktop browsers.", - "default": false + "409": { + "description": "The session is finished (`kyb_session_not_writable`).", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + }, + "code": { + "type": "string" + } + } + }, + "example": { + "detail": "This verification session is no longer accepting changes.", + "code": "kyb_session_not_writable" + } + } + } }, - "max_retry_attempts": { - "type": "integer", - "minimum": 0, - "maximum": 10, - "default": 3, - "description": "Maximum retry attempts allowed after a declined verification. `0` blocks the user after the first decline." + "429": { + "description": "Rate limit exceeded: 300 write (POST, PATCH, DELETE) requests per minute per API key. Wait `Retry-After` seconds before retrying; the `X-RateLimit-*` headers show the budget.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Rate limited": { + "summary": "Budget for the current minute exhausted", + "value": { + "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute." + } + } + } + } + }, + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer", + "minimum": 1, + "example": 30 + } + } + } + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_party_draft(\n \"33333333-4444-5555-6666-777777777777\",\n \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n ownership_percent=55.0,\n)\nprint(result)" }, - "retry_window_days": { - "type": "integer", - "minimum": 1, - "maximum": 365, - "nullable": true, - "default": 7, - "description": "Rolling window in days used to count retries. `null` enforces an all-time limit." + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybPartyDraft(\n \"33333333-4444-5555-6666-777777777777\",\n \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n {\n ownership_percent: 55.0,\n },\n);\nconsole.log(result);" }, - "face_liveness_max_attempts": { - "type": "integer", - "minimum": 1, - "maximum": 3, - "default": 3, - "description": "Maximum liveness submissions per session. Default 3: one initial attempt plus two retries. This value is also copied into generated liveness and age-estimation workflow nodes unless the feature-level config overrides it." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", didit.SessionsUpdateKYBPartyDraftParams{\n\tOwnershipPercent: didit.Float(55.0),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "face_match_max_attempts": { - "type": "integer", - "minimum": 1, - "maximum": 3, - "default": 3, - "description": "Maximum face-match submissions per session. Default 3: one initial attempt plus two retries. This value is also copied into generated face-match workflow nodes unless the feature-level config overrides it." + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybPartyDraftParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", SessionsUpdateKybPartyDraftParams.builder()\n .ownershipPercent(55.0)\n .build());\nSystem.out.println(result);" }, - "session_expiration_time": { - "type": "integer", - "minimum": 3600, - "maximum": 2419200, - "default": 604800, - "description": "Seconds before an unfinished session expires. Minimum 1 hour (3600), maximum 4 weeks (2419200)." - } - } - }, - "SimpleWorkflowUpdateRequest": { - "type": "object", - "description": "Update workflow metadata or replace the full linear feature list. STRICT field whitelist: any key not listed here is rejected with a 400.", - "properties": { - "workflow_label": { - "type": "string", - "maxLength": 50, - "description": "Display name for the workflow (max 50 characters)." + { + "lang": "php", + "label": "PHP", + "source": "sessions->updateKybPartyDraft('33333333-4444-5555-6666-777777777777', '5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d', [\n 'ownership_percent' => 55.0,\n]);\nprint_r($result->toArray());" }, - "is_default": { - "type": "boolean", - "description": "Set this workflow as the default for new sessions." + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_party_draft(\n \"33333333-4444-5555-6666-777777777777\",\n \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n ownership_percent: 55.0\n)\nputs result.to_h" }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ], - "description": "Controls versioning. Omit to update the current version in place (drafts auto-publish). `published` on an already-published version creates and returns a NEW version. `draft` is only valid while the version is still a draft." + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", new SessionsUpdateKybPartyDraftParams\n{\n OwnershipPercent = 55.0,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + }, + "delete": { + "summary": "Delete a KYB party draft", + "description": "Drop one party draft. Declared parties are not affected. Requires `write:businesses`.", + "operationId": "delete_v3_session_kyb_party_draft", + "x-didit-sdk": { + "resource": "sessions", + "method": "delete_kyb_party_draft", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "features": { - "type": "array", - "minItems": 1, - "description": "If provided, this replaces the full feature order and configuration.", - "items": { - "$ref": "#/components/schemas/SimpleWorkflowFeature" + { + "name": "draftId", + "in": "path", + "required": true, + "description": "UUID of the party draft (`draft_id` returned when it was created).", + "schema": { + "type": "string", + "format": "uuid", + "example": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d" } }, - "is_white_label_enabled": { - "type": "boolean", - "description": "Enable white-label customization for sessions created with this workflow." + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Draft deleted. No body." }, - "is_desktop_allowed": { - "type": "boolean", - "description": "Allow the verification flow to run on desktop browsers." - }, - "max_retry_attempts": { - "type": "integer", - "minimum": 0, - "maximum": 10, - "description": "Maximum retry attempts allowed after a declined verification. `0` blocks the user after the first decline." - }, - "retry_window_days": { - "type": "integer", - "minimum": 1, - "maximum": 365, - "nullable": true, - "description": "Rolling window in days used to count retries. `null` enforces an all-time limit." - }, - "face_liveness_max_attempts": { - "type": "integer", - "minimum": 1, - "maximum": 3, - "description": "Maximum liveness submissions per session. This value is also copied into generated liveness and age-estimation workflow nodes unless the feature-level config overrides it." - }, - "face_match_max_attempts": { - "type": "integer", - "minimum": 1, - "maximum": 3, - "description": "Maximum face-match submissions per session. This value is also copied into generated face-match workflow nodes unless the feature-level config overrides it." - }, - "session_expiration_time": { - "type": "integer", - "minimum": 3600, - "maximum": 2419200, - "description": "Seconds before an unfinished session expires. Minimum 1 hour (3600), maximum 4 weeks (2419200)." - } - } - }, - "SimpleWorkflowFeature": { - "type": "object", - "required": [ - "feature" - ], - "properties": { - "feature": { - "type": "string", - "description": "Feature to run. Use the uppercase values shown here.", - "enum": [ - "OCR", - "NFC", - "LIVENESS", - "FACE_MATCH", - "PROOF_OF_ADDRESS", - "QUESTIONNAIRE", - "DOCUMENT_AI", - "PHONE_VERIFICATION", - "EMAIL_VERIFICATION", - "DATABASE_VALIDATION", - "AML", - "IP_ANALYSIS", - "AGE_ESTIMATION", - "KYB_REGISTRY", - "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE", - "SIGNATURE" - ] - }, - "config": { - "type": "object", - "description": "Feature-specific settings. For `QUESTIONNAIRE`, include `questionnaire_uuid` with the `questionnaire_id` returned by the questionnaire create endpoint. For `OCR`, `methods` selects which ID Verification methods each country may use (document capture, non-doc lookup against a government or other authoritative source, and digital identity wallets); omit it and every country is document capture only. For `SIGNATURE`, see [Electronic Signature settings](/management-api/workflows/feature-configs#electronic-signature): `signature_level` accepts `aes` only for now, and workflow documents and their fields are managed in the console, so through the API send documents and fields per session with `signature_documents_source: \"session\"`.", - "additionalProperties": true - }, - "label": { - "type": "string", - "description": "Optional internal label for this workflow node." - } - } - }, - "ReviewItem": { - "type": "object", - "description": "One entry in a session's review / activity feed. Status changes carry `previous_status`, `new_status`, `previous_value`, `new_value`, and `changed_fields`; comments carry `comment` and (for Console comments) `mentioned_emails`; the remaining fields are `null` or empty when they do not apply to the activity type.", - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Unique identifier of this feed entry.", - "example": "de0561bc-5583-4409-9171-1a31a4c8a5f4" - }, - "activity_type": { - "type": "string", - "enum": [ - "COMMENT", - "STATUS_UPDATED", - "KYC_DATA_UPDATED", - "POA_DATA_UPDATED", - "FILE_ADDED", - "FILE_REMOVED", - "AML_ONGOING_MATCH", - "AML_STATUS_UPDATED", - "AML_HIT_STATUS_UPDATED", - "KYB_DATA_UPDATED", - "KYB_DOCUMENT_UPLOADED", - "TAG_ADDED", - "TAG_REMOVED", - "FEATURE_OVERRIDE_PENDING", - "FEATURE_OVERRIDE_APPLIED", - "FEATURE_OVERRIDE_CANCELLED" - ], - "description": "What kind of activity this entry records. `STATUS_UPDATED` rows come from manual decisions (`PATCH /v3/session/{session_id}/update-status/`) and from entries added via `POST …/reviews/` (which default to this type even when no status is recorded). `COMMENT` rows come from Console reviewers; Console detail-page views are also stored as `COMMENT` rows flagged with `metadata.system_event = \"DETAIL_VIEWED\"`. The remaining types track data edits, file changes, tags, and AML monitoring activity. STATUS_UPDATED rows are also written by system actors (e.g. AML ongoing monitoring with actor_type SYSTEM, and automatic feature-status updates), not only by the update-status endpoint and manual review posts. `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` and `FEATURE_OVERRIDE_CANCELLED` record an override of one check's status (`PATCH /v3/session/{session_id}/features/{node_id}/update-status/`): requested to wait for the flow to finish, applied, or cancelled. They carry the check's status in `previous_value` / `new_value` (`{\"status\": ...}`), leave `previous_status` and `new_status` `null`, and name the override in `metadata` (`feature_override_id`, `node_id`, `feature_model`, `forced`, `state`, `cancel_reason`). The entry for the request carries the reviewer's `comment`; an override applied when the flow finishes is recorded with `actor_type` `SYSTEM`.", - "example": "STATUS_UPDATED" - }, - "actor_display": { - "type": "string", - "description": "Human-readable author label, resolved in order: actor's full name → Console account identifier → local part of `actor_email` → `\"API Client\"` (for `API_KEY` actors) → `\"System\"` (for `SYSTEM` actors) → `\"Unknown\"`. Entries created via `POST …/reviews/` always display `\"Unknown\"` because that endpoint records no actor attribution.", - "example": "API Client" - }, - "actor_email": { - "type": "string", - "nullable": true, - "description": "Email of the Console user who performed the action. `null` for API-key and system actors.", - "example": null - }, - "actor_type": { - "type": "string", - "enum": [ - "API_KEY", - "CONSOLE_USER", - "SYSTEM" - ], - "description": "Who performed the action: an API key, a Console user, or Didit itself (`SYSTEM`, e.g. AML ongoing monitoring). Entries created via `POST …/reviews/` carry the default `CONSOLE_USER` regardless of the caller.", - "example": "API_KEY" - }, - "new_status": { - "type": "string", - "nullable": true, - "enum": [ - "Not Started", - "In Progress", - "Approved", - "Declined", - "In Review", - "Expired", - "Abandoned", - "Kyc Expired", - "Resubmitted", - "Awaiting User" - ], - "description": "Session status recorded by this entry (for status updates). `null` for comments and data-change entries.", - "example": "Approved" - }, - "previous_status": { - "type": "string", - "nullable": true, - "enum": [ - "Not Started", - "In Progress", - "Approved", - "Declined", - "In Review", - "Expired", - "Abandoned", - "Kyc Expired", - "Resubmitted", - "Awaiting User" - ], - "description": "Status the session had before the change. Populated on `STATUS_UPDATED` entries written by the update-status endpoint; `null` on entries added via `POST …/reviews/`. Also populated on system-written STATUS_UPDATED rows.", - "example": "In Review" - }, - "comment": { - "type": "string", - "nullable": true, - "description": "Free-text note attached to the entry, or `null`.", - "example": "Document re-checked manually; address matches." - }, - "mentioned_emails": { - "type": "array", - "items": { - "type": "string", - "format": "email" - }, - "description": "Console users `@email`-mentioned in the comment. Always empty for entries created via this API — mention processing is a Console-only feature.", - "example": [] - }, - "previous_value": { - "type": "object", - "nullable": true, - "description": "Snapshot of the changed data before the action, e.g. `{\"status\": \"In Review\"}` on a status change. `null` when nothing was changed.", - "example": { - "status": "In Review" + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." + } + } + } + } } }, - "new_value": { - "type": "object", - "nullable": true, - "description": "Snapshot of the changed data after the action, e.g. `{\"status\": \"Approved\"}`. `null` when nothing was changed.", - "example": { - "status": "Approved" + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." + } + } + } + } } }, - "changed_fields": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Names of the fields modified by this activity (e.g. `[\"status\"]`). Empty for comments and for entries added via `POST …/reviews/`.", - "example": [ - "status" - ] - }, - "metadata": { - "type": "object", - "nullable": true, - "description": "Extra context for system-generated entries. Console detail-page views carry `{\"system_event\": \"DETAIL_VIEWED\", \"detail_type\": \"verification\"}` so they can be filtered out of notification logic. `null` for ordinary entries.", - "example": null - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "When the entry was written, ISO 8601 UTC.", - "example": "2026-06-12T00:19:31.918735Z" - } - } - }, - "QuestionnaireListItem": { - "type": "object", - "description": "One questionnaire version in the list view.", - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Per-version UUID. Use as `{questionnaire_uuid}` for get/update/delete and as `questionnaire_uuid` in a workflow's QUESTIONNAIRE feature config." - }, - "title": { - "type": "string" - }, - "description": { - "type": "string", - "nullable": true - }, - "languages": { - "type": "array", - "items": { - "type": "string" + "404": { + "description": "The session or the draft does not exist, or the session is outside the key's application or a scoped key's limits.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "detail": "Session not found." + } + } } }, - "default_language": { - "type": "string" - }, - "is_active": { - "type": "boolean" - }, - "is_simple_questionnaire": { - "type": "boolean", - "description": "True for linear questionnaires created through this API; false for graph-based questionnaires built in the Console." - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "updated_at": { - "type": "string", - "format": "date-time" + "409": { + "description": "The session is finished (`kyb_session_not_writable`).", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + }, + "code": { + "type": "string" + } + } + }, + "example": { + "detail": "This verification session is no longer accepting changes.", + "code": "kyb_session_not_writable" + } + } + } }, - "question_types": { - "type": "array", - "items": { - "type": "string" + "429": { + "description": "Rate limit exceeded: 300 write (POST, PATCH, DELETE) requests per minute per API key. Wait `Retry-After` seconds before retrying; the `X-RateLimit-*` headers show the budget.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Rate limited": { + "summary": "Budget for the current minute exhausted", + "value": { + "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute." + } + } + } + } }, - "description": "Uppercase element types of the answerable questions, in creation order (e.g. `SHORT_TEXT`, `MULTIPLE_CHOICE`, `FILE_UPLOAD`). Structural `SECTION_HEADER` and `SEPARATOR` elements are excluded. One entry per question, so values can repeat." + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer", + "minimum": 1, + "example": 30 + } + } + } + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.sessions.delete_kyb_party_draft(\n \"33333333-4444-5555-6666-777777777777\",\n \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n)" }, - "workflow_names": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Names of workflows using this questionnaire. Currently always `[]` on this endpoint (populated only in the Console listing)." + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.sessions.deleteKybPartyDraft(\n \"33333333-4444-5555-6666-777777777777\",\n \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n);" }, - "questionnaire_group_id": { - "type": "string", - "format": "uuid", - "description": "Stable identifier that groups all versions of the same questionnaire." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Sessions.DeleteKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", didit.SessionsDeleteKYBPartyDraftParams{}); err != nil {\n\tlog.Fatal(err)\n}" }, - "version": { - "type": "integer", - "description": "Version number within the group, starting at 1." + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().deleteKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\");" }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ] + { + "lang": "php", + "label": "PHP", + "source": "sessions->deleteKybPartyDraft('33333333-4444-5555-6666-777777777777', '5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d');" }, - "published_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When this version was published. `null` for drafts." + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.delete_kyb_party_draft(\n \"33333333-4444-5555-6666-777777777777\",\n \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\"\n)" }, - "is_editable": { - "type": "boolean", - "description": "True when this version is a `draft`." + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Sessions.DeleteKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\");" } - } - }, - "SimpleQuestionnaireRequest": { - "type": "object", - "description": "Create a simple linear questionnaire. The API converts `form_elements` into the internal questionnaire graph.", - "required": [ - "title", - "languages", - "form_elements" + ] + } + }, + "/v3/session/{sessionId}/kyb/parties/submit/": { + "post": { + "summary": "Submit the KYB party drafts", + "description": "Declare the stored drafts as the company's key people. This is the hosted Key People step under your API key: Didit decides from the role settings and ownership thresholds of the workflow which parties must be verified, creates one individual KYC session (or a KYB sub-session for a corporate owner) for each of them, sends the emails the workflow asks for, and advances the session. Each child session is billed like in the hosted flow. The drafts are consumed. Repeating the call after a successful submit changes nothing and answers `200` with `already_submitted: true` and the parties that already exist. The session must be on the Key People step. Send each person's `kyc_session_url` to them, or embed it. Requires `write:businesses`.", + "operationId": "post_v3_session_kyb_parties_submit", + "x-didit-sdk": { + "resource": "sessions", + "method": "submit_kyb_parties", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" ], - "properties": { - "title": { - "type": "string", - "description": "Internal name for the questionnaire." - }, - "description": { - "type": "string", - "nullable": true + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the Business Verification (KYB) session. It must belong to the application of the API key.", + "schema": { + "type": "string", + "format": "uuid", + "example": "33333333-4444-5555-6666-777777777777" + } }, - "languages": { - "type": "array", - "description": "Languages included in every label. Must include `en`.", - "items": { + { + "name": "node_id", + "in": "query", + "required": false, + "description": "Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node.", + "schema": { "type": "string" - }, - "example": [ - "en" - ] - }, - "default_language": { - "type": "string", - "description": "Default language. Must be included in `languages`.", - "example": "en" - }, - "is_active": { - "type": "boolean", - "default": true - }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ], - "description": "Omit this field to create a published questionnaire ready for workflows." - }, - "form_elements": { - "type": "array", - "minItems": 1, - "description": "Questions in the exact order users should see them. Branching and conditional fields are not supported.", - "items": { - "$ref": "#/components/schemas/SimpleQuestionnaireElement" } } - } - }, - "SimpleQuestionnaireUpdateRequest": { - "type": "object", - "description": "Update questionnaire metadata or replace the full linear `form_elements` list.", - "properties": { - "title": { - "type": "string" - }, - "description": { - "type": "string", - "nullable": true - }, - "languages": { - "type": "array", - "items": { - "type": "string" - } - }, - "default_language": { - "type": "string" - }, - "is_active": { - "type": "boolean" - }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ] - }, - "form_elements": { - "type": "array", - "minItems": 1, - "description": "If provided, this replaces the full linear question list.", - "items": { - "$ref": "#/components/schemas/SimpleQuestionnaireElement" + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "locale": { + "type": "string", + "maxLength": 10, + "description": "Locale used to translate the response of the step the session advances to." + } + } + }, + "example": { + "locale": "es" + } } } - } - }, - "SimpleQuestionnaireElement": { - "type": "object", - "required": [ - "element_type", - "label" - ], - "properties": { - "id": { - "type": "string", - "description": "Optional stable question id. If omitted, the API generates `q1`, `q2`, etc. Use lowercase letters, numbers, and underscores for readability.", - "example": "source_of_funds" - }, - "element_type": { - "type": "string", - "description": "Question type. The API accepts these lowercase values and their uppercase equivalents.", - "enum": [ - "short_text", - "long_text", - "dropdown", - "single_choice", - "multiple_choice", - "number", - "image", - "file_upload", - "time", - "email", - "address", - "phone", - "country", - "date_picker", - "consent", - "section_header", - "separator", - "heading", - "paragraph" - ] - }, - "label": { - "type": "object", - "description": "Question label by language code, for example `{ \"en\": \"Source of funds\" }`.", - "additionalProperties": { - "type": "string" + }, + "responses": { + "200": { + "description": "Parties declared (or already declared).", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "valid": { + "type": "boolean" + }, + "next_step": { + "type": "string", + "nullable": true, + "description": "Step the session is on." + }, + "status": { + "type": "string", + "description": "Status of the business session." + }, + "advanced": { + "type": "boolean", + "description": "`true` when this call declared the parties and advanced the session." + }, + "already_submitted": { + "type": "boolean", + "description": "`true` when the parties had been declared by an earlier call." + }, + "kyb_key_people_status": { + "type": "string" + }, + "parties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KYBKeyPeopleParty" + } + } + } + }, + "example": { + "valid": true, + "next_step": "FINISHED", + "status": "In Progress", + "advanced": true, + "already_submitted": false, + "kyb_key_people_status": "In Progress", + "parties": [] + } + } } }, - "description": { - "type": "object", - "nullable": true, - "additionalProperties": { - "type": "string" + "402": { + "description": "The organization has no credit left for the child verification sessions.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "example": { + "detail": "Insufficient credits." + } + } } }, - "placeholder": { - "type": "object", - "nullable": true, - "additionalProperties": { - "type": "string" + "401": { + "description": "The scoped API key has expired. This is the only case that returns `401`: a missing, invalid or revoked key returns `403`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Expired key": { + "summary": "The key's expiry date has passed", + "value": { + "detail": "This API key has expired." + } + } + } + } } }, - "is_required": { - "type": "boolean", - "default": false - }, - "options": { - "type": "array", - "description": "Use for `dropdown`, `single_choice`, and `multiple_choice`. If `value` is omitted, the API generates one from the option label.", - "items": { - "type": "object", - "required": [ - "label" - ], - "properties": { - "value": { - "type": "string" + "403": { + "description": "Authentication or authorization failure. A missing key returns `403`, and so do a key of another application, a scoped key without the permission this endpoint needs, and a request from outside the key's IP allowlist; a wrong, revoked or expired key returns `401`. Distinguish them by `detail`.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } }, - "label": { + "examples": { + "Missing or invalid credentials": { + "summary": "No x-api-key header, or the key failed validation", + "value": { + "detail": "Authentication credentials were not provided or are invalid." + } + }, + "Other application": { + "summary": "A valid key that belongs to a different application than the session", + "value": { + "detail": "You do not have permission to perform this action." + } + }, + "Scoped key without decisions write": { + "summary": "Scoped key lacks decisions: write", + "value": { + "detail": "This API key has no write access to decisions." + } + }, + "IP not allowed": { + "summary": "Request from outside the key's IP allowlist", + "value": { + "detail": "This API key can't be used from this IP address." + } + } + } + } + } + }, + "404": { + "description": "The session does not exist, was deleted, belongs to another application or is outside a scoped key's limits; no detail distinguishes them.", + "content": { + "application/json": { + "schema": { "type": "object", - "additionalProperties": { - "type": "string" + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } } + }, + "example": { + "detail": "Session not found." } } } }, - "max_files": { - "type": "integer", - "minimum": 1, - "maximum": 5, - "description": "Use with `file_upload` or `image`." + "409": { + "description": "`kyb_no_party_drafts`: there is nothing to submit. `kyb_parties_already_submitted`: drafts were added after the parties were declared. `kyb_step_mismatch`: the session is not on the Key People step (`next_step` names its step). `kyb_session_not_writable`: the session is finished.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + }, + "code": { + "type": "string" + }, + "next_step": { + "type": "string" + } + } + }, + "example": { + "detail": "There are no draft parties to submit.", + "code": "kyb_no_party_drafts" + } + } + } }, - "validation": { - "type": "object", - "nullable": true, - "description": "Optional format validation for `short_text`, `long_text`, or `number`. Enforced while the user fills the field (they cannot proceed until it passes) and re-checked by the API on submission.", - "properties": { - "pattern": { - "type": "string", - "description": "Regular expression (ECMA-262 subset) the value must fully match. For `short_text` and `long_text`. Do not add ^/$ anchors; the whole value is matched." - }, - "min_length": { - "type": "integer", - "minimum": 0, - "description": "Minimum number of characters. For `short_text` and `long_text`." - }, - "max_length": { - "type": "integer", - "minimum": 0, - "description": "Maximum number of characters. For `short_text` and `long_text`." - }, - "min": { - "type": "number", - "description": "Minimum numeric value. For `number`." - }, - "max": { - "type": "number", - "description": "Maximum numeric value. For `number`." - }, - "error_message": { - "type": "object", - "description": "Translated message shown when validation fails, keyed by language code.", - "additionalProperties": { - "type": "string" + "429": { + "description": "Rate limit exceeded: 300 write (POST, PATCH, DELETE) requests per minute per API key. Wait `Retry-After` seconds before retrying; the `X-RateLimit-*` headers show the budget.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string", + "description": "Human-readable error message." + } + } + }, + "examples": { + "Rate limited": { + "summary": "Budget for the current minute exhausted", + "value": { + "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute." + } + } + } + } + }, + "headers": { + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer", + "minimum": 1, + "example": 30 } } } } - } - }, - "QuestionnaireDetail": { - "type": "object", - "description": "Full questionnaire detail returned from GET, POST (create) and PATCH (update) endpoints.", - "properties": { - "questionnaire_id": { - "type": "string", - "format": "uuid", - "description": "Unique identifier of the questionnaire. Use this id when referencing the questionnaire from a workflow or in subsequent update/delete requests." + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.submit_kyb_parties(\n \"33333333-4444-5555-6666-777777777777\",\n locale=\"es\",\n)\nprint(result)" }, - "title": { - "type": "string" + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.submitKybParties(\"33333333-4444-5555-6666-777777777777\", {\n locale: \"es\",\n});\nconsole.log(result);" }, - "description": { - "type": "string", - "nullable": true + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.SubmitKYBParties(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsSubmitKYBPartiesParams{\n\tLocale: didit.String(\"es\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "languages": { - "type": "array", - "items": { - "type": "string" - } + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.SessionsSubmitKybPartiesParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().submitKybParties(\"33333333-4444-5555-6666-777777777777\", SessionsSubmitKybPartiesParams.builder()\n .locale(\"es\")\n .build());\nSystem.out.println(result);" }, - "default_language": { - "type": "string" + { + "lang": "php", + "label": "PHP", + "source": "sessions->submitKybParties('33333333-4444-5555-6666-777777777777', [\n 'locale' => 'es',\n]);\nprint_r($result->toArray());" }, - "is_active": { - "type": "boolean" + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.submit_kyb_parties(\n \"33333333-4444-5555-6666-777777777777\",\n locale: \"es\"\n)\nputs result.to_h" }, - "is_simple_questionnaire": { - "type": "boolean" + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.SubmitKybPartiesAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsSubmitKybPartiesParams\n{\n Locale = \"es\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + } + }, + "/v3/session/{sessionId}/files-export/": { + "post": { + "summary": "Export every file of a session", + "description": "Start preparing one ZIP with every image, video and document of a User Verification (KYC) or Business Verification (KYB) session, in original quality: the files are stored in the ZIP as they were captured, never recompressed. Answers `202` with the export; read it with `GET /v3/session/{sessionId}/files-export/{exportId}/` until `status` is `READY`, then download `download_url`. While an export of the same session is still being prepared, that export is returned instead of a new one.\n\nThe ZIP is deleted 24 hours after it is ready, and at once when the session is deleted. A deleted session cannot be exported. Every export and every download link handed out is written to the session's audit log. A scoped API key needs `media: read` and `decisions: read`; a console user needs the privilege to read sessions.", + "operationId": "post_v3_session_files_export", + "x-didit-sdk": { + "resource": "sessions", + "method": "export_files", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs. A deleted session returns `404`.", + "schema": { + "type": "string", + "format": "uuid", + "example": "11111111-2222-3333-4444-555555555555" + } + } + ], + "x-codeSamples": [ + { + "lang": "curl", + "label": "curl", + "source": "curl -X POST 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/files-export/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, - "graph": { - "type": "object", - "description": "Graph structure with start_node and nodes map." + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.export_files(\n \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)" }, - "sections": { - "type": "array", - "description": "Questionnaire content grouped into sections (derived from the graph).", - "items": { - "type": "object" - } + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.exportFiles(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);" }, - "questionnaire_group_id": { - "type": "string", - "format": "uuid", - "description": "Stable identifier that groups all versions of the same questionnaire." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ExportFiles(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "version": { - "type": "integer" + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().exportFiles(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);" }, - "status": { - "type": "string", - "enum": [ - "draft", - "published" - ] + { + "lang": "php", + "label": "PHP", + "source": "sessions->exportFiles('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());" }, - "published_at": { - "type": "string", - "format": "date-time", - "nullable": true + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.export_files(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h" }, - "is_editable": { - "type": "boolean", - "description": "True when the questionnaire can still be edited in place (draft versions)." + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ExportFilesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" } - } - }, - "UserListItem": { - "type": "object", - "description": "A verified user.", - "properties": { - "didit_internal_id": { - "type": "string", - "format": "uuid", - "description": "Didit's stable internal UUID for this user." + ], + "responses": { + "202": { + "description": "The export, being prepared.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SessionFilesExport" + }, + "example": { + "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", + "session_id": "11111111-2222-3333-4444-555555555555", + "status": "PENDING", + "file_count": null, + "size_bytes": null, + "download_url": null, + "expires_at": null, + "error": null, + "created_at": "2026-10-29T12:00:03Z", + "completed_at": null + } + } + } }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "Your unique identifier for this user (passed when creating sessions). This can be null when no vendor identifier was supplied." + "401": { + "$ref": "#/components/responses/Unauthorized" }, - "display_name": { - "type": "string", - "nullable": true, - "description": "Custom display name set by you" + "403": { + "$ref": "#/components/responses/Forbidden" }, - "full_name": { - "type": "string", - "nullable": true, - "description": "Full name extracted from verified documents" + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + } + }, + "/v3/session/{sessionId}/files-export/{exportId}/": { + "get": { + "summary": "Get a session files export", + "description": "Progress of an export started with `POST /v3/session/{sessionId}/files-export/`. Once `status` is `READY`, `download_url` is a signed URL of the ZIP that stays valid for a short time; read the export again for a new one until `expires_at`. Each read that hands out a download link is written to the session's audit log. An export of a deleted session returns `404`.", + "operationId": "get_v3_session_files_export", + "x-didit-sdk": { + "resource": "sessions", + "method": "get_files_export", + "auth": "api_key", + "server": true + }, + "tags": [ + "Sessions" + ], + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs. A deleted session returns `404`.", + "schema": { + "type": "string", + "format": "uuid", + "example": "11111111-2222-3333-4444-555555555555" + } }, - "date_of_birth": { - "type": "string", - "format": "date", - "nullable": true + { + "name": "exportId", + "in": "path", + "required": true, + "description": "The `export_id` returned by `POST /v3/session/{sessionId}/files-export/`.", + "schema": { + "type": "string", + "format": "uuid", + "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + } + } + ], + "x-codeSamples": [ + { + "lang": "curl", + "label": "curl", + "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/' \\\n -H 'x-api-key: YOUR_API_KEY'" }, - "effective_name": { - "type": "string", - "nullable": true, - "description": "Best available name: display_name if set, otherwise full_name" + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.get_files_export(\n \"11111111-2222-3333-4444-555555555555\",\n \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n)\nprint(result)" }, - "status": { - "type": "string", - "enum": [ - "ACTIVE", - "FLAGGED", - "BLOCKED" - ], - "description": "Lifecycle status of the user record (NOT a session status). `ACTIVE` is the default, `FLAGGED` marks the user for manual attention, `BLOCKED` prevents new sessions for this `vendor_data`." + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.getFilesExport(\n \"11111111-2222-3333-4444-555555555555\",\n \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n);\nconsole.log(result);" }, - "portrait_image_url": { - "type": "string", - "nullable": true, - "description": "Presigned URL of the user's portrait photo (expires after a few hours)" + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.GetFilesExport(ctx, \"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" }, - "session_count": { - "type": "integer", - "description": "Total number of verification sessions for this user" + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().getFilesExport(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");\nSystem.out.println(result);" }, - "approved_count": { - "type": "integer", - "description": "Number of approved sessions" + { + "lang": "php", + "label": "PHP", + "source": "sessions->getFilesExport('11111111-2222-3333-4444-555555555555', 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee');\nprint_r($result->toArray());" }, - "declined_count": { - "type": "integer", - "description": "Number of declined sessions" + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.get_files_export(\n \"11111111-2222-3333-4444-555555555555\",\n \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"\n)\nputs result.to_h" }, - "in_review_count": { - "type": "integer", - "description": "Number of sessions in review" + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.GetFilesExportAsync(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ], + "responses": { + "200": { + "description": "The export.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SessionFilesExport" + }, + "example": { + "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", + "session_id": "11111111-2222-3333-4444-555555555555", + "status": "READY", + "file_count": 9, + "size_bytes": 18734120, + "download_url": "https://storage.example.com/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/session-42-files.zip?X-Amz-Signature=...", + "expires_at": "2026-10-30T12:00:41Z", + "error": null, + "created_at": "2026-10-29T12:00:03Z", + "completed_at": "2026-10-29T12:00:41Z" + } + } + } }, - "issuing_states": { - "type": "array", - "items": { + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + } + }, + "/v3/travel-rule/unmatched/": { + "get": { + "summary": "List unmatched Travel Rule deposits", + "description": "Inbound deposits that are still waiting for the originating VASP's Travel Rule data: their transfer is `AWAITING_COUNTERPARTY`, `NOT_ENOUGH_COUNTERPARTY_DATA` or `COUNTERPARTY_VASP_NOT_FOUND`, no received message is paired with them, and nobody matched them by hand. The rows and the filters are the same as in `GET /v3/travel-rule/transfers/`, newest first, paginated with `limit` (default 50) and `offset`. Pair a deposit with the message the originating VASP sent with `POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`.", + "operationId": "listUnmatchedTravelRuleDeposits", + "x-didit-sdk": { + "resource": "travel_rule.unmatched_deposits", + "method": "list", + "auth": "api_key", + "server": true + }, + "tags": [ + "Travel Rule" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "parameters": [ + { + "name": "direction", + "in": "query", + "required": false, + "schema": { "type": "string" }, - "description": "ISO 3166-1 alpha-3 codes of issuing countries seen on this user's approved ID documents, e.g. `[\"USA\", \"ESP\"]`. Empty array when none." + "description": "INBOUND, OUTBOUND, or both comma-separated. Case-sensitive." }, - "approved_emails": { - "type": "array", - "items": { + { + "name": "status", + "in": "query", + "required": false, + "schema": { "type": "string" }, - "description": "Verified email addresses collected from this user's approved sessions, e.g. `[\"john@example.com\"]`." + "description": "One or more transfer statuses, comma-separated." }, - "approved_phones": { - "type": "array", - "items": { + { + "name": "rail", + "in": "query", + "required": false, + "schema": { "type": "string" }, - "description": "Verified phone numbers collected from this user's approved sessions, e.g. `[\"+14155551234\"]`." - }, - "features": { - "type": "object", - "description": "Aggregated per-feature status across all of this user's sessions. Possible keys: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `QUESTIONNAIRE`, `EMAIL_VERIFICATION`, `PHONE`, `AML`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `DATABASE_VALIDATION`. Possible values: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`." + "description": "One or more of INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP, comma-separated." }, - "features_list": { - "type": "array", - "items": { - "type": "object", - "properties": { - "feature": { - "type": "string" - }, - "status": { - "type": "string" - } - } + { + "name": "kind", + "in": "query", + "required": false, + "schema": { + "type": "string" }, - "description": "Same data as `features`, as an ordered array of `{feature, status}` objects." - }, - "last_session_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "Timestamp of the most recent session" - }, - "first_session_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "Timestamp of the first session" - }, - "last_activity_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "Timestamp of the most recent activity on this user (session, transaction, status change, data edit, etc.)." + "description": "withdrawal, deposit or message, comma-separated." }, - "tags": { - "type": "array", - "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "color": { - "type": "string" - } - } + { + "name": "currency", + "in": "query", + "required": false, + "schema": { + "type": "string" }, - "description": "Tags assigned to this user" - }, - "created_at": { - "type": "string", - "format": "date-time" - } - } - }, - "BlocklistItem": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "face", - "document", - "phone", - "email" - ] - }, - "session_id": { - "type": "string", - "format": "uuid" - }, - "session_number": { - "type": "integer" - }, - "blocklisted_at": { - "type": "string", - "format": "date-time" - }, - "face_image": { - "type": "string", - "nullable": true + "description": "The transaction's currency, case-insensitive." }, - "document_type": { - "type": "string", - "nullable": true + { + "name": "start_date", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "date" + }, + "description": "Transfers created on or after this day (UTC), YYYY-MM-DD." }, - "document_number": { - "type": "string", - "nullable": true + { + "name": "end_date", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "date" + }, + "description": "Transfers created on or before this day (UTC), YYYY-MM-DD." }, - "phone_number": { - "type": "string", - "nullable": true + { + "name": "counterparty", + "in": "query", + "required": false, + "schema": { + "type": "string", + "format": "uuid" + }, + "description": "The `id` of a directory entry or Didit network member from GET /v3/travel-rule/vasps/: your transfers with that counterparty. A value that is not a valid id answers 400." }, - "email": { - "type": "string", - "nullable": true - } - } - }, - "UserDetailItem": { - "type": "object", - "description": "Full user detail. Extends UserListItem with metadata, comments, and updated_at.", - "allOf": [ { - "$ref": "#/components/schemas/UserListItem" + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 1000000 + }, + "description": "Page size, default 50." }, { - "type": "object", - "properties": { - "metadata": { - "type": "object", - "description": "Custom metadata JSON you attached to this user. Defaults to `{}`." - }, - "tags": { - "type": "array", - "description": "Tag assignments. NOTE: on detail responses each entry is a tag *link* object (`{uuid, tag: {...}, added_by_email, added_by_name, created_at}`), unlike the flat `{uuid, name, color}` shape used on list responses.", - "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "UUID of the tag assignment (not the tag itself)." - }, - "tag": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "color": { - "type": "string" - }, - "description": { - "type": "string", - "nullable": true - }, - "source": { - "type": "string", - "enum": [ - "didit", - "custom" - ] - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "added_by_email": { - "type": "string", - "nullable": true - }, - "added_by_name": { - "type": "string", - "nullable": true - }, - "created_at": { - "type": "string", - "format": "date-time" - } - } - } - }, - "comments": { - "type": "array", - "items": { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0, + "maximum": 1000000 + }, + "description": "Rows to skip." + } + ], + "responses": { + "200": { + "description": "A page of unmatched deposits.", + "content": { + "application/json": { + "schema": { "type": "object", "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "comment_type": { - "type": "string", - "enum": [ - "COMMENT", - "STATUS_CHANGED", - "METADATA_UPDATED", - "TAG_ADDED", - "TAG_REMOVED", - "PROFILE_UPDATED" - ] - }, - "comment": { - "type": "string", - "nullable": true - }, - "actor_email": { - "type": "string", - "nullable": true + "count": { + "type": "integer" }, - "actor_name": { + "next": { "type": "string", "nullable": true }, - "previous_status": { - "type": "string", - "nullable": true, - "enum": [ - "ACTIVE", - "FLAGGED", - "BLOCKED", - null - ] - }, - "new_status": { + "previous": { "type": "string", - "nullable": true, - "enum": [ - "ACTIVE", - "FLAGGED", - "BLOCKED", - null - ] - }, - "previous_value": { - "type": "object", - "nullable": true, - "description": "Previous field values for PROFILE_UPDATED entries." - }, - "new_value": { - "type": "object", - "nullable": true, - "description": "New field values for PROFILE_UPDATED entries." - }, - "changed_fields": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Names of the fields changed by a PROFILE_UPDATED entry." - }, - "metadata": { - "type": "object", "nullable": true }, - "mentioned_emails": { + "results": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/TravelRuleTransferRow" } - }, - "created_at": { - "type": "string", - "format": "date-time" } } }, - "description": "Activity log and comments for this user (status changes, profile edits, manual notes)." - }, - "updated_at": { - "type": "string", - "format": "date-time" + "example": { + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08", + "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91", + "txn_id": "dep-2026-10-20-0007", + "txn_date": "2026-10-19T08:41:12Z", + "kind": "deposit", + "direction": "INBOUND", + "status": "AWAITING_COUNTERPARTY", + "rail": "TRP", + "asset": "ETH", + "amount": "1.25", + "originator_vasp": "", + "beneficiary_vasp": "Example Counterparty VASP", + "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7", + "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", + "originator_memo": "", + "beneficiary_memo": "", + "originator_wallet_type": "vasp", + "beneficiary_wallet_type": "vasp", + "matched_transaction_id": null, + "deadline_at": null, + "created_at": "2026-10-19T08:41:13Z" + } + ] + } } } - } - ] - }, - "BusinessListItem": { - "type": "object", - "description": "A verified business.", - "properties": { - "didit_internal_id": { - "type": "string", - "format": "uuid", - "description": "Didit's stable internal UUID for this business." }, - "vendor_data": { - "type": "string", - "nullable": true, - "description": "Your unique identifier for this business (passed when creating sessions). This can be null when no vendor identifier was supplied." + "400": { + "description": "A filter value is not valid.", + "content": { + "application/json": { + "example": { + "start_date": [ + "Use the YYYY-MM-DD format." + ] + } + } + } }, - "display_name": { - "type": "string", - "nullable": true, - "description": "Custom display name set by you" + "401": { + "$ref": "#/components/responses/Unauthorized" }, - "legal_name": { - "type": "string", - "nullable": true, - "description": "Official legal name from registry or manual entry" + "403": { + "$ref": "#/components/responses/Forbidden" + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.unmatched_deposits.list():\n print(item)" }, - "registration_number": { - "type": "string", - "nullable": true, - "description": "Company registration or incorporation number" + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.unmatchedDeposits.list()) {\n console.log(item);\n}" }, - "country_code": { - "type": "string", - "nullable": true, - "description": "Country of incorporation (ISO 3166-1 alpha-2, e.g. `GB`, `US`)." + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.UnmatchedDeposits.ListAutoPaging(ctx, didit.TravelRuleUnmatchedDepositsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}" }, - "effective_name": { - "type": "string", - "nullable": true, - "description": "Best available name: display_name if set, otherwise legal_name" + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().unmatchedDeposits().list()) {\n System.out.println(item);\n}" }, - "status": { - "type": "string", - "enum": [ - "ACTIVE", - "FLAGGED", - "BLOCKED" - ], - "description": "Lifecycle status of the business record (NOT a session status). `ACTIVE` is the default, `FLAGGED` marks it for manual attention, `BLOCKED` prevents new sessions for this `vendor_data`." + { + "lang": "php", + "label": "PHP", + "source": "travelRule->unmatchedDeposits->list() as $item) {\n print_r($item->toArray());\n}" }, - "session_count": { - "type": "integer", - "description": "Total number of verification sessions for this business" + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.unmatched_deposits.list.auto_paging_each do |item|\n puts item.to_h\nend" }, - "approved_count": { - "type": "integer", - "description": "Number of approved sessions" + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.UnmatchedDeposits.ListAsync())\n{\n Console.WriteLine(JsonSerializer.Serialize(item));\n}" + } + ] + } + }, + "/v3/travel-rule/unmatched/{transaction_uuid}/match/": { + "post": { + "summary": "Match a Travel Rule deposit to a received message", + "operationId": "matchUnmatchedTravelRuleDeposit", + "x-didit-sdk": { + "resource": "travel_rule.unmatched_deposits", + "method": "match", + "auth": "api_key", + "server": true + }, + "tags": [ + "Travel Rule" + ], + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Pair an inbound deposit that is still waiting for originator data with the Travel Rule message the originating VASP sent for it. The deposit takes the message's originator data, counterparty VASP and rail, and both transfers record the match on their timelines. `transaction_uuid` is the deposit's `transaction_id` from `GET /v3/travel-rule/unmatched/`. `transaction_id` in the body is the received message's `transaction_id`, from a row of `GET /v3/travel-rule/transfers/?kind=message`; the transfer's own `id` is not found. The message must be for the same asset as the deposit. A deposit or message deleted from the Console answers `404`; one that has already moved on (matched, or no longer waiting) answers `409`.", + "parameters": [ + { + "name": "transaction_uuid", + "in": "path", + "required": true, + "description": "The `transaction_id` of the unmatched deposit.", + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TravelRuleManualMatchRequest" + }, + "example": { + "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24" + } + } + } + }, + "responses": { + "200": { + "description": "Both transfers after the match.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TravelRuleManualMatchResponse" + }, + "example": { + "deposit": { + "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08", + "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91", + "txn_id": "dep-2026-10-20-0007", + "txn_date": "2026-10-19T08:41:12Z", + "kind": "deposit", + "direction": "INBOUND", + "status": "AWAITING_COUNTERPARTY", + "rail": "TRP", + "asset": "ETH", + "amount": "1.25", + "originator_vasp": "Example Counterparty VASP", + "beneficiary_vasp": "Example Counterparty VASP", + "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7", + "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", + "originator_memo": "", + "beneficiary_memo": "", + "originator_wallet_type": "vasp", + "beneficiary_wallet_type": "vasp", + "matched_transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24", + "deadline_at": null, + "created_at": "2026-10-19T08:41:13Z" + }, + "message": { + "id": "2b8e6f10-9c3a-47d1-b5e2-0a4c7d9f3e66", + "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24", + "txn_id": "msg-2026-10-20-0003", + "txn_date": "2026-10-19T08:41:12Z", + "kind": "message", + "direction": "INBOUND", + "status": "COMPLETED", + "rail": "TRP", + "asset": "ETH", + "amount": "1.25", + "originator_vasp": "Origin CASP SL", + "beneficiary_vasp": "Example Counterparty VASP", + "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7", + "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", + "originator_memo": "", + "beneficiary_memo": "", + "originator_wallet_type": "vasp", + "beneficiary_wallet_type": "vasp", + "matched_transaction_id": null, + "deadline_at": "2026-10-21T08:41:13Z", + "created_at": "2026-10-19T08:41:13Z" + } + } + } + } }, - "declined_count": { - "type": "integer", - "description": "Number of declined sessions" + "400": { + "description": "Validation error: `transaction_id` is missing, is the deposit itself, is not a received Travel Rule message, or is for a different asset than the deposit; or the transaction in the path is not an inbound deposit.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string" + } + } + }, + "examples": { + "Error": { + "value": { + "transaction_id": [ + "The travel rule message is for a different asset than the deposit." + ] + } + } + } + } + } }, - "in_review_count": { - "type": "integer", - "description": "Number of sessions in review" + "401": { + "$ref": "#/components/responses/Unauthorized" }, - "features": { - "type": "object", - "description": "Aggregated per-feature status across all of this business's KYB sessions. Currently the only key is `KYB` (the registry company check status). Possible values: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`." + "403": { + "$ref": "#/components/responses/Forbidden" }, - "features_list": { - "type": "array", - "items": { - "type": "object", - "properties": { - "feature": { - "type": "string" + "404": { + "description": "Unknown deposit or message, or one of them was deleted.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string" + } + } }, - "status": { - "type": "string" + "example": { + "detail": "No TravelRuleTransfer matches the given query." } } - }, - "description": "Same data as `features`, as an ordered array of `{feature, status}` objects." + } }, - "last_session_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "Timestamp of the most recent session" + "409": { + "description": "The deposit is no longer waiting for originator data, or the message is already matched to a deposit.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "detail": { + "type": "string" + } + } + }, + "examples": { + "Error": { + "value": { + "detail": "This deposit is no longer waiting for originator data." + } + } + } + } + } + } + }, + "x-codeSamples": [ + { + "lang": "python", + "label": "Python", + "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.unmatched_deposits.match(\n \"11111111-2222-3333-4444-555555555555\",\n transaction_id=\"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n)\nprint(result)" }, - "first_session_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "Timestamp of the first session" + { + "lang": "javascript", + "label": "Node.js", + "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.unmatchedDeposits.match(\"11111111-2222-3333-4444-555555555555\", {\n transaction_id: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n});\nconsole.log(result);" }, - "last_activity_at": { + { + "lang": "go", + "label": "Go", + "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UnmatchedDeposits.Match(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleManualMatchRequest{\n\tTransactionID: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)" + }, + { + "lang": "java", + "label": "Java", + "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleManualMatchRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().unmatchedDeposits().match(\"11111111-2222-3333-4444-555555555555\", TravelRuleManualMatchRequest.builder()\n .transactionId(\"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\")\n .build());\nSystem.out.println(result);" + }, + { + "lang": "php", + "label": "PHP", + "source": "travelRule->unmatchedDeposits->match('11111111-2222-3333-4444-555555555555', [\n 'transaction_id' => 'e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24',\n]);\nprint_r($result->toArray());" + }, + { + "lang": "ruby", + "label": "Ruby", + "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.unmatched_deposits.match(\n \"11111111-2222-3333-4444-555555555555\",\n transaction_id: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\"\n)\nputs result.to_h" + }, + { + "lang": "csharp", + "label": ".NET", + "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UnmatchedDeposits.MatchAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleManualMatchRequest\n{\n TransactionId = \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));" + } + ] + } + } + }, + "components": { + "schemas": { + "DocumentAIDetectedCode": { + "type": "object", + "required": [ + "type", + "page_number", + "position", + "x", + "y", + "width", + "height", + "page_width", + "page_height", + "raw_payload", + "parsed_payload" + ], + "properties": { + "type": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "Timestamp of the most recent activity (status change, session update, etc.)" + "description": "Detected symbology, for example `QR_CODE`, `CODE_128`, `EAN_13`, `DATA_MATRIX`, or `PDF_417`." }, - "tags": { + "page_number": { + "type": "integer", + "minimum": 1, + "description": "1-based page number." + }, + "position": { "type": "array", + "nullable": true, + "description": "Detected polygon in rendered-page pixel coordinates. `null` when no reliable location is available.", "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "color": { - "type": "string" - } + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "integer" } - }, - "description": "Tags assigned to this business" + } }, - "created_at": { + "x": { + "type": "integer", + "nullable": true, + "description": "Left edge of the bounding box in rendered-page pixels." + }, + "y": { + "type": "integer", + "nullable": true, + "description": "Top edge of the bounding box in rendered-page pixels." + }, + "width": { + "type": "integer", + "nullable": true, + "description": "Bounding-box width in rendered-page pixels." + }, + "height": { + "type": "integer", + "nullable": true, + "description": "Bounding-box height in rendered-page pixels." + }, + "page_width": { + "type": "integer", + "description": "Rendered page width in pixels." + }, + "page_height": { + "type": "integer", + "description": "Rendered page height in pixels." + }, + "raw_payload": { "type": "string", - "format": "date-time" - } - } - }, - "BusinessDetailItem": { - "type": "object", - "description": "Full business detail. Extends BusinessListItem with metadata and updated_at.", - "allOf": [ - { - "$ref": "#/components/schemas/BusinessListItem" + "description": "Raw decoder payload as a base64 string when available; otherwise an empty string." }, - { - "type": "object", - "properties": { - "metadata": { - "type": "object", - "description": "Custom metadata JSON you attached to this business. Defaults to `{}`." - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } + "parsed_payload": { + "nullable": true, + "description": "Decoded string or structured value. `null` when the code was located but could not be decoded." } - ] + } }, - "TransactionDetail": { + "SessionImportJob": { "type": "object", - "description": "Full monitoring record for one transaction, as returned by `GET /v3/transactions/{transaction_id}/` and `POST /v3/transactions/`.", + "required": [ + "uuid", + "status", + "import_type", + "source_format", + "source_filename", + "total_rows", + "processed_rows", + "created_count", + "updated_count", + "skipped_count", + "failed_count" + ], "properties": { "uuid": { "type": "string", "format": "uuid", - "description": "Didit-stable transaction identifier. Use as `{transaction_id}` for follow-up calls." + "description": "Import job id. Use this value to poll progress and fetch row errors." }, - "environment": { + "status": { "type": "string", "enum": [ - "live", - "sandbox" - ], - "description": "Environment of the application that owns the transaction. A `sandbox` transaction is stored but never evaluated, screened, notified or billed, so its empty `rule_runs` means \"not evaluated\"." + "PENDING", + "PROCESSING", + "COMPLETED", + "FAILED", + "PAUSED", + "CANCELLED", + "READY" + ] }, - "transaction_number": { - "type": "integer", - "description": "Application-scoped sequential transaction number shown in Console (e.g. `4123`)." + "import_type": { + "type": "string", + "enum": [ + "user_verification", + "business_verification", + "status_rules", + "transactions" + ] }, - "txn_id": { + "source_format": { "type": "string", - "description": "The `transaction_id` you supplied at create time (max 128 chars). Unique per application." + "enum": [ + "csv", + "ndjson" + ] }, - "txn_date": { + "source_filename": { + "type": "string" + }, + "total_rows": { + "type": "integer", + "format": "int64" + }, + "processed_rows": { + "type": "integer", + "format": "int64" + }, + "checkpoint_row": { + "type": "integer", + "format": "int64" + }, + "created_count": { + "type": "integer", + "format": "int64" + }, + "updated_count": { + "type": "integer", + "format": "int64" + }, + "skipped_count": { + "type": "integer", + "format": "int64" + }, + "failed_count": { + "type": "integer", + "format": "int64" + }, + "total_media_bytes": { + "type": "integer", + "format": "int64" + }, + "last_error": { "type": "string", - "format": "date-time", - "description": "When the transaction occurred (from `transaction_at`; defaults to submission time)." + "nullable": true }, - "zone_id": { + "created_at": { "type": "string", - "nullable": true, - "description": "IANA time zone identifier provided at create time." + "format": "date-time" }, - "transaction_type": { + "updated_at": { "type": "string", - "description": "Top-level category as stored: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, `auditTrailEvent`. Note multi-word values are echoed back in camelCase even when submitted in snake_case." + "format": "date-time" }, - "action_type": { + "started_at": { "type": "string", - "description": "Sub-type within the category (e.g. `deposit`, `withdrawal`, `transfer`). Defaults to the category when not supplied." + "format": "date-time", + "nullable": true }, - "direction": { + "completed_at": { "type": "string", - "enum": [ - "INBOUND", - "OUTBOUND" - ], - "description": "Direction relative to the subject. Stored uppercase regardless of the casing submitted (`in`/`out`/`inbound`/`outbound` are accepted on input)." + "format": "date-time", + "nullable": true }, - "status": { + "state": { "type": "string", "enum": [ - "APPROVED", - "IN_REVIEW", - "DECLINED", - "AWAITING_USER" + "ready", + "queued", + "running", + "paused", + "completed", + "errors", + "failed", + "cancelled" ], - "description": "Current monitoring verdict. Transactions are created `APPROVED`; rules may flip them to `IN_REVIEW`/`DECLINED` synchronously." + "description": "The job's state as the console shows it; `errors` is a completed job with rejected rows." }, "source": { "type": "string", "enum": [ - "LIVE", - "IMPORTED" - ], - "description": "How the record originated: `LIVE` for transactions submitted through the API or SDK, `IMPORTED` for transactions loaded through the console import." - }, - "amount": { - "type": "string", - "description": "Transaction amount as a decimal string with trailing zeros stripped (e.g. `\"1500\"`, `\"0.5\"`, `\"0.123456789012345678\"`). Up to 18 decimal places." + "file", + "api", + "provider" + ] }, - "currency": { + "provider": { "type": "string", - "description": "Currency code of `amount`. Any ISO 4217 alphabetic code is accepted (e.g. `EUR`, `USD`, `NGN`), as is a crypto asset symbol (e.g. `BTC`). Prefer a currently-circulating code. Not every accepted code has an exchange rate: when none is available for the code (for example the ISO accounting unit `XSU`, or a crypto symbol Didit does not price), automatic conversion fails and `preferred_currency_amount` is returned null unless the request supplied a pre-converted `amount_in_default_currency`." + "description": "Migration source; empty for a file or API import." }, - "currency_type": { - "type": "string", - "nullable": true, - "description": "`fiat` or `crypto`, as submitted in `currency_kind`." + "provider_options": { + "type": "object" }, - "amount_in_default_currency": { + "credential_hint": { "type": "string", - "nullable": true, - "description": "Pre-converted amount you supplied, as a decimal string with trailing zeros stripped." + "description": "The first characters of the key the migration holds. The key itself is never returned." }, - "default_currency_code": { + "credentials_expires_at": { "type": "string", + "format": "date-time", "nullable": true }, - "preferred_currency_amount": { + "resumes_at": { "type": "string", + "format": "date-time", "nullable": true, - "description": "`amount` converted to the application's preferred currency, when available." + "description": "When a job paused by the provider's rate limit resumes by itself." }, - "preferred_currency_code": { + "status_mapping": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "is_dry_run": { + "type": "boolean" + }, + "dry_run_summary": { + "type": "object", + "description": "What a dry run found: `total`, `by_status`, `already_in_didit`, `same_person`, `not_finished`, `failed`, `unmapped_statuses`." + }, + "face_templates_enabled": { + "type": "boolean" + }, + "lawful_basis_confirmed_at": { "type": "string", + "format": "date-time", "nullable": true }, - "payment_details": { - "type": "string", - "nullable": true, - "description": "Free-text payment reference or memo from the submission." + "not_finished_count": { + "type": "integer", + "format": "int64" }, - "payment_txn_id": { - "type": "string", - "nullable": true, - "description": "External payment system reference (e.g. blockchain transaction hash) from `payment_reference_id`." + "same_person_count": { + "type": "integer", + "format": "int64" }, - "score": { + "face_templates_count": { "type": "integer", - "description": "Risk score accumulated by rules (typically 0–100). Higher = riskier." + "format": "int64" }, - "severity": { - "type": "string", - "nullable": true, - "enum": [ - "UNKNOWN", - "LOW", - "MEDIUM", - "HIGH", - "CRITICAL" - ], - "description": "Categorical risk severity set by rules/providers (`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). `null` until something sets it." + "face_duplicates_count": { + "type": "integer", + "format": "int64" }, - "decision_reason_code": { - "type": "string", - "nullable": true, - "description": "Machine-readable reason for the current `status`." + "face_blocklist_hits_count": { + "type": "integer", + "format": "int64" }, - "decision_reason_label": { + "created_by_name": { "type": "string", - "nullable": true, - "description": "Human-readable label for `decision_reason_code`." + "nullable": true }, - "vendor_data": { + "created_by_email": { "type": "string", - "nullable": true, - "description": "Convenience copy of the applicant's `vendor_data`." - }, - "metadata": { + "nullable": true + } + } + }, + "SessionImportError": { + "type": "object", + "required": [ + "uuid", + "row_number", + "error", + "raw_row" + ], + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "row_number": { + "type": "integer", + "format": "int64" + }, + "external_id": { + "type": "string", + "nullable": true + }, + "error": { + "type": "string" + }, + "raw_row": { + "type": "object", + "additionalProperties": true + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "BrandingCustomizationUpdate": { + "type": "object", + "description": "Partial branding update body. Provide only the fields you want to change. Hex colors accept `#RRGGBB` or `#RRGGBBAA`. Custom domain and white-label email are not accepted here.", + "properties": { + "color_primary": { + "type": "string", + "description": "Headers / primary text color." + }, + "color_secondary": { + "type": "string", + "description": "Paragraph / secondary text color." + }, + "color_background": { + "type": "string", + "description": "Page background color." + }, + "color_panel": { + "type": "string", + "description": "Panel / accent color." + }, + "color_panel_10": { + "type": "string", + "description": "Panel color at 10% opacity." + }, + "color_on_panel_1": { + "type": "string", + "description": "Support text color on panels." + }, + "color_on_panel_2": { + "type": "string", + "description": "Pill / badge color on panels." + }, + "color_on_background": { + "type": "string", + "description": "Text color on background." + }, + "color_button_1": { + "type": "string", + "description": "Primary button color." + }, + "color_button_2": { + "type": "string", + "description": "Secondary button color." + }, + "color_button_text_1": { + "type": "string", + "description": "Primary button text color." + }, + "color_button_text_2": { + "type": "string", + "description": "Secondary button text color." + }, + "color_pill_text": { + "type": "string", + "description": "Text color for pills, inputs and selectors." + }, + "border_radius_panel": { + "type": "integer", + "minimum": 0, + "description": "Panel corner radius in pixels." + }, + "border_radius_buttons": { + "type": "integer", + "minimum": 0, + "description": "Button corner radius in pixels." + }, + "font_family": { + "type": "string", + "description": "Google Font family name (e.g. `Inter`, `AR One Sans`)." + }, + "font_weight": { + "type": "string", + "description": "Font weight available for the selected family (e.g. `regular`, `500`, `700`)." + }, + "app_public_name": { + "type": "string", + "nullable": true, + "description": "Public name shown in the verification flow." + }, + "privacy_policy_url": { + "type": "string", + "nullable": true, + "description": "Privacy policy URL shown to the end user." + }, + "skip_welcome_screen": { + "type": "boolean", + "description": "Skip the initial welcome screen." + }, + "disable_login_with_didit": { + "type": "boolean", + "description": "Continue as guest instead of showing the login-with-Didit screen. Cannot be set back to `false` while a custom domain is configured (400)." + }, + "hide_progress_bar": { + "type": "boolean", + "description": "Hide the progress bar during the flow." + }, + "callback_seconds": { + "type": "integer", + "minimum": 0, + "description": "Delay (seconds) before redirecting to the callback URL." + }, + "delete_logo_square": { + "type": "boolean", + "description": "When `true`, removes the current square logo." + }, + "delete_logo_rectangular": { + "type": "boolean", + "description": "When `true`, removes the current rectangular logo." + }, + "delete_logo_rectangular_dark": { + "type": "boolean", + "description": "When `true`, removes the current dark-mode logo, and `logo_rectangular_dark` then reads `null`. If the same multipart request also uploads `image_rectangular_dark`, the upload wins." + }, + "delete_favicon": { + "type": "boolean", + "description": "When `true`, removes the current favicon." + } + } + }, + "BrandingCustomization": { + "type": "object", + "description": "White-label branding for an application: colors, fonts, radii, logo URLs and UI/UX options. Logo URLs are read-only (set them by uploading images). Custom domain and white-label email are not included.", + "properties": { + "color_primary": { + "type": "string" + }, + "color_secondary": { + "type": "string" + }, + "color_background": { + "type": "string" + }, + "color_panel": { + "type": "string" + }, + "color_panel_10": { + "type": "string" + }, + "color_on_panel_1": { + "type": "string" + }, + "color_on_panel_2": { + "type": "string" + }, + "color_on_background": { + "type": "string" + }, + "color_button_1": { + "type": "string" + }, + "color_button_2": { + "type": "string" + }, + "color_button_text_1": { + "type": "string" + }, + "color_button_text_2": { + "type": "string" + }, + "color_pill_text": { + "type": "string" + }, + "border_radius_panel": { + "type": "integer" + }, + "border_radius_buttons": { + "type": "integer" + }, + "font_family": { + "type": "string" + }, + "font_weight": { + "type": "string" + }, + "font_url": { + "type": "string", + "nullable": true, + "description": "Read-only. Resolved Google Fonts stylesheet URL for the selected family." + }, + "logo_square": { + "type": "string", + "nullable": true, + "description": "Read-only URL of the square logo. Upload via `image_square`." + }, + "logo_rectangular": { + "type": "string", + "nullable": true, + "description": "Read-only URL of the rectangular logo. Upload via `image_rectangular`." + }, + "logo_rectangular_dark": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "Read-only. Temporary signed URL of the rectangular logo for dark mode, shown on a dark background. `null` when no dark logo is set or rectangular logos are not shown for your account. Upload it with `image_rectangular_dark`." + }, + "favicon": { + "type": "string", + "nullable": true, + "description": "Read-only URL of the favicon. Upload via `image_favicon`." + }, + "app_public_name": { + "type": "string", + "nullable": true + }, + "privacy_policy_url": { + "type": "string", + "nullable": true + }, + "skip_welcome_screen": { + "type": "boolean" + }, + "disable_login_with_didit": { + "type": "boolean" + }, + "hide_progress_bar": { + "type": "boolean" + }, + "callback_seconds": { + "type": "integer" + } + } + }, + "WebhookEvent": { + "type": "string", + "description": "Supported webhook event name. Use these exact strings in `subscribed_events`; unsupported values are rejected.", + "enum": [ + "status.updated", + "data.updated", + "user.status.updated", + "user.data.updated", + "business.status.updated", + "business.data.updated", + "activity.created", + "transaction.created", + "transaction.status.updated", + "travel_rule.status.updated", + "workflow.compliance_changed", + "transaction_rule_suggestions.created", + "auth.signup", + "auth.login", + "auth.login_failed", + "auth.password_reset_requested", + "auth.password_reset_completed", + "auth.mfa_changed", + "auth.new_device", + "auth.account_locked", + "investigator.report.ready", + "investigator.decision.automated", + "investigator.decision.overridden", + "investigator.decision.contested", + "investigator.question.raised", + "investigator.automation.paused", + "investigator.rfi.answered", + "investigator.rfi.overdue", + "investigator.drift.detected", + "investigator.sla.breached", + "investigator.qa.failed", + "investigator.external.report.ready" + ] + }, + "WebhookSubscribedEvents": { + "type": "array", + "description": "Event filter for this webhook destination. Didit delivers only webhooks whose event type exactly matches one of these values — there is no wildcard subscription. When sent, the list must contain at least one valid event (an explicit `[]` is rejected with 400); a destination whose list is empty (field omitted at create) receives nothing. On update the list is replaced wholesale, never merged.", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/components/schemas/WebhookEvent" + }, + "example": [ + "status.updated", + "data.updated" + ] + }, + "PhoneVerificationSendResponse": { + "type": "object", + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "description": "Session id of the verification. A `Retry` send returns the same `request_id` as the original send. This id appears in the Business Console, is returned again by a finalized `POST /v3/phone/check/`, and can be passed to `GET /v3/session/{sessionId}/decision/`." + }, + "status": { + "type": "string", + "enum": [ + "Success", + "Retry", + "Blocked" + ], + "description": "`Success` — OTP sent to a new verification. `Retry` — OTP re-sent for the pending verification created by a previous send. `Blocked` — the anti-fraud layer refused to send; the verification is immediately finalized as `Declined` and nothing is billed." + }, + "reason": { + "type": "string", + "nullable": true, + "description": "Why a send was `Blocked` (e.g., `repeated_attempts`, `suspicious`, `spam`). `null` on `Success` and `Retry`." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "Echo of the `vendor_data` stored on the session (from the first send)." + }, + "metadata": { + "type": "object", + "nullable": true, + "description": "Echo of the `metadata` stored on the session (from the first send)." + } + } + }, + "PhoneVerificationCheckResponse": { + "type": "object", + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "description": "On `Approved`/`Declined`: the session id of the matched verification — identical to the `request_id` returned by `POST /v3/phone/send/`. On `Failed` and `Expired or Not Found`: a random one-off UUID that cannot be looked up later." + }, + "status": { + "type": "string", + "enum": [ + "Approved", + "Declined", + "Failed", + "Expired or Not Found" + ], + "description": "`Approved` — correct code, no declining risk. `Declined` — terminal: a declining risk matched or the attempt budget (3) was exhausted. `Failed` — wrong code, attempts remaining. `Expired or Not Found` — no pending verification for this number in the last 5 minutes." + }, + "message": { + "type": "string", + "description": "Human-readable explanation of the outcome, including the number of attempts remaining after a wrong code." + }, + "phone": { + "type": "object", + "nullable": true, + "description": "Full phone report. Present (non-null) only on finalized outcomes (`Approved`/`Declined`); `null` on `Failed` and absent on `Expired or Not Found`.", + "properties": { + "status": { + "type": "string", + "enum": [ + "Approved", + "Declined", + "In Review", + "Not Finished", + "Expired" + ], + "description": "Final status of the phone verification. Matches the top-level `status` for finalized checks." + }, + "phone_number_prefix": { + "type": "string", + "description": "Country calling code with leading `+` (e.g., `+1`).", + "example": "+1" + }, + "phone_number": { + "type": "string", + "description": "National number without the country calling code.", + "example": "4155552671" + }, + "full_number": { + "type": "string", + "description": "Complete number in E.164 format.", + "example": "+14155552671" + }, + "country_code": { + "type": "string", + "nullable": true, + "description": "ISO 3166-1 alpha-2 country of the number.", + "example": "US" + }, + "country_name": { + "type": "string", + "description": "Full country name derived from `country_code`.", + "example": "United States" + }, + "carrier": { + "type": "object", + "description": "Current network serving the number, from the carrier lookup run at finalization.", + "properties": { + "name": { + "type": "string", + "description": "Carrier name. Empty string when the lookup could not identify it." + }, + "type": { + "type": "string", + "description": "Line type reported by the lookup: `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `pager`, `payphone`, `satellite`, `service`, `shared_cost`, `short_codes_commercial`, `calling_cards`, `local_rate`, `universal_access`, `voice_mail`, `other`, or `unknown`." + } + } + }, + "is_disposable": { + "type": "boolean", + "description": "`true` when the number belongs to a temporary/burner number service." + }, + "is_virtual": { + "type": "boolean", + "description": "`true` when the line type is virtual (`voip`, `isp`, or `vpn`)." + }, + "verification_method": { + "type": "string", + "description": "Channel that actually delivered the OTP once delivery is confirmed (e.g., `whatsapp`, `sms`); until then, the requested channel." + }, + "verification_attempts": { + "type": "integer", + "description": "Number of OTP sends for this verification (1, or 2 after a retry)." + }, + "verified_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the correct code was entered. `null` if the verification was never approved." + }, + "warnings": { + "type": "array", + "description": "Risk warnings recorded during the verification (duplicate, disposable, VoIP, attempts exceeded, blocklist, etc.). Empty array when there are none.", + "items": { + "type": "object", + "properties": { + "feature": { + "type": "string", + "description": "Feature that produced the warning. Always `PHONE` here." + }, + "risk": { + "type": "string", + "description": "Machine-readable risk code." + }, + "additional_data": { + "type": "object", + "nullable": true, + "description": "Risk-specific context (e.g., the duplicated session id for duplicate risks). `null` when the risk carries no extra data." + }, + "log_type": { + "type": "string", + "enum": [ + "error", + "warning", + "information" + ], + "description": "Severity. `error` risks decline the verification, `warning` flags it for review, `information` is recorded without affecting the status." + }, + "short_description": { + "type": "string", + "description": "Human-readable one-line summary of the risk." + }, + "long_description": { + "type": "string", + "description": "Human-readable explanation of the risk." + } + } + } + }, + "lifecycle": { + "type": "array", + "description": "Chronological audit trail of the verification. Event `type` is one of `PHONE_VERIFICATION_MESSAGE_SENT`, `PHONE_VERIFICATION_RETRY_MESSAGE_SENT`, `PHONE_VERIFICATION_BLOCKED`, `PHONE_DELIVERY_DELIVERED`, `PHONE_DELIVERY_UNDELIVERABLE`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `PHONE_VERIFICATION_APPROVED`, `PHONE_VERIFICATION_DECLINED`, `PHONE_VERIFICATION_IN_REVIEW`, `PHONE_VERIFICATION_EXPIRED`.", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Event type." + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When the event happened." + }, + "details": { + "type": "object", + "nullable": true, + "description": "Event-specific payload. Send events: `{status, reason, channel, actual_channel}` (`actual_channel` is filled once delivery is confirmed). Delivery events: `{channel, status}`. Code-entry events: `{code_tried, status}`. Final-status events: `null`, or `{reason}` when declined or in review." + }, + "fee": { + "type": "number", + "description": "USD amount billed for this event. Non-zero only on send events (the delivery price); 0 for code entries, delivery confirmations, and status events." + } + } + } + }, + "matches": { + "type": "array", + "description": "Other sessions of your application (KYC, KYB, or API) where the same phone number was used by a different user (different `vendor_data`). Up to 5 entries, a synthetic list-entry blocklist match first when present (session-derived matches keep query order). Empty array when there are no matches.", + "items": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "format": "uuid", + "description": "Session id of the other verification that used this phone number." + }, + "session_number": { + "type": "integer", + "description": "Human-friendly sequential number of that session." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "`vendor_data` of that session." + }, + "verification_date": { + "type": "string", + "description": "When that session was created (`YYYY-MM-DDTHH:MM:SSZ`)." + }, + "phone_number": { + "type": "string", + "description": "The matched phone number." + }, + "status": { + "type": "string", + "description": "Status of that session (e.g., `Approved`, `Declined`, `In Progress`)." + }, + "is_blocklisted": { + "type": "boolean", + "description": "Whether the phone number is on your application's blocklist." + }, + "api_service": { + "type": "string", + "nullable": true, + "description": "For API-type sessions, the standalone API that created it (e.g., `PHONE_VERIFICATION`); `null` for regular verification sessions." + }, + "source": { + "type": "string", + "description": "Where the match was found. Usually `session`; a blocklist hit via an organization list entry prepends a synthetic match with `source: \"list_entry\"` and null `session_id`/`session_number`." + } + } + } + }, + "phone_social": { + "$ref": "#/components/schemas/PhoneSocialFootprint" + }, + "phone_intelligence": { + "allOf": [ + { + "$ref": "#/components/schemas/PhoneIntelligence" + } + ], + "description": "Phone intelligence signals. Present only when `enable_enrichment` was `true` on the check." + } + } + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "`vendor_data` of the matched verification's session. `null` on `Expired or Not Found`." + }, + "metadata": { + "type": "object", + "nullable": true, + "description": "`metadata` of the matched verification's session. `null` on `Expired or Not Found`." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of this check response." + } + } + }, + "EmailVerificationSendResponse": { + "type": "object", + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "description": "Session id of the verification. A `Retry` send returns the same `request_id` as the original send. This id appears in the Business Console, is returned again by a finalized `POST /v3/email/check/`, and can be passed to `GET /v3/session/{sessionId}/decision/`." + }, + "status": { + "type": "string", + "enum": [ + "Success", + "Retry", + "Undeliverable" + ], + "description": "`Success` — OTP emailed to a new verification (billed). `Retry` — fresh OTP emailed for the pending verification created by a previous send (free). `Undeliverable` — the address failed deliverability validation or the message could not be sent; the verification is immediately finalized as `Declined` and nothing is billed." + }, + "reason": { + "type": "string", + "nullable": true, + "enum": [ + "email_can_not_be_delivered", + null + ], + "description": "`email_can_not_be_delivered` when `status` is `Undeliverable`; `null` otherwise." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "Echo of the `vendor_data` stored on the session (from the first send)." + }, + "metadata": { + "type": "object", + "nullable": true, + "description": "Echo of the `metadata` stored on the session (from the first send)." + } + } + }, + "EmailVerificationCheckResponse": { + "type": "object", + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "description": "On `Approved`/`Declined`: the session id of the matched verification — identical to the `request_id` returned by `POST /v3/email/send/`. On `Failed` and `Expired or Not Found`: a random one-off UUID that cannot be looked up later." + }, + "status": { + "type": "string", + "enum": [ + "Approved", + "Declined", + "Failed", + "Expired or Not Found" + ], + "description": "`Approved` — correct code, no declining risk. `Declined` — terminal: a declining risk matched or the attempt budget (3) was exhausted. `Failed` — wrong code, attempts remaining. `Expired or Not Found` — no pending verification for this address in the last 5 minutes." + }, + "message": { + "type": "string", + "description": "Human-readable explanation of the outcome, including the number of attempts remaining after a wrong code." + }, + "email": { + "type": "object", + "nullable": true, + "description": "Full email report. Present (non-null) only on finalized outcomes (`Approved`/`Declined`); `null` on `Failed` and absent on `Expired or Not Found`.", + "properties": { + "status": { + "type": "string", + "enum": [ + "Approved", + "Declined", + "In Review", + "Not Finished", + "Expired" + ], + "description": "Final status of the email verification. Matches the top-level `status` for finalized checks." + }, + "email": { + "type": "string", + "format": "email", + "description": "The verified email address.", + "example": "alice@example.com" + }, + "is_breached": { + "type": "boolean", + "description": "`true` when the address appears in known data breaches (breach intelligence lookup run at finalization)." + }, + "breaches": { + "type": "array", + "description": "Up to 5 most recent known breaches containing this address. Empty array (or omitted) when `is_breached` is `false`.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Breach identifier." + }, + "domain": { + "type": "string", + "description": "Domain of the breached service." + }, + "breach_date": { + "type": "string", + "format": "date", + "description": "Date the breach occurred." + }, + "breach_emails_count": { + "type": "integer", + "description": "Total number of accounts exposed in the breach." + }, + "description": { + "type": "string", + "description": "Human-readable description of the breach (may contain HTML markup)." + }, + "logo_path": { + "type": "string", + "description": "URL of the breached service's logo." + }, + "data_classes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Categories of data exposed, in snake_case (e.g., `email_addresses`, `passwords`)." + }, + "is_verified": { + "type": "boolean", + "description": "Whether the breach has been verified as legitimate." + } + } + } + }, + "is_disposable": { + "type": "boolean", + "description": "`true` when the domain belongs to a known disposable/temporary-mail provider." + }, + "is_undeliverable": { + "type": "boolean", + "description": "`true` when the address cannot receive mail (failed syntax or DNS/MX validation, or the message bounced)." + }, + "verification_attempts": { + "type": "integer", + "description": "Number of OTP sends for this verification (1, or 2 after a retry)." + }, + "verified_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the correct code was entered. `null` if the verification was never approved." + }, + "warnings": { + "type": "array", + "description": "Risk warnings recorded during the verification (duplicate, breached, disposable, undeliverable, attempts exceeded, blocklist, etc.). Empty array when there are none.", + "items": { + "type": "object", + "properties": { + "feature": { + "type": "string", + "description": "Feature that produced the warning. Always `EMAIL` here." + }, + "risk": { + "type": "string", + "description": "Machine-readable risk code." + }, + "additional_data": { + "type": "object", + "nullable": true, + "description": "Risk-specific context (e.g., the duplicated session id for duplicate risks). `null` when the risk carries no extra data." + }, + "log_type": { + "type": "string", + "enum": [ + "error", + "warning", + "information" + ], + "description": "Severity. `error` risks decline the verification, `warning` flags it for review, `information` is recorded without affecting the status." + }, + "short_description": { + "type": "string", + "description": "Human-readable one-line summary of the risk." + }, + "long_description": { + "type": "string", + "description": "Human-readable explanation of the risk." + } + } + } + }, + "lifecycle": { + "type": "array", + "description": "Chronological audit trail of the verification. Event `type` is one of `EMAIL_VERIFICATION_MESSAGE_SENT`, `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `EMAIL_VERIFICATION_APPROVED`, `EMAIL_VERIFICATION_DECLINED`, `EMAIL_VERIFICATION_IN_REVIEW`, `EMAIL_VERIFICATION_EXPIRED`.", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Event type." + }, + "timestamp": { + "type": "string", + "format": "date-time", + "description": "When the event happened." + }, + "details": { + "type": "object", + "nullable": true, + "description": "Event-specific payload. Send events: `{status, reason}`. Code-entry events: `{code_tried, status}`. Final-status events: `null`, or `{reason}` when declined or in review." + }, + "fee": { + "type": "number", + "description": "USD amount billed for this event. Non-zero only on the first successful send; 0 for retries, code entries, and status events." + } + } + } + }, + "matches": { + "type": "array", + "description": "Other sessions of your application (KYC, KYB, or API) where the same email address was used by a different user (different `vendor_data`). Up to 5 entries; a synthetic list-entry blocklist match is prepended when present (and only when no session-derived blocklisted email exists) — session-derived matches keep created_at order. Empty array when there are no matches.", + "items": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "format": "uuid", + "description": "Session id of the other verification that used this email address." + }, + "session_number": { + "type": "integer", + "description": "Human-friendly sequential number of that session." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "`vendor_data` of that session." + }, + "verification_date": { + "type": "string", + "description": "When that session was created (`YYYY-MM-DDTHH:MM:SSZ`)." + }, + "email": { + "type": "string", + "description": "The matched email address." + }, + "status": { + "type": "string", + "description": "Status of that session (e.g., `Approved`, `Declined`, `In Progress`)." + }, + "is_blocklisted": { + "type": "boolean", + "description": "Whether the email address is on your application's blocklist." + }, + "api_service": { + "type": "string", + "nullable": true, + "description": "For API-type sessions, the standalone API that created it (e.g., `PHONE_VERIFICATION`); `null` for regular verification sessions." + }, + "source": { + "type": "string", + "description": "Where the match was found. Usually `session`; a blocklist hit via an organization list entry prepends a synthetic match with `source: \"list_entry\"` and null `session_id`/`session_number`." + } + } + } + }, + "email_social": { + "$ref": "#/components/schemas/EmailSocialFootprint" + }, + "email_intelligence": { + "allOf": [ + { + "$ref": "#/components/schemas/EmailIntelligence" + } + ], + "description": "Email intelligence signals. Present only when `enable_enrichment` was `true` on the check." + } + } + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "`vendor_data` of the matched verification's session. `null` on `Expired or Not Found`." + }, + "metadata": { + "type": "object", + "nullable": true, + "description": "`metadata` of the matched verification's session. `null` on `Expired or Not Found`." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of this check response." + } + } + }, + "WorkflowListItem": { + "type": "object", + "description": "One workflow version in the list view.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Per-version UUID. Use as `{settings_uuid}` for get/update/delete, and as `workflow_id` when creating sessions." + }, + "workflow_id": { + "type": "string", + "format": "uuid", + "description": "Stable group ID shared by every version of the same workflow. Equals `uuid` for version 1." + }, + "workflow_label": { + "type": "string", + "description": "Display name for the workflow." + }, + "workflow_type": { + "type": "string", + "nullable": true, + "description": "Base type for simple workflows: `kyc`, `kyb`, `adaptive_age_verification`, `biometric_authentication`, etc. `null` for graph-based workflows without a KYB feature." + }, + "is_default": { + "type": "boolean", + "description": "Whether this is the default workflow for new sessions." + }, + "is_archived": { + "type": "boolean" + }, + "is_white_label_enabled": { + "type": "boolean", + "description": "Whether white-label customization applies to sessions created with this workflow." + }, + "total_price": { + "type": "number", + "description": "Fixed price per verification in USD (JSON number, excludes variable-priced features such as DATABASE_VALIDATION and PHONE_VERIFICATION)." + }, + "min_price": { + "type": "number", + "description": "Cheapest fixed price across workflow-graph paths, in USD." + }, + "max_price": { + "type": "number", + "description": "Most expensive fixed price across workflow-graph paths, in USD." + }, + "features": { + "type": "string", + "description": "Enabled features as a single `\" + \"`-joined string, e.g. `\"OCR + LIVENESS + FACE_MATCH\"`. Split on `\" + \"` to get a list." + }, + "is_simple_workflow": { + "type": "boolean", + "description": "True when the workflow has no custom workflow graph." + }, + "is_editable": { + "type": "boolean", + "description": "True when this version is a `draft` (drafts are editable in place; published versions are immutable in the Console)." + }, + "workflow_url": { + "type": "string", + "format": "uri", + "description": "Public shareable verification URL for this workflow (`https://verify.didit.me/u/`)." + }, + "max_retry_attempts": { + "type": "integer", + "description": "Maximum retry attempts allowed after a declined verification (0-10)." + }, + "retry_window_days": { + "type": "integer", + "nullable": true, + "description": "Rolling window in days used to count retries (1-365). `null` = all-time limit." + }, + "session_expiration_time": { + "type": "integer", + "description": "Seconds before an unfinished session expires (3600-2419200)." + }, + "version": { + "type": "integer", + "description": "Version number within the `workflow_id` group, starting at 1." + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ], + "description": "Version status. New sessions use the latest `published` version of a group." + }, + "has_draft": { + "type": "boolean", + "description": "True when any version in this `workflow_id` group is currently a draft." + }, + "created_by": { + "type": "object", + "nullable": true, + "description": "Who created this version: `{name, email, type}` where `type` is `user` (Console user, `email` set) or `api_key` (`name` is the client id, `email` is null). `null` when no creator was recorded.", + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "enum": [ + "user", + "api_key" + ] + } + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "SimpleWorkflowRequest": { + "type": "object", + "description": "Create a simple linear workflow. The API converts this feature list into a node-based workflow graph internally. STRICT field whitelist: any key not listed here (including `workflow_type`) is rejected with a 400.", + "required": [ + "features" + ], + "properties": { + "workflow_label": { + "type": "string", + "maxLength": 50, + "default": "ID Verification", + "description": "Display name for the workflow (max 50 characters). Defaults to `\"ID Verification\"` when omitted — always set it so workflows stay distinguishable.", + "example": "Standard KYC" + }, + "is_default": { + "type": "boolean", + "description": "Set this workflow as the default for new sessions." + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ], + "description": "Omit this field to create a published workflow ready for sessions. Use `draft` only when you want to save without publishing." + }, + "features": { + "type": "array", + "minItems": 1, + "description": "Verification features in execution order. The API links each item to the next one and adds one final status node automatically.", + "items": { + "$ref": "#/components/schemas/SimpleWorkflowFeature" + } + }, + "is_white_label_enabled": { + "type": "boolean", + "description": "Enable white-label customization for sessions created with this workflow.", + "default": false + }, + "is_desktop_allowed": { + "type": "boolean", + "description": "Allow the verification flow to run on desktop browsers.", + "default": false + }, + "max_retry_attempts": { + "type": "integer", + "minimum": 0, + "maximum": 10, + "default": 3, + "description": "Maximum retry attempts allowed after a declined verification. `0` blocks the user after the first decline." + }, + "retry_window_days": { + "type": "integer", + "minimum": 1, + "maximum": 365, + "nullable": true, + "default": 7, + "description": "Rolling window in days used to count retries. `null` enforces an all-time limit." + }, + "face_liveness_max_attempts": { + "type": "integer", + "minimum": 1, + "maximum": 3, + "default": 3, + "description": "Maximum liveness submissions per session. Default 3: one initial attempt plus two retries. This value is also copied into generated liveness and age-estimation workflow nodes unless the feature-level config overrides it." + }, + "face_match_max_attempts": { + "type": "integer", + "minimum": 1, + "maximum": 3, + "default": 3, + "description": "Maximum face-match submissions per session. Default 3: one initial attempt plus two retries. This value is also copied into generated face-match workflow nodes unless the feature-level config overrides it." + }, + "session_expiration_time": { + "type": "integer", + "minimum": 3600, + "maximum": 2419200, + "default": 604800, + "description": "Seconds before an unfinished session expires. Minimum 1 hour (3600), maximum 4 weeks (2419200)." + } + } + }, + "SimpleWorkflowUpdateRequest": { + "type": "object", + "description": "Update workflow metadata or replace the full linear feature list. STRICT field whitelist: any key not listed here is rejected with a 400.", + "properties": { + "workflow_label": { + "type": "string", + "maxLength": 50, + "description": "Display name for the workflow (max 50 characters)." + }, + "is_default": { + "type": "boolean", + "description": "Set this workflow as the default for new sessions." + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ], + "description": "Controls versioning. Omit to update the current version in place (drafts auto-publish). `published` on an already-published version creates and returns a NEW version. `draft` is only valid while the version is still a draft." + }, + "features": { + "type": "array", + "minItems": 1, + "description": "If provided, this replaces the full feature order and configuration.", + "items": { + "$ref": "#/components/schemas/SimpleWorkflowFeature" + } + }, + "is_white_label_enabled": { + "type": "boolean", + "description": "Enable white-label customization for sessions created with this workflow." + }, + "is_desktop_allowed": { + "type": "boolean", + "description": "Allow the verification flow to run on desktop browsers." + }, + "max_retry_attempts": { + "type": "integer", + "minimum": 0, + "maximum": 10, + "description": "Maximum retry attempts allowed after a declined verification. `0` blocks the user after the first decline." + }, + "retry_window_days": { + "type": "integer", + "minimum": 1, + "maximum": 365, + "nullable": true, + "description": "Rolling window in days used to count retries. `null` enforces an all-time limit." + }, + "face_liveness_max_attempts": { + "type": "integer", + "minimum": 1, + "maximum": 3, + "description": "Maximum liveness submissions per session. This value is also copied into generated liveness and age-estimation workflow nodes unless the feature-level config overrides it." + }, + "face_match_max_attempts": { + "type": "integer", + "minimum": 1, + "maximum": 3, + "description": "Maximum face-match submissions per session. This value is also copied into generated face-match workflow nodes unless the feature-level config overrides it." + }, + "session_expiration_time": { + "type": "integer", + "minimum": 3600, + "maximum": 2419200, + "description": "Seconds before an unfinished session expires. Minimum 1 hour (3600), maximum 4 weeks (2419200)." + } + } + }, + "SimpleWorkflowFeature": { + "type": "object", + "required": [ + "feature" + ], + "properties": { + "feature": { + "type": "string", + "description": "Feature to run. Use the uppercase values shown here.", + "enum": [ + "OCR", + "NFC", + "LIVENESS", + "FACE_MATCH", + "PROOF_OF_ADDRESS", + "QUESTIONNAIRE", + "DOCUMENT_AI", + "PHONE_VERIFICATION", + "EMAIL_VERIFICATION", + "DATABASE_VALIDATION", + "AML", + "IP_ANALYSIS", + "AGE_ESTIMATION", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "SIGNATURE" + ] + }, + "config": { + "type": "object", + "description": "Feature-specific settings. For `QUESTIONNAIRE`, include `questionnaire_uuid` with the `questionnaire_id` returned by the questionnaire create endpoint. For `SIGNATURE`, a workflow that goes live needs a document to sign: set `signature_documents_source` to `session` or `both` so each session can bring its own, or send `status: \"draft\"` and add the documents before you publish. `signature_level: \"aes\"` is refused with `aes_not_available` while `signature_availability.aes` is `false` on the workflow. For `OCR`, `methods` selects which ID Verification methods each country may use (document capture, non-doc lookup against a government or other authoritative source, and digital identity wallets); omit it and every country is document capture only. For `SIGNATURE`, see [E-signature settings](/management-api/workflows/feature-configs#e-signature): `signature_level` accepts `simple` (the default, no ID verification, email or phone needed) and `aes` for now, and workflow documents and their fields are managed in the console, so through the API send documents and fields per session with `signature_documents_source: \"session\"`.", + "additionalProperties": true + }, + "label": { + "type": "string", + "description": "Optional internal label for this workflow node." + } + } + }, + "ReviewItem": { + "type": "object", + "description": "One entry in a session's review / activity feed. Status changes carry `previous_status`, `new_status`, `previous_value`, `new_value`, and `changed_fields`; comments carry `comment` and (for Console comments) `mentioned_emails`; the remaining fields are `null` or empty when they do not apply to the activity type.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of this feed entry.", + "example": "de0561bc-5583-4409-9171-1a31a4c8a5f4" + }, + "activity_type": { + "type": "string", + "enum": [ + "COMMENT", + "STATUS_UPDATED", + "KYC_DATA_UPDATED", + "POA_DATA_UPDATED", + "FILE_ADDED", + "FILE_REMOVED", + "AML_ONGOING_MATCH", + "AML_STATUS_UPDATED", + "AML_HIT_STATUS_UPDATED", + "KYB_DATA_UPDATED", + "KYB_DOCUMENT_UPLOADED", + "TAG_ADDED", + "TAG_REMOVED", + "FEATURE_OVERRIDE_PENDING", + "FEATURE_OVERRIDE_APPLIED", + "FEATURE_OVERRIDE_CANCELLED" + ], + "description": "What kind of activity this entry records. `STATUS_UPDATED` rows come from manual decisions (`PATCH /v3/session/{session_id}/update-status/`) and from entries added via `POST …/reviews/` (which default to this type even when no status is recorded). `COMMENT` rows come from Console reviewers; Console detail-page views are also stored as `COMMENT` rows flagged with `metadata.system_event = \"DETAIL_VIEWED\"`. The remaining types track data edits, file changes, tags, and AML monitoring activity. STATUS_UPDATED rows are also written by system actors (e.g. AML ongoing monitoring with actor_type SYSTEM, and automatic feature-status updates), not only by the update-status endpoint and manual review posts. `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` and `FEATURE_OVERRIDE_CANCELLED` record an override of one check's status (`PATCH /v3/session/{session_id}/features/{node_id}/update-status/`): requested to wait for the flow to finish, applied, or cancelled. They carry the check's status in `previous_value` / `new_value` (`{\"status\": ...}`), leave `previous_status` and `new_status` `null`, and name the override in `metadata` (`feature_override_id`, `node_id`, `feature_model`, `forced`, `state`, `cancel_reason`). The entry for the request carries the reviewer's `comment`; an override applied when the flow finishes is recorded with `actor_type` `SYSTEM`.", + "example": "STATUS_UPDATED" + }, + "actor_display": { + "type": "string", + "description": "Human-readable author label, resolved in order: actor's full name → Console account identifier → local part of `actor_email` → `\"API Client\"` (for `API_KEY` actors) → `\"System\"` (for `SYSTEM` actors) → `\"Unknown\"`. Entries created via `POST …/reviews/` always display `\"Unknown\"` because that endpoint records no actor attribution.", + "example": "API Client" + }, + "actor_email": { + "type": "string", + "nullable": true, + "description": "Email of the Console user who performed the action. `null` for API-key and system actors.", + "example": null + }, + "actor_type": { + "type": "string", + "enum": [ + "API_KEY", + "CONSOLE_USER", + "SYSTEM" + ], + "description": "Who performed the action: an API key, a Console user, or Didit itself (`SYSTEM`, e.g. AML ongoing monitoring). Entries created via `POST …/reviews/` carry the default `CONSOLE_USER` regardless of the caller.", + "example": "API_KEY" + }, + "new_status": { + "type": "string", + "nullable": true, + "enum": [ + "Not Started", + "In Progress", + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned", + "Kyc Expired", + "Resubmitted", + "Awaiting User" + ], + "description": "Session status recorded by this entry (for status updates). `null` for comments and data-change entries.", + "example": "Approved" + }, + "previous_status": { + "type": "string", + "nullable": true, + "enum": [ + "Not Started", + "In Progress", + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned", + "Kyc Expired", + "Resubmitted", + "Awaiting User" + ], + "description": "Status the session had before the change. Populated on `STATUS_UPDATED` entries written by the update-status endpoint; `null` on entries added via `POST …/reviews/`. Also populated on system-written STATUS_UPDATED rows.", + "example": "In Review" + }, + "comment": { + "type": "string", + "nullable": true, + "description": "Free-text note attached to the entry, or `null`.", + "example": "Document re-checked manually; address matches." + }, + "mentioned_emails": { + "type": "array", + "items": { + "type": "string", + "format": "email" + }, + "description": "Console users `@email`-mentioned in the comment. Always empty for entries created via this API — mention processing is a Console-only feature.", + "example": [] + }, + "previous_value": { + "type": "object", + "nullable": true, + "description": "Snapshot of the changed data before the action, e.g. `{\"status\": \"In Review\"}` on a status change. `null` when nothing was changed.", + "example": { + "status": "In Review" + } + }, + "new_value": { + "type": "object", + "nullable": true, + "description": "Snapshot of the changed data after the action, e.g. `{\"status\": \"Approved\"}`. `null` when nothing was changed.", + "example": { + "status": "Approved" + } + }, + "changed_fields": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Names of the fields modified by this activity (e.g. `[\"status\"]`). Empty for comments and for entries added via `POST …/reviews/`.", + "example": [ + "status" + ] + }, + "metadata": { + "type": "object", + "nullable": true, + "description": "Extra context for system-generated entries. Console detail-page views carry `{\"system_event\": \"DETAIL_VIEWED\", \"detail_type\": \"verification\"}` so they can be filtered out of notification logic. `null` for ordinary entries.", + "example": null + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the entry was written, ISO 8601 UTC.", + "example": "2026-06-12T00:19:31.918735Z" + } + } + }, + "QuestionnaireListItem": { + "type": "object", + "description": "One questionnaire version in the list view.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Per-version UUID. Use as `{questionnaire_uuid}` for get/update/delete and as `questionnaire_uuid` in a workflow's QUESTIONNAIRE feature config." + }, + "title": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "languages": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_language": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "is_simple_questionnaire": { + "type": "boolean", + "description": "True for linear questionnaires created through this API; false for graph-based questionnaires built in the Console." + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "question_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Uppercase element types of the answerable questions, in creation order (e.g. `SHORT_TEXT`, `MULTIPLE_CHOICE`, `FILE_UPLOAD`). Structural `SECTION_HEADER` and `SEPARATOR` elements are excluded. One entry per question, so values can repeat." + }, + "workflow_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Names of workflows using this questionnaire. Currently always `[]` on this endpoint (populated only in the Console listing)." + }, + "questionnaire_group_id": { + "type": "string", + "format": "uuid", + "description": "Stable identifier that groups all versions of the same questionnaire." + }, + "version": { + "type": "integer", + "description": "Version number within the group, starting at 1." + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ] + }, + "published_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When this version was published. `null` for drafts." + }, + "is_editable": { + "type": "boolean", + "description": "True when this version is a `draft`." + } + } + }, + "SimpleQuestionnaireRequest": { + "type": "object", + "description": "Create a simple linear questionnaire. The API converts `form_elements` into the internal questionnaire graph.", + "required": [ + "title", + "languages", + "form_elements" + ], + "properties": { + "title": { + "type": "string", + "description": "Internal name for the questionnaire." + }, + "description": { + "type": "string", + "nullable": true + }, + "languages": { + "type": "array", + "description": "Languages included in every label. Must include `en`.", + "items": { + "type": "string" + }, + "example": [ + "en" + ] + }, + "default_language": { + "type": "string", + "description": "Default language. Must be included in `languages`.", + "example": "en" + }, + "is_active": { + "type": "boolean", + "default": true + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ], + "description": "Omit this field to create a published questionnaire ready for workflows." + }, + "form_elements": { + "type": "array", + "minItems": 1, + "description": "Questions in the exact order users should see them. Branching and conditional fields are not supported.", + "items": { + "$ref": "#/components/schemas/SimpleQuestionnaireElement" + } + } + } + }, + "SimpleQuestionnaireUpdateRequest": { + "type": "object", + "description": "Update questionnaire metadata or replace the full linear `form_elements` list.", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "languages": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_language": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ] + }, + "form_elements": { + "type": "array", + "minItems": 1, + "description": "If provided, this replaces the full linear question list.", + "items": { + "$ref": "#/components/schemas/SimpleQuestionnaireElement" + } + } + } + }, + "SimpleQuestionnaireElement": { + "type": "object", + "required": [ + "element_type", + "label" + ], + "properties": { + "id": { + "type": "string", + "description": "Optional stable question id. If omitted, the API generates `q1`, `q2`, etc. Use lowercase letters, numbers, and underscores for readability.", + "example": "source_of_funds" + }, + "element_type": { + "type": "string", + "description": "Question type. The API accepts these lowercase values and their uppercase equivalents.", + "enum": [ + "short_text", + "long_text", + "dropdown", + "single_choice", + "multiple_choice", + "number", + "image", + "file_upload", + "time", + "email", + "address", + "phone", + "country", + "date_picker", + "consent", + "section_header", + "separator", + "heading", + "paragraph" + ] + }, + "label": { + "type": "object", + "description": "Question label by language code, for example `{ \"en\": \"Source of funds\" }`.", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "object", + "nullable": true, + "additionalProperties": { + "type": "string" + } + }, + "placeholder": { + "type": "object", + "nullable": true, + "additionalProperties": { + "type": "string" + } + }, + "is_required": { + "type": "boolean", + "default": false + }, + "options": { + "type": "array", + "description": "Use for `dropdown`, `single_choice`, and `multiple_choice`. If `value` is omitted, the API generates one from the option label.", + "items": { + "type": "object", + "required": [ + "label" + ], + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "max_files": { + "type": "integer", + "minimum": 1, + "maximum": 5, + "description": "Use with `file_upload` or `image`." + }, + "validation": { + "type": "object", + "nullable": true, + "description": "Optional format validation for `short_text`, `long_text`, or `number`. Enforced while the user fills the field (they cannot proceed until it passes) and re-checked by the API on submission.", + "properties": { + "pattern": { + "type": "string", + "description": "Regular expression (ECMA-262 subset) the value must fully match. For `short_text` and `long_text`. Do not add ^/$ anchors; the whole value is matched." + }, + "min_length": { + "type": "integer", + "minimum": 0, + "description": "Minimum number of characters. For `short_text` and `long_text`." + }, + "max_length": { + "type": "integer", + "minimum": 0, + "description": "Maximum number of characters. For `short_text` and `long_text`." + }, + "min": { + "type": "number", + "description": "Minimum numeric value. For `number`." + }, + "max": { + "type": "number", + "description": "Maximum numeric value. For `number`." + }, + "error_message": { + "type": "object", + "description": "Translated message shown when validation fails, keyed by language code.", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "QuestionnaireDetail": { + "type": "object", + "description": "Full questionnaire detail returned from GET, POST (create) and PATCH (update) endpoints.", + "properties": { + "questionnaire_id": { + "type": "string", + "format": "uuid", + "description": "Unique identifier of the questionnaire. Use this id when referencing the questionnaire from a workflow or in subsequent update/delete requests." + }, + "title": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "languages": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_language": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "is_simple_questionnaire": { + "type": "boolean" + }, + "graph": { + "type": "object", + "description": "Graph structure with start_node and nodes map." + }, + "sections": { + "type": "array", + "description": "Questionnaire content grouped into sections (derived from the graph).", + "items": { + "type": "object" + } + }, + "questionnaire_group_id": { + "type": "string", + "format": "uuid", + "description": "Stable identifier that groups all versions of the same questionnaire." + }, + "version": { + "type": "integer" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "published" + ] + }, + "published_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "is_editable": { + "type": "boolean", + "description": "True when the questionnaire can still be edited in place (draft versions)." + } + } + }, + "UserListItem": { + "type": "object", + "description": "A verified user.", + "properties": { + "didit_internal_id": { + "type": "string", + "format": "uuid", + "description": "Didit's stable internal UUID for this user." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "Your unique identifier for this user (passed when creating sessions). This can be null when no vendor identifier was supplied." + }, + "display_name": { + "type": "string", + "nullable": true, + "description": "Custom display name set by you" + }, + "full_name": { + "type": "string", + "nullable": true, + "description": "Full name extracted from verified documents" + }, + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true + }, + "effective_name": { + "type": "string", + "nullable": true, + "description": "Best available name: display_name if set, otherwise full_name" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVE", + "FLAGGED", + "BLOCKED" + ], + "description": "Lifecycle status of the user record (NOT a session status). `ACTIVE` is the default, `FLAGGED` marks the user for manual attention, `BLOCKED` prevents new sessions for this `vendor_data`." + }, + "portrait_image_url": { + "type": "string", + "nullable": true, + "description": "Presigned URL of the user's portrait photo (expires after a few hours)" + }, + "session_count": { + "type": "integer", + "description": "Total number of verification sessions for this user" + }, + "approved_count": { + "type": "integer", + "description": "Number of approved sessions" + }, + "declined_count": { + "type": "integer", + "description": "Number of declined sessions" + }, + "in_review_count": { + "type": "integer", + "description": "Number of sessions in review" + }, + "issuing_states": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ISO 3166-1 alpha-3 codes of issuing countries seen on this user's approved ID documents, e.g. `[\"USA\", \"ESP\"]`. Empty array when none." + }, + "approved_emails": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Verified email addresses collected from this user's approved sessions, e.g. `[\"john@example.com\"]`." + }, + "approved_phones": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Verified phone numbers collected from this user's approved sessions, e.g. `[\"+14155551234\"]`." + }, + "features": { + "type": "object", + "description": "Aggregated per-feature status across all of this user's sessions. Possible keys: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `QUESTIONNAIRE`, `EMAIL_VERIFICATION`, `PHONE`, `AML`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `DATABASE_VALIDATION`. Possible values: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`." + }, + "features_list": { + "type": "array", + "items": { + "type": "object", + "properties": { + "feature": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "description": "Same data as `features`, as an ordered array of `{feature, status}` objects." + }, + "last_session_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the most recent session" + }, + "first_session_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the first session" + }, + "last_activity_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the most recent activity on this user (session, transaction, status change, data edit, etc.)." + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "color": { + "type": "string" + } + } + }, + "description": "Tags assigned to this user" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "BlocklistItem": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "face", + "document", + "phone", + "email" + ] + }, + "session_id": { + "type": "string", + "format": "uuid" + }, + "session_number": { + "type": "integer" + }, + "blocklisted_at": { + "type": "string", + "format": "date-time" + }, + "face_image": { + "type": "string", + "nullable": true + }, + "document_type": { + "type": "string", + "nullable": true + }, + "document_number": { + "type": "string", + "nullable": true + }, + "phone_number": { + "type": "string", + "nullable": true + }, + "email": { + "type": "string", + "nullable": true + } + } + }, + "UserDetailItem": { + "type": "object", + "description": "Full user detail. Extends UserListItem with metadata, comments, and updated_at.", + "allOf": [ + { + "$ref": "#/components/schemas/UserListItem" + }, + { + "type": "object", + "properties": { + "metadata": { + "type": "object", + "description": "Custom metadata JSON you attached to this user. Defaults to `{}`." + }, + "tags": { + "type": "array", + "description": "Tag assignments. NOTE: on detail responses each entry is a tag *link* object (`{uuid, tag: {...}, added_by_email, added_by_name, created_at}`), unlike the flat `{uuid, name, color}` shape used on list responses.", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "UUID of the tag assignment (not the tag itself)." + }, + "tag": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "color": { + "type": "string" + }, + "description": { + "type": "string", + "nullable": true + }, + "source": { + "type": "string", + "enum": [ + "didit", + "custom" + ] + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "added_by_email": { + "type": "string", + "nullable": true + }, + "added_by_name": { + "type": "string", + "nullable": true + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + } + }, + "comments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "comment_type": { + "type": "string", + "enum": [ + "COMMENT", + "STATUS_CHANGED", + "METADATA_UPDATED", + "TAG_ADDED", + "TAG_REMOVED", + "PROFILE_UPDATED" + ] + }, + "comment": { + "type": "string", + "nullable": true + }, + "actor_email": { + "type": "string", + "nullable": true + }, + "actor_name": { + "type": "string", + "nullable": true + }, + "previous_status": { + "type": "string", + "nullable": true, + "enum": [ + "ACTIVE", + "FLAGGED", + "BLOCKED", + null + ] + }, + "new_status": { + "type": "string", + "nullable": true, + "enum": [ + "ACTIVE", + "FLAGGED", + "BLOCKED", + null + ] + }, + "previous_value": { + "type": "object", + "nullable": true, + "description": "Previous field values for PROFILE_UPDATED entries." + }, + "new_value": { + "type": "object", + "nullable": true, + "description": "New field values for PROFILE_UPDATED entries." + }, + "changed_fields": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Names of the fields changed by a PROFILE_UPDATED entry." + }, + "metadata": { + "type": "object", + "nullable": true + }, + "mentioned_emails": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "description": "Activity log and comments for this user (status changes, profile edits, manual notes)." + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + } + ] + }, + "BusinessListItem": { + "type": "object", + "description": "A verified business.", + "properties": { + "didit_internal_id": { + "type": "string", + "format": "uuid", + "description": "Didit's stable internal UUID for this business." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "Your unique identifier for this business (passed when creating sessions). This can be null when no vendor identifier was supplied." + }, + "display_name": { + "type": "string", + "nullable": true, + "description": "Custom display name set by you" + }, + "legal_name": { + "type": "string", + "nullable": true, + "description": "Official legal name from registry or manual entry" + }, + "registration_number": { + "type": "string", + "nullable": true, + "description": "Company registration or incorporation number" + }, + "country_code": { + "type": "string", + "nullable": true, + "description": "Country of incorporation (ISO 3166-1 alpha-2, e.g. `GB`, `US`)." + }, + "effective_name": { + "type": "string", + "nullable": true, + "description": "Best available name: display_name if set, otherwise legal_name" + }, + "status": { + "type": "string", + "enum": [ + "ACTIVE", + "FLAGGED", + "BLOCKED" + ], + "description": "Lifecycle status of the business record (NOT a session status). `ACTIVE` is the default, `FLAGGED` marks it for manual attention, `BLOCKED` prevents new sessions for this `vendor_data`." + }, + "session_count": { + "type": "integer", + "description": "Total number of verification sessions for this business" + }, + "approved_count": { + "type": "integer", + "description": "Number of approved sessions" + }, + "declined_count": { + "type": "integer", + "description": "Number of declined sessions" + }, + "in_review_count": { + "type": "integer", + "description": "Number of sessions in review" + }, + "features": { + "type": "object", + "description": "Aggregated per-feature status across all of this business's KYB sessions. Currently the only key is `KYB` (the registry company check status). Possible values: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`." + }, + "features_list": { + "type": "array", + "items": { + "type": "object", + "properties": { + "feature": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "description": "Same data as `features`, as an ordered array of `{feature, status}` objects." + }, + "last_session_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the most recent session" + }, + "first_session_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the first session" + }, + "last_activity_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Timestamp of the most recent activity (status change, session update, etc.)" + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "color": { + "type": "string" + } + } + }, + "description": "Tags assigned to this business" + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "BusinessDetailItem": { + "type": "object", + "description": "Full business detail. Extends BusinessListItem with metadata and updated_at.", + "allOf": [ + { + "$ref": "#/components/schemas/BusinessListItem" + }, + { + "type": "object", + "properties": { + "metadata": { + "type": "object", + "description": "Custom metadata JSON you attached to this business. Defaults to `{}`." + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + } + ] + }, + "TransactionDetail": { + "type": "object", + "description": "Full monitoring record for one transaction, as returned by `GET /v3/transactions/{transaction_id}/` and `POST /v3/transactions/`.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Didit-stable transaction identifier. Use as `{transaction_id}` for follow-up calls." + }, + "environment": { + "type": "string", + "enum": [ + "live", + "sandbox" + ], + "description": "Environment of the application that owns the transaction. A `sandbox` transaction is stored but never evaluated, screened, notified or billed, so its empty `rule_runs` means \"not evaluated\"." + }, + "transaction_number": { + "type": "integer", + "description": "Application-scoped sequential transaction number shown in Console (e.g. `4123`)." + }, + "txn_id": { + "type": "string", + "description": "The `transaction_id` you supplied at create time (max 128 chars). Unique per application." + }, + "txn_date": { + "type": "string", + "format": "date-time", + "description": "When the transaction occurred (from `transaction_at`; defaults to submission time)." + }, + "zone_id": { + "type": "string", + "nullable": true, + "description": "IANA time zone identifier provided at create time." + }, + "transaction_type": { + "type": "string", + "description": "Top-level category as stored: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, `auditTrailEvent`. Note multi-word values are echoed back in camelCase even when submitted in snake_case." + }, + "action_type": { + "type": "string", + "description": "Sub-type within the category (e.g. `deposit`, `withdrawal`, `transfer`). Defaults to the category when not supplied." + }, + "direction": { + "type": "string", + "enum": [ + "INBOUND", + "OUTBOUND" + ], + "description": "Direction relative to the subject. Stored uppercase regardless of the casing submitted (`in`/`out`/`inbound`/`outbound` are accepted on input)." + }, + "status": { + "type": "string", + "enum": [ + "APPROVED", + "IN_REVIEW", + "DECLINED", + "AWAITING_USER" + ], + "description": "Current monitoring verdict. Transactions are created `APPROVED`; rules may flip them to `IN_REVIEW`/`DECLINED` synchronously." + }, + "source": { + "type": "string", + "enum": [ + "LIVE", + "IMPORTED" + ], + "description": "How the record originated: `LIVE` for transactions submitted through the API or SDK, `IMPORTED` for transactions loaded through the console import." + }, + "amount": { + "type": "string", + "description": "Transaction amount as a decimal string with trailing zeros stripped (e.g. `\"1500\"`, `\"0.5\"`, `\"0.123456789012345678\"`). Up to 18 decimal places." + }, + "currency": { + "type": "string", + "description": "Currency code of `amount`. Any ISO 4217 alphabetic code is accepted (e.g. `EUR`, `USD`, `NGN`), as is a crypto asset symbol (e.g. `BTC`). Prefer a currently-circulating code. Not every accepted code has an exchange rate: when none is available for the code (for example the ISO accounting unit `XSU`, or a crypto symbol Didit does not price), automatic conversion fails and `preferred_currency_amount` is returned null unless the request supplied a pre-converted `amount_in_default_currency`." + }, + "currency_type": { + "type": "string", + "nullable": true, + "description": "`fiat` or `crypto`, as submitted in `currency_kind`." + }, + "amount_in_default_currency": { + "type": "string", + "nullable": true, + "description": "Pre-converted amount you supplied, as a decimal string with trailing zeros stripped." + }, + "default_currency_code": { + "type": "string", + "nullable": true + }, + "preferred_currency_amount": { + "type": "string", + "nullable": true, + "description": "`amount` converted to the application's preferred currency, when available." + }, + "preferred_currency_code": { + "type": "string", + "nullable": true + }, + "payment_details": { + "type": "string", + "nullable": true, + "description": "Free-text payment reference or memo from the submission." + }, + "payment_txn_id": { + "type": "string", + "nullable": true, + "description": "External payment system reference (e.g. blockchain transaction hash) from `payment_reference_id`." + }, + "score": { + "type": "integer", + "description": "Risk score accumulated by rules (typically 0–100). Higher = riskier." + }, + "severity": { + "type": "string", + "nullable": true, + "enum": [ + "UNKNOWN", + "LOW", + "MEDIUM", + "HIGH", + "CRITICAL" + ], + "description": "Categorical risk severity set by rules/providers (`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). `null` until something sets it." + }, + "decision_reason_code": { + "type": "string", + "nullable": true, + "description": "Machine-readable reason for the current `status`." + }, + "decision_reason_label": { + "type": "string", + "nullable": true, + "description": "Human-readable label for `decision_reason_code`." + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "Convenience copy of the applicant's `vendor_data`." + }, + "metadata": { "type": "object", "description": "Snapshot of the `subject` and `counterparty` payloads as submitted at create time." }, @@ -78280,7 +94490,7 @@ } } }, - "description": "Alerts raised by rules and providers." + "description": "Always empty today. An open alert is a transaction with status `IN_REVIEW` or `AWAITING_USER`." }, "rule_runs": { "type": "array", @@ -81951,7 +98161,7 @@ "description": "Comparison operator. in/not_in test membership (value may be a list or a single scalar). contains/not_contains are case-insensitive substring checks against a string value. contains_any takes a list of strings and matches when any is a case-insensitive substring of the field value. regex matches the value pattern against the field. fuzzy_match compares against the value string with the required `score` threshold (0-100). gt/gte/lt/lte never match when either side is missing. exists/is_not_empty/is_not_null (aliases) and not_exists/is_empty/is_null (aliases) are presence checks that ignore `value`." }, "value": { - "description": "Comparison value. Its shape depends on the operator and value_type; omit for the presence-check operators." + "description": "Comparison value. Its shape depends on the operator and value_type; omit it for the presence-check operators. Every other operator needs a value that is not `null` or an empty list, otherwise the rule is refused with `400`. `contains_any` needs a list of strings, and `contains`, `not_contains` and `regex` need a single string." }, "value_type": { "type": "string", @@ -83964,9 +100174,36 @@ "reason_codes": { "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "Stable Didit identifier of the signal, for example `IR-5AC67A32`. Opaque: group and filter on it, do not parse it." + }, + "value": { + "nullable": true, + "description": "For a risk flag (for example `voip`, `leaked`, `disposable`, `spam_trap`), its value: a boolean, a level or a date. Null for a scored reason code." + }, + "direction": { + "type": "string", + "enum": [ + "risk", + "trust" + ], + "description": "Whether the signal raised the risk or added trust." + }, + "message": { + "type": "string", + "description": "Human-readable explanation of the signal, in English." + }, + "impact_level": { + "type": "string", + "nullable": true, + "description": "How strongly the signal moved the score, for example `low`, `medium` or `high`." + } + } }, - "description": "Machine-readable codes explaining the score. Values can grow over time, so do not reject unknown codes." + "description": "Signals that explain the score, each with a stable Didit code, a direction, a message and an impact level. New codes can appear over time, so do not reject unknown codes." } } }, @@ -84027,9 +100264,36 @@ "reason_codes": { "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "Stable Didit identifier of the signal, for example `IR-5AC67A32`. Opaque: group and filter on it, do not parse it." + }, + "value": { + "nullable": true, + "description": "For a risk flag (for example `voip`, `leaked`, `disposable`, `spam_trap`), its value: a boolean, a level or a date. Null for a scored reason code." + }, + "direction": { + "type": "string", + "enum": [ + "risk", + "trust" + ], + "description": "Whether the signal raised the risk or added trust." + }, + "message": { + "type": "string", + "description": "Human-readable explanation of the signal, in English." + }, + "impact_level": { + "type": "string", + "nullable": true, + "description": "How strongly the signal moved the score, for example `low`, `medium` or `high`." + } + } }, - "description": "Machine-readable codes explaining the score. Values can grow over time, so do not reject unknown codes." + "description": "Signals that explain the score, each with a stable Didit code, a direction, a message and an impact level. New codes can appear over time, so do not reject unknown codes." } } }, @@ -85170,6 +101434,456 @@ "unresolved" ] }, + "KYBRegistryData": { + "type": "object", + "nullable": true, + "description": "Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.", + "properties": { + "company_name": { + "type": "string", + "description": "Company name as corrected in the console." + }, + "registration_number": { + "type": "string", + "description": "Registration number as the registry or a console correction states it." + }, + "country_code": { + "type": "string", + "description": "Country of the registration as the registry or a console correction states it." + }, + "region": { + "type": "string", + "description": "Region or state of the registration." + }, + "incorporation_date": { + "type": "string", + "description": "Incorporation date (ISO 8601)." + }, + "registration_date": { + "type": "string", + "description": "Registration date (ISO 8601) when the registry states one apart from the incorporation date." + }, + "dissolution_date": { + "type": "string", + "description": "Dissolution date (ISO 8601) when the registry states one." + }, + "tax_number": { + "type": "string", + "description": "Tax identification number." + }, + "vat_number": { + "type": "string", + "description": "VAT number." + }, + "legal_address": { + "type": "string", + "description": "Legal address as corrected in the console." + }, + "registered_address": { + "type": "string", + "description": "Registered address as the registry states it." + }, + "company_type": { + "type": "string", + "description": "Legal form." + }, + "registry_status": { + "type": "string", + "description": "Company status at the registry." + }, + "verification_status": { + "type": "string", + "description": "Verification status." + }, + "alternative_names": { + "type": "string", + "description": "Other names the company trades or traded under." + }, + "nature_of_business": { + "type": "string", + "description": "Activity description." + }, + "registered_capital": { + "type": "string", + "description": "Registered capital as printed." + }, + "registered_capital_amount": { + "type": "string", + "description": "Registered capital amount, as a decimal string." + }, + "registered_capital_currency": { + "type": "string", + "description": "Registered capital currency (ISO 4217)." + }, + "website": { + "type": "string", + "description": "Website." + }, + "email": { + "type": "string", + "description": "Contact email." + }, + "phone": { + "type": "string", + "description": "Contact phone." + }, + "legal_entity_identifier": { + "type": "string", + "description": "Legal Entity Identifier (LEI)." + }, + "location_of_registration": { + "type": "string", + "description": "Place of registration." + }, + "control_scheme": { + "type": "string", + "description": "Governance scheme when the registry exposes it." + }, + "ownership_error": { + "type": "string", + "enum": [ + "no_owners_on_record", + "no_natural_person_owner", + "ownership_section_unavailable", + "company_not_found", + "ambiguous_company_match", + "missing_registration_number", + "entity_type_not_covered", + "provider_unavailable", + "other" + ], + "description": "Why a requested ownership tier was not delivered, in the same codes as `ownership.unavailable_reason`. `no_owners_on_record` (the registry answered and names no owner) and `ownership_section_unavailable` (the registry did not return the ownership section) are different findings." + }, + "section_errors": { + "type": "object", + "description": "Sections the registry did not return, keyed by section (`officers`, `shareholders`, `group_structure`). A section listed here was never delivered: an empty list next to it says nothing about the company.", + "additionalProperties": { + "$ref": "#/components/schemas/KYBRegistrySectionError" + } + }, + "ubo_resolution": { + "$ref": "#/components/schemas/KYBRegistryUboResolution" + }, + "lite_enrichment": { + "$ref": "#/components/schemas/KYBRegistryLiteEnrichment" + }, + "registry_metadata": { + "type": "object", + "additionalProperties": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ] + }, + "description": "The register's own fields for the company, keyed as the register names them, as plain values (legacy records). Only fields reviewed as registry facts are included." + }, + "registry_sources": { + "type": "array", + "description": "The official registers the record was read from (legacy records). Other sources are not named.", + "items": { + "$ref": "#/components/schemas/KYBRegistrySource" + } + }, + "previous_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Names the company was registered under before (legacy records)." + }, + "parent_companies": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Parent companies the registry names (legacy records)." + }, + "documents_available": { + "type": "integer", + "description": "How many filings the registry offers for the company (legacy records)." + } + } + }, + "KYBRegistryGroupCompany": { + "type": "object", + "description": "A company of the corporate group, by its registry identity.", + "properties": { + "name": { + "type": "string", + "nullable": true, + "description": "Company name." + }, + "country_code": { + "type": "string", + "nullable": true, + "description": "Country of registration." + }, + "registration_number": { + "type": "string", + "nullable": true, + "description": "Registration number." + } + }, + "required": [ + "name", + "country_code", + "registration_number" + ] + }, + "KYBRegistryUboResolution": { + "type": "object", + "description": "How the UBO tier walked the ownership chain above the company.", + "properties": { + "parent_chain": { + "type": "array", + "description": "Corporate parents from the ultimate parent down to the company.", + "items": { + "$ref": "#/components/schemas/KYBRegistryGroupCompany" + } + }, + "subsidiaries": { + "type": "array", + "description": "Companies directly below the company in its corporate group.", + "items": { + "$ref": "#/components/schemas/KYBRegistryGroupCompany" + } + }, + "unresolved": { + "type": "array", + "description": "Parts of the chain the registry could not resolve (the same entries as `ownership.unresolved`).", + "items": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Why, for example `no_group_structure_on_record`, `selected_company_not_in_group_structure` or `section_error`." + }, + "section": { + "type": "string", + "nullable": true, + "description": "The section concerned, for example `group_structure`." + } + }, + "required": [ + "reason", + "section" + ] + } + } + }, + "required": [ + "parent_chain", + "subsidiaries", + "unresolved" + ] + }, + "KYBRegistrySectionError": { + "type": "object", + "description": "A section the registry did not return.", + "properties": { + "status_code": { + "type": "integer", + "nullable": true, + "description": "The status the registry answered for the section." + } + }, + "required": [ + "status_code" + ] + }, + "KYBRegistryLiteEnrichment": { + "type": "object", + "description": "Blank Lite profile fields another of the country's registry sources filled. The source is not named.", + "properties": { + "fields": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The company fields that were filled." + }, + "people_added": { + "type": "integer", + "description": "How many officers or owners were added." + } + }, + "required": [ + "fields", + "people_added" + ] + }, + "KYBRegistrySource": { + "type": "object", + "description": "An official register the record was read from. Only official government registers, regulators and the official identifier system are named; any other source is left out.", + "properties": { + "name": { + "type": "string", + "description": "Register name, for example `UK Companies House`." + }, + "source_type": { + "type": "string", + "enum": [ + "official" + ], + "description": "Always `official`." + } + }, + "required": [ + "name", + "source_type" + ] + }, + "KYBOwnershipStructure": { + "type": "object", + "nullable": true, + "description": "The cap table the registry proved, as it stood when the ownership tier was delivered: direct `shareholders` and `beneficial_owners`. Null when the registry proved no ownership. It never carries the registry source's own rows; read `company.beneficial_owners` and `company.ownership` for the current record.", + "properties": { + "shareholders": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KYBOwnershipStructureOwner" + } + }, + "beneficial_owners": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KYBOwnershipStructureOwner" + } + } + }, + "required": [ + "shareholders", + "beneficial_owners" + ] + }, + "KYBOwnershipStructureOwner": { + "type": "object", + "description": "One owner of the ownership snapshot: the same registry identity and stake as `company.beneficial_owners[]`, and its canonical `shareholding`.", + "properties": { + "name": { + "type": "string", + "nullable": true, + "description": "Owner name as the registry states it." + }, + "first_name": { + "type": "string", + "nullable": true, + "description": "Given name, for a natural person, when the registry states it." + }, + "last_name": { + "type": "string", + "nullable": true, + "description": "Family name, for a natural person, when the registry states it." + }, + "date_of_birth": { + "type": "string", + "nullable": true, + "description": "Date of birth (ISO 8601) when the registry publishes it." + }, + "country_of_birth": { + "type": "string", + "nullable": true, + "description": "Country of birth when the registry publishes it." + }, + "company_name": { + "type": "string", + "nullable": true, + "description": "Company name, for a corporate owner." + }, + "registration_number": { + "type": "string", + "nullable": true, + "description": "Registration number, for a corporate owner." + }, + "entity_type": { + "type": "string", + "nullable": true, + "enum": [ + "person", + "company", + null + ], + "description": "Whether the owner is a natural person or a company." + }, + "nationality": { + "type": "string", + "nullable": true, + "description": "Nationality when the registry states it." + }, + "designation": { + "type": "string", + "nullable": true, + "description": "The owner's title or role as the registry prints it." + }, + "roles": { + "type": "array", + "items": { + "type": "string" + }, + "description": "`shareholder` for a direct holder, `ubo` for a beneficial owner." + }, + "ownership_min_shares": { + "type": "string", + "nullable": true, + "description": "Lower bound of the stake, in percent (equal to the upper bound for an exact stake)." + }, + "ownership_max_shares": { + "type": "string", + "nullable": true, + "description": "Upper bound of the stake, in percent." + }, + "voting_min_shares": { + "type": "string", + "nullable": true, + "description": "Lower bound of the voting rights, in percent." + }, + "voting_max_shares": { + "type": "string", + "nullable": true, + "description": "Upper bound of the voting rights, in percent." + }, + "appointment_date": { + "type": "string", + "nullable": true, + "description": "Date the holding or appointment started (ISO 8601)." + }, + "is_active": { + "type": "boolean", + "nullable": true, + "description": "False for a former owner." + }, + "shareholding": { + "$ref": "#/components/schemas/KYBRegistryShareholding" + } + }, + "required": [ + "name", + "first_name", + "last_name", + "date_of_birth", + "country_of_birth", + "company_name", + "registration_number", + "entity_type", + "nationality", + "designation", + "roles", + "ownership_min_shares", + "ownership_max_shares", + "voting_min_shares", + "voting_max_shares", + "appointment_date", + "is_active", + "shareholding" + ] + }, "DigitalIdWalletApiWalletVerificationError": { "type": "object", "properties": { @@ -85410,13 +102124,21 @@ "$ref": "#/components/schemas/DigitalIdWalletApiWalletNextActionTypeEnum" } ], - "description": "redirect: send the user's browser to url. confirm_in_app: show verification_code to the user, who checks it matches the code in their wallet app and confirms there; then poll.\n\n* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app" + "description": "redirect: send the user's browser to url. confirm_in_app: show verification_code to the user, who checks it matches the code in their wallet app and confirms there; then poll. request_digital_credential: in a user gesture on the origin you started with, ask the wallet with digital_credentials.request, then send what it returns to POST .../verifications/{request_id}/response/.\n\n* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app\n* `request_digital_credential` - request_digital_credential" }, "url": { "type": "string", "format": "uri", "description": "redirect only: where the user signs in with the wallet." }, + "digital_credentials": { + "allOf": [ + { + "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialsRequest" + } + ], + "description": "request_digital_credential only: the request to hand to the wallet." + }, "verification_code": { "type": "string", "description": "confirm_in_app only: the 4-digit comparison code the wallet app shows too." @@ -85433,18 +102155,20 @@ "DigitalIdWalletApiWalletNextActionTypeEnum": { "enum": [ "redirect", - "confirm_in_app" + "confirm_in_app", + "request_digital_credential" ], "type": "string", - "description": "* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app" + "description": "* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app\n* `request_digital_credential` - request_digital_credential" }, "DigitalIdWalletApiInteractionEnum": { "enum": [ "redirect", - "in_app" + "in_app", + "digital_credentials" ], "type": "string", - "description": "* `redirect` - redirect\n* `in_app` - in_app" + "description": "* `redirect` - redirect\n* `in_app` - in_app\n* `digital_credentials` - digital_credentials" }, "DigitalIdWalletApiWalletVerificationResultOutcomeEnum": { "enum": [ @@ -89802,7 +106526,7 @@ }, "SignatureResult": { "type": "object", - "description": "One signer's result for one Electronic Signature step. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature).", + "description": "One signer's result for one E-signature step. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature).", "properties": { "id": { "type": "string", @@ -89838,21 +106562,24 @@ "level": { "type": "string", "enum": [ + "simple", "aes", "qes" ], - "description": "`aes`. `qes` (Qualified Electronic Signature, QES) is coming soon." + "description": "`simple` (default) or `aes`. `qes` (Qualified Electronic Signature, QES) is an add-on that is not available yet." }, "format": { "type": "string", "enum": [ + "pdf", "pades" - ] + ], + "description": "`pdf` for a Simple signature, `pades` for Advanced (AES)." }, "profile": { "type": "string", "nullable": true, - "description": "`PAdES-B-LT` once signed." + "description": "`PAdES-B-LT` once an Advanced (AES) signature is signed, otherwise null." }, "signer": { "type": "object", @@ -89860,7 +106587,7 @@ "name": { "type": "string", "nullable": true, - "description": "Verified name." + "description": "The signer's name. Verified (from the approved ID verification or the session) except at the Simple level without a verified session name, where it is the name the signer typed and is not verified." }, "capacity": { "type": "string", @@ -89894,6 +106621,7 @@ }, "identity_used": { "type": "object", + "description": "The verified identity the signature relies on. Empty for a Simple signature with no verified identity.", "properties": { "session_id": { "type": "string", @@ -89917,7 +106645,7 @@ "certificate": { "type": "object", "nullable": true, - "description": "The certificate the documents were signed with. `null` until signed.", + "description": "The certificate the documents were signed with. `null` until signed, and always `null` for a Simple signature.", "properties": { "issuer": { "type": "string" @@ -89944,10 +106672,12 @@ "properties": { "channel": { "type": "string", + "nullable": true, "enum": [ "email", "sms" - ] + ], + "description": "`null` for a Simple signature, which has no code." }, "destination": { "type": "string", @@ -89968,7 +106698,7 @@ "timestamp": { "type": "object", "nullable": true, - "description": "The trusted timestamp in the signature. `null` until signed.", + "description": "The RFC 3161 timestamp in the signature, issued by Didit. `null` until signed, and always `null` for a Simple signature.", "properties": { "time": { "type": "string", @@ -90150,7 +106880,7 @@ }, "warnings": { "type": "array", - "description": "Warnings raised for this signer. See [Electronic Signature warnings](/core-technology/electronic-signature/warnings-electronic-signature).", + "description": "Warnings raised for this signer. See [E-signature warnings](/core-technology/electronic-signature/warnings-electronic-signature).", "items": { "type": "object", "properties": { @@ -90232,7 +106962,7 @@ "certificate": { "type": "object", "nullable": true, - "description": "The certificate the documents were signed with. `null` until signed.", + "description": "The certificate the documents were signed with. `null` until signed, and always `null` for a Simple signature.", "properties": { "issuer": { "type": "string" @@ -90257,7 +106987,7 @@ "timestamp": { "type": "object", "nullable": true, - "description": "The trusted timestamp in the signature. `null` until signed.", + "description": "The RFC 3161 timestamp in the signature, issued by Didit. `null` until signed, and always `null` for a Simple signature.", "properties": { "time": { "type": "string", @@ -91747,6 +108477,11 @@ "nullable": true, "description": "For a session cloned with `POST /v3/session/import-shared/`: the `session_id` of the original session in the source application. `null` for every other session. Omitted when `include=events` is passed." }, + "shared_from_session_number": { + "type": "integer", + "nullable": true, + "description": "`session_number` of the source session when this session was imported from another application of your organization. `null` otherwise." + }, "session_number": { "type": "integer", "description": "The number of the session.", @@ -91774,6 +108509,213 @@ ], "description": "Overall lifecycle status of the session — the rolled-up workflow result. Terminal values are `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired`, and `Abandoned`; `Not Started`, `In Progress`, `Awaiting User`, and `Resubmitted` indicate the session is still moving through the workflow." }, + "status_override": { + "type": "object", + "nullable": true, + "description": "Present when a reviewer set `status` by hand. `null` when the status is the automatic one. Use it to tell a manual approval from an automatic one.", + "properties": { + "overridden_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "automatic_status": { + "type": "string", + "nullable": true, + "description": "The status the platform's own checks conclude." + } + } + }, + "decision_trace": { + "type": "object", + "description": "How the status was reached: who set it and which warnings did.", + "properties": { + "status": { + "type": "string", + "description": "The session status." + }, + "decided_by": { + "type": "string", + "nullable": true, + "enum": [ + "manual", + "automatic", + "investigator", + null + ], + "description": "Who set the status. `null` while the session is not decided." + }, + "decided_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "automatic_status": { + "type": "string", + "nullable": true, + "description": "What the platform's own checks conclude, which differs from `status` after a manual decision." + }, + "terminal_node_id": { + "type": "string", + "nullable": true, + "description": "The workflow status node that ended the session, when one did." + }, + "actor": { + "type": "object", + "nullable": true, + "description": "The reviewer behind a manual decision.", + "properties": { + "user": { + "type": "string", + "nullable": true + }, + "actor_type": { + "type": "string", + "nullable": true + } + } + }, + "warning_counts": { + "type": "object", + "description": "Warnings per `log_type` (`error`, `warning`, `information`) and `total`.", + "additionalProperties": { + "type": "integer" + } + }, + "status_warnings": { + "type": "array", + "description": "The warnings that set a `Declined` or `In Review` status.", + "items": { + "type": "object", + "properties": { + "risk": { + "type": "string" + }, + "feature": { + "type": "string", + "nullable": true + }, + "node_id": { + "type": "string", + "nullable": true + }, + "log_type": { + "type": "string", + "nullable": true + }, + "check_status": { + "type": "string", + "nullable": true + }, + "source": { + "type": "string", + "description": "The payload list the warning came from, for example `id_verifications`." + }, + "short_description": { + "type": "string", + "nullable": true + } + } + } + } + } + }, + "linked_records": { + "type": "object", + "nullable": true, + "description": "A summary of other records linked to the session. `null` when there is nothing to show, and for workflows that declare an age assurance standard.", + "properties": { + "same_face": { + "type": "object", + "nullable": true, + "description": "Other people whose face matched one of this session's face searches.", + "properties": { + "count": { + "type": "integer" + }, + "best_match": { + "type": "object", + "nullable": true, + "properties": { + "session_id": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "session_number": { + "type": "integer", + "nullable": true + }, + "vendor_user_id": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "similarity_percentage": { + "type": "number", + "nullable": true + } + } + } + } + }, + "earlier_verifications": { + "type": "object", + "nullable": true, + "properties": { + "count": { + "type": "integer" + }, + "vendor_user_id": { + "type": "string", + "format": "uuid", + "nullable": true + } + } + }, + "networks": { + "type": "object", + "nullable": true, + "properties": { + "count": { + "type": "integer" + }, + "open": { + "type": "integer" + }, + "dismissed": { + "type": "integer" + }, + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "network_id": { + "type": "string", + "format": "uuid" + }, + "display_number": { + "type": "integer", + "nullable": true + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "risk_score": { + "type": "number", + "nullable": true + } + } + } + } + } + } + } + }, "workflow_id": { "type": "string", "format": "uuid", @@ -91786,7 +108728,7 @@ "type": "string", "description": "The feature of the session." }, - "description": "List of verification features configured for this session, as display names: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH` (Business Verification sessions use the KYB feature set: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). With `include=events` each entry becomes an object `{feature, node_id}` instead of a plain string, and the email feature is renamed: it appears as `EMAIL` in events mode instead of the `EMAIL_VERIFICATION` used here." + "description": "List of verification features configured for this session, as display names: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH`, `GEOLOCATION` (Location verification) (Business Verification sessions use the KYB feature set: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). With `include=events` each entry becomes an object `{feature, node_id}` instead of a plain string, and the email feature is renamed: it appears as `EMAIL` in events mode instead of the `EMAIL_VERIFICATION` used here." }, "vendor_data": { "type": "string", @@ -92810,7 +109752,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning (e.g., `ID_VERIFICATION`, `NFC`, `LIVENESS`). The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module, but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -93045,6 +109989,25 @@ ], "nullable": true, "description": "Address Validation of the address printed on this document: whether it exists and its normalised form, as the document read it (a later correction of `address` does not run it again). Present when this ID verification step enabled the Address Validation add-on; `null` otherwise." + }, + "region": { + "type": "string", + "nullable": true, + "description": "Region or state of the document's issuing country where the document identifies one." + }, + "extracted_data": { + "type": "object", + "nullable": true, + "additionalProperties": true, + "description": "Snapshot of the data extracted from the document that the person was shown to review, kept next to the confirmed values so you can compare what was read with what the person confirmed. `null` when the person was not asked to review." + }, + "barcodes": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "Data read from the document's barcodes. Empty when the document has none or none was read." } } } @@ -93389,7 +110352,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -93585,7 +110550,116 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" + ], + "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." + }, + "risk": { + "type": "string" + }, + "additional_data": { + "type": "object", + "nullable": true + }, + "log_type": { + "type": "string" + }, + "short_description": { + "type": "string" + }, + "long_description": { + "type": "string" + }, + "node_id": { + "type": "string", + "description": "The workflow graph node ID that generated this warning" + } + } + } + }, + "face_quality": { + "type": "number", + "nullable": true, + "description": "Face image quality score (0-100%). Only available for passive liveness." + }, + "face_luminance": { + "type": "number", + "nullable": true, + "description": "Face luminance/brightness score (0-100%). Only available for passive liveness." + } + } + } + }, + "face_matches": { + "type": "array", + "nullable": true, + "description": "**Array of face-match reports** produced by face-match steps in the workflow graph. Always a JSON array — never a singular `face_match` object. `null` until at least one face-match step has produced data. Each item is the full report, including `node_id`, feature-level `status`, similarity `score`, `source_image`, `target_image`, and `warnings[]`.", + "items": { + "type": "object", + "description": "One face-match report — the full report.", + "properties": { + "node_id": { + "type": "string", + "description": "Workflow graph node id of the face-match step that produced this report." + }, + "status": { + "type": "string", + "enum": [ + "Not Finished", + "Approved", + "Declined", + "In Review", + "Resub Requested" + ], + "description": "Feature-level status of this face-match step. Independent of the top-level session `status` — a session can reach its overall decision while an individual feature stays `In Review`." + }, + "score": { + "type": "number", + "description": "Confidence score of the face match" + }, + "source_image_session_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Session id under which the source (reference) portrait is stored. In biometric-authentication flows this is the session's own id (the submitted portrait is stored under the new session). `null` when the source image is the same session's document portrait." + }, + "source_image": { + "type": "string", + "format": "uri", + "description": "URL of the source image used for comparison" + }, + "target_image": { + "type": "string", + "format": "uri", + "description": "URL of the target image used for comparison" + }, + "warnings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "feature": { + "type": "string", + "enum": [ + "ID_VERIFICATION", + "NFC", + "LIVENESS", + "FACEMATCH", + "PROOF_OF_ADDRESS", + "PHONE", + "EMAIL", + "AML", + "LOCATION", + "DATABASE_VALIDATION", + "QUESTIONNAIRE", + "DOCUMENT_AI", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -93610,113 +110684,69 @@ "description": "The workflow graph node ID that generated this warning" } } - } - }, - "face_quality": { - "type": "number", - "nullable": true, - "description": "Face image quality score (0-100%). Only available for passive liveness." - }, - "face_luminance": { - "type": "number", - "nullable": true, - "description": "Face luminance/brightness score (0-100%). Only available for passive liveness." - } - } - } - }, - "face_matches": { - "type": "array", - "nullable": true, - "description": "**Array of face-match reports** produced by face-match steps in the workflow graph. Always a JSON array — never a singular `face_match` object. `null` until at least one face-match step has produced data. Each item is the full report, including `node_id`, feature-level `status`, similarity `score`, `source_image`, `target_image`, and `warnings[]`.", - "items": { - "type": "object", - "description": "One face-match report — the full report.", - "properties": { - "node_id": { - "type": "string", - "description": "Workflow graph node id of the face-match step that produced this report." - }, - "status": { - "type": "string", - "enum": [ - "Not Finished", - "Approved", - "Declined", - "In Review", - "Resub Requested" - ], - "description": "Feature-level status of this face-match step. Independent of the top-level session `status` — a session can reach its overall decision while an individual feature stays `In Review`." - }, - "score": { - "type": "number", - "description": "Confidence score of the face match" + }, + "description": "Face match verification warnings" }, - "source_image_session_id": { - "type": "string", - "format": "uuid", + "face_coverage": { + "type": "object", "nullable": true, - "description": "Session id under which the source (reference) portrait is stored. In biometric-authentication flows this is the session's own id (the submitted portrait is stored under the new session). `null` when the source image is the same session's document portrait." - }, - "source_image": { - "type": "string", - "format": "uri", - "description": "URL of the source image used for comparison" - }, - "target_image": { - "type": "string", - "format": "uri", - "description": "URL of the target image used for comparison" - }, - "warnings": { - "type": "array", - "items": { - "type": "object", - "properties": { - "feature": { - "type": "string", - "enum": [ - "ID_VERIFICATION", - "NFC", - "LIVENESS", - "FACEMATCH", - "PROOF_OF_ADDRESS", - "PHONE", - "EMAIL", - "AML", - "LOCATION", - "DATABASE_VALIDATION", - "QUESTIONNAIRE", - "DOCUMENT_AI", - "KYB_REGISTRY", - "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" - ], - "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." - }, - "risk": { - "type": "string" - }, - "additional_data": { - "type": "object", - "nullable": true - }, - "log_type": { - "type": "string" - }, - "short_description": { - "type": "string" - }, - "long_description": { - "type": "string" - }, - "node_id": { - "type": "string", - "description": "The workflow graph node ID that generated this warning" + "description": "Whether the eyes, mouth and face are covered in the captured image. Returned by `GET /v3/session/{sessionId}/decision/` only; it is not part of webhook payloads. `null` when no coverage reading exists.", + "properties": { + "eyes": { + "type": "object", + "properties": { + "covered": { + "type": "boolean", + "nullable": true + }, + "calibrated": { + "type": "boolean", + "nullable": true, + "description": "`false` means the reading is shadow evidence only and no warning acts on it." + }, + "visibility_score": { + "type": "number", + "nullable": true + } + } + }, + "mouth": { + "type": "object", + "properties": { + "covered": { + "type": "boolean", + "nullable": true + }, + "calibrated": { + "type": "boolean", + "nullable": true, + "description": "`false` means the reading is shadow evidence only and no warning acts on it." + }, + "visibility_score": { + "type": "number", + "nullable": true + } + } + }, + "face": { + "type": "object", + "properties": { + "covered": { + "type": "boolean", + "nullable": true + }, + "calibrated": { + "type": "boolean", + "nullable": true, + "description": "`false` means the reading is shadow evidence only and no warning acts on it." + }, + "visibility_score": { + "type": "number", + "nullable": true + } } } - }, - "description": "Face match verification warnings" + } } } } @@ -93864,7 +110894,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -93939,6 +110971,22 @@ } } } + }, + "phone_intelligence": { + "allOf": [ + { + "$ref": "#/components/schemas/PhoneIntelligence" + } + ], + "description": "Phone intelligence signals. Present only when the phone intelligence add-on ran for this number." + }, + "phone_social": { + "allOf": [ + { + "$ref": "#/components/schemas/PhoneSocialFootprint" + } + ], + "description": "Social footprint of the number. Present only when the social footprint add-on ran for this number." } } } @@ -94058,7 +111106,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -94170,6 +111220,22 @@ } } } + }, + "email_intelligence": { + "allOf": [ + { + "$ref": "#/components/schemas/EmailIntelligence" + } + ], + "description": "Email intelligence signals. Present only when the email intelligence add-on ran for this address." + }, + "email_social": { + "allOf": [ + { + "$ref": "#/components/schemas/EmailSocialFootprint" + } + ], + "description": "Social footprint of the address. Present only when the social footprint add-on ran for this address." } } } @@ -94523,7 +111589,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -94905,14 +111973,14 @@ "bank_verifications": { "type": "array", "nullable": true, - "description": "Bank Verification results, one item per Bank Verification step, for User and Business Verification. `null` until a step produces one. Each item's `method` says how the account was verified: `open_banking` (bank sign-in) or `account_lookup` (account check), or a `statement` or `microdeposits` fallback, and `none` when the person continued without a bank before any attempt was evaluated (`continued_without_bank`). See [Bank verification methods](/core-technology/bank-verification/verification-methods).", + "description": "Bank Verification results, one item per Bank Verification step, for User and Business Verification. `null` until a step produces one. Each item's `method` says how the account was verified: `open_banking` (bank sign-in) or `account_lookup` (account check), or a `statement` or `microdeposits` fallback, and `none` when the person continued without a bank before any attempt was evaluated (`continued_without_bank`). See [Bank verification methods](/core-technology/bank-verification/verification-methods). Bank Verification is not enabled in production yet, so this stays `null` on production sessions until it is.", "items": { "$ref": "#/components/schemas/BankVerificationResult" } }, "signatures": { "type": "array", - "description": "Electronic Signature results, one item per signer and signature step, for User and Business Verification. Present only when the workflow has an Electronic Signature step; an empty array until a signer reaches it. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature).", + "description": "E-signature results, one item per signer and signature step, for User and Business Verification. Present only when the workflow has an E-signature step; an empty array until a signer reaches it. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature).", "items": { "$ref": "#/components/schemas/SignatureResult" } @@ -95141,7 +112209,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -95329,10 +112399,65 @@ } } } + }, + "browser_version": { + "type": "string", + "nullable": true + }, + "os_version": { + "type": "string", + "nullable": true + }, + "user_agent": { + "type": "string", + "nullable": true, + "description": "The browser's user agent string." + }, + "accept_language": { + "type": "string", + "nullable": true, + "description": "The `Accept-Language` header the browser sent." + }, + "session_identifier": { + "type": "string", + "nullable": true, + "description": "Identifier of the browsing session the verification ran in." + }, + "session_age_ms": { + "type": "integer", + "nullable": true, + "description": "Age of that browsing session in milliseconds when the step ran." + }, + "coords_accuracy": { + "type": "number", + "nullable": true, + "description": "Accuracy radius, in metres, of the coordinates the device reported." + }, + "raw_device_data": { + "type": "object", + "nullable": true, + "additionalProperties": true, + "description": "Raw device signals collected for the step." } } } }, + "geolocation_checks": { + "type": "array", + "nullable": true, + "description": "**Array of Location verification results**, one per Location verification step: that step's accepted attempt. `null` until a Location verification step has produced data. Earlier attempts of the same step are in `geolocation_attempts`.", + "items": { + "$ref": "#/components/schemas/GeolocationCheck" + } + }, + "geolocation_attempts": { + "type": "array", + "nullable": true, + "description": "Every attempt of every Location verification step of this session, oldest first. Attempts that a resubmission replaced are left out. A workflow that withholds `geolocation_checks` through its response attributes withholds this list too.", + "items": { + "$ref": "#/components/schemas/GeolocationAttempt" + } + }, "database_validations": { "type": "array", "nullable": true, @@ -95505,7 +112630,9 @@ "DOCUMENT_AI", "KYB_REGISTRY", "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" ], "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, @@ -95536,6 +112663,22 @@ } } }, + "database_validation_not_performed_reason": { + "type": "object", + "nullable": true, + "additionalProperties": true, + "description": "Why a configured database validation produced no result, as `{code, message}` plus context fields. Present only when `database_validations` is `null` for a workflow that has the step, so you can tell \"the registry agreed\" from \"nothing ran\". `null` otherwise.", + "properties": { + "code": { + "type": "string", + "description": "Stable machine-readable reason." + }, + "message": { + "type": "string", + "description": "Human-readable explanation." + } + } + }, "reviews": { "type": "array", "items": { @@ -95558,6 +112701,34 @@ } } }, + "assignee": { + "type": "object", + "nullable": true, + "description": "The Console reviewer the session is assigned to, or `null` when nobody holds it.", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "assigned_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "waiting_since": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the session started waiting for review. `null` unless the session is `In Review` and your application sets a review deadline." + }, + "sla_due_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the review is due. `null` unless the session is `In Review` and your application sets a review deadline." + }, "created_at": { "type": "string", "format": "date-time", @@ -95996,8 +113167,7 @@ "description": "Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts." }, "registry_data": { - "type": "object", - "description": "Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead." + "$ref": "#/components/schemas/KYBRegistryData" }, "user_provided_data": { "type": "object", @@ -96033,12 +113203,60 @@ "type": "string", "nullable": true, "description": "`not_requested`, `pending`, `delivered`, `not_held` or `unavailable`. Also in `ownership.status`." + }, + "registry_monitoring": { + "type": "object", + "nullable": true, + "description": "The latest registry monitor for the company, or `null` when none exists.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string" + }, + "unavailable_reason": { + "type": "string", + "nullable": true + }, + "enrolled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "cancelled_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "last_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "next_bill_date": { + "type": "string", + "format": "date", + "nullable": true + }, + "last_event_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "events_count": { + "type": "integer" + }, + "watched_fields": { + "description": "The company fields the monitor watches." + } + } } } }, "ownership_structure": { - "type": "object", - "description": "Raw ownership snapshot kept for reviewers; its shape differs by registry source and is not a stable contract. Read `company.beneficial_owners` and `company.ownership` instead." + "$ref": "#/components/schemas/KYBOwnershipStructure" }, "warnings": { "type": "array", @@ -97136,6 +114354,11 @@ ], "description": "Whether the session was created by a live application (`live`) or a sandbox application (`sandbox`). Sandbox sessions are free, fully simulated, and never bill credits." }, + "sandbox_scenario": { + "type": "string", + "nullable": true, + "description": "The sandbox scenario the session was created with. `null` for live sessions and for sandbox sessions created without one." + }, "resubmissions": { "type": "array", "description": "Returned only with `include=resubmissions`, for user and business sessions. One entry per resubmission request, oldest first. Each entry carries the results the resubmitted steps returned before the request, so earlier submissions stay readable. Deleting the session deletes every submission.", @@ -97371,6 +114594,27 @@ }, "investigator": { "$ref": "#/components/schemas/InvestigatorBlock" + }, + "biometric_retention": { + "$ref": "#/components/schemas/BiometricRetention" + }, + "fraud_check": { + "type": "object", + "nullable": true, + "additionalProperties": true, + "description": "The result of a Fraud Check API call. `null` for every other session." + }, + "full_session_video": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "Expiring URL of the full-session recording. Returned only when your organization records full-session video." + }, + "full_session_video_recorded_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the full-session recording was made. Returned only when your organization records full-session video." } } }, @@ -97513,6 +114757,24 @@ "type": "string", "format": "date-time" }, + "signature_availability": { + "type": "object", + "description": "Which E-signature levels can sign right now. Check it before you set `signature_level`. Returned on `kyc`, `kyb` and graph workflows.", + "properties": { + "simple": { + "type": "boolean", + "description": "Simple is always available." + }, + "aes": { + "type": "boolean", + "description": "Whether Advanced (AES) can sign now. While it is `false`, saving a new step at `signature_level: \"aes\"` is refused with `aes_not_available`." + }, + "qes": { + "type": "boolean", + "description": "Whether Qualified (QES) can sign now. It is `false` until a qualified provider is connected." + } + } + }, "is_bank_verification_enabled": { "type": "boolean", "description": "Whether a simple KYC or KYB workflow runs Bank verification. It runs after the contact steps (and Location verification) and before database validation, AML and IP analysis. Bank verification is not generally available yet: turning it on is refused wherever it is not enabled." @@ -97676,7 +114938,8 @@ "AML", "IP_ANALYSIS", "AGE_ESTIMATION", - "DATABASE_VALIDATION" + "DATABASE_VALIDATION", + "GEOLOCATION" ], "description": "Verification feature identifier.", "example": "ID_VERIFICATION" @@ -97904,6 +115167,63 @@ } } } + }, + "assignee": { + "type": "object", + "nullable": true, + "description": "The Console reviewer the session is assigned to, or `null` when nobody holds it.", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "assigned_at": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "waiting_since": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the session started waiting for review. `null` unless the session is `In Review`." + }, + "sla_due_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the review is due, from the review deadline set for your application in the Console. `null` unless the session is `In Review` and a deadline is set." + }, + "top_warnings": { + "type": "array", + "description": "Up to a few of the session's most important warnings, for a quick triage view. The full list is in the decision.", + "items": { + "type": "object", + "properties": { + "risk": { + "type": "string", + "description": "Warning code, for example `FACE_MATCH_LOW_SIMILARITY`." + }, + "feature": { + "type": "string", + "description": "The feature that raised it." + }, + "log_type": { + "type": "string", + "nullable": true, + "description": "`error` or `warning`; `null` for a legacy entry." + }, + "short_description": { + "type": "string" + } + } + } + }, + "warnings_count": { + "type": "integer", + "description": "Number of warnings on the session." } } }, @@ -98328,8 +115648,8 @@ "properties": { "kyb_response_id": { "type": "string", - "maxLength": 255, - "description": "Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral — use it shortly after the search that produced it.", + "maxLength": 1024, + "description": "Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length.", "example": "69aeeb95febb0f1704042259" }, "vendor_data": { @@ -98435,7 +115755,7 @@ }, "trigger": { "type": "string", - "description": "Present when the event was not produced by the verification flow itself, for example `manual_review`, `manual_step_update`, `ongoing_monitoring`, `webhook_reconciliation`, `manual_webhook_recovery`, `kyb_registry_change` or a `console_*` edit." + "description": "Present when the event was not produced by the verification flow itself, for example `manual_review`, `manual_step_update`, `ongoing_monitoring`, `webhook_reconciliation` (a `status.updated` resent because the first terminal webhook was never created, so you may receive a second event for a decision you already got: deduplicate on `session_id` and `status`), `manual_webhook_recovery`, `kyb_registry_change`, `biometric_retention` (a `data.updated` sent when the session's live biometric data is deleted on schedule) or a `console_*` edit such as `console_registry_edit`, `console_key_people_skip` or `console_key_people_regenerate`." }, "workflow_id": { "type": "string", @@ -99267,6 +116587,9 @@ }, { "$ref": "#/components/schemas/WorkflowComplianceChangedEvent" + }, + { + "$ref": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent" } ], "discriminator": { @@ -99281,7 +116604,8 @@ "transaction.created": "#/components/schemas/TransactionCreatedEvent", "transaction.status.updated": "#/components/schemas/TransactionStatusUpdatedEvent", "travel_rule.status.updated": "#/components/schemas/TravelRuleStatusUpdatedEvent", - "workflow.compliance_changed": "#/components/schemas/WorkflowComplianceChangedEvent" + "workflow.compliance_changed": "#/components/schemas/WorkflowComplianceChangedEvent", + "transaction_rule_suggestions.created": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent" } } }, @@ -99383,7 +116707,7 @@ "properties": { "id": { "type": "string", - "description": "Unique identifier of the match" + "description": "Didit's stable identifier for the hit: `hit_` followed by 24 hexadecimal characters. The same matched entity keeps the same `id` when the subject is screened again. Pass it as `hit_id` to the AML hit review endpoints." }, "url": { "type": "string", @@ -99428,10 +116752,11 @@ "Fitness and Probity", "SIP", "SIE", - "Insolvency" + "Insolvency", + "Other Lists" ] }, - "description": "List of dataset categories where the match was found. Indicates whether the entity appeared in PEP lists (with level), sanctions databases, adverse media, warnings/regulatory enforcement, or other compliance datasets." + "description": "List of dataset categories where the match was found. Indicates whether the entity appeared in PEP lists (with level), sanctions databases, adverse media, warnings/regulatory enforcement, or other compliance datasets. `Other Lists` when the entity's source states none of these categories." }, "features": { "type": "object", @@ -99915,849 +117240,1819 @@ } } }, - "sanction_matches": { - "type": "array", - "description": "List of sanction list matches found for this entity.", - "items": { - "type": "object", - "properties": { - "list_name": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "description": "Name(s) of the sanction list(s)" - }, - "matched_name": { - "type": "string", - "description": "Name matched in the sanction list" - }, - "description": { - "type": "string", - "description": "Description of the sanction entry" - }, - "reason": { - "type": "string", - "nullable": true, - "description": "Free-text reason why the entity was sanctioned. Joined from the sanction list's reason entries. Examples: 'Executive Order 13224 (Terrorism)', 'Support for actions undermining Ukraine's sovereignty', 'Listed due to national security concerns.'" - }, - "source_url": { - "type": "string", - "format": "uri", - "description": "URL to the source of the sanction" - }, - "other_sources": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Additional source URLs" - }, - "details": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Additional details about the sanction" - }, - "legal_basis": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Legal basis for the sanction" - }, - "listed_on": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "description": "Date(s) when the entity was listed" - }, - "sanction_list": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "description": "Sanction list identifier(s)" - }, - "sanction_program": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Sanction program(s) the entity is listed under" - }, - "sanctioning_authority": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Authority/authorities that imposed the sanction" - }, - "updated_on": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Date(s) when the sanction entry was last updated" - }, - "additional_data": { - "type": "object", - "description": "Additional data from the sanction source not captured in the main fields" - } - } + "sanction_matches": { + "type": "array", + "description": "List of sanction list matches found for this entity.", + "items": { + "type": "object", + "properties": { + "list_name": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "description": "Name(s) of the sanction list(s)" + }, + "matched_name": { + "type": "string", + "description": "Name matched in the sanction list" + }, + "description": { + "type": "string", + "description": "Description of the sanction entry" + }, + "reason": { + "type": "string", + "nullable": true, + "description": "Free-text reason why the entity was sanctioned. Joined from the sanction list's reason entries. Examples: 'Executive Order 13224 (Terrorism)', 'Support for actions undermining Ukraine's sovereignty', 'Listed due to national security concerns.'" + }, + "source_url": { + "type": "string", + "format": "uri", + "description": "URL to the source of the sanction" + }, + "other_sources": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional source URLs" + }, + "details": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional details about the sanction" + }, + "legal_basis": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Legal basis for the sanction" + }, + "listed_on": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "description": "Date(s) when the entity was listed" + }, + "sanction_list": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "description": "Sanction list identifier(s)" + }, + "sanction_program": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Sanction program(s) the entity is listed under" + }, + "sanctioning_authority": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Authority/authorities that imposed the sanction" + }, + "updated_on": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Date(s) when the sanction entry was last updated" + }, + "additional_data": { + "type": "object", + "description": "Additional data from the sanction source not captured in the main fields" + } + } + } + }, + "adverse_media_details": { + "type": "object", + "properties": { + "sentiment": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "sentiment_score": { + "type": "integer" + }, + "adverse_keywords": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "adverse_media_matches": { + "type": "array", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string" + }, + "summary": { + "type": "string" + }, + "headline": { + "type": "string" + }, + "sentiment": { + "type": "string" + }, + "thumbnail": { + "type": "string", + "format": "uri" + }, + "source_url": { + "type": "string", + "format": "uri" + }, + "author_name": { + "type": "string", + "nullable": true + }, + "other_sources": { + "type": "array", + "items": { + "type": "string" + } + }, + "adverse_keywords": { + "type": "array", + "items": { + "type": "string" + } + }, + "sentiment_score": { + "type": "integer" + }, + "publication_date": { + "type": "string", + "format": "date-time" + } + } + } + }, + "additional_information": { + "type": "object" + } + } + } + }, + "score": { + "type": "number", + "format": "float", + "nullable": true, + "minimum": 0, + "maximum": 100, + "description": "Overall AML screening score — the highest risk score across all hits (float, 0-100). `null` until computed." + }, + "screened_data": { + "type": "object", + "properties": { + "full_name": { + "type": "string" + }, + "nationality": { + "type": "string" + }, + "date_of_birth": { + "type": "string", + "format": "date" + }, + "document_number": { + "type": "string", + "nullable": true + } + } + }, + "is_ongoing_monitoring_enabled": { + "type": "boolean", + "description": "Whether AML ongoing monitoring is enabled for this screening. When `true`, the entity is re-screened periodically and any new hits update the report." + }, + "next_ongoing_monitoring_bill_date": { + "type": "string", + "format": "date", + "nullable": true, + "description": "Date (YYYY-MM-DD) when this ongoing-monitoring subscription will next be billed. Computed as the date of the last ongoing-monitoring billing plus 365 days when `is_ongoing_monitoring_enabled = true`; otherwise `null`. This is a billing date, not a screening date - use `last_ongoing_screening_at` for that." + }, + "last_ongoing_screening_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When ongoing monitoring last completed a re-screening of this record, whether or not the result changed. `null` when the record has never been re-screened; it is never back-filled from the enablement or billing date." + }, + "last_ongoing_screening_datasets_updated_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "The most recent AML dataset update date the provider reported at the time of that screening. `null` when the provider reported no dataset dates; never estimated." + }, + "warnings": { + "type": "array", + "items": { + "type": "object", + "properties": { + "feature": { + "type": "string", + "enum": [ + "ID_VERIFICATION", + "NFC", + "LIVENESS", + "FACEMATCH", + "PROOF_OF_ADDRESS", + "PHONE", + "EMAIL", + "AML", + "LOCATION", + "DATABASE_VALIDATION", + "QUESTIONNAIRE", + "DOCUMENT_AI", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" + ], + "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Within an AML screening this is typically `AML`, but the enum above is authoritative across all feature warnings on the decision payload." + }, + "risk": { + "type": "string" + }, + "additional_data": { + "type": "object", + "nullable": true + }, + "log_type": { + "type": "string" + }, + "short_description": { + "type": "string" + }, + "long_description": { + "type": "string" + }, + "node_id": { + "type": "string", + "description": "The workflow graph node ID that generated this warning" + } + } + } + } + } + }, + "MonitoringEvent": { + "type": "object", + "description": "One stored monitoring event as returned by the list and subject-timeline endpoints. Restricted evidence (payload, device context, rule evidence) is only returned by `GET /v3/events/{event_uuid}/`.", + "required": [ + "event_uuid", + "event_id", + "event_category", + "action_type", + "occurred_at", + "received_at", + "status", + "score", + "subject_vendor_data", + "subject_entity_type", + "subject_uuid", + "counterparty_vendor_data", + "session_id", + "device_fingerprint", + "ip_address", + "ip_country", + "amount", + "currency", + "game_id", + "round_id", + "bonus_id", + "affiliate_code", + "payment_reference_id", + "retention_class", + "rules_matched_count", + "correlation_pending", + "is_droppable" + ], + "properties": { + "event_uuid": { + "type": "string", + "format": "uuid", + "description": "Didit identifier of the event. Use it as `{event_uuid}` in the retrieve and delete calls." + }, + "event_id": { + "type": "string", + "maxLength": 128, + "description": "Your own identifier, the idempotency key you sent." + }, + "event_category": { + "type": "string", + "enum": [ + "auth", + "session", + "gameplay", + "bonus", + "affiliate", + "payment", + "dispute", + "security", + "responsible_gambling", + "custom" + ], + "description": "Event category." + }, + "action_type": { + "type": "string", + "maxLength": 128, + "description": "What happened within the category, as you sent it." + }, + "occurred_at": { + "type": "string", + "format": "date-time", + "description": "When the event happened on your side." + }, + "received_at": { + "type": "string", + "format": "date-time", + "description": "When Didit accepted the event." + }, + "status": { + "type": "string", + "enum": [ + "ACCEPTED", + "APPROVED", + "IN_REVIEW", + "DECLINED" + ], + "description": "`ACCEPTED`: stored, no matched rule changed its standing (the normal answer for most events, and always the answer in a sandbox application, where no rules run). `APPROVED`: a rule matched and the score stayed under your review threshold. `IN_REVIEW`: a rule pushed the score over the review threshold or set the status. `DECLINED`: a rule declined it or the score crossed your decline threshold." + }, + "score": { + "type": "integer", + "description": "Accumulated rule score. Starts at 0; rule `add_score` actions move it (negative deltas are allowed)." + }, + "subject_vendor_data": { + "type": "string", + "maxLength": 255, + "description": "`subject.vendor_data` of the event: your id for the user or company." + }, + "subject_entity_type": { + "type": "string", + "description": "`individual` or `company`: which kind of subject `subject_vendor_data` names.", + "example": "individual" + }, + "subject_uuid": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "UUID of the user (individual) or company the event resolved to, or null when that record no longer exists." + }, + "counterparty_vendor_data": { + "type": "string", + "nullable": true, + "description": "The other player of a P2P event (promoted from `payload.counterparty_vendor_data`).", + "maxLength": 255 + }, + "session_id": { + "type": "string", + "nullable": true, + "description": "`session.session_id` sent with the event.", + "maxLength": 255 + }, + "device_fingerprint": { + "type": "string", + "nullable": true, + "description": "`device_context.fingerprint` sent with the event.", + "maxLength": 255 + }, + "ip_address": { + "type": "string", + "nullable": true, + "description": "IP address of the event. On the server lane this is `device_context.network_context.ip_address` as you sent it; on the device lane it is the IP of the request.", + "maxLength": 64 + }, + "ip_country": { + "type": "string", + "nullable": true, + "description": "Country code of `ip_address` from IP enrichment, or null when the address was not enriched (missing, private, or low-value telemetry whose address was not already known).", + "example": "ES" + }, + "amount": { + "type": "string", + "nullable": true, + "description": "Amount as a decimal string with 18 decimal places, from `transaction_context.amount`, `payload.amount` or `payload.stake_amount`, in that order.", + "example": "250.000000000000000000" + }, + "currency": { + "type": "string", + "nullable": true, + "description": "Currency from `transaction_context.currency` or `payload.currency`.", + "maxLength": 10 + }, + "game_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.game_id`.", + "maxLength": 128 + }, + "round_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.round_id`.", + "maxLength": 128 + }, + "bonus_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.bonus_id`.", + "maxLength": 128 + }, + "affiliate_code": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.affiliate_code`.", + "maxLength": 128 + }, + "payment_reference_id": { + "type": "string", + "nullable": true, + "description": "Payment reference from `transaction_context.payment_reference_id` or `payload.payment_reference_id`.", + "maxLength": 255 + }, + "retention_class": { + "type": "string", + "enum": [ + "low_value", + "standard", + "risk_relevant", + "monetary_or_compliance" + ], + "description": "Retention class. Payment and dispute events are `monetary_or_compliance`; security and responsible-gambling events are `risk_relevant`; `session.page_view`, `session.sdk_heartbeat`, `session.sdk_loaded`, `session.device_seen`, `session.bot_signal_observed`, `bonus.promotion_viewed` and `affiliate.referral_clicked` are `low_value`; everything else is `standard`. An event an active rule matched is promoted to `risk_relevant` (never demoted)." + }, + "rules_matched_count": { + "type": "integer", + "minimum": 0, + "description": "Number of rules that matched the event, including rules in `TEST` mode (which record evidence but apply no actions)." + }, + "correlation_pending": { + "type": "boolean", + "description": "`true` while an asynchronous rule (cross-subject correlation, or a sequence longer than 24 hours) still has to run for this event. It resolves within minutes and `status`, `score` and `rules_matched_count` update in place." + }, + "is_droppable": { + "type": "boolean", + "description": "Whether an SDK under backpressure may drop events of this kind. `false` for every `security`, `payment`, `dispute` and `responsible_gambling` event and for `gameplay.bet_placed`, `gameplay.bet_settled` and `gameplay.p2p_settlement`." + } + } + }, + "MonitoringEventDetail": { + "description": "One monitoring event with its full envelope, enrichment and rule evidence. Every field of `MonitoringEvent` plus the fields below.", + "allOf": [ + { + "$ref": "#/components/schemas/MonitoringEvent" + }, + { + "type": "object", + "required": [ + "payload", + "custom_values", + "device_context", + "field_sources", + "session_sequence", + "table_id", + "hand_id", + "match_id", + "market_id", + "side", + "role", + "net_result_amount", + "payment_fingerprint", + "instrument_reference_hash", + "withdrawal_address_hash", + "dispute_id", + "chargeback_id", + "changed_field", + "identity_match_ref", + "schema_version", + "expires_at", + "rules_evaluated_count", + "rule_runs", + "ip_enrichment", + "subject_profile", + "tags" + ], + "properties": { + "payload": { + "type": "object", + "additionalProperties": true, + "description": "The category fields you sent in `payload`." + }, + "custom_values": { + "type": "object", + "additionalProperties": true, + "description": "The scalar `custom_values` you sent. Didit adds `vpn_or_proxy_detected: true` or `is_data_center: true` when IP enrichment flags the address and you did not set them." + }, + "device_context": { + "type": "object", + "additionalProperties": true, + "description": "The device context as stored: your `device_context` (including `fingerprint`, `persistent_device_id` and `bot_score` when sent) with `network_context` completed by IP enrichment (`ip_country`, `ip_country_code`, `ip_city`, `asn_number`, `asn_organization`, `is_vpn_or_tor`, `is_data_center`, `proxy_type`, `connection_type`) for keys you left empty." + }, + "field_sources": { + "type": "object", + "additionalProperties": { + "type": "string", + "enum": [ + "customer", + "sdk", + "server" + ] + }, + "description": "Field path to provenance: `customer` (sent by your backend), `sdk` (sent through the device lane) or `server` (derived by Didit, such as `received_at` and enriched network fields). Check it before acting on a match." + }, + "session_sequence": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "`session.sequence` sent with the event." + }, + "table_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.table_id`.", + "maxLength": 128 + }, + "hand_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.hand_id`.", + "maxLength": 128 + }, + "match_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.match_id`.", + "maxLength": 128 + }, + "market_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.market_id`.", + "maxLength": 128 + }, + "side": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.side`.", + "maxLength": 64 + }, + "role": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.role`.", + "maxLength": 64 + }, + "net_result_amount": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.net_result_amount`, as a decimal string with 18 decimal places.", + "example": "-120.000000000000000000" + }, + "payment_fingerprint": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.payment_fingerprint`.", + "maxLength": 255 + }, + "instrument_reference_hash": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.instrument_reference_hash`.", + "maxLength": 255 + }, + "withdrawal_address_hash": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.withdrawal_address_hash` (or `payload.destination_reference_hash`).", + "maxLength": 255 + }, + "dispute_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.dispute_id`.", + "maxLength": 255 + }, + "chargeback_id": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.chargeback_id`.", + "maxLength": 255 + }, + "changed_field": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.changed_field` (security change events).", + "maxLength": 128 + }, + "identity_match_ref": { + "type": "string", + "nullable": true, + "description": "Promoted from `payload.identity_match_ref` (responsible-gambling registry matches).", + "maxLength": 255 + }, + "schema_version": { + "type": "integer", + "description": "Version of the event envelope schema. Currently `1`.", + "example": 1 + }, + "expires_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the event expires under its retention class and is deleted: `occurred_at` plus the class period (14, 30 or 90 days by default, adjustable per application). Null for `monetary_or_compliance` events, which follow transaction retention." + }, + "rules_evaluated_count": { + "type": "integer", + "minimum": 0, + "description": "Number of event rules evaluated for this event." + }, + "rule_runs": { + "type": "array", + "description": "Every rule that matched the event, newest first.", + "items": { + "$ref": "#/components/schemas/MonitoringEventRuleRun" + } + }, + "ip_enrichment": { + "type": "object", + "nullable": true, + "description": "Enrichment of the event's IP address, or null when the address was not enriched. See [IP enrichment](https://docs.didit.me/transaction-monitoring/ip-enrichment).", + "properties": { + "ip_country_code": { + "type": "string", + "nullable": true, + "description": "Country code of the address." + }, + "ip_city": { + "type": "string", + "nullable": true, + "description": "City of the address." + }, + "asn_number": { + "type": "integer", + "nullable": true, + "description": "Autonomous system number." + }, + "asn_organization": { + "type": "string", + "nullable": true, + "description": "Organization that operates the autonomous system." + }, + "is_vpn_or_tor": { + "type": "boolean", + "description": "Whether the address is a known VPN or Tor exit." + }, + "is_data_center": { + "type": "boolean", + "description": "Whether the address belongs to a hosting or data-centre network." + }, + "proxy_type": { + "type": "string", + "nullable": true, + "description": "Proxy classification of the address as an opaque string, or null." + }, + "last_enriched_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the address was last enriched." } }, - "adverse_media_details": { - "type": "object", - "properties": { - "sentiment": { + "required": [ + "ip_country_code", + "ip_city", + "asn_number", + "asn_organization", + "is_vpn_or_tor", + "is_data_center", + "proxy_type", + "last_enriched_at" + ] + }, + "subject_profile": { + "type": "object", + "nullable": true, + "description": "Cached email and phone risk signals of the subject, or null when no profile exists for the subject.", + "properties": { + "email_risk_score": { + "type": "integer", + "nullable": true, + "description": "Email risk score." + }, + "email_deliverability": { + "type": "string", + "nullable": true, + "description": "Email deliverability verdict." + }, + "email_is_disposable": { + "type": "boolean", + "nullable": true, + "description": "Whether the email address is disposable." + }, + "email_is_breached": { + "type": "boolean", + "nullable": true, + "description": "Whether the email address appears in known data breaches." + }, + "email_social_count": { + "type": "integer", + "nullable": true, + "description": "Number of online accounts linked to the email address." + }, + "email_social_providers": { + "type": "array", + "items": { "type": "string" }, - "entity_type": { + "description": "Names of the online services where an account linked to the email address was found." + }, + "phone_risk_score": { + "type": "integer", + "nullable": true, + "description": "Phone risk score." + }, + "phone_line_type": { + "type": "string", + "nullable": true, + "description": "Phone line type." + }, + "phone_carrier": { + "type": "string", + "nullable": true, + "description": "Phone carrier name." + }, + "phone_social_count": { + "type": "integer", + "nullable": true, + "description": "Number of online accounts linked to the phone number." + }, + "phone_social_providers": { + "type": "array", + "items": { "type": "string" }, - "sentiment_score": { - "type": "integer" - }, - "adverse_keywords": { - "type": "object", - "additionalProperties": { - "type": "integer" - } - } + "description": "Names of the online services where an account linked to the phone number was found." + }, + "source_provider": { + "type": "string", + "nullable": true, + "description": "Opaque identifier of the source of the profile." + }, + "last_enriched_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the profile was last refreshed." } }, - "adverse_media_matches": { - "type": "array", - "items": { - "type": "object", - "properties": { - "country": { - "type": "string" - }, - "summary": { - "type": "string" - }, - "headline": { - "type": "string" - }, - "sentiment": { - "type": "string" - }, - "thumbnail": { - "type": "string", - "format": "uri" - }, - "source_url": { - "type": "string", - "format": "uri" - }, - "author_name": { - "type": "string", - "nullable": true - }, - "other_sources": { - "type": "array", - "items": { - "type": "string" - } - }, - "adverse_keywords": { - "type": "array", - "items": { - "type": "string" - } - }, - "sentiment_score": { - "type": "integer" - }, - "publication_date": { - "type": "string", - "format": "date-time" - } - } - } + "required": [ + "email_risk_score", + "email_deliverability", + "email_is_disposable", + "email_is_breached", + "email_social_count", + "email_social_providers", + "phone_risk_score", + "phone_line_type", + "phone_carrier", + "phone_social_count", + "phone_social_providers", + "source_provider", + "last_enriched_at" + ] + }, + "tags": { + "type": "array", + "items": { + "type": "string" }, - "additional_information": { - "type": "object" - } + "description": "Names of the tags attached to the event (rule `add_tags` actions)." } } + } + ] + }, + "MonitoringEventRuleRun": { + "type": "object", + "properties": { + "rule_uuid": { + "type": "string", + "format": "uuid", + "description": "UUID of the transaction monitoring rule." + }, + "rule_title": { + "type": "string", + "description": "Title of the rule." + }, + "library_key": { + "type": "string", + "nullable": true, + "description": "Library key when the rule was installed from the rules library, otherwise null." + }, + "matched": { + "type": "boolean", + "description": "Always `true`: only matching runs are recorded." + }, + "mode": { + "type": "string", + "enum": [ + "ACTIVE", + "TEST" + ], + "description": "Mode of the rule when it ran. A `TEST` run records evidence but applied no actions." + }, + "is_async": { + "type": "boolean", + "description": "`true` when the run came from the asynchronous correlation pass rather than the ingest request." + }, + "severity": { + "type": "string", + "nullable": true, + "enum": [ + "UNKNOWN", + "LOW", + "MEDIUM", + "HIGH", + "CRITICAL", + null + ], + "description": "Severity of the rule. Null for `TEST` runs and for rules without a severity." + }, + "score_delta": { + "type": "integer", + "description": "How much this run changed the event's score (0 for `TEST` runs)." + }, + "action_summary": { + "type": "string", + "nullable": true, + "description": "Short summary of the actions applied, for example `score +40; add_tag:VPN_LOGIN`. Null when nothing was applied." + }, + "matched_payload": { + "type": "array", + "description": "The conditions and aggregations that matched. Condition entries carry `field`, `operator`, `expected_value`, `current_value`, `matched`, `group_index`, `group_logic` and `field_source` (`server`, `sdk` or `customer`); aggregation entries carry `metric`, `field`, `operator`, `expected_value`, `computed_value`, `window`, `filters`, `matched` and `sample_references`.", + "items": { + "type": "object", + "additionalProperties": true + } }, - "score": { - "type": "number", - "format": "float", + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the rule run was recorded." + } + }, + "required": [ + "rule_uuid", + "rule_title", + "library_key", + "matched", + "mode", + "is_async", + "severity", + "score_delta", + "action_summary", + "matched_payload", + "created_at" + ] + }, + "MonitoringEventPage": { + "type": "object", + "description": "One page of monitoring events, newest `occurred_at` first.", + "required": [ + "count", + "next", + "previous", + "results" + ], + "properties": { + "count": { + "type": "integer", + "description": "Number of matching events, exact up to 100 and capped at 100 above that. Do not compute page counts from it; follow `next` until it is null." + }, + "next": { + "type": "string", + "format": "uri", "nullable": true, - "minimum": 0, - "maximum": 100, - "description": "Overall AML screening score — the highest risk score across all hits (float, 0-100). `null` until computed." + "description": "URL of the next page, or null on the last page." }, - "screened_data": { + "previous": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "URL of the previous page, or null on the first page." + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MonitoringEvent" + } + } + } + }, + "MonitoringEventCreateRequest": { + "type": "object", + "description": "The event envelope, the same for every category. camelCase aliases are accepted: `eventId`, `eventCategory` (or `category`), `actionType`, `occurredAt`, `timeZone` (or `zoneId`), `deviceContext` (or `device`), `transactionContext`, `customValues` (or `props`); inside `subject`: `vendorData`, `entityType`, `fullName`; inside `session`: `sessionId`, `pageUrl`; inside `transaction_context`: `paymentReferenceId`.", + "required": [ + "event_id", + "event_category", + "action_type", + "occurred_at", + "subject" + ], + "properties": { + "event_id": { + "type": "string", + "maxLength": 128, + "description": "Your identifier for the event, unique per application. It is the idempotency key: resending the same `event_category`, `action_type`, `occurred_at`, `subject.vendor_data` and `payload` under it is a replay, anything different is a conflict.", + "example": "login-2026-10-17-000001" + }, + "event_category": { + "type": "string", + "enum": [ + "auth", + "session", + "gameplay", + "bonus", + "affiliate", + "payment", + "dispute", + "security", + "responsible_gambling", + "custom" + ], + "description": "Event category.", + "example": "auth" + }, + "action_type": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "What happened within the category. Open vocabulary; the managed actions listed in [Event ingestion](https://docs.didit.me/transaction-monitoring/events) (for example `login`, `deposit_completed`, `chargeback_opened`) unlock typed validation and managed rule fields. Leading and trailing whitespace is trimmed.", + "example": "login" + }, + "occurred_at": { + "type": "string", + "format": "date-time", + "description": "When the event happened on your side, ISO 8601 (a value without an offset is read as UTC). Must be no more than 7 days in the past and no more than 5 minutes in the future.", + "example": "2026-10-17T09:15:02.481Z" + }, + "time_zone": { + "type": "string", + "nullable": true, + "maxLength": 64, + "description": "Time zone of the occurrence on your side, for example `Europe/Madrid`. Stored with the event; not returned by the read endpoints." + }, + "subject": { "type": "object", + "description": "The user or company the event belongs to. It resolves to the user (or company) with this `vendor_data` in your application; one is created when none exists.", + "required": [ + "vendor_data" + ], "properties": { + "vendor_data": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Your id for the subject.", + "example": "user-42" + }, + "entity_type": { + "type": "string", + "maxLength": 32, + "default": "individual", + "description": "`company` resolves the subject to a company; any other value (default `individual`) resolves it to an individual. The same `vendor_data` can name one of each.", + "example": "individual" + }, "full_name": { - "type": "string" + "type": "string", + "nullable": true, + "maxLength": 512, + "description": "Display name, used only when this event creates the user or company." }, - "nationality": { - "type": "string" + "email": { + "type": "string", + "format": "email", + "nullable": true, + "description": "Validated as an email address; not stored on the event." }, - "date_of_birth": { + "phone": { "type": "string", - "format": "date" + "nullable": true, + "maxLength": 32, + "description": "Validated; not stored on the event." }, - "document_number": { + "country": { "type": "string", - "nullable": true + "nullable": true, + "maxLength": 3, + "description": "Validated; not stored on the event." } } }, - "is_ongoing_monitoring_enabled": { - "type": "boolean", - "description": "Whether AML ongoing monitoring is enabled for this screening. When `true`, the entity is re-screened periodically and any new hits update the report." + "business": { + "type": "object", + "description": "The business the event belongs to, when it differs from the subject. Only `vendor_data` is read.", + "additionalProperties": true, + "properties": { + "vendor_data": { + "type": "string", + "maxLength": 255, + "description": "Your id for the business. Filterable as `business_vendor_data`.", + "example": "merchant-7" + } + } }, - "next_ongoing_monitoring_bill_date": { + "session": { + "type": "object", + "description": "Your session context for the event.", + "properties": { + "session_id": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Your session identifier. Filterable and returned as `session_id`." + }, + "sequence": { + "type": "integer", + "nullable": true, + "description": "Position of the event within the session. Returned as `session_sequence`." + }, + "page_url": { + "type": "string", + "nullable": true, + "maxLength": 2048, + "description": "Validated; not stored on the event." + }, + "referrer": { + "type": "string", + "nullable": true, + "maxLength": 2048, + "description": "Validated; not stored on the event." + } + } + }, + "device_context": { + "type": "object", + "additionalProperties": true, + "description": "Device and network context, stored as sent and returned by `GET /v3/events/{event_uuid}/`. On this server lane Didit does not see the end user's connection, so the IP enriched and used by rules is `network_context.ip_address` as you send it.", + "properties": { + "fingerprint": { + "type": "string", + "maxLength": 255, + "description": "Device fingerprint. Filterable as `device_fingerprint`." + }, + "persistent_device_id": { + "type": "string", + "maxLength": 255, + "description": "Your persistent device identifier." + }, + "bot_score": { + "type": "integer", + "description": "Bot score from your own detection, as an integer." + }, + "network_context": { + "type": "object", + "additionalProperties": true, + "properties": { + "ip_address": { + "type": "string", + "maxLength": 64, + "description": "End user's IP address. Public addresses are enriched once per unique address.", + "example": "203.0.113.42" + } + } + } + } + }, + "transaction_context": { + "type": "object", + "description": "Money context. Non-empty values here also satisfy the required payload keys of the action.", + "properties": { + "amount": { + "type": "string", + "nullable": true, + "description": "Amount as a decimal string (a number is also accepted).", + "example": "1000.00" + }, + "currency": { + "type": "string", + "nullable": true, + "maxLength": 10, + "description": "Currency code." + }, + "direction": { + "type": "string", + "nullable": true, + "maxLength": 16, + "description": "Direction of the money movement, for example `inbound` or `outbound`." + }, + "payment_reference_id": { + "type": "string", + "nullable": true, + "maxLength": 255, + "description": "Your payment reference. Filterable as `payment_reference_id`." + } + } + }, + "payload": { + "type": "object", + "additionalProperties": true, + "description": "The category's domain fields, at most 16384 bytes once JSON-encoded. Some actions require keys (in `payload` or `transaction_context`): `gameplay.p2p_settlement` needs `game_id`, `counterparty_vendor_data`, `stake_amount`, `net_result_amount`, `role` and one of `hand_id`, `round_id`, `match_id`; `gameplay.bet_placed` and `gameplay.bet_settled` need `game_id`; `payment.deposit_initiated`, `payment.deposit_completed`, `payment.withdrawal_requested` and `payment.withdrawal_completed` need `payment_reference_id`, `amount`, `currency`, `payment_method`, `status`; `payment.withdrawal_address_changed` needs `withdrawal_address_hash`; `dispute.chargeback_opened`, `dispute.chargeback_won` and `dispute.chargeback_lost` need `payment_reference_id` and one of `dispute_id`, `chargeback_id`; `session.bot_signal_observed` needs `telemetry_schema_version` and one of `bot_score`, `actions_per_minute`, `timing_variance_ms`, `pointer_entropy`, `keystroke_entropy`, `reaction_time_ms_p50`; `responsible_gambling.self_exclusion_match` needs `registry_source`, `exclusion_status`, `identity_match_ref`. Every `security` action ending in `_changed` needs `changed_field`, plus `previous_reference_hash` or `new_reference_hash` when the field is `password`, `mfa_method`, `mfa`, `email`, `phone`, `withdrawal_address`, `payout_method` or `api_key`. Send hashes and references, never a card number, a full withdrawal address, a password hash or an MFA secret." + }, + "custom_values": { + "type": "object", + "description": "Up to 100 keys of your own, addressable from rules as `custom_values.`. Values must be scalars (string, number, boolean or null); nested objects and arrays are rejected.", + "additionalProperties": { + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ] + } + } + }, + "example": { + "event_id": "login-2026-10-17-000001", + "event_category": "auth", + "action_type": "login", + "occurred_at": "2026-10-17T09:15:02.481Z", + "time_zone": "Europe/Madrid", + "subject": { + "vendor_data": "user-42", + "entity_type": "individual" + }, + "session": { + "session_id": "web-session-abc", + "sequence": 142 + }, + "device_context": { + "fingerprint": "fp-a8c1", + "network_context": { + "ip_address": "203.0.113.42" + } + }, + "payload": { + "method": "password" + }, + "custom_values": { + "vip_tier": "gold" + } + } + }, + "MonitoringEventIngestResult": { + "type": "object", + "description": "Outcome of ingesting one event. The same shape is returned for a new event and for an idempotent replay.", + "required": [ + "event_uuid", + "event_id", + "status", + "score", + "rules_evaluated_count", + "rules_matched_count", + "correlation_pending", + "retention_class", + "expires_at", + "idempotent_replay", + "rule_matches" + ], + "properties": { + "event_uuid": { "type": "string", - "format": "date", - "nullable": true, - "description": "Date (YYYY-MM-DD) when this ongoing-monitoring subscription will next be billed. Computed as the date of the last ongoing-monitoring billing plus 365 days when `is_ongoing_monitoring_enabled = true`; otherwise `null`. This is a billing date, not a screening date - use `last_ongoing_screening_at` for that." + "format": "uuid", + "description": "Didit identifier of the stored event." }, - "last_ongoing_screening_at": { + "event_id": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "When ongoing monitoring last completed a re-screening of this record, whether or not the result changed. `null` when the record has never been re-screened; it is never back-filled from the enablement or billing date." + "description": "Your `event_id`." }, - "last_ongoing_screening_datasets_updated_at": { + "status": { + "type": "string", + "enum": [ + "ACCEPTED", + "APPROVED", + "IN_REVIEW", + "DECLINED" + ], + "description": "Status after the real-time rules ran. See `MonitoringEvent.status`." + }, + "score": { + "type": "integer", + "description": "Score after the real-time rules ran." + }, + "rules_evaluated_count": { + "type": "integer", + "minimum": 0, + "description": "Number of event rules evaluated in the request. 0 in a sandbox application, where no rules run." + }, + "rules_matched_count": { + "type": "integer", + "minimum": 0, + "description": "Number of rules that matched, including `TEST` mode rules." + }, + "correlation_pending": { + "type": "boolean", + "description": "`true` when an asynchronous rule still has to run. Read `GET /v3/events/{event_uuid}/` a few minutes later for the final `status` and `score`." + }, + "retention_class": { + "type": "string", + "enum": [ + "low_value", + "standard", + "risk_relevant", + "monetary_or_compliance" + ], + "description": "Retention class, after any promotion by a matched rule." + }, + "expires_at": { "type": "string", "format": "date-time", "nullable": true, - "description": "The most recent AML dataset update date the provider reported at the time of that screening. `null` when the provider reported no dataset dates; never estimated." + "description": "When the event expires under its retention class and is deleted. Null for `monetary_or_compliance` (payment and dispute) events." }, - "warnings": { + "idempotent_replay": { + "type": "boolean", + "description": "`true` when an event with this `event_id` and the same content was already stored; the values are those of the stored event and no rule ran again." + }, + "rule_matches": { "type": "array", + "description": "Rules that matched the event.", "items": { "type": "object", + "required": [ + "rule_id", + "library_key", + "mode", + "is_async" + ], "properties": { - "feature": { + "rule_id": { "type": "string", - "enum": [ - "ID_VERIFICATION", - "NFC", - "LIVENESS", - "FACEMATCH", - "PROOF_OF_ADDRESS", - "PHONE", - "EMAIL", - "AML", - "LOCATION", - "DATABASE_VALIDATION", - "QUESTIONNAIRE", - "DOCUMENT_AI", - "KYB_REGISTRY", - "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE" - ], - "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Within an AML screening this is typically `AML`, but the enum above is authoritative across all feature warnings on the decision payload." - }, - "risk": { - "type": "string" - }, - "additional_data": { - "type": "object", - "nullable": true - }, - "log_type": { - "type": "string" - }, - "short_description": { - "type": "string" + "format": "uuid", + "description": "UUID of the rule." }, - "long_description": { - "type": "string" + "library_key": { + "type": "string", + "nullable": true, + "description": "Library key when the rule was installed from the rules library, otherwise null." }, - "node_id": { + "mode": { "type": "string", - "description": "The workflow graph node ID that generated this warning" + "enum": [ + "ACTIVE", + "TEST" + ], + "description": "`TEST` rules record the match but apply no actions." + }, + "is_async": { + "type": "boolean", + "description": "`true` when the match came from the asynchronous pass." } } } } } }, - "MonitoringEvent": { - "type": "object", - "description": "One stored monitoring event as returned by the list and subject-timeline endpoints. Restricted evidence (payload, device context, rule evidence) is only returned by `GET /v3/events/{event_uuid}/`.", - "required": [ - "event_uuid", - "event_id", - "event_category", - "action_type", - "occurred_at", - "received_at", - "status", - "score", - "subject_vendor_data", - "subject_entity_type", - "subject_uuid", - "counterparty_vendor_data", - "session_id", - "device_fingerprint", - "ip_address", - "ip_country", - "amount", - "currency", - "game_id", - "round_id", - "bonus_id", - "affiliate_code", - "payment_reference_id", - "retention_class", - "rules_matched_count", - "correlation_pending", - "is_droppable" + "ComplianceList": { + "type": "object", + "description": "A blocklist, allowlist or custom list of one application.", + "required": [ + "uuid", + "name", + "description", + "list_type", + "entry_type", + "is_system", + "entry_count", + "last_entry_added_at", + "created_at", + "updated_at" ], "properties": { - "event_uuid": { + "uuid": { "type": "string", "format": "uuid", - "description": "Didit identifier of the event. Use it as `{event_uuid}` in the retrieve and delete calls." + "description": "List identifier. Use it as `list_uuid` in the list and entry endpoints, and as the value of a workflow or transaction rule condition with `value_type: \"list\"`." }, - "event_id": { + "name": { "type": "string", - "maxLength": 128, - "description": "Your own identifier, the idempotency key you sent." + "maxLength": 255, + "description": "List name, unique among the application's lists." }, - "event_category": { + "description": { + "type": "string", + "description": "Free-text description. Empty string when not set." + }, + "list_type": { "type": "string", "enum": [ - "auth", - "session", - "gameplay", - "bonus", - "affiliate", - "payment", - "dispute", - "security", - "responsible_gambling", + "blocklist", + "allowlist", "custom" ], - "description": "Event category." - }, - "action_type": { - "type": "string", - "maxLength": 128, - "description": "What happened within the category, as you sent it." - }, - "occurred_at": { - "type": "string", - "format": "date-time", - "description": "When the event happened on your side." - }, - "received_at": { - "type": "string", - "format": "date-time", - "description": "When Didit accepted the event." + "description": "`blocklist`: a match declines the session or transaction (system lists only, one per entry type). `allowlist`: matching items are trusted, for example a face allowlist skips the duplicated-face action; never overrides a blocklist match. `custom`: used in workflow and transaction rule conditions (`value_type: \"list\"`)." }, - "status": { + "entry_type": { "type": "string", "enum": [ - "ACCEPTED", - "APPROVED", - "IN_REVIEW", - "DECLINED" + "face", + "document", + "phone", + "email", + "ip_address", + "device_fingerprint", + "wallet_address", + "bank_account", + "country", + "user", + "business", + "key" ], - "description": "`ACCEPTED`: stored, no matched rule changed its standing (the normal answer for most events, and always the answer in a sandbox application, where no rules run). `APPROVED`: a rule matched and the score stayed under your review threshold. `IN_REVIEW`: a rule pushed the score over the review threshold or set the status. `DECLINED`: a rule declined it or the score crossed your decline threshold." - }, - "score": { - "type": "integer", - "description": "Accumulated rule score. Starts at 0; rule `add_score` actions move it (negative deltas are allowed)." - }, - "subject_vendor_data": { - "type": "string", - "maxLength": 255, - "description": "`subject.vendor_data` of the event: your id for the user or company." - }, - "subject_entity_type": { - "type": "string", - "description": "`individual` or `company`: which kind of subject `subject_vendor_data` names.", - "example": "individual" + "description": "What the list holds: `face`, `document` (document number), `phone`, `email`, `ip_address` (IP address or CIDR range), `device_fingerprint`, `wallet_address`, `bank_account`, `country` (ISO 3166-1 alpha-3), `user` or `business` (your `vendor_data`), or `key` (any string). It decides how entry values are validated and matched." }, - "subject_uuid": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "UUID of the user (individual) or company the event resolved to, or null when that record no longer exists." + "is_system": { + "type": "boolean", + "description": "`true` for the lists Didit provisions: one blocklist per entry type (`face`, `document`, `phone`, `email`, `ip_address`, `device_fingerprint`, `wallet_address`, `bank_account`, `user`, `business`), the **High Risk Countries** custom list, and system allowlists. System lists cannot be renamed, edited or deleted; you can add and delete their entries." }, - "counterparty_vendor_data": { - "type": "string", - "nullable": true, - "description": "The other player of a P2P event (promoted from `payload.counterparty_vendor_data`).", - "maxLength": 255 + "entry_count": { + "type": "integer", + "minimum": 0, + "description": "Number of entries currently in the list." }, - "session_id": { + "last_entry_added_at": { "type": "string", + "format": "date-time", "nullable": true, - "description": "`session.session_id` sent with the event.", - "maxLength": 255 + "description": "When the newest current entry was added. `null` for an empty list." }, - "device_fingerprint": { + "created_at": { "type": "string", - "nullable": true, - "description": "`device_context.fingerprint` sent with the event.", - "maxLength": 255 + "format": "date-time", + "description": "When the list was created." }, - "ip_address": { + "updated_at": { "type": "string", - "nullable": true, - "description": "IP address of the event. On the server lane this is `device_context.network_context.ip_address` as you sent it; on the device lane it is the IP of the request.", - "maxLength": 64 - }, - "ip_country": { + "format": "date-time", + "description": "When the list was last updated." + } + } + }, + "ComplianceListEntry": { + "type": "object", + "description": "One value in a list.", + "required": [ + "uuid", + "value", + "display_label", + "comment", + "added_by", + "reference_session_id", + "reference_session_number", + "reference_session_type", + "reference_object_uuid", + "metadata", + "created_at" + ], + "properties": { + "uuid": { "type": "string", - "nullable": true, - "description": "Country code of `ip_address` from IP enrichment, or null when the address was not enriched (missing, private, or low-value telemetry whose address was not already known).", - "example": "ES" + "format": "uuid", + "description": "Entry identifier. Use it as `entry_uuid` in Delete a list entry." }, - "amount": { + "value": { "type": "string", - "nullable": true, - "description": "Amount as a decimal string with 18 decimal places, from `transaction_context.amount`, `payload.amount` or `payload.stake_amount`, in that order.", - "example": "250.000000000000000000" + "description": "The listed value: a phone number in E.164, an email address, a document number, an IP address or CIDR range, a device fingerprint, a wallet address, a bank account, an ISO 3166-1 alpha-3 country code, a `vendor_data`, any string on a `key` list, or the UUID of the stored face on a face list. Values you send are stored in lower case, except phone numbers and country codes. Matching is case-insensitive." }, - "currency": { + "display_label": { "type": "string", "nullable": true, - "description": "Currency from `transaction_context.currency` or `payload.currency`.", - "maxLength": 10 + "maxLength": 512, + "description": "Human-readable label. Didit fills it for entries taken from a session (for example the holder's name and document number) when you send none." }, - "game_id": { + "comment": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.game_id`.", - "maxLength": 128 + "description": "Free-text note. Empty string when not set." }, - "round_id": { + "added_by": { "type": "string", "nullable": true, - "description": "Promoted from `payload.round_id`.", - "maxLength": 128 + "description": "Who added the entry: `api` (an API key), a console user's email address or `console`, `system` or `migration` (entries Didit created), or `rule` (a transaction or monitoring rule action)." }, - "bonus_id": { + "reference_session_id": { "type": "string", + "format": "uuid", "nullable": true, - "description": "Promoted from `payload.bonus_id`.", - "maxLength": 128 + "description": "Verification session the entry was taken from. `null` when the entry was added by value." }, - "affiliate_code": { - "type": "string", + "reference_session_number": { + "type": "integer", "nullable": true, - "description": "Promoted from `payload.affiliate_code`.", - "maxLength": 128 + "description": "Application-scoped number of that session, as shown in the console." }, - "payment_reference_id": { + "reference_session_type": { "type": "string", "nullable": true, - "description": "Payment reference from `transaction_context.payment_reference_id` or `payload.payment_reference_id`.", - "maxLength": 255 - }, - "retention_class": { - "type": "string", "enum": [ - "low_value", - "standard", - "risk_relevant", - "monetary_or_compliance" + "kyc", + "kyb", + null ], - "description": "Retention class. Payment and dispute events are `monetary_or_compliance`; security and responsible-gambling events are `risk_relevant`; `session.page_view`, `session.sdk_heartbeat`, `session.sdk_loaded`, `session.device_seen`, `session.bot_signal_observed`, `bonus.promotion_viewed` and `affiliate.referral_clicked` are `low_value`; everything else is `standard`. An event an active rule matched is promoted to `risk_relevant` (never demoted)." - }, - "rules_matched_count": { - "type": "integer", - "minimum": 0, - "description": "Number of rules that matched the event, including rules in `TEST` mode (which record evidence but apply no actions)." - }, - "correlation_pending": { - "type": "boolean", - "description": "`true` while an asynchronous rule (cross-subject correlation, or a sequence longer than 24 hours) still has to run for this event. It resolves within minutes and `status`, `score` and `rules_matched_count` update in place." + "description": "`kyc` for a person verification session, `kyb` for a business verification session, `null` when there is no session." }, - "is_droppable": { - "type": "boolean", - "description": "Whether an SDK under backpressure may drop events of this kind. `false` for every `security`, `payment`, `dispute` and `responsible_gambling` event and for `gameplay.bet_placed`, `gameplay.bet_settled` and `gameplay.p2p_settlement`." - } - } - }, - "MonitoringEventDetail": { - "description": "One monitoring event with its full envelope, enrichment and rule evidence. Every field of `MonitoringEvent` plus the fields below.", - "allOf": [ - { - "$ref": "#/components/schemas/MonitoringEvent" + "reference_object_uuid": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "The record the entry stands for: the face, document, phone or email record read from a session, the face created by Upload a face to a list, or the UUID you sent (for example a transaction UUID or a user's `didit_internal_id`)." }, - { + "metadata": { "type": "object", - "required": [ - "payload", - "custom_values", - "device_context", - "field_sources", - "session_sequence", - "table_id", - "hand_id", - "match_id", - "market_id", - "side", - "role", - "net_result_amount", - "payment_fingerprint", - "instrument_reference_hash", - "withdrawal_address_hash", - "dispute_id", - "chargeback_id", - "changed_field", - "identity_match_ref", - "schema_version", - "expires_at", - "rules_evaluated_count", - "rule_runs", - "ip_enrichment", - "subject_profile", - "tags" - ], + "nullable": true, + "additionalProperties": true, + "description": "Extra context. Holds the keys Didit sets (listed here) merged with any `metadata` you sent when creating the entry, returned as stored. `null` when there is none.", "properties": { - "payload": { - "type": "object", - "additionalProperties": true, - "description": "The category fields you sent in `payload`." - }, - "custom_values": { - "type": "object", - "additionalProperties": true, - "description": "The scalar `custom_values` you sent. Didit adds `vpn_or_proxy_detected: true` or `is_data_center: true` when IP enrichment flags the address and you did not set them." - }, - "device_context": { - "type": "object", - "additionalProperties": true, - "description": "The device context as stored: your `device_context` (including `fingerprint`, `persistent_device_id` and `bot_score` when sent) with `network_context` completed by IP enrichment (`ip_country`, `ip_country_code`, `ip_city`, `asn_number`, `asn_organization`, `is_vpn_or_tor`, `is_data_center`, `proxy_type`, `connection_type`) for keys you left empty." - }, - "field_sources": { - "type": "object", - "additionalProperties": { - "type": "string", - "enum": [ - "customer", - "sdk", - "server" - ] - }, - "description": "Field path to provenance: `customer` (sent by your backend), `sdk` (sent through the device lane) or `server` (derived by Didit, such as `received_at` and enriched network fields). Check it before acting on a match." + "reference_image_url": { + "type": "string", + "description": "Face entries: short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`. Absent when no image belongs to the entry." }, - "session_sequence": { - "type": "integer", - "format": "int64", - "nullable": true, - "description": "`session.sequence` sent with the event." + "front_image_url": { + "type": "string", + "description": "Document entries that carry a document front image: short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`." }, - "table_id": { + "full_name": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.table_id`.", - "maxLength": 128 + "description": "Document entries taken from a session: holder's full name." }, - "hand_id": { + "issuing_state": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.hand_id`.", - "maxLength": 128 + "description": "Document entries taken from a session: ISO 3166-1 alpha-3 issuing country." }, - "match_id": { + "document_type": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.match_id`.", - "maxLength": 128 + "description": "Document entries taken from a session: document type code, for example `P`, `ID` or `DL`." }, - "market_id": { + "region": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.market_id`.", - "maxLength": 128 + "description": "Document entries taken from a session: issuing state or province of a regionally issued document, empty when not applicable. Not set by Add session items to the blocklist." }, - "side": { + "document_number": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.side`.", - "maxLength": 64 + "description": "Document entries taken from a session: the document number." }, - "role": { + "face_image_source": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.role`.", - "maxLength": 64 + "enum": [ + "front_image_camera_front", + "back_image_camera_front" + ], + "description": "Face entries taken from a document-capture selfie: which selfie. Absent for liveness faces." }, - "net_result_amount": { + "reference_node_id": { "type": "string", "nullable": true, - "description": "Promoted from `payload.net_result_amount`, as a decimal string with 18 decimal places.", - "example": "-120.000000000000000000" + "description": "Face entries taken from a document-capture selfie: the ID verification node the selfie came from." }, - "payment_fingerprint": { + "fingerprint_tier": { "type": "string", "nullable": true, - "description": "Promoted from `payload.payment_fingerprint`.", - "maxLength": 255 + "enum": [ + "persistent_id", + "composite_hash", + "legacy_fp", + "unknown", + null + ], + "description": "Device fingerprint entries taken from a session: how the fingerprint was derived. `persistent_id` identifies one device; `composite_hash` and `legacy_fp` can be shared by devices of the same model." }, - "instrument_reference_hash": { + "sandbox": { + "type": "boolean", + "description": "`true` on a face entry uploaded in a sandbox application; such an entry matches nothing." + }, + "reference_type": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.instrument_reference_hash`.", - "maxLength": 255 + "enum": [ + "transaction", + "vendor_user", + "vendor_business" + ], + "description": "Set by you: what `reference_object_uuid` points to, so the console links back to it." }, - "withdrawal_address_hash": { + "reference_id": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.withdrawal_address_hash` (or `payload.destination_reference_hash`).", - "maxLength": 255 + "description": "Set by you: identifier of the source record." + } + } + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the entry was added." + } + } + }, + "BlocklistedItem": { + "type": "object", + "description": "One blocklisted face, identity document, phone number or email address of a verification session. Fields that do not apply to the item's `type` are `null`.", + "required": [ + "type", + "session_id", + "session_number", + "blocklisted_at", + "face_image", + "document_type", + "document_number", + "front_image", + "phone_number", + "country_code", + "email" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "face", + "document", + "phone", + "email" + ], + "description": "What was blocklisted." + }, + "session_id": { + "type": "string", + "format": "uuid", + "description": "Verification session the item belongs to." + }, + "session_number": { + "type": "integer", + "nullable": true, + "description": "Application-scoped number of that session, as shown in the console." + }, + "blocklisted_at": { + "type": "string", + "format": "date-time", + "description": "When the item was last blocklisted." + }, + "face_image": { + "type": "string", + "nullable": true, + "description": "Face items: short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`. Also `null` when no reference image is stored." + }, + "document_type": { + "type": "string", + "nullable": true, + "description": "Document items: document type code, for example `P` (passport), `ID` (national ID), `DL` (driver's license) or `RP` (residence permit)." + }, + "document_number": { + "type": "string", + "nullable": true, + "description": "Document items: the document number, or the personal number when the document has none." + }, + "front_image": { + "type": "string", + "nullable": true, + "description": "Document items: front image of the document, short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`." + }, + "phone_number": { + "type": "string", + "nullable": true, + "description": "Phone items: the phone number in E.164." + }, + "country_code": { + "type": "string", + "nullable": true, + "description": "Phone items: ISO 3166-1 alpha-2 country of the number." + }, + "email": { + "type": "string", + "nullable": true, + "description": "Email items: the email address." + } + } + }, + "TransactionNote": { + "type": "object", + "description": "One note on a monitored transaction's review timeline.", + "required": [ + "uuid", + "note", + "actor_email", + "actor_name", + "metadata", + "created_at" + ], + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Note identifier." + }, + "note": { + "type": "string", + "description": "Plain-text note body." + }, + "actor_email": { + "type": "string", + "format": "email", + "nullable": true, + "description": "Email of the Console user who wrote the note or changed the status. `null` for notes created with an API key and for notes Didit adds automatically." + }, + "actor_name": { + "type": "string", + "nullable": true, + "description": "Display name of the Console user (their email when they have no name). `Rule Engine` on notes Didit adds automatically. `null` for notes created with an API key." + }, + "metadata": { + "type": "object", + "description": "Tells the note types apart. Notes written through the API or the Console carry `mentioned_emails`. A status change made in the Console carries `type: status_change` with `previous_status`, `new_status`, `reason_code` and `reason_label`. Notes Didit adds carry `source`: `rule_action` (with `rule_uuid`) for a rule's `add_note` action, or `remediation_session` for a problem creating the user-action verification session.", + "properties": { + "mentioned_emails": { + "type": "array", + "items": { + "type": "string", + "format": "email" + }, + "description": "Mentioned organization members, lower-cased and de-duplicated. Empty when nobody was mentioned." }, - "dispute_id": { + "type": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.dispute_id`.", - "maxLength": 255 + "enum": [ + "status_change" + ], + "description": "Present on notes recording a status change made in the Console." }, - "chargeback_id": { + "previous_status": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.chargeback_id`.", - "maxLength": 255 + "enum": [ + "APPROVED", + "IN_REVIEW", + "DECLINED", + "AWAITING_USER" + ], + "description": "Status before the change." }, - "changed_field": { + "new_status": { "type": "string", - "nullable": true, - "description": "Promoted from `payload.changed_field` (security change events).", - "maxLength": 128 + "enum": [ + "APPROVED", + "IN_REVIEW", + "DECLINED", + "AWAITING_USER" + ], + "description": "Status after the change." }, - "identity_match_ref": { + "reason_code": { "type": "string", "nullable": true, - "description": "Promoted from `payload.identity_match_ref` (responsible-gambling registry matches).", - "maxLength": 255 - }, - "schema_version": { - "type": "integer", - "description": "Version of the event envelope schema. Currently `1`.", - "example": 1 + "description": "Reason code given with the change." }, - "expires_at": { + "reason_label": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the event expires under its retention class and is deleted: `occurred_at` plus the class period (14, 30 or 90 days by default, adjustable per application). Null for `monetary_or_compliance` events, which follow transaction retention." - }, - "rules_evaluated_count": { - "type": "integer", - "minimum": 0, - "description": "Number of event rules evaluated for this event." - }, - "rule_runs": { - "type": "array", - "description": "Every rule that matched the event, newest first.", - "items": { - "$ref": "#/components/schemas/MonitoringEventRuleRun" - } - }, - "ip_enrichment": { - "type": "object", "nullable": true, - "description": "Enrichment of the event's IP address, or null when the address was not enriched. See [IP enrichment](https://docs.didit.me/transaction-monitoring/ip-enrichment).", - "properties": { - "ip_country_code": { - "type": "string", - "nullable": true, - "description": "Country code of the address." - }, - "ip_city": { - "type": "string", - "nullable": true, - "description": "City of the address." - }, - "asn_number": { - "type": "integer", - "nullable": true, - "description": "Autonomous system number." - }, - "asn_organization": { - "type": "string", - "nullable": true, - "description": "Organization that operates the autonomous system." - }, - "is_vpn_or_tor": { - "type": "boolean", - "description": "Whether the address is a known VPN or Tor exit." - }, - "is_data_center": { - "type": "boolean", - "description": "Whether the address belongs to a hosting or data-centre network." - }, - "proxy_type": { - "type": "string", - "nullable": true, - "description": "Proxy classification of the address as an opaque string, or null." - }, - "last_enriched_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the address was last enriched." - } - }, - "required": [ - "ip_country_code", - "ip_city", - "asn_number", - "asn_organization", - "is_vpn_or_tor", - "is_data_center", - "proxy_type", - "last_enriched_at" - ] + "description": "Reason label given with the change." }, - "subject_profile": { - "type": "object", - "nullable": true, - "description": "Cached email and phone risk signals of the subject, or null when no profile exists for the subject.", - "properties": { - "email_risk_score": { - "type": "integer", - "nullable": true, - "description": "Email risk score." - }, - "email_deliverability": { - "type": "string", - "nullable": true, - "description": "Email deliverability verdict." - }, - "email_is_disposable": { - "type": "boolean", - "nullable": true, - "description": "Whether the email address is disposable." - }, - "email_is_breached": { - "type": "boolean", - "nullable": true, - "description": "Whether the email address appears in known data breaches." - }, - "email_social_count": { - "type": "integer", - "nullable": true, - "description": "Number of online accounts linked to the email address." - }, - "email_social_providers": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Names of the online services where an account linked to the email address was found." - }, - "phone_risk_score": { - "type": "integer", - "nullable": true, - "description": "Phone risk score." - }, - "phone_line_type": { - "type": "string", - "nullable": true, - "description": "Phone line type." - }, - "phone_carrier": { - "type": "string", - "nullable": true, - "description": "Phone carrier name." - }, - "phone_social_count": { - "type": "integer", - "nullable": true, - "description": "Number of online accounts linked to the phone number." - }, - "phone_social_providers": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Names of the online services where an account linked to the phone number was found." - }, - "source_provider": { - "type": "string", - "nullable": true, - "description": "Opaque identifier of the source of the profile." - }, - "last_enriched_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the profile was last refreshed." - } - }, - "required": [ - "email_risk_score", - "email_deliverability", - "email_is_disposable", - "email_is_breached", - "email_social_count", - "email_social_providers", - "phone_risk_score", - "phone_line_type", - "phone_carrier", - "phone_social_count", - "phone_social_providers", - "source_provider", - "last_enriched_at" - ] + "source": { + "type": "string", + "enum": [ + "rule_action", + "remediation_session" + ], + "description": "Present on notes Didit adds automatically." }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Names of the tags attached to the event (rule `add_tags` actions)." + "rule_uuid": { + "type": "string", + "format": "uuid", + "description": "Rule whose `add_note` action wrote the note (with `source: rule_action`)." } } + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the note was stored." } - ] + } }, - "MonitoringEventRuleRun": { + "TransactionSummary": { "type": "object", + "description": "Summary of a monitored transaction, the shape `GET /v3/transactions/` lists. Call `GET /v3/transactions/{transaction_id}/` with `uuid` for parties, alerts and rule runs.", "properties": { - "rule_uuid": { + "uuid": { "type": "string", "format": "uuid", - "description": "UUID of the transaction monitoring rule." + "description": "Didit transaction UUID. Use it as `{transaction_id}` on the transaction endpoints." }, - "rule_title": { - "type": "string", - "description": "Title of the rule." + "transaction_number": { + "type": "integer", + "nullable": true, + "description": "Application-scoped sequential number shown in the Console." }, - "library_key": { + "txn_id": { "type": "string", "nullable": true, - "description": "Library key when the rule was installed from the rules library, otherwise null." + "description": "Your own identifier from the create call. Unique per application." }, - "matched": { - "type": "boolean", - "description": "Always `true`: only matching runs are recorded." + "transaction_type": { + "type": "string", + "description": "Category as stored: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange` or `auditTrailEvent`." }, - "mode": { + "action_type": { + "type": "string", + "description": "Sub-type within the category, for example `withdrawal`." + }, + "status": { "type": "string", "enum": [ - "ACTIVE", - "TEST" + "APPROVED", + "IN_REVIEW", + "DECLINED", + "AWAITING_USER" ], - "description": "Mode of the rule when it ran. A `TEST` run records evidence but applied no actions." + "description": "Current monitoring verdict." }, - "is_async": { - "type": "boolean", - "description": "`true` when the run came from the asynchronous correlation pass rather than the ingest request." + "source": { + "type": "string", + "enum": [ + "LIVE", + "IMPORTED" + ], + "description": "`LIVE` for transactions submitted for monitoring, `IMPORTED` for historical imports." + }, + "direction": { + "type": "string", + "enum": [ + "INBOUND", + "OUTBOUND" + ], + "description": "Direction relative to the subject." + }, + "amount": { + "type": "string", + "description": "Amount as a decimal string with trailing zeros removed (up to 18 decimal places)." + }, + "currency": { + "type": "string", + "description": "Currency code or crypto asset symbol of `amount`." + }, + "currency_type": { + "type": "string", + "nullable": true, + "description": "`fiat` or `crypto` when known." + }, + "preferred_currency_amount": { + "type": "string", + "nullable": true, + "description": "`amount` converted to the application's preferred currency, when a rate was available." + }, + "preferred_currency_code": { + "type": "string", + "nullable": true, + "description": "Currency of `preferred_currency_amount`." + }, + "payment_details": { + "type": "string", + "nullable": true, + "description": "Free-text payment reference." + }, + "txn_date": { + "type": "string", + "format": "date-time", + "description": "When the transaction occurred." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When Didit recorded it." + }, + "score": { + "type": "integer", + "description": "Risk score. Higher is riskier." }, "severity": { "type": "string", @@ -100770,8088 +119065,8206 @@ "CRITICAL", null ], - "description": "Severity of the rule. Null for `TEST` runs and for rules without a severity." + "description": "Risk severity, `null` until something sets it." }, - "score_delta": { - "type": "integer", - "description": "How much this run changed the event's score (0 for `TEST` runs)." + "decision_reason_code": { + "type": "string", + "nullable": true, + "description": "Machine-readable reason for the current `status`." }, - "action_summary": { + "decision_reason_label": { "type": "string", "nullable": true, - "description": "Short summary of the actions applied, for example `score +40; add_tag:VPN_LOGIN`. Null when nothing was applied." + "description": "Human-readable label for `decision_reason_code`." }, - "matched_payload": { + "tags": { "type": "array", - "description": "The conditions and aggregations that matched. Condition entries carry `field`, `operator`, `expected_value`, `current_value`, `matched`, `group_index`, `group_logic` and `field_source` (`server`, `sdk` or `customer`); aggregation entries carry `metric`, `field`, `operator`, `expected_value`, `computed_value`, `window`, `filters`, `matched` and `sample_references`.", + "description": "Tags on the transaction.", "items": { "type": "object", - "additionalProperties": true + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "color": { + "type": "string", + "description": "Hex color, for example `#F59E0B`." + }, + "description": { + "type": "string", + "nullable": true + }, + "source": { + "type": "string", + "enum": [ + "didit", + "custom" + ], + "description": "Didit preset or custom tag." + } + } } }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "When the rule run was recorded." + "subject_name": { + "type": "string", + "nullable": true, + "description": "Full name of the `APPLICANT` party." + }, + "subject_vendor_data": { + "type": "string", + "nullable": true, + "description": "Your `vendor_data` for the applicant." + }, + "subject_type": { + "type": "string", + "nullable": true, + "enum": [ + "user", + "business", + null + ], + "description": "Whether the applicant is linked to a Didit user or business; `null` when it is linked to neither." + }, + "subject_uuid": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "UUID of the Didit user or business the applicant is linked to." + }, + "subject_country": { + "type": "string", + "nullable": true, + "description": "Country code of the applicant." + }, + "counterparty_name": { + "type": "string", + "nullable": true, + "description": "Full name of the `COUNTERPARTY` party, if any." + }, + "counterparty_vendor_data": { + "type": "string", + "nullable": true, + "description": "Your `vendor_data` for the counterparty." + }, + "counterparty_country": { + "type": "string", + "nullable": true, + "description": "Country code of the counterparty." + }, + "assigned_to_name": { + "type": "string", + "nullable": true, + "description": "Name of the Console reviewer assigned to the transaction." + }, + "travel_rule_status": { + "type": "string", + "nullable": true, + "description": "Status of the transaction's Travel Rule transfer, or `null` when it has none." + }, + "application_id": { + "type": "string", + "format": "uuid", + "description": "Application that owns the transaction." + }, + "application_name": { + "type": "string", + "nullable": true, + "description": "Name of that application." + }, + "organization_id": { + "type": "string", + "format": "uuid", + "description": "Organization that owns the application." + }, + "organization_name": { + "type": "string", + "nullable": true, + "description": "Name of that organization." + } + } + }, + "ApplicationAnalyticsDataPoint": { + "type": "object", + "description": "Session counts for one day, by creation date (UTC). Each count reflects the session's current status. Points of the previous period carry at least the required fields.", + "required": [ + "rounded_date", + "total", + "approved", + "declined", + "canceled", + "pending" + ], + "properties": { + "rounded_date": { + "type": "string", + "format": "date", + "description": "The day, `YYYY-MM-DD`." + }, + "total": { + "type": "integer", + "description": "Sessions created that day." + }, + "approved": { + "type": "integer", + "description": "Of those, sessions `Approved` or `Kyc Expired`." + }, + "declined": { + "type": "integer", + "description": "Sessions `Declined`." + }, + "canceled": { + "type": "integer", + "description": "Sessions `Expired` or `Abandoned`." + }, + "pending": { + "type": "integer", + "description": "Sessions `Not Started`, `In Progress` or `In Review`." + }, + "in_review": { + "type": "integer", + "description": "Sessions `In Review`." + }, + "expired": { + "type": "integer", + "description": "Sessions `Expired`." + }, + "abandoned": { + "type": "integer", + "description": "Sessions `Abandoned`." + }, + "in_progress": { + "type": "integer", + "description": "Sessions `In Progress`." + }, + "not_started": { + "type": "integer", + "description": "Sessions `Not Started`." + }, + "manually_approved": { + "type": "integer", + "description": "Sessions a reviewer approved after the workflow gave another verdict." + }, + "manually_declined": { + "type": "integer", + "description": "Sessions a reviewer declined after the workflow gave another verdict." } - }, - "required": [ - "rule_uuid", - "rule_title", - "library_key", - "matched", - "mode", - "is_async", - "severity", - "score_delta", - "action_summary", - "matched_payload", - "created_at" - ] + } }, - "MonitoringEventPage": { + "ApplicationAnalyticsRequestBreakdown": { "type": "object", - "description": "One page of monitoring events, newest `occurred_at` first.", + "description": "Status totals for the range. The previous-period breakdown carries at least the required fields.", "required": [ - "count", - "next", - "previous", - "results" + "total_approved", + "total_in_review", + "total_declined", + "total_canceled", + "total_pending" ], "properties": { - "count": { + "total_approved": { "type": "integer", - "description": "Number of matching events, exact up to 100 and capped at 100 above that. Do not compute page counts from it; follow `next` until it is null." + "description": "Sessions `Approved` or `Kyc Expired`." }, - "next": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "URL of the next page, or null on the last page." + "total_in_review": { + "type": "integer", + "description": "Sessions `In Review`." }, - "previous": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "URL of the previous page, or null on the first page." + "total_declined": { + "type": "integer", + "description": "Sessions `Declined`." }, - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MonitoringEvent" - } + "total_canceled": { + "type": "integer", + "description": "Sessions `Expired` or `Abandoned`." + }, + "total_pending": { + "type": "integer", + "description": "Sessions `Not Started`, `In Progress` or `In Review` (includes `total_in_review`)." + }, + "total_expired": { + "type": "integer", + "description": "Sessions `Expired`." + }, + "total_abandoned": { + "type": "integer", + "description": "Sessions `Abandoned`." + }, + "total_in_progress": { + "type": "integer", + "description": "Sessions `In Progress`." + }, + "total_not_started": { + "type": "integer", + "description": "Sessions `Not Started`." + }, + "total_manually_approved": { + "type": "integer", + "description": "Approved by a reviewer." + }, + "total_manually_declined": { + "type": "integer", + "description": "Declined by a reviewer." } } }, - "MonitoringEventCreateRequest": { + "ApplicationAnalyticsCountryCount": { "type": "object", - "description": "The event envelope, the same for every category. camelCase aliases are accepted: `eventId`, `eventCategory` (or `category`), `actionType`, `occurredAt`, `timeZone` (or `zoneId`), `deviceContext` (or `device`), `transactionContext`, `customValues` (or `props`); inside `subject`: `vendorData`, `entityType`, `fullName`; inside `session`: `sessionId`, `pageUrl`; inside `transaction_context`: `paymentReferenceId`.", - "required": [ - "event_id", - "event_category", - "action_type", - "occurred_at", - "subject" - ], "properties": { - "event_id": { - "type": "string", - "maxLength": 128, - "description": "Your identifier for the event, unique per application. It is the idempotency key: resending the same `event_category`, `action_type`, `occurred_at`, `subject.vendor_data` and `payload` under it is a replay, anything different is a conflict.", - "example": "login-2026-10-17-000001" - }, - "event_category": { + "country": { "type": "string", - "enum": [ - "auth", - "session", - "gameplay", - "bonus", - "affiliate", - "payment", - "dispute", - "security", - "responsible_gambling", - "custom" - ], - "description": "Event category.", - "example": "auth" + "description": "Country name." }, - "action_type": { + "country_code": { "type": "string", - "minLength": 1, - "maxLength": 128, - "description": "What happened within the category. Open vocabulary; the managed actions listed in [Event ingestion](https://docs.didit.me/transaction-monitoring/events) (for example `login`, `deposit_completed`, `chargeback_opened`) unlock typed validation and managed rule fields. Leading and trailing whitespace is trimmed.", - "example": "login" + "description": "Two-letter country code." }, - "occurred_at": { - "type": "string", - "format": "date-time", - "description": "When the event happened on your side, ISO 8601 (a value without an offset is read as UTC). Must be no more than 7 days in the past and no more than 5 minutes in the future.", - "example": "2026-10-17T09:15:02.481Z" + "session_count": { + "type": "integer", + "description": "Sessions from that country." + } + } + }, + "ApplicationAnalyticsLocationStats": { + "type": "object", + "properties": { + "ip_countries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount" + }, + "description": "Countries of the users' IP addresses, most sessions first." }, - "time_zone": { - "type": "string", - "nullable": true, - "maxLength": 64, - "description": "Time zone of the occurrence on your side, for example `Europe/Madrid`. Stored with the event; not returned by the read endpoints." + "countries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount" + }, + "description": "Same list as `ip_countries`." }, - "subject": { - "type": "object", - "description": "The user or company the event belongs to. It resolves to the user (or company) with this `vendor_data` in your application; one is created when none exists.", - "required": [ - "vendor_data" - ], - "properties": { - "vendor_data": { - "type": "string", - "minLength": 1, - "maxLength": 255, - "description": "Your id for the subject.", - "example": "user-42" - }, - "entity_type": { - "type": "string", - "maxLength": 32, - "default": "individual", - "description": "`company` resolves the subject to a company; any other value (default `individual`) resolves it to an individual. The same `vendor_data` can name one of each.", - "example": "individual" - }, - "full_name": { - "type": "string", - "nullable": true, - "maxLength": 512, - "description": "Display name, used only when this event creates the user or company." - }, - "email": { - "type": "string", - "format": "email", - "nullable": true, - "description": "Validated as an email address; not stored on the event." - }, - "phone": { - "type": "string", - "nullable": true, - "maxLength": 32, - "description": "Validated; not stored on the event." - }, - "country": { - "type": "string", - "nullable": true, - "maxLength": 3, - "description": "Validated; not stored on the event." - } - } + "id_countries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount" + }, + "description": "Issuing countries of the verified ID documents, most sessions first." }, - "business": { - "type": "object", - "description": "The business the event belongs to, when it differs from the subject. Only `vendor_data` is read.", - "additionalProperties": true, - "properties": { - "vendor_data": { - "type": "string", - "maxLength": 255, - "description": "Your id for the business. Filterable as `business_vendor_data`.", - "example": "merchant-7" + "conversion_by_country": { + "type": "array", + "description": "Per document issuing country: finished sessions (approved, declined or in review) and how many were approved. Most finished first.", + "items": { + "type": "object", + "properties": { + "country": { + "type": "string" + }, + "country_code": { + "type": "string" + }, + "finished": { + "type": "integer" + }, + "approved": { + "type": "integer" + } } } }, - "session": { - "type": "object", - "description": "Your session context for the event.", - "properties": { - "session_id": { - "type": "string", - "nullable": true, - "maxLength": 255, - "description": "Your session identifier. Filterable and returned as `session_id`." - }, - "sequence": { - "type": "integer", - "nullable": true, - "description": "Position of the event within the session. Returned as `session_sequence`." - }, - "page_url": { - "type": "string", - "nullable": true, - "maxLength": 2048, - "description": "Validated; not stored on the event." - }, - "referrer": { - "type": "string", - "nullable": true, - "maxLength": 2048, - "description": "Validated; not stored on the event." + "cities": { + "type": "array", + "description": "Up to 100 IP cities, most sessions first.", + "items": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "`City, Country`." + }, + "session_count": { + "type": "integer" + }, + "latitude": { + "type": "number", + "nullable": true + }, + "longitude": { + "type": "number", + "nullable": true + } } } - }, - "device_context": { + } + } + }, + "ApplicationAnalyticsDemographicStats": { + "type": "object", + "properties": { + "age_distribution": { "type": "object", - "additionalProperties": true, - "description": "Device and network context, stored as sent and returned by `GET /v3/events/{event_uuid}/`. On this server lane Didit does not see the end user's connection, so the IP enriched and used by rules is `network_context.ip_address` as you send it.", + "description": "Sessions per age band from the ID document. Empty when there is no data.", "properties": { - "fingerprint": { - "type": "string", - "maxLength": 255, - "description": "Device fingerprint. Filterable as `device_fingerprint`." - }, - "persistent_device_id": { - "type": "string", - "maxLength": 255, - "description": "Your persistent device identifier." + "under_18": { + "type": "integer" }, - "bot_score": { - "type": "integer", - "description": "Bot score from your own detection, as an integer." + "18_24": { + "type": "integer" }, - "network_context": { - "type": "object", - "additionalProperties": true, - "properties": { - "ip_address": { - "type": "string", - "maxLength": 64, - "description": "End user's IP address. Public addresses are enriched once per unique address.", - "example": "203.0.113.42" - } - } - } - } - }, - "transaction_context": { - "type": "object", - "description": "Money context. Non-empty values here also satisfy the required payload keys of the action.", - "properties": { - "amount": { - "type": "string", - "nullable": true, - "description": "Amount as a decimal string (a number is also accepted).", - "example": "1000.00" + "25_34": { + "type": "integer" }, - "currency": { - "type": "string", - "nullable": true, - "maxLength": 10, - "description": "Currency code." + "35_44": { + "type": "integer" }, - "direction": { - "type": "string", - "nullable": true, - "maxLength": 16, - "description": "Direction of the money movement, for example `inbound` or `outbound`." + "45_64": { + "type": "integer" }, - "payment_reference_id": { - "type": "string", - "nullable": true, - "maxLength": 255, - "description": "Your payment reference. Filterable as `payment_reference_id`." + "65_plus": { + "type": "integer" } + }, + "additionalProperties": { + "type": "integer" } }, - "payload": { - "type": "object", - "additionalProperties": true, - "description": "The category's domain fields, at most 16384 bytes once JSON-encoded. Some actions require keys (in `payload` or `transaction_context`): `gameplay.p2p_settlement` needs `game_id`, `counterparty_vendor_data`, `stake_amount`, `net_result_amount`, `role` and one of `hand_id`, `round_id`, `match_id`; `gameplay.bet_placed` and `gameplay.bet_settled` need `game_id`; `payment.deposit_initiated`, `payment.deposit_completed`, `payment.withdrawal_requested` and `payment.withdrawal_completed` need `payment_reference_id`, `amount`, `currency`, `payment_method`, `status`; `payment.withdrawal_address_changed` needs `withdrawal_address_hash`; `dispute.chargeback_opened`, `dispute.chargeback_won` and `dispute.chargeback_lost` need `payment_reference_id` and one of `dispute_id`, `chargeback_id`; `session.bot_signal_observed` needs `telemetry_schema_version` and one of `bot_score`, `actions_per_minute`, `timing_variance_ms`, `pointer_entropy`, `keystroke_entropy`, `reaction_time_ms_p50`; `responsible_gambling.self_exclusion_match` needs `registry_source`, `exclusion_status`, `identity_match_ref`. Every `security` action ending in `_changed` needs `changed_field`, plus `previous_reference_hash` or `new_reference_hash` when the field is `password`, `mfa_method`, `mfa`, `email`, `phone`, `withdrawal_address`, `payout_method` or `api_key`. Send hashes and references, never a card number, a full withdrawal address, a password hash or an MFA secret." - }, - "custom_values": { + "gender_distribution": { "type": "object", - "description": "Up to 100 keys of your own, addressable from rules as `custom_values.`. Values must be scalars (string, number, boolean or null); nested objects and arrays are rejected.", + "description": "Sessions per document gender code: `M`, `F` or `U` (unknown).", "additionalProperties": { - "nullable": true, - "oneOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - } - ] - } - } - }, - "example": { - "event_id": "login-2026-10-17-000001", - "event_category": "auth", - "action_type": "login", - "occurred_at": "2026-10-17T09:15:02.481Z", - "time_zone": "Europe/Madrid", - "subject": { - "vendor_data": "user-42", - "entity_type": "individual" - }, - "session": { - "session_id": "web-session-abc", - "sequence": 142 - }, - "device_context": { - "fingerprint": "fp-a8c1", - "network_context": { - "ip_address": "203.0.113.42" + "type": "integer" } - }, - "payload": { - "method": "password" - }, - "custom_values": { - "vip_tier": "gold" } } }, - "MonitoringEventIngestResult": { + "ApplicationAnalyticsDeviceDetails": { "type": "object", - "description": "Outcome of ingesting one event. The same shape is returned for a new event and for an idempotent replay.", - "required": [ - "event_uuid", - "event_id", - "status", - "score", - "rules_evaluated_count", - "rules_matched_count", - "correlation_pending", - "retention_class", - "expires_at", - "idempotent_replay", - "rule_matches" - ], + "description": "Top five of each, most sessions first.", "properties": { - "event_uuid": { - "type": "string", - "format": "uuid", - "description": "Didit identifier of the stored event." - }, - "event_id": { - "type": "string", - "description": "Your `event_id`." - }, - "status": { - "type": "string", - "enum": [ - "ACCEPTED", - "APPROVED", - "IN_REVIEW", - "DECLINED" - ], - "description": "Status after the real-time rules ran. See `MonitoringEvent.status`." - }, - "score": { - "type": "integer", - "description": "Score after the real-time rules ran." - }, - "rules_evaluated_count": { - "type": "integer", - "minimum": 0, - "description": "Number of event rules evaluated in the request. 0 in a sandbox application, where no rules run." - }, - "rules_matched_count": { - "type": "integer", - "minimum": 0, - "description": "Number of rules that matched, including `TEST` mode rules." - }, - "correlation_pending": { - "type": "boolean", - "description": "`true` when an asynchronous rule still has to run. Read `GET /v3/events/{event_uuid}/` a few minutes later for the final `status` and `score`." - }, - "retention_class": { - "type": "string", - "enum": [ - "low_value", - "standard", - "risk_relevant", - "monetary_or_compliance" - ], - "description": "Retention class, after any promotion by a matched rule." - }, - "expires_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the event expires under its retention class and is deleted. Null for `monetary_or_compliance` (payment and dispute) events." + "device_models": { + "type": "array", + "description": "Device brands: `Apple`, `Android`, `LG`, everything else grouped as `Other`.", + "items": { + "type": "object", + "properties": { + "device": { + "type": "string" + }, + "count": { + "type": "integer" + } + } + } }, - "idempotent_replay": { - "type": "boolean", - "description": "`true` when an event with this `event_id` and the same content was already stored; the values are those of the stored event and no rule ran again." + "browsers": { + "type": "array", + "description": "Browsers: `Chrome`, `Safari`, `Didit App`, `Firefox`, everything else grouped as `Other`.", + "items": { + "type": "object", + "properties": { + "browser": { + "type": "string" + }, + "count": { + "type": "integer" + } + } + } }, - "rule_matches": { + "operating_systems": { "type": "array", - "description": "Rules that matched the event.", + "description": "Operating systems.", "items": { "type": "object", - "required": [ - "rule_id", - "library_key", - "mode", - "is_async" - ], "properties": { - "rule_id": { - "type": "string", - "format": "uuid", - "description": "UUID of the rule." - }, - "library_key": { - "type": "string", - "nullable": true, - "description": "Library key when the rule was installed from the rules library, otherwise null." - }, - "mode": { - "type": "string", - "enum": [ - "ACTIVE", - "TEST" - ], - "description": "`TEST` rules record the match but apply no actions." + "os": { + "type": "string" }, - "is_async": { - "type": "boolean", - "description": "`true` when the match came from the asynchronous pass." + "count": { + "type": "integer" } } } } } }, - "ComplianceList": { + "ApplicationAnalyticsWorkflowFunnel": { "type": "object", - "description": "A blocklist, allowlist or custom list of one application.", - "required": [ - "uuid", - "name", - "description", - "list_type", - "entry_type", - "is_system", - "entry_count", - "last_entry_added_at", - "created_at", - "updated_at" - ], - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "List identifier. Use it as `list_uuid` in the list and entry endpoints, and as the value of a workflow or transaction rule condition with `value_type: \"list\"`." - }, - "name": { - "type": "string", - "maxLength": 255, - "description": "List name, unique among the application's lists." - }, - "description": { - "type": "string", - "description": "Free-text description. Empty string when not set." - }, - "list_type": { - "type": "string", - "enum": [ - "blocklist", - "allowlist", - "custom" - ], - "description": "`blocklist`: a match declines the session or transaction (system lists only, one per entry type). `allowlist`: matching items are trusted, for example a face allowlist skips the duplicated-face action; never overrides a blocklist match. `custom`: used in workflow and transaction rule conditions (`value_type: \"list\"`)." - }, - "entry_type": { - "type": "string", - "enum": [ - "face", - "document", - "phone", - "email", - "ip_address", - "device_fingerprint", - "wallet_address", - "bank_account", - "country", - "user", - "business", - "key" - ], - "description": "What the list holds: `face`, `document` (document number), `phone`, `email`, `ip_address` (IP address or CIDR range), `device_fingerprint`, `wallet_address`, `bank_account`, `country` (ISO 3166-1 alpha-3), `user` or `business` (your `vendor_data`), or `key` (any string). It decides how entry values are validated and matched." - }, - "is_system": { - "type": "boolean", - "description": "`true` for the lists Didit provisions: one blocklist per entry type (`face`, `document`, `phone`, `email`, `ip_address`, `device_fingerprint`, `wallet_address`, `bank_account`, `user`, `business`), the **High Risk Countries** custom list, and system allowlists. System lists cannot be renamed, edited or deleted; you can add and delete their entries." - }, - "entry_count": { - "type": "integer", - "minimum": 0, - "description": "Number of entries currently in the list." - }, - "last_entry_added_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the newest current entry was added. `null` for an empty list." - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "When the list was created." - }, - "updated_at": { - "type": "string", - "format": "date-time", - "description": "When the list was last updated." + "description": "Keyed by workflow ID. `total` is the sessions started on that workflow; `steps` counts the sessions that reached each step (`OCR`, `LIVENESS`, `FACE_MATCH`, `AML`, `POA`, `PHONE`, `EMAIL`, `NFC`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`). Reaching a step is not passing it.", + "additionalProperties": { + "type": "object", + "properties": { + "total": { + "type": "integer" + }, + "steps": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "reached": { + "type": "integer" + } + } + } + } } } }, - "ComplianceListEntry": { + "ApplicationAnalyticsVerificationTimeStats": { "type": "object", - "description": "One value in a list.", - "required": [ - "uuid", - "value", - "display_label", - "comment", - "added_by", - "reference_session_id", - "reference_session_number", - "reference_session_type", - "reference_object_uuid", - "metadata", - "created_at" - ], + "description": "Active time users spent verifying, ignoring idle gaps. An empty object when there is no data.", "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Entry identifier. Use it as `entry_uuid` in Delete a list entry." - }, - "value": { - "type": "string", - "description": "The listed value: a phone number in E.164, an email address, a document number, an IP address or CIDR range, a device fingerprint, a wallet address, a bank account, an ISO 3166-1 alpha-3 country code, a `vendor_data`, any string on a `key` list, or the UUID of the stored face on a face list. Values you send are stored in lower case, except phone numbers and country codes. Matching is case-insensitive." - }, - "display_label": { - "type": "string", - "nullable": true, - "maxLength": 512, - "description": "Human-readable label. Didit fills it for entries taken from a session (for example the holder's name and document number) when you send none." - }, - "comment": { - "type": "string", - "description": "Free-text note. Empty string when not set." - }, - "added_by": { - "type": "string", - "nullable": true, - "description": "Who added the entry: `api` (an API key), a console user's email address or `console`, `system` or `migration` (entries Didit created), or `rule` (a transaction or monitoring rule action)." - }, - "reference_session_id": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "Verification session the entry was taken from. `null` when the entry was added by value." + "overall_avg_seconds": { + "type": "number", + "description": "Average per session, one decimal." }, - "reference_session_number": { + "overall_count": { "type": "integer", - "nullable": true, - "description": "Application-scoped number of that session, as shown in the console." - }, - "reference_session_type": { - "type": "string", - "nullable": true, - "enum": [ - "kyc", - "kyb", - null - ], - "description": "`kyc` for a person verification session, `kyb` for a business verification session, `null` when there is no session." - }, - "reference_object_uuid": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "The record the entry stands for: the face, document, phone or email record read from a session, the face created by Upload a face to a list, or the UUID you sent (for example a transaction UUID or a user's `didit_internal_id`)." + "description": "Sessions measured." }, - "metadata": { + "per_feature": { "type": "object", - "nullable": true, - "additionalProperties": true, - "description": "Extra context. Holds the keys Didit sets (listed here) merged with any `metadata` you sent when creating the entry, returned as stored. `null` when there is none.", - "properties": { - "reference_image_url": { - "type": "string", - "description": "Face entries: short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`. Absent when no image belongs to the entry." - }, - "front_image_url": { - "type": "string", - "description": "Document entries that carry a document front image: short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`." - }, - "full_name": { - "type": "string", - "description": "Document entries taken from a session: holder's full name." - }, - "issuing_state": { - "type": "string", - "description": "Document entries taken from a session: ISO 3166-1 alpha-3 issuing country." - }, - "document_type": { - "type": "string", - "description": "Document entries taken from a session: document type code, for example `P`, `ID` or `DL`." - }, - "region": { - "type": "string", - "description": "Document entries taken from a session: issuing state or province of a regionally issued document, empty when not applicable. Not set by Add session items to the blocklist." - }, - "document_number": { - "type": "string", - "description": "Document entries taken from a session: the document number." - }, - "face_image_source": { - "type": "string", - "enum": [ - "front_image_camera_front", - "back_image_camera_front" - ], - "description": "Face entries taken from a document-capture selfie: which selfie. Absent for liveness faces." - }, - "reference_node_id": { - "type": "string", - "nullable": true, - "description": "Face entries taken from a document-capture selfie: the ID verification node the selfie came from." - }, - "fingerprint_tier": { - "type": "string", - "nullable": true, - "enum": [ - "persistent_id", - "composite_hash", - "legacy_fp", - "unknown", - null - ], - "description": "Device fingerprint entries taken from a session: how the fingerprint was derived. `persistent_id` identifies one device; `composite_hash` and `legacy_fp` can be shared by devices of the same model." - }, - "sandbox": { - "type": "boolean", - "description": "`true` on a face entry uploaded in a sandbox application; such an entry matches nothing." - }, - "reference_type": { - "type": "string", - "enum": [ - "transaction", - "vendor_user", - "vendor_business" - ], - "description": "Set by you: what `reference_object_uuid` points to, so the console links back to it." - }, - "reference_id": { - "type": "string", - "description": "Set by you: identifier of the source record." + "description": "Keyed by feature, for example `OCR` or `LIVENESS`.", + "additionalProperties": { + "type": "object", + "properties": { + "avg_seconds": { + "type": "number" + }, + "total_seconds": { + "type": "number" + }, + "count": { + "type": "integer" + } } } }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "When the entry was added." + "per_sub_step": { + "type": "object", + "description": "Keyed by feature, then by sub-step, for example `front_id_photo`.", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "avg_seconds": { + "type": "number" + }, + "total_seconds": { + "type": "number" + }, + "count": { + "type": "integer" + } + } + } + } } } }, - "BlocklistedItem": { + "ApplicationAnalyticsResubmissionStats": { "type": "object", - "description": "One blocklisted face, identity document, phone number or email address of a verification session. Fields that do not apply to the item's `type` are `null`.", - "required": [ - "type", - "session_id", - "session_number", - "blocklisted_at", - "face_image", - "document_type", - "document_number", - "front_image", - "phone_number", - "country_code", - "email" - ], "properties": { - "type": { - "type": "string", - "enum": [ - "face", - "document", - "phone", - "email" - ], - "description": "What was blocklisted." - }, - "session_id": { - "type": "string", - "format": "uuid", - "description": "Verification session the item belongs to." - }, - "session_number": { + "first_pass": { "type": "integer", - "nullable": true, - "description": "Application-scoped number of that session, as shown in the console." - }, - "blocklisted_at": { - "type": "string", - "format": "date-time", - "description": "When the item was last blocklisted." - }, - "face_image": { - "type": "string", - "nullable": true, - "description": "Face items: short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`. Also `null` when no reference image is stored." - }, - "document_type": { - "type": "string", - "nullable": true, - "description": "Document items: document type code, for example `P` (passport), `ID` (national ID), `DL` (driver's license) or `RP` (residence permit)." - }, - "document_number": { - "type": "string", - "nullable": true, - "description": "Document items: the document number, or the personal number when the document has none." - }, - "front_image": { - "type": "string", - "nullable": true, - "description": "Document items: front image of the document, short-lived signed URL, issued again on every call; `null` for a scoped API key without `media: read`." + "description": "Finished sessions with no resubmission." }, - "phone_number": { - "type": "string", - "nullable": true, - "description": "Phone items: the phone number in E.164." + "second": { + "type": "integer", + "description": "Finished sessions resubmitted once." }, - "country_code": { - "type": "string", - "nullable": true, - "description": "Phone items: ISO 3166-1 alpha-2 country of the number." + "third_plus": { + "type": "integer", + "description": "Finished sessions resubmitted two or more times." }, - "email": { - "type": "string", - "nullable": true, - "description": "Email items: the email address." + "abandoned": { + "type": "integer", + "description": "Abandoned sessions." } } }, - "TransactionNote": { + "ApplicationAnalyticsOriginalStatusStats": { "type": "object", - "description": "One note on a monitored transaction's review timeline.", - "required": [ - "uuid", - "note", - "actor_email", - "actor_name", - "metadata", - "created_at" - ], + "description": "The workflow's automatic verdict, before any reviewer changed it.", "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Note identifier." - }, - "note": { - "type": "string", - "description": "Plain-text note body." - }, - "actor_email": { - "type": "string", - "format": "email", - "nullable": true, - "description": "Email of the Console user who wrote the note or changed the status. `null` for notes created with an API key and for notes Didit adds automatically." + "approved": { + "type": "integer" }, - "actor_name": { - "type": "string", - "nullable": true, - "description": "Display name of the Console user (their email when they have no name). `Rule Engine` on notes Didit adds automatically. `null` for notes created with an API key." + "in_review": { + "type": "integer" }, - "metadata": { - "type": "object", - "description": "Tells the note types apart. Notes written through the API or the Console carry `mentioned_emails`. A status change made in the Console carries `type: status_change` with `previous_status`, `new_status`, `reason_code` and `reason_label`. Notes Didit adds carry `source`: `rule_action` (with `rule_uuid`) for a rule's `add_note` action, or `remediation_session` for a problem creating the user-action verification session.", - "properties": { - "mentioned_emails": { - "type": "array", - "items": { - "type": "string", - "format": "email" - }, - "description": "Mentioned organization members, lower-cased and de-duplicated. Empty when nobody was mentioned." - }, - "type": { - "type": "string", - "enum": [ - "status_change" - ], - "description": "Present on notes recording a status change made in the Console." - }, - "previous_status": { - "type": "string", - "enum": [ - "APPROVED", - "IN_REVIEW", - "DECLINED", - "AWAITING_USER" - ], - "description": "Status before the change." - }, - "new_status": { - "type": "string", - "enum": [ - "APPROVED", - "IN_REVIEW", - "DECLINED", - "AWAITING_USER" - ], - "description": "Status after the change." - }, - "reason_code": { - "type": "string", - "nullable": true, - "description": "Reason code given with the change." - }, - "reason_label": { - "type": "string", - "nullable": true, - "description": "Reason label given with the change." - }, - "source": { - "type": "string", - "enum": [ - "rule_action", - "remediation_session" - ], - "description": "Present on notes Didit adds automatically." - }, - "rule_uuid": { - "type": "string", - "format": "uuid", - "description": "Rule whose `add_note` action wrote the note (with `source: rule_action`)." + "declined": { + "type": "integer" + } + } + }, + "ApplicationAnalyticsWarningStats": { + "type": "object", + "description": "Keyed by feature (`ID_VERIFICATION`, `LIVENESS`, `FACEMATCH`, `AML`, `PROOF_OF_ADDRESS`, `PHONE`, `EMAIL`, `NFC`, `LOCATION`, `DATABASE_VALIDATION`, `QUESTIONNAIRE` and the KYB features). `total` is the sessions that reached the feature; `risks` counts sessions per warning code and level.", + "additionalProperties": { + "type": "object", + "properties": { + "total": { + "type": "integer" + }, + "risks": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "error": { + "type": "integer" + }, + "warning": { + "type": "integer" + }, + "information": { + "type": "integer" + } + } } } - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "When the note was stored." } } }, - "TransactionSummary": { + "ApplicationAnalyticsDemographicPoint": { "type": "object", - "description": "Summary of a monitored transaction, the shape `GET /v3/transactions/` lists. Call `GET /v3/transactions/{transaction_id}/` with `uuid` for parties, alerts and rule runs.", "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Didit transaction UUID. Use it as `{transaction_id}` on the transaction endpoints." - }, - "transaction_number": { - "type": "integer", - "nullable": true, - "description": "Application-scoped sequential number shown in the Console." - }, - "txn_id": { - "type": "string", - "nullable": true, - "description": "Your own identifier from the create call. Unique per application." - }, - "transaction_type": { - "type": "string", - "description": "Category as stored: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange` or `auditTrailEvent`." - }, - "action_type": { + "date": { "type": "string", - "description": "Sub-type within the category, for example `withdrawal`." + "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." }, - "status": { - "type": "string", - "enum": [ - "APPROVED", - "IN_REVIEW", - "DECLINED", - "AWAITING_USER" - ], - "description": "Current monitoring verdict." + "age_distribution": { + "type": "object", + "additionalProperties": { + "type": "integer" + } }, - "source": { + "gender_distribution": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "ApplicationAnalyticsDevicePoint": { + "type": "object", + "properties": { + "date": { "type": "string", - "enum": [ - "LIVE", - "IMPORTED" - ], - "description": "`LIVE` for transactions submitted for monitoring, `IMPORTED` for historical imports." + "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." }, - "direction": { - "type": "string", - "enum": [ - "INBOUND", - "OUTBOUND" - ], - "description": "Direction relative to the subject." + "devices": { + "type": "object", + "additionalProperties": { + "type": "integer" + } }, - "amount": { - "type": "string", - "description": "Amount as a decimal string with trailing zeros removed (up to 18 decimal places)." + "browsers": { + "type": "object", + "additionalProperties": { + "type": "integer" + } }, - "currency": { + "operating_systems": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "ApplicationAnalyticsVerificationTimePoint": { + "type": "object", + "properties": { + "date": { "type": "string", - "description": "Currency code or crypto asset symbol of `amount`." + "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." }, - "currency_type": { - "type": "string", - "nullable": true, - "description": "`fiat` or `crypto` when known." + "overall_avg": { + "type": "number", + "description": "Average active seconds per session." }, - "preferred_currency_amount": { + "per_feature": { + "type": "object", + "description": "Average active seconds per feature.", + "additionalProperties": { + "type": "number" + } + } + } + }, + "ApplicationAnalyticsResubmissionPoint": { + "type": "object", + "properties": { + "date": { "type": "string", - "nullable": true, - "description": "`amount` converted to the application's preferred currency, when a rate was available." + "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." }, - "preferred_currency_code": { - "type": "string", - "nullable": true, - "description": "Currency of `preferred_currency_amount`." + "first_pass": { + "type": "integer" }, - "payment_details": { - "type": "string", - "nullable": true, - "description": "Free-text payment reference." + "second": { + "type": "integer" }, - "txn_date": { - "type": "string", - "format": "date-time", - "description": "When the transaction occurred." + "third_plus": { + "type": "integer" }, - "created_at": { + "abandoned": { + "type": "integer" + } + } + }, + "ApplicationAnalyticsOriginalStatusPoint": { + "type": "object", + "properties": { + "date": { "type": "string", - "format": "date-time", - "description": "When Didit recorded it." + "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." }, - "score": { - "type": "integer", - "description": "Risk score. Higher is riskier." + "approved": { + "type": "integer" }, - "severity": { - "type": "string", - "nullable": true, - "enum": [ - "UNKNOWN", - "LOW", - "MEDIUM", - "HIGH", - "CRITICAL", - null - ], - "description": "Risk severity, `null` until something sets it." + "in_review": { + "type": "integer" }, - "decision_reason_code": { - "type": "string", - "nullable": true, - "description": "Machine-readable reason for the current `status`." + "declined": { + "type": "integer" + } + } + }, + "ApplicationAnalyticsSummary": { + "type": "object", + "description": "User verification (KYC) summary, returned when neither `scope` nor `widget_keys` is sent.", + "required": [ + "data_points", + "request_breakdown", + "previous_data_points", + "previous_request_breakdown", + "conversion_rate", + "location_stats", + "demographic_stats", + "device_details", + "workflow_funnel_stats", + "verification_time_stats", + "resubmission_stats", + "warning_stats", + "original_status_stats", + "grouping_mode", + "demographic_time_series", + "device_time_series", + "verification_time_time_series", + "resubmission_time_series", + "original_status_time_series" + ], + "properties": { + "data_points": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" + }, + "description": "One point per day, from the first day with sessions in the range to `end_date`. Always daily, whatever `grouping_mode` says." }, - "decision_reason_label": { - "type": "string", - "nullable": true, - "description": "Human-readable label for `decision_reason_code`." + "request_breakdown": { + "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" }, - "tags": { + "previous_data_points": { "type": "array", - "description": "Tags on the transaction.", "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "color": { - "type": "string", - "description": "Hex color, for example `#F59E0B`." - }, - "description": { - "type": "string", - "nullable": true - }, - "source": { - "type": "string", - "enum": [ - "didit", - "custom" - ], - "description": "Didit preset or custom tag." - } - } - } + "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" + }, + "description": "Daily points for the period of the same length right before `start_date`." }, - "subject_name": { - "type": "string", - "nullable": true, - "description": "Full name of the `APPLICANT` party." + "previous_request_breakdown": { + "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" }, - "subject_vendor_data": { - "type": "string", + "conversion_rate": { + "type": "number", "nullable": true, - "description": "Your `vendor_data` for the applicant." + "description": "`total_approved / (total_approved + total_declined + total_in_review) x 100`, one decimal. `null` when nothing finished." }, - "subject_type": { - "type": "string", - "nullable": true, - "enum": [ - "user", - "business", - null - ], - "description": "Whether the applicant is linked to a Didit user or business; `null` when it is linked to neither." + "location_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsLocationStats" }, - "subject_uuid": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "UUID of the Didit user or business the applicant is linked to." + "demographic_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats" }, - "subject_country": { - "type": "string", - "nullable": true, - "description": "Country code of the applicant." + "device_details": { + "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails" }, - "counterparty_name": { - "type": "string", - "nullable": true, - "description": "Full name of the `COUNTERPARTY` party, if any." + "workflow_funnel_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel" }, - "counterparty_vendor_data": { - "type": "string", - "nullable": true, - "description": "Your `vendor_data` for the counterparty." + "verification_time_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats" }, - "counterparty_country": { - "type": "string", - "nullable": true, - "description": "Country code of the counterparty." + "resubmission_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats" }, - "assigned_to_name": { - "type": "string", - "nullable": true, - "description": "Name of the Console reviewer assigned to the transaction." + "warning_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats" }, - "travel_rule_status": { - "type": "string", - "nullable": true, - "description": "Status of the transaction's Travel Rule transfer, or `null` when it has none." + "original_status_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats" }, - "application_id": { + "grouping_mode": { "type": "string", - "format": "uuid", - "description": "Application that owns the transaction." + "enum": [ + "day", + "week", + "month" + ], + "description": "How the `*_time_series` lists are grouped: `day` for up to 14 days, `week` up to 90, `month` beyond. Measured from the first day with sessions in the range." }, - "application_name": { - "type": "string", - "nullable": true, - "description": "Name of that application." + "demographic_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint" + } }, - "organization_id": { - "type": "string", - "format": "uuid", - "description": "Organization that owns the application." + "device_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint" + } }, - "organization_name": { - "type": "string", - "nullable": true, - "description": "Name of that organization." + "verification_time_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint" + } + }, + "resubmission_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint" + } + }, + "original_status_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint" + } } } }, - "ApplicationAnalyticsDataPoint": { + "ApplicationAnalyticsWidget": { "type": "object", - "description": "Session counts for one day, by creation date (UTC). Each count reflects the session's current status. Points of the previous period carry at least the required fields.", + "description": "One dashboard widget. Every widget has `kind` and `title`; the other fields depend on `kind`. The session widgets reuse the summary objects (`data_points`, `request_breakdown`, `workflow_funnel_stats` and so on); list widgets put their entries in `items`; transaction metrics use `value`.", "required": [ - "rounded_date", - "total", - "approved", - "declined", - "canceled", - "pending" + "kind", + "title" ], "properties": { - "rounded_date": { + "kind": { "type": "string", - "format": "date", - "description": "The day, `YYYY-MM-DD`." - }, - "total": { - "type": "integer", - "description": "Sessions created that day." - }, - "approved": { - "type": "integer", - "description": "Of those, sessions `Approved` or `Kyc Expired`." - }, - "declined": { - "type": "integer", - "description": "Sessions `Declined`." - }, - "canceled": { - "type": "integer", - "description": "Sessions `Expired` or `Abandoned`." - }, - "pending": { - "type": "integer", - "description": "Sessions `Not Started`, `In Progress` or `In Review`." - }, - "in_review": { - "type": "integer", - "description": "Sessions `In Review`." - }, - "expired": { - "type": "integer", - "description": "Sessions `Expired`." - }, - "abandoned": { - "type": "integer", - "description": "Sessions `Abandoned`." - }, - "in_progress": { - "type": "integer", - "description": "Sessions `In Progress`." + "enum": [ + "sessions_volume", + "workflow_funnel", + "average_verification_time", + "country_distribution", + "warning_insights", + "conversion_rate", + "conversion_by_country", + "resubmission_insights", + "original_status_distribution", + "database_validation_coverage", + "database_validation_latency", + "demographics", + "device_details", + "horizontal_bar", + "kyb_registry_coverage", + "kyb_registry_data_completeness", + "metric", + "time_series", + "breakdown", + "status_time_series", + "leaderboard", + "histogram" + ], + "description": "Widget type." }, - "not_started": { - "type": "integer", - "description": "Sessions `Not Started`." + "title": { + "type": "string", + "description": "Display title, for example `Verification volume`." }, - "manually_approved": { - "type": "integer", - "description": "Sessions a reviewer approved after the workflow gave another verdict." + "grouping_mode": { + "type": "string", + "enum": [ + "day", + "week", + "month" + ], + "description": "How the `*_time_series` lists are grouped: `day` for up to 14 days, `week` up to 90, `month` beyond. Measured from the first day with sessions in the range." }, - "manually_declined": { - "type": "integer", - "description": "Sessions a reviewer declined after the workflow gave another verdict." - } - } - }, - "ApplicationAnalyticsRequestBreakdown": { - "type": "object", - "description": "Status totals for the range. The previous-period breakdown carries at least the required fields.", - "required": [ - "total_approved", - "total_in_review", - "total_declined", - "total_canceled", - "total_pending" - ], - "properties": { - "total_approved": { - "type": "integer", - "description": "Sessions `Approved` or `Kyc Expired`." + "data_points": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" + } }, - "total_in_review": { - "type": "integer", - "description": "Sessions `In Review`." + "request_breakdown": { + "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" }, - "total_declined": { - "type": "integer", - "description": "Sessions `Declined`." + "previous_data_points": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" + } }, - "total_canceled": { - "type": "integer", - "description": "Sessions `Expired` or `Abandoned`." + "previous_request_breakdown": { + "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" }, - "total_pending": { - "type": "integer", - "description": "Sessions `Not Started`, `In Progress` or `In Review` (includes `total_in_review`)." + "conversion_rate": { + "type": "number", + "nullable": true }, - "total_expired": { - "type": "integer", - "description": "Sessions `Expired`." + "workflow_funnel_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel" }, - "total_abandoned": { - "type": "integer", - "description": "Sessions `Abandoned`." + "verification_time_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats" }, - "total_in_progress": { - "type": "integer", - "description": "Sessions `In Progress`." + "verification_time_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint" + } }, - "total_not_started": { - "type": "integer", - "description": "Sessions `Not Started`." + "warning_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats" }, - "total_manually_approved": { - "type": "integer", - "description": "Approved by a reviewer." + "resubmission_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats" }, - "total_manually_declined": { - "type": "integer", - "description": "Declined by a reviewer." - } - } - }, - "ApplicationAnalyticsCountryCount": { - "type": "object", - "properties": { - "country": { - "type": "string", - "description": "Country name." + "resubmission_time_series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint" + } }, - "country_code": { - "type": "string", - "description": "Two-letter country code." + "original_status_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats" }, - "session_count": { - "type": "integer", - "description": "Sessions from that country." - } - } - }, - "ApplicationAnalyticsLocationStats": { - "type": "object", - "properties": { - "ip_countries": { + "original_status_time_series": { "type": "array", "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount" - }, - "description": "Countries of the users' IP addresses, most sessions first." + "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint" + } }, - "countries": { + "demographic_stats": { + "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats" + }, + "demographic_time_series": { "type": "array", "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount" - }, - "description": "Same list as `ip_countries`." + "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint" + } }, - "id_countries": { + "device_details": { + "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails" + }, + "device_time_series": { "type": "array", "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount" - }, - "description": "Issuing countries of the verified ID documents, most sessions first." + "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint" + } }, - "conversion_by_country": { + "items": { "type": "array", - "description": "Per document issuing country: finished sessions (approved, declined or in review) and how many were approved. Most finished first.", + "description": "Entries of a list widget. `country_distribution` (KYC): `country`, `country_code`, `session_count`. `conversion_by_country`: `country`, `country_code`, `finished`, `approved`. `time_series`: `date`, `value`. `status_time_series`: `date`, `approved`, `declined`, `flagged`. `breakdown`: `transaction_type` or `action_type` with `count` and `volume`, or `tag_id`, `tag_name`, `count`. `leaderboard`: `rule_title`, `trigger_count` or `assignee`, `handled_count`, `average_processing_seconds`, each with `approved_percentage`, `declined_percentage`, `flagged_percentage`. `histogram`: `score`, `count`.", "items": { "type": "object", - "properties": { - "country": { - "type": "string" - }, - "country_code": { - "type": "string" - }, - "finished": { - "type": "integer" - }, - "approved": { - "type": "integer" - } - } + "additionalProperties": {} } }, - "cities": { + "previous_items": { "type": "array", - "description": "Up to 100 IP cities, most sessions first.", + "description": "Transaction time series for the period of the same length right before `start_date`.", "items": { "type": "object", - "properties": { - "location": { - "type": "string", - "description": "`City, Country`." - }, - "session_count": { - "type": "integer" - }, - "latitude": { - "type": "number", - "nullable": true - }, - "longitude": { - "type": "number", - "nullable": true - } - } + "additionalProperties": {} } - } - } - }, - "ApplicationAnalyticsDemographicStats": { - "type": "object", - "properties": { - "age_distribution": { + }, + "value": { + "type": "number", + "description": "`metric` widgets: the figure for the range." + }, + "currency": { + "type": "string", + "nullable": true, + "description": "Transaction volume and amount widgets: the application's default transaction currency." + }, + "thresholds": { "type": "object", - "description": "Sessions per age band from the ID document. Empty when there is no data.", + "description": "`histogram` widget: the application's review and decline score thresholds.", "properties": { - "under_18": { - "type": "integer" - }, - "18_24": { - "type": "integer" - }, - "25_34": { + "review": { "type": "integer" }, - "35_44": { + "decline": { "type": "integer" - }, - "45_64": { + } + } + }, + "search": { + "type": "object", + "description": "`kyb_registry_coverage` widget: registry search totals.", + "properties": { + "searches_total": { "type": "integer" }, - "65_plus": { + "searches_with_no_candidates": { "type": "integer" } - }, - "additionalProperties": { - "type": "integer" } + } + } + }, + "ApplicationAnalyticsWidgetResponse": { + "type": "object", + "description": "Dashboard widgets, returned when `scope` or `widget_keys` is sent.", + "required": [ + "scope", + "available_widget_keys", + "requested_widget_keys", + "widgets" + ], + "properties": { + "scope": { + "type": "string", + "enum": [ + "home", + "kyc", + "kyb", + "transactions" + ], + "description": "Dashboard tab." }, - "gender_distribution": { + "available_widget_keys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Every widget key this scope accepts." + }, + "requested_widget_keys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The widget keys answered, in order: your valid `widget_keys`, or the scope's defaults." + }, + "widgets": { "type": "object", - "description": "Sessions per document gender code: `M`, `F` or `U` (unknown).", + "description": "Keyed by widget key, in the order of `requested_widget_keys`.", "additionalProperties": { - "type": "integer" + "$ref": "#/components/schemas/ApplicationAnalyticsWidget" } } } }, - "ApplicationAnalyticsDeviceDetails": { + "ApplicationAnalyticsToday": { "type": "object", - "description": "Top five of each, most sessions first.", + "description": "Today's verifications by local hour against the same weekday last week.", + "required": [ + "time_zone", + "date", + "current_hour", + "previous_date", + "hours", + "previous_hours", + "total", + "previous_total_so_far", + "outcomes" + ], "properties": { - "device_models": { - "type": "array", - "description": "Device brands: `Apple`, `Android`, `LG`, everything else grouped as `Other`.", - "items": { - "type": "object", - "properties": { - "device": { - "type": "string" - }, - "count": { - "type": "integer" - } - } - } + "time_zone": { + "type": "string", + "description": "The IANA time zone the day and its hours are in.", + "example": "Europe/Madrid" }, - "browsers": { + "date": { + "type": "string", + "format": "date", + "description": "Today in that time zone.", + "example": "2026-10-30" + }, + "current_hour": { + "type": "integer", + "minimum": 0, + "maximum": 23, + "description": "The local hour it is now.", + "example": 14 + }, + "previous_date": { + "type": "string", + "format": "date", + "description": "The comparison day: the same weekday one week before.", + "example": "2026-10-23" + }, + "hours": { "type": "array", - "description": "Browsers: `Chrome`, `Safari`, `Didit App`, `Firefox`, everything else grouped as `Other`.", "items": { - "type": "object", - "properties": { - "browser": { - "type": "string" - }, - "count": { - "type": "integer" - } - } - } + "type": "integer", + "minimum": 0 + }, + "minItems": 24, + "maxItems": 24, + "description": "Verifications created today, per local hour from 00:00. The hours still to come are 0." }, - "operating_systems": { + "previous_hours": { "type": "array", - "description": "Operating systems.", "items": { - "type": "object", - "properties": { - "os": { - "type": "string" - }, - "count": { - "type": "integer" - } + "type": "integer", + "minimum": 0 + }, + "minItems": 24, + "maxItems": 24, + "description": "Verifications created on the comparison day, per local hour from 00:00." + }, + "total": { + "type": "integer", + "minimum": 0, + "description": "Verifications created today so far.", + "example": 165 + }, + "previous_total_so_far": { + "type": "integer", + "minimum": 0, + "description": "Verifications created on the comparison day up to the same local time.", + "example": 151 + }, + "outcomes": { + "type": "object", + "description": "Of today's verifications, how many are approved, waiting in review and declined now. The rest are not finished yet.", + "required": [ + "approved", + "in_review", + "declined" + ], + "properties": { + "approved": { + "type": "integer", + "minimum": 0 + }, + "in_review": { + "type": "integer", + "minimum": 0 + }, + "declined": { + "type": "integer", + "minimum": 0 } } } } }, - "ApplicationAnalyticsWorkflowFunnel": { + "WebhookConfigDestination": { "type": "object", - "description": "Keyed by workflow ID. `total` is the sessions started on that workflow; `steps` counts the sessions that reached each step (`OCR`, `LIVENESS`, `FACE_MATCH`, `AML`, `POA`, `PHONE`, `EMAIL`, `NFC`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`). Reaching a step is not passing it.", - "additionalProperties": { - "type": "object", - "properties": { - "total": { - "type": "integer" - }, - "steps": { - "type": "object", - "additionalProperties": { - "type": "object", - "properties": { - "reached": { - "type": "integer" - } - } - } + "description": "A webhook destination as listed in the webhook configuration, without delivery metrics. `GET /v3/webhook/destinations/{destination_uuid}/` adds its delivery summary.", + "required": [ + "uuid", + "label", + "url", + "enabled", + "webhook_version", + "secret_shared_key", + "subscribed_events", + "created_at", + "updated_at" + ], + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Destination ID." + }, + "label": { + "type": "string", + "maxLength": 255, + "description": "Human-readable name." + }, + "url": { + "type": "string", + "format": "uri", + "maxLength": 2000, + "description": "HTTPS endpoint Didit posts events to." + }, + "enabled": { + "type": "boolean", + "description": "`false` pauses deliveries to this destination." + }, + "webhook_version": { + "type": "string", + "enum": [ + "v1", + "v2", + "v3" + ], + "description": "Payload version sent to this destination." + }, + "secret_shared_key": { + "type": "string", + "description": "This destination's signing secret (43-character URL-safe token). Verify each webhook with the secret of the destination it was sent to. API-key callers always receive it in full; Console users without `read:webhooks` receive an empty string." + }, + "subscribed_events": { + "type": "array", + "uniqueItems": true, + "description": "Event types delivered to this destination. Empty when the destination was created without events, in which case it receives nothing.", + "items": { + "$ref": "#/components/schemas/WebhookEvent" } + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "updated_at": { + "type": "string", + "format": "date-time" } } }, - "ApplicationAnalyticsVerificationTimeStats": { + "WebhookConfig": { "type": "object", - "description": "Active time users spent verifying, ignoring idle gaps. An empty object when there is no data.", + "description": "Application-level webhook configuration, retention policy and Digital ID wallet return hosts, with every webhook destination.", + "required": [ + "webhook_url", + "webhook_version", + "secret_shared_key", + "capture_method", + "data_retention_months", + "face_retention_policy", + "face_retention_days", + "available_events", + "allowed_return_hosts", + "endpoints" + ], "properties": { - "overall_avg_seconds": { - "type": "number", - "description": "Average per session, one decimal." + "webhook_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "Application-level (legacy) webhook URL. Didit sends to it only while the application has no enabled destination, and then only `status.updated` and `data.updated`. Every create, update or delete of a destination sets it to the URL of the oldest enabled destination, or `null` when none is enabled." }, - "overall_count": { + "webhook_version": { + "type": "string", + "enum": [ + "v1", + "v2", + "v3" + ], + "description": "Payload version of the legacy `webhook_url`. Each destination has its own `webhook_version`." + }, + "secret_shared_key": { + "type": "string", + "description": "Application-level signing secret (43-character URL-safe token). It signs only deliveries to the legacy `webhook_url`; each destination signs with its own `secret_shared_key`. API-key callers always receive it in full; Console users without `read:webhooks` receive an empty string." + }, + "capture_method": { + "type": "string", + "enum": [ + "MOBILE", + "MOBILE_AND_DESKTOP" + ], + "description": "Legacy application setting. The verification flow does not read it: capture options are configured per workflow." + }, + "data_retention_months": { "type": "integer", - "description": "Sessions measured." + "nullable": true, + "minimum": 1, + "maximum": 120, + "description": "Automatic deletion window. User verification sessions created more than this many months ago (a month counts as 30 days) are deleted automatically, and that deletion is irreversible. `null` means sessions are never deleted automatically. See [Data retention](https://docs.didit.me/console/data-retention)." }, - "per_feature": { - "type": "object", - "description": "Keyed by feature, for example `OCR` or `LIVENESS`.", - "additionalProperties": { + "face_retention_policy": { + "type": "string", + "enum": [ + "delete_with_session", + "retain_until_user_deleted" + ], + "description": "What happens to a session's face embedding when the session is deleted. `delete_with_session` (default) deletes it with the session. `retain_until_user_deleted` is the opt-in [biometric template retention](https://docs.didit.me/console/data-retention#biometric-template-retention): an image-free biometric template linked to the User is managed separately until its retention period ends, the User is deleted, or you purge it." + }, + "face_retention_days": { + "type": "integer", + "nullable": true, + "minimum": 1, + "maximum": 3650, + "description": "Retention period, in days, of biometric templates under `retain_until_user_deleted`. Required when that policy is set." + }, + "biometric_consent_mode": { + "type": "string", + "enum": [ + "auto", + "always", + "never" + ], + "description": "When the hosted flow and the native SDKs ask the person for explicit biometric consent before a face capture. `auto` (default) asks only where a trigger applies: a declared state, the person's IP, or the identity document's issuer is in Illinois, Texas or Colorado, or the person looks to be in the US without a known state. `always` asks every person whose workflow captures a face. `never` never shows the step, and you collect consent yourself before the selfie. Each change is recorded in the audit log. See [Biometric consent](https://docs.didit.me/getting-started/biometric-consent)." + }, + "available_events": { + "type": "array", + "description": "Every event type a destination can subscribe to, with a display label.", + "items": { "type": "object", + "required": [ + "value", + "label" + ], "properties": { - "avg_seconds": { - "type": "number" - }, - "total_seconds": { - "type": "number" + "value": { + "$ref": "#/components/schemas/WebhookEvent" }, - "count": { - "type": "integer" + "label": { + "type": "string", + "description": "Display label, for example `Session status updated`." } } } }, - "per_sub_step": { - "type": "object", - "description": "Keyed by feature, then by sub-step, for example `front_id_photo`.", - "additionalProperties": { - "type": "object", - "additionalProperties": { - "type": "object", - "properties": { - "avg_seconds": { - "type": "number" - }, - "total_seconds": { - "type": "number" - }, - "count": { - "type": "integer" - } - } - } + "allowed_return_hosts": { + "type": "array", + "maxItems": 20, + "description": "Hostnames (exact match, HTTPS only) a standalone Digital ID wallet verification may send the user back to with its `return_url`. Your white-label domain is always allowed as well. See [Register your return destination](https://docs.didit.me/standalone-apis/digital-id-wallets#register-your-return-destination).", + "items": { + "type": "string", + "maxLength": 253 } + }, + "endpoints": { + "type": "array", + "description": "Every webhook destination of the application, oldest first, each with its signing secret. Read only here: manage destinations with the `/v3/webhook/destinations/` endpoints.", + "items": { + "$ref": "#/components/schemas/WebhookConfigDestination" + } + }, + "allowed_domains": { + "type": "array", + "maxItems": 50, + "items": { + "type": "string", + "maxLength": 300 + }, + "description": "Origins (for example `https://app.example.com`; `http` only for `localhost`) the hosted verification flow may be embedded in and may send the user back to with a session callback. Server-to-server calls are not affected. An empty list means no restriction. Didit stores each origin in lower case without a default port. An invalid entry fails with `400` on `allowed_domains`.", + "example": [ + "https://app.example.com" + ] } } }, - "ApplicationAnalyticsResubmissionStats": { + "WebhookDestinationDelivery": { "type": "object", + "description": "One delivery attempt to a webhook destination. The first send of an event, each automatic retry and each resend are separate deliveries.", + "required": [ + "uuid", + "session_id", + "request_url", + "response_status", + "response_time_ms", + "status", + "webhook_type", + "created_at" + ], "properties": { - "first_pass": { - "type": "integer", - "description": "Finished sessions with no resubmission." + "uuid": { + "type": "string", + "format": "uuid", + "description": "Delivery ID, for the detail and resend calls." }, - "second": { - "type": "integer", - "description": "Finished sessions resubmitted once." + "session_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "User verification session the event is about. `null` for business session, user, business, transaction, Travel Rule and workflow events." }, - "third_plus": { + "request_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "URL the delivery was sent to: the destination's URL when the event was generated." + }, + "response_status": { "type": "integer", - "description": "Finished sessions resubmitted two or more times." + "nullable": true, + "description": "HTTP status your endpoint returned. `null` while the delivery is queued and not yet attempted. When no HTTP answer was received Didit records a status of its own: `504` when your endpoint did not answer within 5 seconds, `503` for a connection failure, `400` when the URL was refused as unsafe (for example a private or internal address), and `404` for any other request error. `400` or above counts as a failed delivery." }, - "abandoned": { + "response_time_ms": { "type": "integer", - "description": "Abandoned sessions." - } - } - }, - "ApplicationAnalyticsOriginalStatusStats": { - "type": "object", - "description": "The workflow's automatic verdict, before any reviewer changed it.", - "properties": { - "approved": { - "type": "integer" + "nullable": true, + "minimum": 0, + "description": "Time the attempt took, in milliseconds. `null` while the delivery is queued." }, - "in_review": { - "type": "integer" + "status": { + "type": "string", + "nullable": true, + "description": "Status the event reported when it was generated: the session status for session events (for example `Approved` or `In Review`), the person's or company's status for user and business events, and the transaction status for transaction events. `null` for events that carry no status." }, - "declined": { - "type": "integer" - } - } - }, - "ApplicationAnalyticsWarningStats": { - "type": "object", - "description": "Keyed by feature (`ID_VERIFICATION`, `LIVENESS`, `FACEMATCH`, `AML`, `PROOF_OF_ADDRESS`, `PHONE`, `EMAIL`, `NFC`, `LOCATION`, `DATABASE_VALIDATION`, `QUESTIONNAIRE` and the KYB features). `total` is the sessions that reached the feature; `risks` counts sessions per warning code and level.", - "additionalProperties": { - "type": "object", - "properties": { - "total": { - "type": "integer" - }, - "risks": { - "type": "object", - "additionalProperties": { - "type": "object", - "properties": { - "error": { - "type": "integer" - }, - "warning": { - "type": "integer" - }, - "information": { - "type": "integer" - } - } - } - } + "webhook_type": { + "$ref": "#/components/schemas/WebhookEvent" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the delivery was created." } } }, - "ApplicationAnalyticsDemographicPoint": { + "WebhookDestinationDeliveryDetail": { "type": "object", + "description": "One delivery attempt to a webhook destination, with the exact request headers and body Didit sent.", + "required": [ + "uuid", + "session_id", + "request_url", + "response_status", + "response_time_ms", + "status", + "webhook_type", + "created_at", + "request_header", + "request_body" + ], "properties": { - "date": { + "uuid": { "type": "string", - "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." + "format": "uuid", + "description": "Delivery ID, for the detail and resend calls." }, - "age_distribution": { - "type": "object", - "additionalProperties": { - "type": "integer" - } + "session_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "User verification session the event is about. `null` for business session, user, business, transaction, Travel Rule and workflow events." }, - "gender_distribution": { - "type": "object", - "additionalProperties": { - "type": "integer" - } + "request_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "URL the delivery was sent to: the destination's URL when the event was generated." + }, + "response_status": { + "type": "integer", + "nullable": true, + "description": "HTTP status your endpoint returned. `null` while the delivery is queued and not yet attempted. When no HTTP answer was received Didit records a status of its own: `504` when your endpoint did not answer within 5 seconds, `503` for a connection failure, `400` when the URL was refused as unsafe (for example a private or internal address), and `404` for any other request error. `400` or above counts as a failed delivery." + }, + "response_time_ms": { + "type": "integer", + "nullable": true, + "minimum": 0, + "description": "Time the attempt took, in milliseconds. `null` while the delivery is queued." + }, + "status": { + "type": "string", + "nullable": true, + "description": "Status the event reported when it was generated: the session status for session events (for example `Approved` or `In Review`), the person's or company's status for user and business events, and the transaction status for transaction events. `null` for events that carry no status." + }, + "webhook_type": { + "$ref": "#/components/schemas/WebhookEvent" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the delivery was created." + }, + "request_header": { + "type": "string", + "description": "JSON text (a string) of the request headers Didit sent: `Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp` and `User-Agent`. Parse it with a JSON parser. It holds signatures, never the signing secret." + }, + "request_body": { + "type": "string", + "description": "JSON text (a string) of the exact payload Didit sent, keys sorted, including `event_id` and `timestamp`. Parse it with a JSON parser; see [Payload shape](https://docs.didit.me/integration/webhooks#payload-shape). For a scoped key without `media: read`, media URLs inside it are `null`; without `sessions: write`, session tokens and hosted verification links are `null`. A body changed that way no longer matches its signatures. Didit does not record the response body your endpoint returned." } } }, - "ApplicationAnalyticsDevicePoint": { + "SessionWebhookDelivery": { "type": "object", + "description": "One webhook delivery attempt recorded for a verification session, with the exact request headers and body Didit sent.", + "required": [ + "uuid", + "session_id", + "request_url", + "response_status", + "status", + "webhook_type", + "request_header", + "request_body", + "created_at" + ], "properties": { - "date": { + "uuid": { "type": "string", - "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." + "format": "uuid", + "description": "Delivery ID. Use it as `{webhook_uuid}` to get or resend this delivery." }, - "devices": { - "type": "object", - "additionalProperties": { - "type": "integer" - } + "session_id": { + "type": "string", + "format": "uuid", + "description": "The session the delivery belongs to (the session in the path)." }, - "browsers": { - "type": "object", - "additionalProperties": { - "type": "integer" - } + "request_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "URL the delivery was sent to." }, - "operating_systems": { - "type": "object", - "additionalProperties": { - "type": "integer" - } + "response_status": { + "type": "integer", + "nullable": true, + "description": "HTTP status your endpoint returned. `null` while the delivery is queued and not yet attempted. When no HTTP answer was received Didit records a status of its own: `504` when your endpoint did not answer within 5 seconds, `503` for a connection failure, `400` when the URL was refused as unsafe (for example a private or internal address), and `404` for any other request error. `400` or above counts as a failed delivery." + }, + "status": { + "type": "string", + "nullable": true, + "description": "Session status when the event was generated, for example `In Progress`, `Approved` or `Declined`." + }, + "webhook_type": { + "$ref": "#/components/schemas/WebhookEvent" + }, + "request_header": { + "type": "string", + "description": "JSON text (a string) of the request headers Didit sent: `Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp` and `User-Agent`. Parse it with a JSON parser. It holds signatures, never the signing secret." + }, + "request_body": { + "type": "string", + "description": "JSON text (a string) of the exact payload Didit sent, keys sorted, including `event_id` and `timestamp`. Parse it with a JSON parser; see [Payload shape](https://docs.didit.me/integration/webhooks#payload-shape). For a scoped key without `media: read`, media URLs inside it are `null`; without `sessions: write`, session tokens and hosted verification links are `null`. A body changed that way no longer matches its signatures. Didit does not record the response body your endpoint returned." + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "When the delivery was created." } } }, - "ApplicationAnalyticsVerificationTimePoint": { + "SessionEvent": { "type": "object", + "description": "One entry of a verification session's event timeline.", + "required": [ + "uuid", + "event_type", + "created_at", + "component", + "feature_step", + "step", + "details", + "ip_address", + "user_agent", + "device_info", + "file_url", + "sent_at" + ], "properties": { - "date": { + "uuid": { "type": "string", - "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." + "format": "uuid", + "description": "Event identifier." }, - "overall_avg": { - "type": "number", - "description": "Average active seconds per session." + "event_type": { + "type": "string", + "enum": [ + "SESSION_CREATED", + "SESSION_COMPLETED", + "SESSION_STATUS_CHANGED", + "LINK_OPENED", + "FORM_SUBMITTED", + "BUTTON_CLICKED", + "FILE_UPLOADED", + "ATTEMPT_FAILED", + "FEATURE_STEP_CHANGED", + "STEP_RENDERED", + "NOTE_ADDED", + "MANUAL_REVIEW_STARTED", + "WORKFLOW_BRANCH_EVALUATED", + "WORKFLOW_STATUS_NODE_REACHED", + "LOG" + ], + "description": "What happened. Reported by the device during the hosted flow or SDK: `LINK_OPENED`, `STEP_RENDERED`, `BUTTON_CLICKED`, `FORM_SUBMITTED`, `FILE_UPLOADED`, `ATTEMPT_FAILED` and `LOG` (debugging). Recorded by the server: `SESSION_CREATED`, `SESSION_STATUS_CHANGED` (`details.old_status`, `details.current_status`), `FEATURE_STEP_CHANGED` (`details.old_feature_step`, `details.current_feature_step`), `WORKFLOW_BRANCH_EVALUATED` and `WORKFLOW_STATUS_NODE_REACHED` (the workflow routing trace). `SESSION_COMPLETED`, `NOTE_ADDED` and `MANUAL_REVIEW_STARTED` can appear on older sessions." }, - "per_feature": { + "created_at": { + "type": "string", + "format": "date-time", + "description": "When Didit stored the event. Events are stored asynchronously, a few seconds after `sent_at`." + }, + "component": { + "type": "string", + "nullable": true, + "description": "UI component that reported the event (device events only)." + }, + "feature_step": { + "type": "string", + "nullable": true, + "enum": [ + "OCR", + "OCR_BACK", + "NFC", + "AML", + "FACE", + "LIVENESS", + "FACE_MATCH", + "IP_ANALYSIS", + "AGE_ESTIMATION", + "PROOF_OF_ADDRESS", + "PHONE_VERIFICATION", + "EMAIL_VERIFICATION", + "FACE_SEARCH", + "DATABASE_VALIDATION", + "QUESTIONNAIRE", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "DOCUMENT_AI", + "GEOLOCATION", + null + ], + "description": "Verification feature the session was on when the event happened." + }, + "step": { + "type": "string", + "nullable": true, + "description": "Screen within the feature, for example `DOCUMENT_CAPTURE_FRONT` or `FACE_PASSIVE_LIVENESS`." + }, + "details": { "type": "object", - "description": "Average active seconds per feature.", - "additionalProperties": { - "type": "number" - } - } - } - }, - "ApplicationAnalyticsResubmissionPoint": { - "type": "object", - "properties": { - "date": { + "nullable": true, + "additionalProperties": true, + "description": "Event-specific data. The keys depend on `event_type`." + }, + "ip_address": { "type": "string", - "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." + "nullable": true, + "description": "IP address the device reported the event from. `null` for server-recorded events." }, - "first_pass": { - "type": "integer" + "user_agent": { + "type": "string", + "nullable": true, + "description": "User agent of the device. `null` for server-recorded events." }, - "second": { - "type": "integer" + "device_info": { + "type": "object", + "nullable": true, + "additionalProperties": true, + "description": "Device details the SDK or browser reported." }, - "third_plus": { - "type": "integer" + "file_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "Short-lived presigned link to a file attached to the event (for example a captured image). `null` when there is none, and always `null` for a scoped API key without `media: read`." }, - "abandoned": { - "type": "integer" + "sent_at": { + "type": "integer", + "format": "int64", + "description": "When the event happened, as a Unix timestamp in milliseconds. Results are ordered by it." } } }, - "ApplicationAnalyticsOriginalStatusPoint": { + "AMLDatasetSourceFreshness": { "type": "object", + "description": "Freshness of one family of AML datasets.", + "required": [ + "last_updated_at", + "oldest_updated_at", + "dataset_count", + "dated_dataset_count" + ], "properties": { - "date": { + "last_updated_at": { "type": "string", - "description": "Period key: `YYYY-MM-DD` for a day, the Monday of a week, or `YYYY-MM` for a month, following `grouping_mode`." + "format": "date-time", + "description": "Most recent update of any dataset in the family." }, - "approved": { - "type": "integer" + "oldest_updated_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Staleness bound: every dataset in the family is at least this current. `null` when at least one dataset in the family reported no update date, because the bound is then unknown." }, - "in_review": { - "type": "integer" + "dataset_count": { + "type": "integer", + "description": "Number of datasets in the family." }, - "declined": { - "type": "integer" + "dated_dataset_count": { + "type": "integer", + "description": "Number of those datasets that reported an update date." } } }, - "ApplicationAnalyticsSummary": { + "AMLDatasetFreshness": { "type": "object", - "description": "User verification (KYC) summary, returned when neither `scope` nor `widget_keys` is sent.", + "description": "How current the AML datasets were when a screening ran. Dates are never estimated.", "required": [ - "data_points", - "request_breakdown", - "previous_data_points", - "previous_request_breakdown", - "conversion_rate", - "location_stats", - "demographic_stats", - "device_details", - "workflow_funnel_stats", - "verification_time_stats", - "resubmission_stats", - "warning_stats", - "original_status_stats", - "grouping_mode", - "demographic_time_series", - "device_time_series", - "verification_time_time_series", - "resubmission_time_series", - "original_status_time_series" + "captured_at", + "provider", + "catalog_version", + "sources" ], "properties": { - "data_points": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" - }, - "description": "One point per day, from the first day with sessions in the range to `end_date`. Always daily, whatever `grouping_mode` says." - }, - "request_breakdown": { - "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" - }, - "previous_data_points": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" - }, - "description": "Daily points for the period of the same length right before `start_date`." + "captured_at": { + "type": "string", + "format": "date-time", + "description": "When Didit read the dataset catalog this freshness comes from." }, - "previous_request_breakdown": { - "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" + "provider": { + "type": "string", + "description": "Opaque identifier of the AML data source. Treat it as an opaque string; do not branch on it.", + "example": "aml_data_source" }, - "conversion_rate": { - "type": "number", + "catalog_version": { + "type": "string", "nullable": true, - "description": "`total_approved / (total_approved + total_declined + total_in_review) x 100`, one decimal. `null` when nothing finished." - }, - "location_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsLocationStats" + "description": "Version identifier of the dataset catalog, when the source reports one." }, - "demographic_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats" + "sources": { + "type": "object", + "description": "Freshness per dataset family. A family whose datasets reported no update date is absent rather than filled with `null`.", + "properties": { + "sanctions": { + "$ref": "#/components/schemas/AMLDatasetSourceFreshness" + }, + "pep": { + "$ref": "#/components/schemas/AMLDatasetSourceFreshness" + }, + "warnings": { + "$ref": "#/components/schemas/AMLDatasetSourceFreshness" + }, + "adverse_media": { + "$ref": "#/components/schemas/AMLDatasetSourceFreshness" + } + } + } + } + }, + "AMLScreeningRun": { + "type": "object", + "description": "One completed ongoing-monitoring re-screen of an AML check.", + "required": [ + "uuid", + "run_id", + "completed_at", + "started_at", + "outcome", + "trigger", + "provider", + "status", + "score", + "total_hits", + "new_hits", + "entities_screened", + "dataset_freshness" + ], + "properties": { + "uuid": { + "type": "string", + "format": "uuid", + "description": "Identifier of this screening run." }, - "device_details": { - "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails" + "run_id": { + "type": "string", + "format": "uuid", + "description": "The monitoring run this screening belongs to. Every verification screened in the same run shares it." }, - "workflow_funnel_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel" + "completed_at": { + "type": "string", + "format": "date-time", + "description": "When this subject's re-screen finished. Results are ordered by it, newest first." }, - "verification_time_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats" + "started_at": { + "type": "string", + "format": "date-time", + "description": "When the monitoring batch this re-screen belongs to started." }, - "resubmission_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats" + "outcome": { + "type": "string", + "enum": [ + "NO_CHANGE", + "CHANGED", + "FAILED" + ], + "description": "`NO_CHANGE`: completed and the result did not move. `CHANGED`: completed and the score, status, hit count or hits changed. `FAILED`: no usable answer for this subject, so the check was left as it was." }, - "warning_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats" + "trigger": { + "type": "string", + "enum": [ + "ONGOING_MONITORING" + ], + "description": "What started the screening. Always `ONGOING_MONITORING` today." }, - "original_status_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats" + "provider": { + "type": "string", + "description": "Opaque identifier of the AML data source that answered. Treat it as an opaque string; do not branch on it.", + "example": "aml_data_source" }, - "grouping_mode": { + "status": { "type": "string", + "nullable": true, "enum": [ - "day", - "week", - "month" + "Not Finished", + "Approved", + "Declined", + "In Review", + "Resub Requested", + null ], - "description": "How the `*_time_series` lists are grouped: `day` for up to 14 days, `week` up to 90, `month` beyond. Measured from the first day with sessions in the range." + "description": "AML check status this run left the check in." }, - "demographic_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint" - } + "score": { + "type": "number", + "format": "float", + "nullable": true, + "minimum": 0, + "maximum": 100, + "description": "AML score this run left the check in." }, - "device_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint" - } + "total_hits": { + "type": "integer", + "nullable": true, + "description": "Number of hits this run left the check in." }, - "verification_time_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint" - } + "new_hits": { + "type": "integer", + "nullable": true, + "description": "Number of hits this run found that the check did not have before it. `0` when nothing new was found; `null` when the run failed or was recorded before this count existed." }, - "resubmission_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint" - } + "entities_screened": { + "type": "integer", + "minimum": 0, + "maximum": 1, + "description": "Number of entities this run screened for the verification: `1` when the subject was screened, `0` when the run failed." }, - "original_status_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint" - } + "dataset_freshness": { + "allOf": [ + { + "$ref": "#/components/schemas/AMLDatasetFreshness" + } + ], + "nullable": true, + "description": "Dataset freshness behind this run, or `null` when no dates were available." } } }, - "ApplicationAnalyticsWidget": { + "KYBKeyPeopleParty": { "type": "object", - "description": "One dashboard widget. Every widget has `kind` and `title`; the other fields depend on `kind`. The session widgets reuse the summary objects (`data_points`, `request_breakdown`, `workflow_funnel_stats` and so on); list widgets put their entries in `items`; transaction metrics use `value`.", + "description": "A Key People party of a Business Verification (KYB) session, with its child verification. The same party appears in `key_people_checks[].submitted.parties[]` of the business session decision.", "required": [ - "kind", - "title" + "uuid", + "entity_type", + "source", + "name", + "is_active", + "is_skipped", + "requires_verification", + "roles", + "kyc_session_deleted", + "kyb_sub_session_deleted" ], "properties": { - "kind": { + "uuid": { "type": "string", - "enum": [ - "sessions_volume", - "workflow_funnel", - "average_verification_time", - "country_distribution", - "warning_insights", - "conversion_rate", - "conversion_by_country", - "resubmission_insights", - "original_status_distribution", - "database_validation_coverage", - "database_validation_latency", - "demographics", - "device_details", - "horizontal_bar", - "kyb_registry_coverage", - "kyb_registry_data_completeness", - "metric", - "time_series", - "breakdown", - "status_time_series", - "leaderboard", - "histogram" - ], - "description": "Widget type." + "format": "uuid", + "description": "Party identifier." }, - "title": { + "entity_type": { "type": "string", - "description": "Display title, for example `Verification volume`." + "enum": [ + "person", + "company" + ], + "description": "Whether the party is an individual or a company." }, - "grouping_mode": { + "source": { "type": "string", "enum": [ - "day", - "week", - "month" + "REGISTRY", + "USER" ], - "description": "How the `*_time_series` lists are grouped: `day` for up to 14 days, `week` up to 90, `month` beyond. Measured from the first day with sessions in the range." + "description": "`REGISTRY`: taken from the company registry. `USER`: entered in the Key People screen." }, - "data_points": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" - } + "name": { + "type": "string", + "description": "Display name of the party." }, - "request_breakdown": { - "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" + "first_name": { + "type": "string", + "nullable": true, + "description": "First name (persons)." }, - "previous_data_points": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint" - } + "last_name": { + "type": "string", + "nullable": true, + "description": "Last name (persons)." }, - "previous_request_breakdown": { - "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown" + "company_name": { + "type": "string", + "nullable": true, + "description": "Company name (company parties)." }, - "conversion_rate": { - "type": "number", - "nullable": true + "registration_number": { + "type": "string", + "nullable": true, + "description": "Company registration number (company parties)." }, - "workflow_funnel_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel" + "email": { + "type": "string", + "format": "email", + "nullable": true, + "description": "Email the verification link is sent to." }, - "verification_time_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats" + "nationality": { + "type": "string", + "nullable": true, + "description": "Nationality for persons, country of incorporation for companies." }, - "verification_time_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint" - } + "phone_number": { + "type": "string", + "nullable": true, + "description": "Phone number collected for the party." }, - "warning_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats" + "date_of_birth": { + "type": "string", + "format": "date", + "nullable": true, + "description": "Date of birth (persons)." }, - "resubmission_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats" + "position": { + "type": "string", + "nullable": true, + "description": "Free-text job title (persons)." }, - "resubmission_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint" - } + "custom_fields": { + "type": "object", + "additionalProperties": true, + "description": "Workflow-defined custom fields collected for the party, keyed by field key." }, - "original_status_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats" + "is_active": { + "type": "boolean", + "description": "Whether the party is active." }, - "original_status_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint" - } + "is_skipped": { + "type": "boolean", + "description": "Whether the party is exempt from verification. Regenerating clears it." }, - "demographic_stats": { - "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats" + "requires_verification": { + "type": "boolean", + "description": "Whether the role and ownership rules require a verification for this party." }, - "demographic_time_series": { + "roles": { "type": "array", + "description": "Roles the party holds in the company.", "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint" + "type": "object", + "required": [ + "role", + "ownership_percent", + "voting_percent" + ], + "properties": { + "role": { + "type": "string", + "enum": [ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other" + ], + "description": "Role code." + }, + "ownership_percent": { + "type": "number", + "nullable": true, + "description": "Ownership percentage for this role, when known." + }, + "voting_percent": { + "type": "number", + "nullable": true, + "description": "Voting-rights percentage for this role, when known." + } + } } }, - "device_details": { - "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails" + "kyc_session_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Child individual KYC session (persons)." }, - "device_time_series": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint" - } + "kyc_session_status": { + "type": "string", + "nullable": true, + "enum": [ + "Not Started", + "In Progress", + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned", + "Kyc Expired", + "Resubmitted", + "Awaiting User", + null + ], + "description": "Status of the child KYC session. A deleted session keeps the status it had when it was deleted." }, - "items": { - "type": "array", - "description": "Entries of a list widget. `country_distribution` (KYC): `country`, `country_code`, `session_count`. `conversion_by_country`: `country`, `country_code`, `finished`, `approved`. `time_series`: `date`, `value`. `status_time_series`: `date`, `approved`, `declined`, `flagged`. `breakdown`: `transaction_type` or `action_type` with `count` and `volume`, or `tag_id`, `tag_name`, `count`. `leaderboard`: `rule_title`, `trigger_count` or `assignee`, `handled_count`, `average_processing_seconds`, each with `approved_percentage`, `declined_percentage`, `flagged_percentage`. `histogram`: `score`, `count`.", - "items": { - "type": "object", - "additionalProperties": {} - } + "kyc_session_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "Hosted link of the child KYC session. `null` when there is none or it was deleted, and for a scoped API key without `sessions: write`." }, - "previous_items": { - "type": "array", - "description": "Transaction time series for the period of the same length right before `start_date`.", - "items": { - "type": "object", - "additionalProperties": {} - } + "kyc_session_deleted": { + "type": "boolean", + "description": "The child KYC session was deleted, so it can never settle." }, - "value": { - "type": "number", - "description": "`metric` widgets: the figure for the range." + "kyb_sub_session_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Child KYB session (company parties)." }, - "currency": { + "kyb_sub_session_status": { "type": "string", "nullable": true, - "description": "Transaction volume and amount widgets: the application's default transaction currency." + "enum": [ + "Not Started", + "In Progress", + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned", + "Kyc Expired", + "Resubmitted", + "Awaiting User", + null + ], + "description": "Status of the child KYB session." }, - "thresholds": { - "type": "object", - "description": "`histogram` widget: the application's review and decline score thresholds.", - "properties": { - "review": { - "type": "integer" - }, - "decline": { - "type": "integer" - } - } + "kyb_sub_session_url": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "Hosted link of the child KYB session, with the same `null` rules as `kyc_session_url`." }, - "search": { - "type": "object", - "description": "`kyb_registry_coverage` widget: registry search totals.", - "properties": { - "searches_total": { - "type": "integer" - }, - "searches_with_no_candidates": { - "type": "integer" + "kyb_sub_session_deleted": { + "type": "boolean", + "description": "Company-party counterpart of `kyc_session_deleted`." + }, + "verification_workflow_type": { + "type": "string", + "nullable": true, + "enum": [ + "kyc", + "kyb", + "adaptive_age_verification", + "biometric_authentication", + "address_verification", + "questionnaire_verification", + "email_verification", + "phone_verification", + null + ], + "description": "Type of the workflow the child session runs." + }, + "verification_workflow_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Workflow the child session runs." + }, + "verification_workflow_label": { + "type": "string", + "nullable": true, + "description": "Label of that workflow." + }, + "verification_workflow_features": { + "type": "array", + "nullable": true, + "description": "Features of the child session's workflow with their current status.", + "items": { + "type": "object", + "required": [ + "feature", + "status" + ], + "properties": { + "feature": { + "type": "string", + "description": "Feature code, for example `ID_VERIFICATION` or `LIVENESS`." + }, + "status": { + "type": "string", + "description": "Feature status, `Not Finished` until it runs." + } } } + }, + "didit_internal_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "Didit's identifier of the verified person, once known." } } }, - "ApplicationAnalyticsWidgetResponse": { + "TravelRuleDelivery": { "type": "object", - "description": "Dashboard widgets, returned when `scope` or `widget_keys` is sent.", + "description": "Where the latest message the transfer owes the other side stands. Didit contacts the counterparty after the request that created or changed the transfer has returned, so this object says whether that message got through: queued, being sent, waiting to be retried after an error, delivered, or failed. A failure the network may still recover from (no answer in time, a failed connection, HTTP `408`, `429` or `5xx`) is tried again after 30 seconds, 2 minutes, 10 minutes, 30 minutes and 1 hour. When a first message (`kind: SEND`) fails for good, because the network refused it or the sixth attempt failed too, the transfer moves to `COUNTERPARTY_VASP_NOT_REACHABLE` with `last_error` in its `timeline`; any other message that fails for good is noted in the `timeline`. The transfer's `status` stays the source of truth for the exchange itself.", "required": [ - "scope", - "available_widget_keys", - "requested_widget_keys", - "widgets" + "kind", + "status", + "rail", + "attempts", + "last_error", + "next_attempt_at", + "delivered_at" ], "properties": { - "scope": { + "kind": { + "type": "string", + "enum": [ + "SEND", + "ANSWER", + "TXID", + "CANCEL", + "POLL" + ], + "description": "What the message carries. `SEND`: the transfer's first message to the counterparty (outbound; the rail is chosen when it is sent). `ANSWER`: your accept or decline, owed to the network that asked (inbound). `TXID`: the on-chain transaction hash, after you finish the transfer. `CANCEL`: the cancellation, after you cancel it. `POLL`: a status query to a network that offers one, repeated every 5 minutes while the transfer waits on the counterparty." + }, + "status": { + "type": "string", + "enum": [ + "QUEUED", + "SENDING", + "RETRYING", + "DELIVERED", + "FAILED" + ], + "description": "`QUEUED`: waiting to be sent. `SENDING`: an attempt is running. `RETRYING`: an attempt failed and the next one runs at `next_attempt_at`. `DELIVERED`: the other side took the message. `FAILED`: the other side refused it, or the last attempt failed." + }, + "rail": { "type": "string", "enum": [ - "home", - "kyc", - "kyb", - "transactions" + "INTERNAL", + "TRP", + "GTR", + "TRUST", + "VERIFYVASP", + "SYGNA", + "EMAIL", + "" ], - "description": "Dashboard tab." + "description": "The rail that carries the message. Empty until Didit has chosen one for a first message." }, - "available_widget_keys": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Every widget key this scope accepts." + "attempts": { + "type": "integer", + "minimum": 0, + "description": "Attempts made so far for this message. A message that is not a status poll is attempted at most 6 times." }, - "requested_widget_keys": { - "type": "array", - "items": { - "type": "string" - }, - "description": "The widget keys answered, in order: your valid `widget_keys`, or the scope's defaults." + "last_error": { + "type": "string", + "description": "The kind of failure the last attempt hit, `\"\"` when none did: for example `email undeliverable`, `trp identity endpoint unreachable` or `trp transfer inquiry delivery failed`. It never carries the counterparty's own answer, which stays on the transfer's `timeline`.\nWhen GTR answers with an error, its own status code and message are included. Response bodies are never included.", + "example": "email undeliverable" }, - "widgets": { - "type": "object", - "description": "Keyed by widget key, in the order of `requested_widget_keys`.", - "additionalProperties": { - "$ref": "#/components/schemas/ApplicationAnalyticsWidget" - } + "next_attempt_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the next attempt runs while the message is `QUEUED` or `RETRYING`." + }, + "delivered_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the other side took the message." } } }, - "WebhookConfigDestination": { + "TravelRuleDiscoveryStep": { "type": "object", - "description": "A webhook destination as listed in the webhook configuration, without delivery metrics. `GET /v3/webhook/destinations/{destination_uuid}/` adds its delivery summary.", - "required": [ - "uuid", - "label", - "url", - "enabled", - "webhook_version", - "secret_shared_key", - "subscribed_events", - "created_at", - "updated_at" - ], + "description": "One step of the counterparty discovery Didit ran for an outbound transfer, in the order it ran them. The first step that names a VASP with a route ends the chain.", "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Destination ID." - }, - "label": { - "type": "string", - "maxLength": 255, - "description": "Human-readable name." - }, - "url": { + "step": { "type": "string", - "format": "uri", - "maxLength": 2000, - "description": "HTTPS endpoint Didit posts events to." - }, - "enabled": { - "type": "boolean", - "description": "`false` pauses deliveries to this destination." + "enum": [ + "internal_address_book", + "wallet_attribution", + "network_lookup", + "customer_hint", + "end_user" + ], + "description": "`internal_address_book`: another Didit customer that proved control of the destination wallet. `wallet_attribution`: the wallet's blockchain analytics attribution. `network_lookup`: a network that can say which VASP holds the address. `customer_hint`: the VASP name, LEI or jurisdiction you sent in `beneficiary_data`. `end_user`: the counterparty the end user (or you) picked, or the request to pick one." }, - "webhook_version": { + "outcome": { "type": "string", "enum": [ - "v1", - "v2", - "v3" + "match", + "miss", + "skipped" ], - "description": "Payload version sent to this destination." + "description": "`match`: the step named a counterparty. `miss`: it ran and found none. `skipped`: it could not run, and `reason` says why." }, - "secret_shared_key": { + "reason": { "type": "string", - "description": "This destination's signing secret (43-character URL-safe token). Verify each webhook with the secret of the destination it was sent to. API-key callers always receive it in full; Console users without `read:webhooks` receive an empty string." + "description": "Machine-readable reason, `\"\"` on a match: `no_proven_internal_wallet`, `attribution_disabled`, `already_attributed`, `no_attributed_entity`, `directory_match_no_route`, `gtr_address_lookup_runs_on_dispatch`, `no_membership`, `network_switched_off`, `no_network_address_lookup`, `no_directory_match`, `awaiting_end_user` or `picked_member_without_proven_wallet`." }, - "subscribed_events": { - "type": "array", - "uniqueItems": true, - "description": "Event types delivered to this destination. Empty when the destination was created without events, in which case it receives nothing.", - "items": { - "$ref": "#/components/schemas/WebhookEvent" - } + "vasp": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "The directory VASP the step named, when it named one." }, - "created_at": { + "rail": { "type": "string", - "format": "date-time" + "nullable": true, + "description": "The rail that reaches that counterparty, when the step found one." }, - "updated_at": { + "at": { "type": "string", "format": "date-time" } } }, - "WebhookConfig": { + "TravelRuleNextAction": { "type": "object", - "description": "Application-level webhook configuration, retention policy and Digital ID wallet return hosts, with every webhook destination.", - "required": [ - "webhook_url", - "webhook_version", - "secret_shared_key", - "capture_method", - "data_retention_months", - "face_retention_policy", - "face_retention_days", - "available_events", - "allowed_return_hosts", - "endpoints" - ], + "description": "One thing that moves a `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE` transfer on. See [Why a transfer is stuck](/transaction-monitoring/travel-rule#why-a-transfer-is-stuck).", "properties": { - "webhook_url": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "Application-level (legacy) webhook URL. Didit sends to it only while the application has no enabled destination, and then only `status.updated` and `data.updated`. Every create, update or delete of a destination sets it to the URL of the oldest enabled destination, or `null` when none is enabled." - }, - "webhook_version": { + "action": { "type": "string", "enum": [ - "v1", - "v2", - "v3" + "select_counterparty_vasp", + "declare_self_hosted", + "add_vasp_hint", + "update_compliance_email", + "resend" ], - "description": "Payload version of the legacy `webhook_url`. Each destination has its own `webhook_version`." + "description": "`select_counterparty_vasp`: the end user picks the destination VASP in the wallet-ownership widget, or you PATCH `action=beneficiary_vasp`. `declare_self_hosted`: the end user declares the wallet self-hosted in the widget. `add_vasp_hint`: tell Didit who the counterparty is, with a VASP name, LEI or travel address (for example a `travel_address` on the destination wallet's address-book entry), then resend. `update_compliance_email` and `resend` are `action` values of `PATCH /v3/transactions/{transaction_id}/travel-rule/`: give the counterparty's compliance email again, and re-run routing." }, - "secret_shared_key": { + "url": { "type": "string", - "description": "Application-level signing secret (43-character URL-safe token). It signs only deliveries to the legacy `webhook_url`; each destination signs with its own `secret_shared_key`. API-key callers always receive it in full; Console users without `read:webhooks` receive an empty string." + "format": "uri", + "description": "The wallet-ownership widget link, on `select_counterparty_vasp` and `declare_self_hosted` while the transfer has an open widget session." + } + }, + "required": [ + "action" + ] + }, + "TransactionTravelRule": { + "type": "object", + "description": "A transaction's Travel Rule transfer, as `GET /v3/transactions/{transaction_id}/`, the `201` of `POST /v3/transactions/` and each row of `GET /v3/transactions/` return it. `direction`, `rail`, `counterparty_vasp`, `delivery`, `discovery`, `reason` and `next_actions` have the same shape as on `PATCH /v3/transactions/{transaction_id}/travel-rule/`, so one read of a transaction says why its transfer is stuck and what moves it on.", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" }, - "capture_method": { + "status": { + "type": "string" + }, + "protocol": { "type": "string", - "enum": [ - "MOBILE", - "MOBILE_AND_DESKTOP" - ], - "description": "Legacy application setting. The verification flow does not read it: capture options are configured per workflow." + "nullable": true }, - "data_retention_months": { - "type": "integer", + "required": { + "type": "boolean" + }, + "obligations_count": { + "type": "integer" + }, + "originator_data": { + "type": "object", + "description": "Originator party. For an inbound transfer the counterparty's values are masked until ownership is confirmed." + }, + "beneficiary_data": { + "type": "object", + "description": "Beneficiary party. For an inbound transfer the counterparty's values are masked until ownership is confirmed." + }, + "name_match": { + "type": "object", "nullable": true, - "minimum": 1, - "maximum": 120, - "description": "Automatic deletion window. User verification sessions created more than this many months ago (a month counts as 30 days) are deleted automatically, and that deletion is irreversible. `null` means sessions are never deleted automatically. See [Data retention](https://docs.didit.me/console/data-retention)." + "description": "The name comparison that decided the transfer (score and strictness). Null until one ran. The compared names are masked together with the parties." }, - "face_retention_policy": { + "data_match": { + "$ref": "#/components/schemas/TravelRuleDataMatch" + }, + "mismatched_fields": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Shortcut for `data_match.mismatched_fields`. Empty when nothing differs." + }, + "data_unmasked": { + "$ref": "#/components/schemas/TravelRuleDataUnmasked" + }, + "data_masked": { + "type": "boolean", + "description": "True while the counterparty's personal data is masked in this response." + }, + "metadata": { + "type": "object" + }, + "direction": { "type": "string", "enum": [ - "delete_with_session", - "retain_until_user_deleted" + "INBOUND", + "OUTBOUND" ], - "description": "What happens to a session's face embedding when the session is deleted. `delete_with_session` (default) deletes it with the session. `retain_until_user_deleted` is the opt-in [biometric template retention](https://docs.didit.me/console/data-retention#biometric-template-retention): an image-free biometric template linked to the User is managed separately until its retention period ends, the User is deleted, or you purge it." + "description": "Which side of the exchange this transfer is." }, - "face_retention_days": { - "type": "integer", + "rail": { + "type": "string", "nullable": true, - "minimum": 1, - "maximum": 3650, - "description": "Retention period, in days, of biometric templates under `retain_until_user_deleted`. Required when that policy is set." + "description": "The rail the transfer went over: `INTERNAL`, `TRP`, `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` or `EMAIL` (`TEST_VASP` on a sandbox application, when the Didit Test VASP answered), or `null` until a rail is chosen." }, - "biometric_consent_mode": { - "type": "string", - "enum": [ - "auto", - "always", - "never" + "counterparty_vasp": { + "type": "object", + "nullable": true, + "properties": { + "name": { + "type": "string" + }, + "lei": { + "type": "string" + }, + "dd_score": { + "type": "integer", + "description": "Due-diligence score from 0 to 100, where higher is better. Same scale as in the VASP directory." + }, + "dd_score_breakdown": { + "type": "object", + "description": "Per-component contributions to dd_score, one object per component as in the VASP directory (jurisdiction, verification, protocol, lei, history, essentials, responsiveness), each {points, max, reason, detail}. {} until the counterparty has been assessed.", + "additionalProperties": { + "type": "object", + "properties": { + "points": { + "type": "number", + "description": "Points awarded for this component." + }, + "max": { + "type": "integer", + "description": "Maximum points this component can award." + }, + "reason": { + "type": "string", + "description": "Machine-readable code of the component's verdict." + }, + "detail": { + "type": "string", + "description": "Human-readable reason for the awarded points." + } + } + } + }, + "dd_assessed_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the due-diligence assessment last ran. Null until the counterparty has been assessed." + } + }, + "description": "The counterparty's directory entry, or `null` when the transfer links none." + }, + "delivery": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/TravelRuleDelivery" + } ], - "description": "When the hosted flow and the native SDKs ask the person for explicit biometric consent before a face capture. `auto` (default) asks only where a trigger applies: a declared state, the person's IP, or the identity document's issuer is in Illinois, Texas or Colorado, or the person looks to be in the US without a known state. `always` asks every person whose workflow captures a face. `never` never shows the step, and you collect consent yourself before the selfie. Each change is recorded in the audit log. See [Biometric consent](https://docs.didit.me/getting-started/biometric-consent)." + "description": "The newest message the transfer owes another party. `null` when it has owed none, for example below `threshold_amount` or for a declared self-hosted wallet." }, - "available_events": { + "discovery": { "type": "array", - "description": "Every event type a destination can subscribe to, with a display label.", + "description": "How Didit looked for the counterparty, one entry per step that ran. Empty when no discovery ran, for example on an inbound transfer.", "items": { - "type": "object", - "required": [ - "value", - "label" - ], - "properties": { - "value": { - "$ref": "#/components/schemas/WebhookEvent" - }, - "label": { - "type": "string", - "description": "Display label, for example `Session status updated`." + "$ref": "#/components/schemas/TravelRuleDiscoveryStep" + } + }, + "reason": { + "type": "string", + "description": "Why a `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE` transfer is stuck; `\"\"` for any other status. A failed delivery decides it first, on `COUNTERPARTY_VASP_NOT_REACHABLE` only: `email_undeliverable` (the mail provider refused the compliance email and no address is left to try: when it was sent, on a reminder, or as a permanent bounce reported later) or `delivery_failed` (the rail that was delivering failed for good: a network rail refused the message or ran out of retries, a `TRP` identity host did not answer, or the counterparty's `TRP` host did not accept the inquiry). Otherwise the `discovery` trace decides it: `awaiting_end_user` (no step named a counterparty Didit can reach), `directory_match_no_route` (a step named a directory VASP that has no route), `picked_member_without_proven_wallet` (the end user picked a Didit customer that has not proven control of the wallet), or `no_directory_match` when the trace gives no other reason. A resend moves the transfer on, so the reason clears. See [Why a transfer is stuck](/transaction-monitoring/travel-rule#why-a-transfer-is-stuck)." + }, + "next_actions": { + "type": "array", + "description": "What moves the transfer on; `[]` for any status but `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE`. `email_undeliverable` offers `update_compliance_email`, then `resend`. `delivery_failed` offers `resend`. A discovery reason offers `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint` and `resend`.", + "items": { + "$ref": "#/components/schemas/TravelRuleNextAction" + } + }, + "chain_details": { + "$ref": "#/components/schemas/TravelRuleChainDetails" + } + } + }, + "NetworkListCounts": { + "type": "object", + "description": "Network counts for the list's views and filter options, each network counted once. Returned only when `summary` is not `false`. `scopes` count every network visible to the application. `views` count the visible networks inside the selected `scope`. `facets` count the networks in the selected `scope` and `status` view (dismissed networks are left out unless `status` includes them). The other list filters do not change these counts.", + "properties": { + "scopes": { + "type": "object", + "description": "Visible networks by product.", + "properties": { + "all": { + "type": "integer" + }, + "identity": { + "type": "integer", + "description": "Every other network." + }, + "transactions": { + "type": "integer", + "description": "Networks whose members are all transaction parties." + } + } + }, + "views": { + "type": "object", + "description": "Visible networks inside the selected `scope`, by status, plus two saved views.", + "properties": { + "all": { + "type": "integer" + }, + "active": { + "type": "integer" + }, + "in_review": { + "type": "integer" + }, + "resolved": { + "type": "integer" + }, + "dismissed": { + "type": "integer" + }, + "mine": { + "type": "integer", + "description": "Networks assigned to the calling console member. Always 0 for an API key." + }, + "high_risk": { + "type": "integer", + "description": "Networks with a risk score of 80 or more that are not dismissed." + } + } + }, + "facets": { + "type": "object", + "description": "Counts for each filter option, inside the selected `scope` and status view.", + "properties": { + "total": { + "type": "integer", + "description": "Networks in the selected `scope` and status view." + }, + "last_activity_days": { + "type": "object", + "description": "Networks with activity in the last 7, 30 and 90 days, keyed by the number of days.", + "properties": { + "7": { + "type": "integer" + }, + "30": { + "type": "integer" + }, + "90": { + "type": "integer" + } + } + }, + "risk_min": { + "type": "object", + "description": "Networks with a risk score of at least 50 and at least 80, keyed by the threshold.", + "properties": { + "50": { + "type": "integer" + }, + "80": { + "type": "integer" + } + } + }, + "signal_types": { + "type": "object", + "description": "Networks with at least one signal of each type.", + "properties": { + "ip_address": { + "type": "integer" + }, + "device": { + "type": "integer" + }, + "face": { + "type": "integer" + }, + "document_number": { + "type": "integer" + }, + "phone": { + "type": "integer" + }, + "email": { + "type": "integer" + }, + "address": { + "type": "integer" + } + } + }, + "priority": { + "type": "object", + "description": "Networks by priority. `none` counts networks without a priority.", + "properties": { + "low": { + "type": "integer" + }, + "medium": { + "type": "integer" + }, + "high": { + "type": "integer" + }, + "none": { + "type": "integer" + } + } + }, + "assignee": { + "type": "object", + "description": "Networks by assignee.", + "properties": { + "me": { + "type": "integer", + "description": "Assigned to the calling console member. Always 0 for an API key." + }, + "unassigned": { + "type": "integer", + "description": "Assigned to nobody." + }, + "users": { + "type": "array", + "description": "One entry per assignee, most networks first.", + "items": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + }, + "full_name": { + "type": "string", + "description": "The assignee's name, or their email when no name is set." + }, + "email": { + "type": "string" + }, + "count": { + "type": "integer" + } + } + } + } + } + }, + "has_case": { + "type": "integer", + "description": "Networks this application opened a case for." + }, + "min_size": { + "type": "object", + "description": "Networks with at least 10 members, keyed by the minimum size.", + "properties": { + "10": { + "type": "integer" + } } } } - }, - "allowed_return_hosts": { - "type": "array", - "maxItems": 20, - "description": "Hostnames (exact match, HTTPS only) a standalone Digital ID wallet verification may send the user back to with its `return_url`. Your white-label domain is always allowed as well. See [Register your return destination](https://docs.didit.me/standalone-apis/digital-id-wallets#register-your-return-destination).", - "items": { - "type": "string", - "maxLength": 253 - } - }, - "endpoints": { - "type": "array", - "description": "Every webhook destination of the application, oldest first, each with its signing secret. Read only here: manage destinations with the `/v3/webhook/destinations/` endpoints.", - "items": { - "$ref": "#/components/schemas/WebhookConfigDestination" - } } } }, - "WebhookDestinationDelivery": { + "NetworkTag": { "type": "object", - "description": "One delivery attempt to a webhook destination. The first send of an event, each automatic retry and each resend are separate deliveries.", - "required": [ - "uuid", - "session_id", - "request_url", - "response_status", - "response_time_ms", - "status", - "webhook_type", - "created_at" - ], + "description": "One of your application's tags on the network.", "properties": { "uuid": { "type": "string", "format": "uuid", - "description": "Delivery ID, for the detail and resend calls." + "description": "The tag's UUID, the same value you pass as `tag_uuid`." }, - "session_id": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "User verification session the event is about. `null` for business session, user, business, transaction, Travel Rule and workflow events." + "name": { + "type": "string" }, - "request_url": { + "color": { "type": "string", - "format": "uri", - "nullable": true, - "description": "URL the delivery was sent to: the destination's URL when the event was generated." - }, - "response_status": { - "type": "integer", - "nullable": true, - "description": "HTTP status your endpoint returned. `null` while the delivery is queued and not yet attempted. When no HTTP answer was received Didit records a status of its own: `504` when your endpoint did not answer within 5 seconds, `503` for a connection failure, `400` when the URL was refused as unsafe (for example a private or internal address), and `404` for any other request error. `400` or above counts as a failed delivery." + "description": "Hex color, for example `#6366F1`." }, - "response_time_ms": { - "type": "integer", - "nullable": true, - "minimum": 0, - "description": "Time the attempt took, in milliseconds. `null` while the delivery is queued." + "source": { + "type": "string", + "enum": [ + "didit", + "custom" + ], + "description": "`didit` for a Didit preset tag, `custom` for a tag your team created." }, - "status": { + "added_by": { "type": "string", "nullable": true, - "description": "Status the event reported when it was generated: the session status for session events (for example `Approved` or `In Review`), the person's or company's status for user and business events, and the transaction status for transaction events. `null` for events that carry no status." - }, - "webhook_type": { - "$ref": "#/components/schemas/WebhookEvent" + "description": "Email of the console member who added the tag. Null when an API key added it." }, - "created_at": { + "added_at": { "type": "string", - "format": "date-time", - "description": "When the delivery was created." + "format": "date-time" } } }, - "WebhookDestinationDeliveryDetail": { + "NetworkOutcomes": { "type": "object", - "description": "One delivery attempt to a webhook destination, with the exact request headers and body Didit sent.", - "required": [ - "uuid", - "session_id", - "request_url", - "response_status", - "response_time_ms", - "status", - "webhook_type", - "created_at", - "request_header", - "request_body" - ], + "description": "Where the network's people and businesses stand. Each member you may see counts once, by the status of their most recent verification that reached a decision. Transaction parties are not counted.", "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Delivery ID, for the detail and resend calls." + "approved": { + "type": "integer", + "description": "Members whose most recent decided verification was approved." }, - "session_id": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "User verification session the event is about. `null` for business session, user, business, transaction, Travel Rule and workflow events." + "declined": { + "type": "integer", + "description": "Members whose most recent decided verification was declined." }, - "request_url": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "URL the delivery was sent to: the destination's URL when the event was generated." + "in_review": { + "type": "integer", + "description": "Members whose most recent decided verification is in review." }, - "response_status": { + "total": { "type": "integer", + "description": "Members with at least one verification, decided or not. A member whose verifications are all undecided (not started, in progress, expired or abandoned) counts here and in no other key." + } + } + }, + "NetworkPatternScore": { + "type": "object", + "description": "How alike one kind of the members' data is across the whole network. A pattern is not a signal: no shared value links the members.", + "properties": { + "type": { + "type": "string", + "enum": [ + "background" + ], + "description": "`background`: the mean similarity of every pair of member selfie backgrounds, with the person masked out. It reads the newest selfie of each person, at most the 50 newest, and leaves out age assurance sessions. It covers the whole network, not only the members of your applications." + }, + "score": { + "type": "number", "nullable": true, - "description": "HTTP status your endpoint returned. `null` while the delivery is queued and not yet attempted. When no HTTP answer was received Didit records a status of its own: `504` when your endpoint did not answer within 5 seconds, `503` for a connection failure, `400` when the URL was refused as unsafe (for example a private or internal address), and `404` for any other request error. `400` or above counts as a failed delivery." + "minimum": 0, + "maximum": 1, + "description": "From 0 to 1, rounded to 4 decimals. Null when `reason` is set." }, - "response_time_ms": { + "members": { "type": "integer", "nullable": true, - "minimum": 0, - "description": "Time the attempt took, in milliseconds. `null` while the delivery is queued." + "description": "How many members' selfies the score compared. A selfie that cannot be read, or shows too little background, is not compared. Null while `computing`; 0 or 1 with `not_enough_selfies`." }, - "status": { + "reason": { "type": "string", + "enum": [ + "computing", + "not_enough_selfies" + ], "nullable": true, - "description": "Status the event reported when it was generated: the session status for session events (for example `Approved` or `In Review`), the person's or company's status for user and business events, and the transaction status for transaction events. `null` for events that carry no status." - }, - "webhook_type": { - "$ref": "#/components/schemas/WebhookEvent" + "description": "Why there is no score. `computing`: the score for the current members is being computed; read the network again later. `not_enough_selfies`: fewer than two members have a usable selfie. Null when there is a score." }, - "created_at": { + "computed_at": { "type": "string", "format": "date-time", - "description": "When the delivery was created." - }, - "request_header": { - "type": "string", - "description": "JSON text (a string) of the request headers Didit sent: `Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp` and `User-Agent`. Parse it with a JSON parser. It holds signatures, never the signing secret." - }, - "request_body": { - "type": "string", - "description": "JSON text (a string) of the exact payload Didit sent, keys sorted, including `event_id` and `timestamp`. Parse it with a JSON parser; see [Payload shape](https://docs.didit.me/integration/webhooks#payload-shape). For a scoped key without `media: read`, media URLs inside it are `null`; without `sessions: write`, session tokens and hosted verification links are `null`. A body changed that way no longer matches its signatures. Didit does not record the response body your endpoint returned." + "nullable": true, + "description": "When the score was computed. Null while `computing`." } } }, - "SessionWebhookDelivery": { + "NetworkDetailResponse": { + "description": "The network detail, plus the organization's sharing mode, whether cross-organization signals apply to it, your application's tags on the network, member outcomes and pattern scores.", + "allOf": [ + { + "$ref": "#/components/schemas/NetworkDetail" + }, + { + "type": "object", + "properties": { + "sharing_mode": { + "type": "string", + "enum": [ + "off", + "private", + "global" + ], + "description": "The organization's cross-organization sharing mode. Only `global` compares networks across organizations; `private` and `off` keep them to the organization's own history.", + "example": "global" + }, + "cross_org_available": { + "type": "boolean", + "description": "Whether cross-organization signals apply to this organization. They need both the Enterprise plan and the `global` sharing mode.", + "example": true + }, + "cross_org_unavailable_reason": { + "type": "string", + "enum": [ + "plan", + "sharing_mode" + ], + "nullable": true, + "description": "Why cross-organization signals do not apply, checked in this order. `plan`: the organization's plan does not include the cross-organization fraud network (it needs the Enterprise plan), whatever the sharing mode. `sharing_mode`: the plan includes it, but the sharing mode is `private` or `off`. Null when `cross_org_available` is `true`.", + "example": null + }, + "tags": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkTag" + }, + "description": "Your application's tags on the network, oldest first. Each application sees only its own tags. `fraud_tags` is separate and unchanged: the tags the network's members carry." + }, + "outcomes": { + "$ref": "#/components/schemas/NetworkOutcomes" + }, + "patterns": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkPatternScore" + }, + "description": "Pattern scores over the whole network. Today one item, `background`." + } + } + } + ] + }, + "NetworkTagRequest": { "type": "object", - "description": "One webhook delivery attempt recorded for a verification session, with the exact request headers and body Didit sent.", "required": [ - "uuid", - "session_id", - "request_url", - "response_status", - "status", - "webhook_type", - "request_header", - "request_body", - "created_at" + "tag_uuid" ], "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Delivery ID. Use it as `{webhook_uuid}` to get or resend this delivery." - }, - "session_id": { + "tag_uuid": { "type": "string", "format": "uuid", - "description": "The session the delivery belongs to (the session in the path)." - }, - "request_url": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "URL the delivery was sent to." - }, - "response_status": { - "type": "integer", - "nullable": true, - "description": "HTTP status your endpoint returned. `null` while the delivery is queued and not yet attempted. When no HTTP answer was received Didit records a status of its own: `504` when your endpoint did not answer within 5 seconds, `503` for a connection failure, `400` when the URL was refused as unsafe (for example a private or internal address), and `404` for any other request error. `400` or above counts as a failed delivery." + "description": "UUID of one of your application's tags." + } + }, + "example": { + "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7" + } + }, + "NetworkTimeline": { + "title": "Default timeline (no contract)", + "type": "object", + "description": "Without `contract`: the network's own events, oldest first, not paginated.", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkTimelineEvent" + } + } + } + }, + "NetworkTimelinePage": { + "title": "Typed timeline page (contract=2)", + "type": "object", + "description": "With `contract=2`: one page of typed events, newest first.", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkTypedTimelineEvent" + } }, - "status": { + "next_cursor": { "type": "string", "nullable": true, - "description": "Session status when the event was generated, for example `In Progress`, `Approved` or `Declined`." - }, - "webhook_type": { - "$ref": "#/components/schemas/WebhookEvent" - }, - "request_header": { - "type": "string", - "description": "JSON text (a string) of the request headers Didit sent: `Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp` and `User-Agent`. Parse it with a JSON parser. It holds signatures, never the signing secret." - }, - "request_body": { - "type": "string", - "description": "JSON text (a string) of the exact payload Didit sent, keys sorted, including `event_id` and `timestamp`. Parse it with a JSON parser; see [Payload shape](https://docs.didit.me/integration/webhooks#payload-shape). For a scoped key without `media: read`, media URLs inside it are `null`; without `sessions: write`, session tokens and hosted verification links are `null`. A body changed that way no longer matches its signatures. Didit does not record the response body your endpoint returned." - }, - "created_at": { - "type": "string", - "format": "date-time", - "description": "When the delivery was created." + "description": "Pass as `cursor` to read the next page. Null on the last page." } } }, - "SessionEvent": { + "NetworkTypedTimelineEvent": { "type": "object", - "description": "One entry of a verification session's event timeline.", - "required": [ - "uuid", - "event_type", - "created_at", - "component", - "feature_step", - "step", - "details", - "ip_address", - "user_agent", - "device_info", - "file_url", - "sent_at" - ], + "description": "One typed timeline event: the four default fields, plus its id, when Didit stored it, the member account and record it belongs to, and the detail block of its event type. The other detail blocks are null.", "properties": { - "uuid": { + "id": { "type": "string", - "format": "uuid", - "description": "Event identifier." + "description": "`:`, unique within the timeline.", + "example": "session:3fa85f64-5717-4562-b3fc-2c963f66afa6" }, "event_type": { "type": "string", "enum": [ - "SESSION_CREATED", - "SESSION_COMPLETED", - "SESSION_STATUS_CHANGED", - "LINK_OPENED", - "FORM_SUBMITTED", - "BUTTON_CLICKED", - "FILE_UPLOADED", - "ATTEMPT_FAILED", - "FEATURE_STEP_CHANGED", - "STEP_RENDERED", - "NOTE_ADDED", - "MANUAL_REVIEW_STARTED", - "WORKFLOW_BRANCH_EVALUATED", - "WORKFLOW_STATUS_NODE_REACHED", - "LOG" - ], - "description": "What happened. Reported by the device during the hosted flow or SDK: `LINK_OPENED`, `STEP_RENDERED`, `BUTTON_CLICKED`, `FORM_SUBMITTED`, `FILE_UPLOADED`, `ATTEMPT_FAILED` and `LOG` (debugging). Recorded by the server: `SESSION_CREATED`, `SESSION_STATUS_CHANGED` (`details.old_status`, `details.current_status`), `FEATURE_STEP_CHANGED` (`details.old_feature_step`, `details.current_feature_step`), `WORKFLOW_BRANCH_EVALUATED` and `WORKFLOW_STATUS_NODE_REACHED` (the workflow routing trace). `SESSION_COMPLETED`, `NOTE_ADDED` and `MANUAL_REVIEW_STARTED` can appear on older sessions." + "network_detected", + "signal_observed", + "network_active", + "network_in_review", + "network_resolved", + "network_dismissed", + "verification_attempt", + "transaction", + "login", + "rule_hit", + "case_linked", + "note_added" + ] }, - "created_at": { + "occurred_at": { "type": "string", "format": "date-time", - "description": "When Didit stored the event. Events are stored asynchronously, a few seconds after `sent_at`." + "description": "When it happened." }, - "component": { + "ingested_at": { "type": "string", - "nullable": true, - "description": "UI component that reported the event (device events only)." + "format": "date-time", + "description": "When Didit stored it." }, - "feature_step": { + "label": { "type": "string", + "description": "A short English label, for example `Verification attempt 2 of 3`." + }, + "metadata": { + "type": "object", + "description": "For the network's own events, the same metadata as the default timeline. Empty otherwise." + }, + "account": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineAccount" + } + ], "nullable": true, - "enum": [ - "OCR", - "OCR_BACK", - "NFC", - "AML", - "FACE", - "LIVENESS", - "FACE_MATCH", - "IP_ANALYSIS", - "AGE_ESTIMATION", - "PROOF_OF_ADDRESS", - "PHONE_VERIFICATION", - "EMAIL_VERIFICATION", - "FACE_SEARCH", - "DATABASE_VALIDATION", - "QUESTIONNAIRE", - "KYB_REGISTRY", - "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE", - "DOCUMENT_AI", - "GEOLOCATION", - null + "description": "The member account. Null for the network's own events, `case_linked` and `note_added`." + }, + "source_ref": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineSourceRef" + } ], - "description": "Verification feature the session was on when the event happened." + "nullable": true, + "description": "The source record. Null for the network's own events and `note_added`." }, - "step": { - "type": "string", + "verification_attempt": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineAttempt" + } + ], "nullable": true, - "description": "Screen within the feature, for example `DOCUMENT_CAPTURE_FRONT` or `FACE_PASSIVE_LIVENESS`." + "description": "Set on `verification_attempt` events." }, - "details": { - "type": "object", + "transaction": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineTransaction" + } + ], "nullable": true, - "additionalProperties": true, - "description": "Event-specific data. The keys depend on `event_type`." + "description": "Set on `transaction` events." }, - "ip_address": { - "type": "string", + "login": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineLogin" + } + ], "nullable": true, - "description": "IP address the device reported the event from. `null` for server-recorded events." + "description": "Set on `login` events." }, - "user_agent": { - "type": "string", + "rule_hit": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineRuleHit" + } + ], "nullable": true, - "description": "User agent of the device. `null` for server-recorded events." + "description": "Set on `rule_hit` events." }, - "device_info": { - "type": "object", + "case_linked": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineCaseLinked" + } + ], "nullable": true, - "additionalProperties": true, - "description": "Device details the SDK or browser reported." + "description": "Set on `case_linked` events." + }, + "note_added": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineNoteAdded" + } + ], + "nullable": true, + "description": "Set on `note_added` events. Never returned to an API key." + } + } + }, + "NetworkTimelineAccount": { + "type": "object", + "description": "The member account the event belongs to.", + "properties": { + "node_id": { + "type": "string", + "description": "`:`, where kind is `vendor_user`, `vendor_business` or `transaction_party`.", + "example": "vendor_user:3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "node_type": { + "type": "string", + "enum": [ + "account", + "business_account", + "transaction_party" + ] + }, + "uuid": { + "type": "string", + "format": "uuid" + }, + "vendor_data": { + "type": "string", + "nullable": true }, - "file_url": { + "display_name": { "type": "string", - "format": "uri", - "nullable": true, - "description": "Short-lived presigned link to a file attached to the event (for example a captured image). `null` when there is none, and always `null` for a scoped API key without `media: read`." + "nullable": true }, - "sent_at": { - "type": "integer", - "format": "int64", - "description": "When the event happened, as a Unix timestamp in milliseconds. Results are ordered by it." + "ownership": { + "type": "string", + "enum": [ + "owned", + "organization" + ], + "description": "`owned` when the record belongs to the application you called (for a console member, to an application they were granted). `organization` when it belongs to another application of your organization." + }, + "route": { + "$ref": "#/components/schemas/NetworkTimelineRoute" } } }, - "AMLDatasetSourceFreshness": { + "NetworkTimelineSourceRef": { "type": "object", - "description": "Freshness of one family of AML datasets.", - "required": [ - "last_updated_at", - "oldest_updated_at", - "dataset_count", - "dated_dataset_count" - ], + "description": "The record the event was read from.", "properties": { - "last_updated_at": { + "kind": { "type": "string", - "format": "date-time", - "description": "Most recent update of any dataset in the family." + "enum": [ + "session", + "business_session", + "transaction", + "monitoring_event", + "case" + ] }, - "oldest_updated_at": { + "id": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "Staleness bound: every dataset in the family is at least this current. `null` when at least one dataset in the family reported no update date, because the bound is then unknown." + "format": "uuid" }, - "dataset_count": { - "type": "integer", - "description": "Number of datasets in the family." + "ownership": { + "type": "string", + "enum": [ + "owned", + "organization" + ], + "description": "`owned` when the record belongs to the application you called (for a console member, to an application they were granted). `organization` when it belongs to another application of your organization." }, - "dated_dataset_count": { - "type": "integer", - "description": "Number of those datasets that reported an update date." + "route": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineRoute" + } + ], + "description": "Absent for `monitoring_event` and `case`." } } }, - "AMLDatasetFreshness": { + "NetworkTimelineRoute": { "type": "object", - "description": "How current the AML datasets were when a screening ran. Dates are never estimated.", - "required": [ - "captured_at", - "provider", - "catalog_version", - "sources" - ], + "description": "Where the record opens: its kind, its UUID and the application it belongs to.", "properties": { - "captured_at": { + "kind": { "type": "string", - "format": "date-time", - "description": "When Didit read the dataset catalog this freshness comes from." + "description": "`user`, `business` or `transaction_party` for an account; `session`, `business_session` or `transaction` for a source record." }, - "provider": { + "id": { "type": "string", - "description": "Opaque identifier of the AML data source. Treat it as an opaque string; do not branch on it.", - "example": "aml_data_source" + "format": "uuid" }, - "catalog_version": { + "application_id": { "type": "string", - "nullable": true, - "description": "Version identifier of the dataset catalog, when the source reports one." - }, - "sources": { - "type": "object", - "description": "Freshness per dataset family. A family whose datasets reported no update date is absent rather than filled with `null`.", - "properties": { - "sanctions": { - "$ref": "#/components/schemas/AMLDatasetSourceFreshness" - }, - "pep": { - "$ref": "#/components/schemas/AMLDatasetSourceFreshness" - }, - "warnings": { - "$ref": "#/components/schemas/AMLDatasetSourceFreshness" - }, - "adverse_media": { - "$ref": "#/components/schemas/AMLDatasetSourceFreshness" - } - } + "format": "uuid" } } }, - "AMLScreeningRun": { + "NetworkTimelineAttempt": { "type": "object", - "description": "One completed ongoing-monitoring re-screen of an AML check.", - "required": [ - "uuid", - "completed_at", - "started_at", - "outcome", - "trigger", - "provider", - "status", - "score", - "total_hits", - "dataset_freshness" - ], + "description": "One verification session of the account.", "properties": { - "uuid": { + "session_id": { "type": "string", "format": "uuid", - "description": "Identifier of this screening run." + "description": "The session UUID, or the business session UUID for a company." }, - "completed_at": { + "session_number": { + "type": "integer", + "nullable": true + }, + "attempt": { + "type": "integer", + "description": "This session's position among the account's sessions, in creation order." + }, + "attempt_count": { + "type": "integer", + "description": "How many sessions the account has." + }, + "status": { "type": "string", - "format": "date-time", - "description": "When this subject's re-screen finished. Results are ordered by it, newest first." + "description": "The session status, for example `Approved` or `Declined`." }, - "started_at": { + "status_changed_at": { "type": "string", "format": "date-time", - "description": "When the monitoring batch this re-screen belongs to started." + "nullable": true }, - "outcome": { + "decline_reasons": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NetworkTimelineDeclineReason" + }, + "description": "For a declined session only: its warnings, oldest first, once per warning. Empty otherwise." + } + } + }, + "NetworkTimelineDeclineReason": { + "type": "object", + "properties": { + "risk": { "type": "string", - "enum": [ - "NO_CHANGE", - "CHANGED", - "FAILED" - ], - "description": "`NO_CHANGE`: completed and the result did not move. `CHANGED`: completed and the score, status, hit count or hits changed. `FAILED`: no usable answer for this subject, so the check was left as it was." + "description": "The warning code." }, - "trigger": { + "feature": { "type": "string", - "enum": [ - "ONGOING_MONITORING" - ], - "description": "What started the screening. Always `ONGOING_MONITORING` today." + "description": "The feature that raised the warning." }, - "provider": { + "short_description": { + "type": "string" + } + } + }, + "NetworkTimelineTransaction": { + "type": "object", + "description": "A transaction a member account took part in, dated by its transaction date.", + "properties": { + "transaction_id": { "type": "string", - "description": "Opaque identifier of the AML data source that answered. Treat it as an opaque string; do not branch on it.", - "example": "aml_data_source" + "format": "uuid" }, - "status": { - "type": "string", - "nullable": true, - "enum": [ - "Not Finished", - "Approved", - "Declined", - "In Review", - "Resub Requested", - null - ], - "description": "AML check status this run left the check in." + "transaction_number": { + "type": "integer", + "nullable": true }, - "score": { - "type": "number", - "format": "float", - "nullable": true, - "minimum": 0, - "maximum": 100, - "description": "AML score this run left the check in." + "transaction_type": { + "type": "string" }, - "total_hits": { - "type": "integer", - "nullable": true, - "description": "Number of hits this run left the check in." + "action_type": { + "type": "string" }, - "dataset_freshness": { + "amount": { "allOf": [ { - "$ref": "#/components/schemas/AMLDatasetFreshness" + "$ref": "#/components/schemas/NetworkTimelineAmount" } ], "nullable": true, - "description": "Dataset freshness behind this run, or `null` when no dates were available." + "description": "Null when the transaction has no amount." + }, + "status": { + "type": "string" + }, + "decision_reason_code": { + "type": "string", + "nullable": true + }, + "decision_reason_label": { + "type": "string", + "nullable": true + }, + "party_role": { + "type": "string", + "description": "The account's role in the transaction: `APPLICANT`, `REMITTER`, `BENEFICIARY` or `COUNTERPARTY`." } } }, - "KYBKeyPeopleParty": { + "NetworkTimelineAmount": { "type": "object", - "description": "A Key People party of a Business Verification (KYB) session, with its child verification. The same party appears in `key_people_checks[].submitted.parties[]` of the business session decision.", - "required": [ - "uuid", - "entity_type", - "source", - "name", - "is_active", - "is_skipped", - "requires_verification", - "roles", - "kyc_session_deleted", - "kyb_sub_session_deleted" - ], "properties": { - "uuid": { + "value": { "type": "string", - "format": "uuid", - "description": "Party identifier." + "description": "Decimal amount as a string." }, - "entity_type": { - "type": "string", - "enum": [ - "person", - "company" - ], - "description": "Whether the party is an individual or a company." + "currency": { + "type": "string" }, - "source": { + "direction": { "type": "string", - "enum": [ - "REGISTRY", - "USER" - ], - "description": "`REGISTRY`: taken from the company registry. `USER`: entered in the Key People screen." - }, - "name": { + "nullable": true + } + } + }, + "NetworkTimelineLogin": { + "type": "object", + "description": "A sign-in event you posted for a person through the events API.", + "properties": { + "action": { "type": "string", - "description": "Display name of the party." + "description": "`.`: `auth.login` or `security.login_succeeded` for a sign-in, `auth.login_failed` or `security.login_failed` for a failed one." }, - "first_name": { + "succeeded": { + "type": "boolean" + }, + "status": { "type": "string", + "description": "The event's status." + }, + "ip": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineIP" + } + ], "nullable": true, - "description": "First name (persons)." + "description": "Null when the event has no IP address." }, - "last_name": { - "type": "string", + "device": { + "allOf": [ + { + "$ref": "#/components/schemas/NetworkTimelineDevice" + } + ], "nullable": true, - "description": "Last name (persons)." + "description": "Null when the event has no device fingerprint or context." }, - "company_name": { + "is_first_login": { + "type": "boolean", + "description": "The account's first successful sign-in on record." + }, + "is_new_device": { + "type": "boolean", + "description": "A successful sign-in from a device none of the account's earlier successful sign-ins came from. Never true on the first sign-in." + } + } + }, + "NetworkTimelineIP": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "country_code": { "type": "string", - "nullable": true, - "description": "Company name (company parties)." + "nullable": true }, - "registration_number": { + "city": { "type": "string", - "nullable": true, - "description": "Company registration number (company parties)." + "nullable": true }, - "email": { + "connection_type": { "type": "string", - "format": "email", "nullable": true, - "description": "Email the verification link is sent to." + "description": "The connection type label for the address, as free text." }, - "nationality": { + "is_vpn_or_tor": { + "type": "boolean" + }, + "is_data_center": { + "type": "boolean" + } + } + }, + "NetworkTimelineDevice": { + "type": "object", + "properties": { + "fingerprint": { "type": "string", - "nullable": true, - "description": "Nationality for persons, country of incorporation for companies." + "nullable": true }, - "phone_number": { + "label": { "type": "string", "nullable": true, - "description": "Phone number collected for the party." + "description": "A readable device label built from the event's device context." + } + } + }, + "NetworkTimelineRuleHit": { + "type": "object", + "description": "A live rule that matched a member's transaction or event. Test-mode matches are not included.", + "properties": { + "rule_id": { + "type": "string", + "format": "uuid" }, - "date_of_birth": { + "rule_title": { + "type": "string" + }, + "rule_category": { + "type": "string" + }, + "rule_source": { + "type": "string" + }, + "severity": { "type": "string", - "format": "date", - "nullable": true, - "description": "Date of birth (persons)." + "nullable": true }, - "position": { + "score_delta": { + "type": "integer" + }, + "status_target": { "type": "string", - "nullable": true, - "description": "Free-text job title (persons)." + "nullable": true }, - "custom_fields": { - "type": "object", - "additionalProperties": true, - "description": "Workflow-defined custom fields collected for the party, keyed by field key." + "action_summary": { + "type": "string", + "nullable": true + } + } + }, + "NetworkTimelineCaseLinked": { + "type": "object", + "description": "A case opened for the network in your organization. `source_ref.ownership` says whether it belongs to the application you called.", + "properties": { + "case_id": { + "type": "string", + "format": "uuid" }, - "is_active": { - "type": "boolean", - "description": "Whether the party is active." + "case_number": { + "type": "string", + "nullable": true }, - "is_skipped": { - "type": "boolean", - "description": "Whether the party is exempt from verification. Regenerating clears it." + "status": { + "type": "string" }, - "requires_verification": { - "type": "boolean", - "description": "Whether the role and ownership rules require a verification for this party." + "author_email": { + "type": "string", + "nullable": true }, - "roles": { - "type": "array", - "description": "Roles the party holds in the company.", - "items": { - "type": "object", - "required": [ - "role", - "ownership_percent", - "voting_percent" - ], - "properties": { - "role": { - "type": "string", - "enum": [ - "director", - "non_executive_director", - "secretary", - "chairman", - "ubo", - "shareholder", - "representative", - "founder", - "legal_advisor", - "authorized_signatory", - "trustee", - "beneficiary", - "settlor", - "protector", - "company_officer", - "investor", - "other" - ], - "description": "Role code." - }, - "ownership_percent": { - "type": "number", - "nullable": true, - "description": "Ownership percentage for this role, when known." - }, - "voting_percent": { - "type": "number", - "nullable": true, - "description": "Voting-rights percentage for this role, when known." - } - } - } + "author_name": { + "type": "string", + "nullable": true + } + } + }, + "NetworkTimelineNoteAdded": { + "type": "object", + "description": "A note left on the network. The note text is not included.", + "properties": { + "note_id": { + "type": "string", + "format": "uuid" }, - "kyc_session_id": { + "author_email": { + "type": "string" + } + } + }, + "FeatureStatusOverride": { + "type": "object", + "description": "One override of a check (feature) status made with `PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`: what it changes, whether it applied or still waits for the person to finish the flow, who asked and why.", + "required": [ + "id", + "node_id", + "feature_type", + "feature_model", + "previous_status", + "new_status", + "state", + "forced", + "reason", + "requested_by", + "requested_at", + "applied_at", + "cancelled_at", + "cancel_reason" + ], + "properties": { + "id": { "type": "string", "format": "uuid", - "nullable": true, - "description": "Child individual KYC session (persons)." + "description": "Identifier of the override. Pass it to the cancel endpoint.", + "example": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }, - "kyc_session_status": { + "node_id": { "type": "string", - "nullable": true, - "enum": [ - "Not Started", - "In Progress", - "Approved", - "Declined", - "In Review", - "Expired", - "Abandoned", - "Kyc Expired", - "Resubmitted", - "Awaiting User", - null - ], - "description": "Status of the child KYC session. A deleted session keeps the status it had when it was deleted." + "description": "The workflow node the request named (`default` for a step without a node).", + "example": "feature_ocr_1" }, - "kyc_session_url": { + "feature_type": { "type": "string", - "format": "uri", - "nullable": true, - "description": "Hosted link of the child KYC session. `null` when there is none or it was deleted, and for a scoped API key without `sessions: write`." - }, - "kyc_session_deleted": { - "type": "boolean", - "description": "The child KYC session was deleted, so it can never settle." + "description": "The `feature_type` the request passed, or an empty string when it passed none.", + "example": "" }, - "kyb_sub_session_id": { + "feature_model": { "type": "string", - "format": "uuid", - "nullable": true, - "description": "Child KYB session (company parties)." + "description": "The kind of check that was overridden, for example `KYC`, `Face`, `AML` or `GeolocationCheck`.", + "example": "KYC" }, - "kyb_sub_session_status": { + "previous_status": { "type": "string", - "nullable": true, "enum": [ - "Not Started", - "In Progress", + "Not Finished", "Approved", "Declined", "In Review", - "Expired", - "Abandoned", - "Kyc Expired", - "Resubmitted", - "Awaiting User", - null + "Resub Requested" ], - "description": "Status of the child KYB session." + "description": "The check's status when the override was requested.", + "example": "In Review" }, - "kyb_sub_session_url": { + "new_status": { "type": "string", - "format": "uri", - "nullable": true, - "description": "Hosted link of the child KYB session, with the same `null` rules as `kyc_session_url`." - }, - "kyb_sub_session_deleted": { - "type": "boolean", - "description": "Company-party counterpart of `kyc_session_deleted`." + "enum": [ + "Approved", + "Declined", + "In Review" + ], + "description": "The status the override sets.", + "example": "Approved" }, - "verification_workflow_type": { + "state": { "type": "string", - "nullable": true, "enum": [ - "kyc", - "kyb", - "adaptive_age_verification", - "biometric_authentication", - "address_verification", - "questionnaire_verification", - "email_verification", - "phone_verification", - null + "applied", + "pending_until_flow_finishes", + "cancelled" ], - "description": "Type of the workflow the child session runs." + "description": "`applied`: the check has the new status. `pending_until_flow_finishes`: the override waits and applies when the person finishes the flow. `cancelled`: it waited and never applied (see `cancel_reason`).", + "example": "applied" }, - "verification_workflow_id": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "Workflow the child session runs." + "forced": { + "type": "boolean", + "description": "`true` when the override applied at once while the person was still in the flow.", + "example": false }, - "verification_workflow_label": { + "reason": { "type": "string", "nullable": true, - "description": "Label of that workflow." + "description": "The `comment` sent with the request, or `null`.", + "example": "Document manually verified by compliance." }, - "verification_workflow_features": { - "type": "array", + "requested_by": { + "type": "object", "nullable": true, - "description": "Features of the child session's workflow with their current status.", - "items": { - "type": "object", - "required": [ - "feature", - "status" - ], - "properties": { - "feature": { - "type": "string", - "description": "Feature code, for example `ID_VERIFICATION` or `LIVENESS`." - }, - "status": { - "type": "string", - "description": "Feature status, `Not Finished` until it runs." - } + "description": "Who requested the override, or `null` when that is not known.", + "properties": { + "email": { + "type": "string", + "format": "email", + "nullable": true, + "description": "Email of the console user, or `null` for API keys and the system.", + "example": "reviewer@example.com" + }, + "name": { + "type": "string", + "nullable": true, + "description": "Display name of the requester, or `null`.", + "example": "Alex Reviewer" + }, + "type": { + "type": "string", + "enum": [ + "CONSOLE_USER", + "API_KEY", + "SYSTEM" + ], + "description": "Who made the request: a console user, an API key, or Didit itself.", + "example": "CONSOLE_USER" } } }, - "didit_internal_id": { + "requested_at": { "type": "string", - "format": "uuid", + "format": "date-time", + "description": "When the override was requested.", + "example": "2026-10-13T09:15:00Z" + }, + "applied_at": { + "type": "string", + "format": "date-time", "nullable": true, - "description": "Didit's identifier of the verified person, once known." + "description": "When the check took the new status, or `null` while it waits or once it is cancelled.", + "example": "2026-10-13T09:15:00Z" + }, + "cancelled_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When a waiting override was cancelled, or `null`.", + "example": null + }, + "cancel_reason": { + "type": "string", + "nullable": true, + "enum": [ + "cancelled_by_reviewer", + "replaced", + "check_changed", + "session_closed", + null + ], + "description": "Why a waiting override never applied, or `null`. `cancelled_by_reviewer`: cancelled with the cancel endpoint. `replaced`: a newer override on the same check replaced it. `check_changed`: the person redid the check before finishing the flow. `session_closed`: the session left the flow before the person finished it (abandoned, expired, or decided mid-flow).", + "example": null } } }, - "TravelRuleDelivery": { + "SandboxSimulateRequest": { "type": "object", - "description": "Where the latest message the transfer owes the other side stands. Didit contacts the counterparty after the request that created or changed the transfer has returned, so this object says whether that message got through: queued, being sent, waiting to be retried after an error, delivered, or failed. A failure the network may still recover from (no answer in time, a failed connection, HTTP `408`, `429` or `5xx`) is tried again after 30 seconds, 2 minutes, 10 minutes, 30 minutes and 1 hour. When a first message (`kind: SEND`) fails for good, because the network refused it or the sixth attempt failed too, the transfer moves to `COUNTERPARTY_VASP_NOT_REACHABLE` with `last_error` in its `timeline`; any other message that fails for good is noted in the `timeline`. The transfer's `status` stays the source of truth for the exchange itself.", - "required": [ - "kind", - "status", - "rail", - "attempts", - "last_error", - "next_attempt_at", - "delivered_at" - ], + "description": "Force a sandbox session's status. Every field is optional, but at least one of `new_status`, `scenario` or `risk` is required.", "properties": { - "kind": { + "new_status": { "type": "string", "enum": [ - "SEND", - "ANSWER", - "TXID", - "CANCEL", - "POLL" + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned" ], - "description": "What the message carries. `SEND`: the transfer's first message to the counterparty (outbound; the rail is chosen when it is sent). `ANSWER`: your accept or decline, owed to the network that asked (inbound). `TXID`: the on-chain transaction hash, after you finish the transfer. `CANCEL`: the cancellation, after you cancel it. `POLL`: a status query to a network that offers one, repeated every 5 minutes while the transfer waits on the counterparty." + "description": "The status to set. When you leave it out, it defaults to the default status of the risk case (`risk`, or the first risk the scenario's magic values carry), else to the scenario's default status.", + "example": "Declined" }, - "status": { + "comment": { "type": "string", - "enum": [ - "QUEUED", - "SENDING", - "RETRYING", - "DELIVERED", - "FAILED" - ], - "description": "`QUEUED`: waiting to be sent. `SENDING`: an attempt is running. `RETRYING`: an attempt failed and the next one runs at `next_attempt_at`. `DELIVERED`: the other side took the message. `FAILED`: the other side refused it, or the last attempt failed." + "maxLength": 500, + "description": "Note added to the activity entry the status change records.", + "example": "Testing the decline path" }, - "rail": { + "scenario": { "type": "string", - "enum": [ - "INTERNAL", - "TRP", - "GTR", - "TRUST", - "VERIFYVASP", - "SYGNA", - "EMAIL", - "" - ], - "description": "The rail that carries the message. Empty until Didit has chosen one for a first message." - }, - "attempts": { - "type": "integer", - "minimum": 0, - "description": "Attempts made so far for this message. A message that is not a status poll is attempted at most 6 times." + "maxLength": 100, + "description": "A scenario slug from the catalog (`GET /v1/sandbox/scenarios/`). It supplies the default status and, without `risk`, the warning its magic values carry. An unknown slug returns `400`.", + "example": "decline_aml_hit" }, - "last_error": { + "risk": { "type": "string", - "description": "The kind of failure the last attempt hit, `\"\"` when none did: for example `email undeliverable`, `trp identity endpoint unreachable` or `trp transfer inquiry delivery failed`. It never carries the counterparty's own answer, which stays on the transfer's `timeline`.\nWhen GTR answers with an error, its own status code and message are included. Response bodies are never included.", - "example": "email undeliverable" + "maxLength": 128, + "description": "A risk case from the catalog. Its warning is added to the session, with a log type that follows `new_status`. An unknown value returns `400`.", + "example": "POSSIBLE_MATCH_FOUND" }, - "next_attempt_at": { + "node_id": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the next attempt runs while the message is `QUEUED` or `RETRYING`." + "maxLength": 128, + "description": "Workflow node the risk warning is attached to. Defaults to the session's current node.", + "example": "feature_aml_1" }, - "delivered_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the other side took the message." + "send_webhooks": { + "type": "boolean", + "default": true, + "description": "`true` sends exactly the webhooks a real status change sends to the sandbox application's destinations: `status.updated`, plus the `user.status.updated` / `user.data.updated` (or `business.status.updated` / `business.data.updated`) events the change causes, for destinations subscribed to them. `false` changes the status without logging or sending any webhook: the missed-webhook recovery never re-sends that decision, the console still updates live, and the next status change of the session sends webhooks as usual.", + "example": true } } }, - "TravelRuleDiscoveryStep": { + "SandboxSimulateResponse": { "type": "object", - "description": "One step of the counterparty discovery Didit ran for an outbound transfer, in the order it ran them. The first step that names a VASP with a route ends the chain.", + "required": [ + "session_id", + "previous_status", + "status", + "scenario", + "risk", + "send_webhooks" + ], "properties": { - "step": { + "session_id": { "type": "string", - "enum": [ - "internal_address_book", - "wallet_attribution", - "network_lookup", - "customer_hint", - "end_user" - ], - "description": "`internal_address_book`: another Didit customer that proved control of the destination wallet. `wallet_attribution`: the wallet's blockchain analytics attribution. `network_lookup`: a network that can say which VASP holds the address. `customer_hint`: the VASP name, LEI or jurisdiction you sent in `beneficiary_data`. `end_user`: the counterparty the end user (or you) picked, or the request to pick one." + "format": "uuid", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" }, - "outcome": { + "previous_status": { "type": "string", "enum": [ - "match", - "miss", - "skipped" + "Not Started", + "In Progress", + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned", + "Kyc Expired", + "Resubmitted", + "Awaiting User" ], - "description": "`match`: the step named a counterparty. `miss`: it ran and found none. `skipped`: it could not run, and `reason` says why." + "description": "The session's status before the simulation.", + "example": "In Progress" }, - "reason": { + "status": { "type": "string", - "description": "Machine-readable reason, `\"\"` on a match: `no_proven_internal_wallet`, `attribution_disabled`, `already_attributed`, `no_attributed_entity`, `directory_match_no_route`, `gtr_address_lookup_runs_on_dispatch`, `no_membership`, `network_switched_off`, `no_network_address_lookup`, `no_directory_match`, `awaiting_end_user` or `picked_member_without_proven_wallet`." + "enum": [ + "Approved", + "Declined", + "In Review", + "Expired", + "Abandoned" + ], + "description": "The status the simulation set.", + "example": "Declined" }, - "vasp": { + "scenario": { "type": "string", - "format": "uuid", "nullable": true, - "description": "The directory VASP the step named, when it named one." + "description": "The scenario slug you passed, or `null`.", + "example": "decline_aml_hit" }, - "rail": { + "risk": { "type": "string", "nullable": true, - "description": "The rail that reaches that counterparty, when the step found one." + "description": "The risk case applied (`risk`, or the one taken from the scenario), or `null` when none.", + "example": "POSSIBLE_MATCH_FOUND" }, - "at": { - "type": "string", - "format": "date-time" + "send_webhooks": { + "type": "boolean", + "description": "The `send_webhooks` value the simulation applied.", + "example": false } } }, - "TravelRuleNextAction": { + "CaseTeamSummary": { "type": "object", - "description": "One thing that moves a `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE` transfer on. See [Why a transfer is stuck](/transaction-monitoring/travel-rule#why-a-transfer-is-stuck).", + "nullable": true, + "description": "The review team that owns the case, or null when no team owns it. Routing sets it when a routing rule places the case with one of its teams. Change or clear it with `PATCH .../cases/{case_uuid}/` (`team`).", "properties": { - "action": { + "uuid": { "type": "string", - "enum": [ - "select_counterparty_vasp", - "declare_self_hosted", - "add_vasp_hint", - "update_compliance_email", - "resend" - ], - "description": "`select_counterparty_vasp`: the end user picks the destination VASP in the wallet-ownership widget, or you PATCH `action=beneficiary_vasp`. `declare_self_hosted`: the end user declares the wallet self-hosted in the widget. `add_vasp_hint`: tell Didit who the counterparty is, with a VASP name, LEI or travel address (for example a `travel_address` on the destination wallet's address-book entry), then resend. `update_compliance_email` and `resend` are `action` values of `PATCH /v3/transactions/{transaction_id}/travel-rule/`: give the counterparty's compliance email again, and re-run routing." + "format": "uuid" }, - "url": { - "type": "string", - "format": "uri", - "description": "The wallet-ownership widget link, on `select_counterparty_vasp` and `declare_self_hosted` while the transfer has an open widget session." + "name": { + "type": "string" } - }, - "required": [ - "action" - ] + } }, - "TransactionTravelRule": { + "CaseChecker": { "type": "object", - "description": "A transaction's Travel Rule transfer, as `GET /v3/transactions/{transaction_id}/`, the `201` of `POST /v3/transactions/` and each row of `GET /v3/transactions/` return it. `direction`, `rail`, `counterparty_vasp`, `delivery`, `discovery`, `reason` and `next_actions` have the same shape as on `PATCH /v3/transactions/{transaction_id}/travel-rule/`, so one read of a transaction says why its transfer is stuck and what moves it on.", + "nullable": true, + "description": "The member named to approve or reject the pending resolution. Set only while a four-eyes resolution waits on a named checker. Null when nothing is pending, while the pending resolution waits on the checker queue, and once the resolution is approved, rejected, or returned for a new review because the evidence changed.", "properties": { - "uuid": { + "member_uuid": { "type": "string", - "format": "uuid" - }, - "status": { - "type": "string" + "format": "uuid", + "description": "The member's user uuid: the value you pass as `checker` when you resolve the case." }, - "protocol": { + "name": { "type": "string", - "nullable": true - }, - "required": { - "type": "boolean" - }, - "obligations_count": { - "type": "integer" - }, - "originator_data": { - "type": "object", - "description": "Originator party. For an inbound transfer the counterparty's values are masked until ownership is confirmed." - }, - "beneficiary_data": { - "type": "object", - "description": "Beneficiary party. For an inbound transfer the counterparty's values are masked until ownership is confirmed." - }, - "name_match": { - "type": "object", "nullable": true, - "description": "The name comparison that decided the transfer (score and strictness). Null until one ran. The compared names are masked together with the parties." - }, - "data_match": { - "$ref": "#/components/schemas/TravelRuleDataMatch" - }, - "mismatched_fields": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Shortcut for `data_match.mismatched_fields`. Empty when nothing differs." - }, - "data_unmasked": { - "$ref": "#/components/schemas/TravelRuleDataUnmasked" - }, - "data_masked": { - "type": "boolean", - "description": "True while the counterparty's personal data is masked in this response." - }, - "metadata": { - "type": "object" - }, - "direction": { - "type": "string", - "enum": [ - "INBOUND", - "OUTBOUND" - ], - "description": "Which side of the exchange this transfer is." + "description": "The member's full name, or null when it is not known." }, - "rail": { + "email": { "type": "string", - "nullable": true, - "description": "The rail the transfer went over: `INTERNAL`, `TRP`, `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA` or `EMAIL` (`TEST_VASP` on a sandbox application, when the Didit Test VASP answered), or `null` until a rail is chosen." - }, - "counterparty_vasp": { - "type": "object", - "nullable": true, - "properties": { - "name": { - "type": "string" - }, - "lei": { - "type": "string" - }, - "dd_score": { - "type": "integer", - "description": "Due-diligence score from 0 to 100, where higher is better. Same scale as in the VASP directory." - }, - "dd_score_breakdown": { - "type": "object", - "description": "Per-component contributions to dd_score, one object per component as in the VASP directory (jurisdiction, verification, protocol, lei, history, essentials, responsiveness), each {points, max, reason, detail}. {} until the counterparty has been assessed.", - "additionalProperties": { - "type": "object", - "properties": { - "points": { - "type": "number", - "description": "Points awarded for this component." - }, - "max": { - "type": "integer", - "description": "Maximum points this component can award." - }, - "reason": { - "type": "string", - "description": "Machine-readable code of the component's verdict." - }, - "detail": { - "type": "string", - "description": "Human-readable reason for the awarded points." - } - } - } - }, - "dd_assessed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the due-diligence assessment last ran. Null until the counterparty has been assessed." - } - }, - "description": "The counterparty's directory entry, or `null` when the transfer links none." - }, - "delivery": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/TravelRuleDelivery" - } + "format": "email" + } + } + }, + "ServiceStatusFeed": { + "type": "object", + "description": "Public service status: the state of each Didit service, the overall state, and the incidents that are ongoing or were resolved in the last 7 days.", + "required": [ + "status", + "updated_at", + "services", + "incidents" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "operational", + "degraded", + "down" ], - "description": "The newest message the transfer owes another party. `null` when it has owed none, for example below `threshold_amount` or for a declared self-hosted wallet." + "description": "The worst state of any service right now, decided by the ongoing incidents only.", + "example": "degraded" }, - "discovery": { + "updated_at": { + "type": "string", + "format": "date-time", + "description": "When Didit built this response (ISO 8601, UTC). Responses are cached for 30 seconds, so it can be up to 30 seconds old.", + "example": "2026-10-13T09:41:07.512345Z" + }, + "services": { "type": "array", - "description": "How Didit looked for the counterparty, one entry per step that ran. Empty when no discovery ran, for example on an inbound transfer.", + "description": "One entry per service, every service always listed.", "items": { - "$ref": "#/components/schemas/TravelRuleDiscoveryStep" + "$ref": "#/components/schemas/ServiceStatusService" } }, - "reason": { - "type": "string", - "description": "Why a `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE` transfer is stuck; `\"\"` for any other status. A failed delivery decides it first, on `COUNTERPARTY_VASP_NOT_REACHABLE` only: `email_undeliverable` (the mail provider refused the compliance email and no address is left to try: when it was sent, on a reminder, or as a permanent bounce reported later) or `delivery_failed` (the rail that was delivering failed for good: a network rail refused the message or ran out of retries, a `TRP` identity host did not answer, or the counterparty's `TRP` host did not accept the inquiry). Otherwise the `discovery` trace decides it: `awaiting_end_user` (no step named a counterparty Didit can reach), `directory_match_no_route` (a step named a directory VASP that has no route), `picked_member_without_proven_wallet` (the end user picked a Didit customer that has not proven control of the wallet), or `no_directory_match` when the trace gives no other reason. A resend moves the transfer on, so the reason clears. See [Why a transfer is stuck](/transaction-monitoring/travel-rule#why-a-transfer-is-stuck)." - }, - "next_actions": { + "incidents": { "type": "array", - "description": "What moves the transfer on; `[]` for any status but `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE`. `email_undeliverable` offers `update_compliance_email`, then `resend`. `delivery_failed` offers `resend`. A discovery reason offers `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint` and `resend`.", + "description": "Newest `started_at` first. Every ongoing incident, plus the incidents resolved in the last 7 days (at most 50 resolved incidents). Empty when nothing happened in that time.", "items": { - "$ref": "#/components/schemas/TravelRuleNextAction" + "$ref": "#/components/schemas/ServiceStatusIncident" } - }, - "chain_details": { - "$ref": "#/components/schemas/TravelRuleChainDetails" } } }, - "NetworkListCounts": { + "ServiceStatusService": { "type": "object", - "description": "Network counts for the list's views and filter options, each network counted once. Returned only when `summary` is not `false`. `scopes` count every network visible to the application. `views` count the visible networks inside the selected `scope`. `facets` count the networks in the selected `scope` and `status` view (dismissed networks are left out unless `status` includes them). The other list filters do not change these counts.", + "required": [ + "key", + "name", + "status" + ], "properties": { - "scopes": { - "type": "object", - "description": "Visible networks by product.", - "properties": { - "all": { - "type": "integer" - }, - "identity": { - "type": "integer", - "description": "Every other network." - }, - "transactions": { - "type": "integer", - "description": "Networks whose members are all transaction parties." - } - } + "key": { + "type": "string", + "enum": [ + "service_id_verification", + "service_liveness_face_match", + "service_aml_screening", + "service_kyb_registries", + "service_database_validation", + "service_phone_delivery", + "service_email_delivery", + "service_transaction_monitoring" + ], + "description": "Stable service key. Match on this, never on the display name. `service_id_verification`: ID verification, `service_liveness_face_match`: Liveness and face match, `service_aml_screening`: AML screening, `service_kyb_registries`: KYB registries, `service_database_validation`: Database validation, `service_phone_delivery`: Phone verification delivery, `service_email_delivery`: Email verification delivery, `service_transaction_monitoring`: Transaction monitoring.", + "example": "service_database_validation" }, - "views": { - "type": "object", - "description": "Visible networks inside the selected `scope`, by status, plus two saved views.", - "properties": { - "all": { - "type": "integer" - }, - "active": { - "type": "integer" - }, - "in_review": { - "type": "integer" - }, - "resolved": { - "type": "integer" - }, - "dismissed": { - "type": "integer" - }, - "mine": { - "type": "integer", - "description": "Networks assigned to the calling console member. Always 0 for an API key." - }, - "high_risk": { - "type": "integer", - "description": "Networks with a risk score of 80 or more that are not dismissed." - } - } + "name": { + "type": "string", + "description": "English display name of the service.", + "example": "Database validation" }, - "facets": { - "type": "object", - "description": "Counts for each filter option, inside the selected `scope` and status view.", - "properties": { - "total": { - "type": "integer", - "description": "Networks in the selected `scope` and status view." - }, - "last_activity_days": { - "type": "object", - "description": "Networks with activity in the last 7, 30 and 90 days, keyed by the number of days.", - "properties": { - "7": { - "type": "integer" - }, - "30": { - "type": "integer" - }, - "90": { - "type": "integer" - } - } - }, - "risk_min": { - "type": "object", - "description": "Networks with a risk score of at least 50 and at least 80, keyed by the threshold.", - "properties": { - "50": { - "type": "integer" - }, - "80": { - "type": "integer" - } - } - }, - "signal_types": { - "type": "object", - "description": "Networks with at least one signal of each type.", - "properties": { - "ip_address": { - "type": "integer" - }, - "device": { - "type": "integer" - }, - "face": { - "type": "integer" - }, - "document_number": { - "type": "integer" - }, - "phone": { - "type": "integer" - }, - "email": { - "type": "integer" - }, - "address": { - "type": "integer" - } - } - }, - "priority": { - "type": "object", - "description": "Networks by priority. `none` counts networks without a priority.", - "properties": { - "low": { - "type": "integer" - }, - "medium": { - "type": "integer" - }, - "high": { - "type": "integer" - }, - "none": { - "type": "integer" - } - } - }, - "assignee": { - "type": "object", - "description": "Networks by assignee.", - "properties": { - "me": { - "type": "integer", - "description": "Assigned to the calling console member. Always 0 for an API key." - }, - "unassigned": { - "type": "integer", - "description": "Assigned to nobody." - }, - "users": { - "type": "array", - "description": "One entry per assignee, most networks first.", - "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - }, - "full_name": { - "type": "string", - "description": "The assignee's name, or their email when no name is set." - }, - "email": { - "type": "string" - }, - "count": { - "type": "integer" - } - } - } - } - } - }, - "has_case": { - "type": "integer", - "description": "Networks this application opened a case for." - }, - "min_size": { - "type": "object", - "description": "Networks with at least 10 members, keyed by the minimum size.", - "properties": { - "10": { - "type": "integer" - } - } - } - } + "status": { + "type": "string", + "enum": [ + "operational", + "degraded", + "down" + ], + "description": "`operational` when no incident is ongoing for the service, otherwise the worst state of its ongoing incidents.", + "example": "degraded" } } }, - "NetworkTag": { + "ServiceStatusIncident": { "type": "object", - "description": "One of your application's tags on the network.", + "required": [ + "id", + "service", + "service_name", + "state", + "status", + "title", + "body", + "affected", + "country_name", + "started_at", + "resolved_at", + "duration_minutes" + ], "properties": { - "uuid": { + "id": { "type": "string", "format": "uuid", - "description": "The tag's UUID, the same value you pass as `tag_uuid`." + "description": "Incident ID.", + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" }, - "name": { - "type": "string" + "service": { + "type": "string", + "enum": [ + "service_id_verification", + "service_liveness_face_match", + "service_aml_screening", + "service_kyb_registries", + "service_database_validation", + "service_phone_delivery", + "service_email_delivery", + "service_transaction_monitoring" + ], + "description": "Key of the affected service (see `services[].key`).", + "example": "service_database_validation" }, - "color": { + "service_name": { "type": "string", - "description": "Hex color, for example `#6366F1`." + "description": "English display name of the affected service.", + "example": "Database validation" }, - "source": { + "state": { "type": "string", "enum": [ - "didit", - "custom" + "degraded", + "down" ], - "description": "`didit` for a Didit preset tag, `custom` for a tag your team created." + "description": "How the service is affected. A resolved incident keeps the last state it had.", + "example": "degraded" }, - "added_by": { + "status": { "type": "string", - "nullable": true, - "description": "Email of the console member who added the tag. Null when an API key added it." + "enum": [ + "ongoing", + "resolved" + ], + "description": "`ongoing` until the service recovers, then `resolved`.", + "example": "ongoing" }, - "added_at": { + "title": { "type": "string", - "format": "date-time" - } - } - }, - "NetworkOutcomes": { - "type": "object", - "description": "Where the network's people and businesses stand. Each member you may see counts once, by the status of their most recent verification that reached a decision. Transaction parties are not counted.", - "properties": { - "approved": { - "type": "integer", - "description": "Members whose most recent decided verification was approved." + "description": "English headline. To translate it, build your own text from `service`, `state` and `country_name`.", + "example": "Database validation is degraded in Brazil." }, - "declined": { - "type": "integer", - "description": "Members whose most recent decided verification was declined." + "body": { + "type": "string", + "description": "English detail line: since when checks may be slow or fail, or when it recovered.", + "example": "Checks against Brazil (CPF) may be slow or fail since 08:55 UTC." }, - "in_review": { - "type": "integer", - "description": "Members whose most recent decided verification is in review." + "affected": { + "type": "string", + "description": "Countries or registries affected, for example `Brazil (CPF)`. Empty when the incident is not tied to a country or registry.", + "example": "Brazil (CPF)" }, - "total": { + "country_name": { + "type": "string", + "description": "Country affected, in English. Empty when the incident is not tied to a country.", + "example": "Brazil" + }, + "started_at": { + "type": "string", + "format": "date-time", + "description": "When the incident started (ISO 8601, UTC).", + "example": "2026-10-13T08:55:00Z" + }, + "resolved_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the service recovered (ISO 8601, UTC). `null` while the incident is ongoing." + }, + "duration_minutes": { "type": "integer", - "description": "Members with at least one verification, decided or not. A member whose verifications are all undecided (not started, in progress, expired or abandoned) counts here and in no other key." + "nullable": true, + "description": "Whole minutes from `started_at` to `resolved_at`. `null` while the incident is ongoing." } } }, - "NetworkPatternScore": { + "TravelRuleJoinInvitation": { "type": "object", - "description": "How alike one kind of the members' data is across the whole network. A pattern is not a signal: no shared value links the members.", + "description": "What the join page shows before anything is typed.", "properties": { - "type": { + "email": { "type": "string", - "enum": [ - "background" - ], - "description": "`background`: the mean similarity of every pair of member selfie backgrounds, with the person masked out. It reads the newest selfie of each person, at most the 50 newest, and leaves out age assurance sessions. It covers the whole network, not only the members of your applications." - }, - "score": { - "type": "number", - "nullable": true, - "minimum": 0, - "maximum": 1, - "description": "From 0 to 1, rounded to 4 decimals. Null when `reason` is set." + "format": "email", + "description": "The address the invitation went to." }, - "members": { - "type": "integer", - "nullable": true, - "description": "How many members' selfies the score compared. A selfie that cannot be read, or shows too little background, is not compared. Null while `computing`; 0 or 1 with `not_enough_selfies`." + "vasp_name": { + "type": "string" }, - "reason": { + "source": { "type": "string", - "enum": [ - "computing", - "not_enough_selfies" - ], - "nullable": true, - "description": "Why there is no score. `computing`: the score for the current members is being computed; read the network again later. `not_enough_selfies`: fewer than two members have a usable selfie. Null when there is a score." + "description": "Where the invitation came from, for example `pickup`." }, - "computed_at": { + "expires_at": { "type": "string", "format": "date-time", - "nullable": true, - "description": "When the score was computed. Null while `computing`." - } - } - }, - "NetworkDetailResponse": { - "description": "The network detail, plus the organization's sharing mode, whether cross-organization signals apply to it, your application's tags on the network, member outcomes and pattern scores.", - "allOf": [ - { - "$ref": "#/components/schemas/NetworkDetail" + "nullable": true }, - { + "prefill": { "type": "object", "properties": { - "sharing_mode": { + "vasp_id": { "type": "string", - "enum": [ - "off", - "private", - "global" - ], - "description": "The organization's cross-organization sharing mode. Only `global` compares networks across organizations; `private` and `off` keep them to the organization's own history.", - "example": "global" - }, - "cross_org_available": { - "type": "boolean", - "description": "Whether cross-organization signals apply to this organization. They need both the Enterprise plan and the `global` sharing mode.", - "example": true + "format": "uuid", + "nullable": true }, - "cross_org_unavailable_reason": { - "type": "string", - "enum": [ - "plan", - "sharing_mode" - ], - "nullable": true, - "description": "Why cross-organization signals do not apply, checked in this order. `plan`: the organization's plan does not include the cross-organization fraud network (it needs the Enterprise plan), whatever the sharing mode. `sharing_mode`: the plan includes it, but the sharing mode is `private` or `off`. Null when `cross_org_available` is `true`.", - "example": null + "legal_name": { + "type": "string" }, - "tags": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NetworkTag" - }, - "description": "Your application's tags on the network, oldest first. Each application sees only its own tags. `fraud_tags` is separate and unchanged: the tags the network's members carry." + "lei": { + "type": "string" }, - "outcomes": { - "$ref": "#/components/schemas/NetworkOutcomes" + "jurisdiction": { + "type": "string" }, - "patterns": { + "domains": { "type": "array", "items": { - "$ref": "#/components/schemas/NetworkPatternScore" - }, - "description": "Pattern scores over the whole network. Today one item, `background`." + "type": "string" + } + } + } + } + } + }, + "TravelRuleJoinRegisterRequest": { + "type": "object", + "required": [ + "email", + "password" + ], + "properties": { + "email": { + "type": "string", + "format": "email", + "maxLength": 254, + "description": "Must be the address the invitation went to." + }, + "password": { + "type": "string", + "minLength": 8, + "maxLength": 128 + } + } + }, + "TravelRuleJoinVerifyRequest": { + "type": "object", + "required": [ + "email", + "code" + ], + "properties": { + "email": { + "type": "string", + "format": "email", + "maxLength": 254 + }, + "code": { + "type": "string", + "minLength": 6, + "maxLength": 6, + "description": "The 6-character code emailed after registering." + } + } + }, + "TravelRuleJoinCredentials": { + "type": "object", + "description": "The new free organization and the credentials its application calls the API with.", + "properties": { + "organization": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" + } + } + }, + "application": { + "type": "object", + "properties": { + "uuid": { + "type": "string", + "format": "uuid" } } + }, + "client_id": { + "type": "string" + }, + "api_key": { + "type": "string", + "description": "Send as the `x-api-key` header on the workspace endpoints." } - ] + } }, - "NetworkTagRequest": { + "TravelRuleWorkspaceClaimRequest": { "type": "object", "required": [ - "tag_uuid" + "vasp_id" ], "properties": { - "tag_uuid": { + "vasp_id": { "type": "string", "format": "uuid", - "description": "UUID of one of your application's tags." + "description": "The directory entry this workspace is. Read ids from `GET /v3/travel-rule/vasps/`." } - }, - "example": { - "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7" } }, - "NetworkTimeline": { - "title": "Default timeline (no contract)", + "TravelRuleWorkspaceDomainConfirmRequest": { "type": "object", - "description": "Without `contract`: the network's own events, oldest first, not paginated.", + "required": [ + "code" + ], "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NetworkTimelineEvent" - } + "code": { + "type": "string", + "minLength": 6, + "maxLength": 6 } } }, - "NetworkTimelinePage": { - "title": "Typed timeline page (contract=2)", + "TravelRuleWorkspaceBillingRequest": { "type": "object", - "description": "With `contract=2`: one page of typed events, newest first.", "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NetworkTypedTimelineEvent" - } - }, - "next_cursor": { - "type": "string", - "nullable": true, - "description": "Pass as `cursor` to read the next page. Null on the last page." + "enabled": { + "type": "boolean", + "default": true, + "description": "Only `true` is accepted: outbound billing cannot be turned back off through the API." } } }, - "NetworkTypedTimelineEvent": { + "TravelRuleWorkspaceDomainCodeResponse": { "type": "object", - "description": "One typed timeline event: the four default fields, plus its id, when Didit stored it, the member account and record it belongs to, and the detail block of its event type. The other detail blocks are null.", "properties": { - "id": { - "type": "string", - "description": "`:`, unique within the timeline.", - "example": "session:3fa85f64-5717-4562-b3fc-2c963f66afa6" + "domain": { + "type": "string" }, - "event_type": { + "status": { "type": "string", "enum": [ - "network_detected", - "signal_observed", - "network_active", - "network_in_review", - "network_resolved", - "network_dismissed", - "verification_attempt", - "transaction", - "login", - "rule_hit", - "case_linked", - "note_added" + "unverified", + "code_sent", + "verified" ] }, - "occurred_at": { + "txt": { + "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord" + } + } + }, + "TravelRuleWorkspaceTxtRecord": { + "type": "object", + "description": "The TXT record to publish for the DNS proof. Empty until a proof has been started.", + "properties": { + "host": { "type": "string", - "format": "date-time", - "description": "When it happened." + "example": "didit-tr-verify.example.com" }, - "ingested_at": { + "value": { + "type": "string" + } + } + }, + "TravelRuleWorkspace": { + "type": "object", + "description": "The free Travel Rule workspace of an application that joined free.", + "properties": { + "joined_free": { + "type": "boolean" + }, + "work_email": { "type": "string", - "format": "date-time", - "description": "When Didit stored it." + "format": "email" }, - "label": { + "joined_at": { "type": "string", - "description": "A short English label, for example `Verification attempt 2 of 3`." + "format": "date-time", + "nullable": true }, - "metadata": { + "claim": { "type": "object", - "description": "For the network's own events, the same metadata as the default timeline. Empty otherwise." - }, - "account": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineAccount" - } - ], - "nullable": true, - "description": "The member account. Null for the network's own events, `case_linked` and `note_added`." - }, - "source_ref": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineSourceRef" + "properties": { + "status": { + "type": "string", + "enum": [ + "unclaimed", + "pending_review", + "claimed", + "rejected" + ] + }, + "proved_by_domain": { + "type": "boolean" + }, + "claimed_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "reviewed_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "review_note": { + "type": "string" + }, + "vasp_id": { + "type": "string", + "format": "uuid", + "nullable": true + }, + "vasp_name": { + "type": "string" } - ], - "nullable": true, - "description": "The source record. Null for the network's own events and `note_added`." + } }, - "verification_attempt": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineAttempt" - } - ], - "nullable": true, - "description": "Set on `verification_attempt` events." + "prefill": { + "type": "object", + "description": "Profile values taken from the directory entry: `vasp_id`, `legal_name`, `lei`, `jurisdiction`, `compliance_email`, `domains`. Nothing is written until the claim is made." }, - "transaction": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineTransaction" + "domain": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "unverified", + "code_sent", + "verified" + ] + }, + "verified_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "txt": { + "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord" } - ], - "nullable": true, - "description": "Set on `transaction` events." + } }, - "login": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineLogin" - } - ], - "nullable": true, - "description": "Set on `login` events." + "billing_enabled": { + "type": "boolean", + "description": "Receiving Travel Rule data is free. Sending is billed only after billing is enabled." }, - "rule_hit": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineRuleHit" - } - ], - "nullable": true, - "description": "Set on `rule_hit` events." + "billing_enabled_at": { + "type": "string", + "format": "date-time", + "nullable": true }, - "case_linked": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineCaseLinked" - } - ], - "nullable": true, - "description": "Set on `case_linked` events." + "didit_network": { + "type": "object", + "description": "Whether the Didit network lists this VASP and, when not, each condition it still misses." }, - "note_added": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineNoteAdded" - } - ], - "nullable": true, - "description": "Set on `note_added` events. Never returned to an API key." + "settings": { + "$ref": "#/components/schemas/TravelRuleSettingsDetail" } } }, - "NetworkTimelineAccount": { + "InvestigatorDecision": { "type": "object", - "description": "The member account the event belongs to.", + "description": "How the item left the Investigator queue. `decided_by`, `original_outcome` and `overrides` are returned by the accept and override endpoints and the report; the `investigator` block of a session decision carries the other fields.", "properties": { - "node_id": { + "outcome": { "type": "string", - "description": "`:`, where kind is `vendor_user`, `vendor_business` or `transaction_party`.", - "example": "vendor_user:3fa85f64-5717-4562-b3fc-2c963f66afa6" + "enum": [ + "accepted", + "edited", + "overridden", + "decided_elsewhere", + "automated" + ], + "description": "`accepted` or `edited` took the recommendation (`edited` with a rewritten narrative), `overridden` took another action, `decided_elsewhere` is a decision taken outside the Investigator while the report was open, `automated` is a decision the Investigator took on its own." }, - "node_type": { + "action": { "type": "string", "enum": [ - "account", - "business_account", - "transaction_party" + "approve", + "decline", + "escalate", + "request" ] }, - "uuid": { - "type": "string", - "format": "uuid" - }, - "vendor_data": { + "actor_email": { "type": "string", "nullable": true }, - "display_name": { + "actor_name": { "type": "string", "nullable": true }, - "ownership": { - "type": "string", - "enum": [ - "owned", - "organization" - ], - "description": "`owned` when the record belongs to the application you called (for a console member, to an application they were granted). `organization` when it belongs to another application of your organization." - }, - "route": { - "$ref": "#/components/schemas/NetworkTimelineRoute" - } - } - }, - "NetworkTimelineSourceRef": { - "type": "object", - "description": "The record the event was read from.", - "properties": { - "kind": { - "type": "string", - "enum": [ - "session", - "business_session", - "transaction", - "monitoring_event", - "case" - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "ownership": { + "override_category": { "type": "string", "enum": [ - "owned", - "organization" - ], - "description": "`owned` when the record belongs to the application you called (for a console member, to an application they were granted). `organization` when it belongs to another application of your organization." - }, - "route": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineRoute" - } + "missing_context", + "needs_information", + "policy_differs", + "evidence_misread", + "other", + "" ], - "description": "Absent for `monitoring_event` and `case`." - } - } - }, - "NetworkTimelineRoute": { - "type": "object", - "description": "Where the record opens: its kind, its UUID and the application it belongs to.", - "properties": { - "kind": { - "type": "string", - "description": "`user`, `business` or `transaction_party` for an account; `session`, `business_session` or `transaction` for a source record." + "nullable": true }, - "id": { + "override_reason": { "type": "string", - "format": "uuid" + "nullable": true }, - "application_id": { - "type": "string", - "format": "uuid" - } - } - }, - "NetworkTimelineAttempt": { - "type": "object", - "description": "One verification session of the account.", - "properties": { - "session_id": { + "final_status": { "type": "string", - "format": "uuid", - "description": "The session UUID, or the business session UUID for a company." + "description": "The item's status after the decision." }, - "session_number": { - "type": "integer", + "agreed": { + "type": "boolean", + "description": "Whether the decision matched the recommendation.", "nullable": true }, - "attempt": { - "type": "integer", - "description": "This session's position among the account's sessions, in creation order." + "decided_at": { + "type": "string", + "format": "date-time" }, - "attempt_count": { - "type": "integer", - "description": "How many sessions the account has." + "billed": { + "type": "boolean", + "description": "The review was charged." }, - "status": { + "decided_by": { "type": "string", - "description": "The session status, for example `Approved` or `Declined`." + "enum": [ + "investigator", + "member" + ] }, - "status_changed_at": { - "type": "string", - "format": "date-time", + "original_outcome": { + "type": "object", + "description": "The decision the Investigator took on its own, unchanged by later overrides. Null for a decision the team took.", + "properties": { + "action": { + "type": "string" + }, + "final_status": { + "type": "string" + }, + "decided_at": { + "type": "string", + "format": "date-time" + } + }, "nullable": true }, - "decline_reasons": { + "overrides": { "type": "array", + "description": "Every override of a decision the Investigator took on its own, oldest first.", "items": { - "$ref": "#/components/schemas/NetworkTimelineDeclineReason" - }, - "description": "For a declined session only: its warnings, oldest first, once per warning. Empty otherwise." + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "actor_email": { + "type": "string", + "nullable": true + }, + "actor_name": { + "type": "string", + "nullable": true + }, + "override_category": { + "type": "string" + }, + "override_reason": { + "type": "string" + }, + "previous_status": { + "type": "string" + }, + "final_status": { + "type": "string" + }, + "agreed": { + "type": "boolean", + "nullable": true + }, + "overridden_at": { + "type": "string", + "format": "date-time" + } + } + } } } }, - "NetworkTimelineDeclineReason": { + "InvestigatorBlock": { "type": "object", + "nullable": true, + "description": "The item's latest Investigator review, or null when it never had one. Carried by the V3 session and business session decision (and so by `status.updated` webhooks).", "properties": { - "risk": { + "run_id": { "type": "string", - "description": "The warning code." + "format": "uuid" }, - "feature": { + "status": { "type": "string", - "description": "The feature that raised the warning." + "enum": [ + "running", + "completed", + "failed" + ] }, - "short_description": { - "type": "string" - } - } - }, - "NetworkTimelineTransaction": { - "type": "object", - "description": "A transaction a member account took part in, dated by its transaction date.", - "properties": { - "transaction_id": { + "stage": { "type": "string", - "format": "uuid" - }, - "transaction_number": { - "type": "integer", - "nullable": true - }, - "transaction_type": { - "type": "string" - }, - "action_type": { - "type": "string" + "enum": [ + "shadow", + "live" + ] }, - "amount": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineAmount" - } - ], - "nullable": true, - "description": "Null when the transaction has no amount." + "queue": { + "type": "string", + "enum": [ + "kyc", + "kyb", + "aml", + "transactions", + "cases" + ] }, - "status": { - "type": "string" + "is_open": { + "type": "boolean" }, - "decision_reason_code": { + "recommendation": { "type": "string", + "enum": [ + "approve", + "decline", + "escalate", + "request" + ], "nullable": true }, - "decision_reason_label": { + "recommendation_detail": { "type": "string", "nullable": true }, - "party_role": { - "type": "string", - "description": "The account's role in the transaction: `APPLICANT`, `REMITTER`, `BENEFICIARY` or `COUNTERPARTY`." - } - } - }, - "NetworkTimelineAmount": { - "type": "object", - "properties": { - "value": { + "confidence": { "type": "string", - "description": "Decimal amount as a string." - }, - "currency": { - "type": "string" + "enum": [ + "high", + "moderate", + "low" + ], + "nullable": true }, - "direction": { + "summary": { "type": "string", "nullable": true - } - } - }, - "NetworkTimelineLogin": { - "type": "object", - "description": "A sign-in event you posted for a person through the events API.", - "properties": { - "action": { - "type": "string", - "description": "`.`: `auth.login` or `security.login_succeeded` for a sign-in, `auth.login_failed` or `security.login_failed` for a failed one." }, - "succeeded": { + "ready_to_accept": { "type": "boolean" }, - "status": { + "prepared_at": { "type": "string", - "description": "The event's status." + "format": "date-time", + "nullable": true }, - "ip": { - "allOf": [ - { - "$ref": "#/components/schemas/NetworkTimelineIP" - } + "automated": { + "type": "boolean", + "description": "The Investigator decided on its own, even if the decision was later overridden." + }, + "decided_by": { + "type": "string", + "enum": [ + "investigator", + "member" ], - "nullable": true, - "description": "Null when the event has no IP address." + "nullable": true }, - "device": { + "decision": { + "nullable": true, "allOf": [ { - "$ref": "#/components/schemas/NetworkTimelineDevice" + "$ref": "#/components/schemas/InvestigatorDecision" } ], - "nullable": true, - "description": "Null when the event has no device fingerprint or context." - }, - "is_first_login": { - "type": "boolean", - "description": "The account's first successful sign-in on record." - }, - "is_new_device": { - "type": "boolean", - "description": "A successful sign-in from a device none of the account's earlier successful sign-ins came from. Never true on the first sign-in." + "type": "object" } } }, - "NetworkTimelineIP": { + "InvestigatorQueueRow": { "type": "object", "properties": { - "address": { - "type": "string" + "run_id": { + "type": "string", + "format": "uuid" }, - "country_code": { + "kind": { "type": "string", - "nullable": true + "enum": [ + "session", + "business_session", + "transaction", + "case" + ] }, - "city": { + "queue": { "type": "string", - "nullable": true + "enum": [ + "kyc", + "kyb", + "aml", + "transactions", + "cases" + ] }, - "connection_type": { + "stage": { "type": "string", - "nullable": true, - "description": "The connection type label for the address, as free text." + "enum": [ + "shadow", + "live" + ] }, - "is_vpn_or_tor": { - "type": "boolean" + "subject": { + "type": "object", + "description": "The item under review: `id`, `number`, `status`, `name` and, depending on the kind, `country`, `workflow`, `vendor_data`, `txn_id`, `amount`, `currency`, `direction`, `title` or `priority`.", + "additionalProperties": true }, - "is_data_center": { - "type": "boolean" - } - } - }, - "NetworkTimelineDevice": { - "type": "object", - "properties": { - "fingerprint": { + "recommendation": { "type": "string", - "nullable": true + "enum": [ + "approve", + "decline", + "escalate", + "request" + ] }, - "label": { - "type": "string", - "nullable": true, - "description": "A readable device label built from the event's device context." - } - } - }, - "NetworkTimelineRuleHit": { - "type": "object", - "description": "A live rule that matched a member's transaction or event. Test-mode matches are not included.", - "properties": { - "rule_id": { + "recommendation_detail": { + "type": "string" + }, + "confidence": { "type": "string", - "format": "uuid" + "enum": [ + "high", + "moderate", + "low" + ] }, - "rule_title": { + "summary": { "type": "string" }, - "rule_category": { - "type": "string" + "sources_count": { + "type": "integer" }, - "rule_source": { - "type": "string" + "ready_to_accept": { + "type": "boolean" }, - "severity": { + "guardrails": { + "description": "The locked guardrails that hold this item, if any." + }, + "waiting_since": { "type": "string", + "format": "date-time", "nullable": true }, - "score_delta": { - "type": "integer" - }, - "status_target": { + "due_at": { "type": "string", + "format": "date-time", "nullable": true }, - "action_summary": { + "prepared_at": { "type": "string", + "format": "date-time", "nullable": true } } }, - "NetworkTimelineCaseLinked": { + "InvestigatorRunDetail": { + "allOf": [ + { + "$ref": "#/components/schemas/InvestigatorQueueRow" + }, + { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "is_open": { + "type": "boolean" + }, + "lookups": { + "type": "integer", + "description": "How many sections and linked records it read." + }, + "duration_ms": { + "type": "integer", + "nullable": true + }, + "agent_version": { + "type": "string" + }, + "prepared_before_opened": { + "type": "boolean", + "nullable": true + }, + "report": { + "type": "object", + "additionalProperties": true, + "description": "The report: reasoning, evidence points with their verdict (`ok`, `risk`, `look`, `explained`, `context`) and cited sources, screening hit verdicts (`same`, `not_same`, `unclear`) and suggested next steps." + }, + "trail": { + "description": "What I checked: the overview, sections and records it read, in order." + }, + "decision": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/InvestigatorDecision" + } + ], + "type": "object" + }, + "autonomy": { + "type": "object", + "additionalProperties": true, + "description": "What autonomy made of the report (`result`, `reason`, `tier`, `policy_version`, `rule`, `agreement`, `decisions`, `threshold`, `at`). Null when the queue is not automated.", + "nullable": true + } + } + } + ] + }, + "InvestigatorAcceptRequest": { "type": "object", - "description": "A case opened for the network in your organization. `source_ref.ownership` says whether it belongs to the application you called.", "properties": { - "case_id": { - "type": "string", - "format": "uuid" - }, - "case_number": { + "narrative": { "type": "string", - "nullable": true + "maxLength": 4000, + "description": "A rewritten narrative. Sending one records the decision as edited and accepted." }, - "status": { - "type": "string" + "send_email": { + "type": "boolean", + "default": false, + "description": "Email the person about the decision." }, - "author_email": { + "email_address": { "type": "string", - "nullable": true + "format": "email", + "description": "Required when `send_email` is true." }, - "author_name": { - "type": "string", - "nullable": true - } - } - }, - "NetworkTimelineNoteAdded": { - "type": "object", - "description": "A note left on the network. The note text is not included.", - "properties": { - "note_id": { + "email_language": { "type": "string", - "format": "uuid" - }, - "author_email": { - "type": "string" + "default": "en", + "maxLength": 16 } } }, - "FeatureStatusOverride": { + "InvestigatorOverrideRequest": { "type": "object", - "description": "One override of a check (feature) status made with `PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`: what it changes, whether it applied or still waits for the person to finish the flow, who asked and why.", "required": [ - "id", - "node_id", - "feature_type", - "feature_model", - "previous_status", - "new_status", - "state", - "forced", - "reason", - "requested_by", - "requested_at", - "applied_at", - "cancelled_at", - "cancel_reason" + "action", + "category", + "reason" ], "properties": { - "id": { - "type": "string", - "format": "uuid", - "description": "Identifier of the override. Pass it to the cancel endpoint.", - "example": "7c9e6679-7425-40de-944b-e07fc1f90ae7" - }, - "node_id": { - "type": "string", - "description": "The workflow node the request named (`default` for a step without a node).", - "example": "feature_ocr_1" - }, - "feature_type": { - "type": "string", - "description": "The `feature_type` the request passed, or an empty string when it passed none.", - "example": "" - }, - "feature_model": { - "type": "string", - "description": "The kind of check that was overridden, for example `KYC`, `Face`, `AML` or `GeolocationCheck`.", - "example": "KYC" - }, - "previous_status": { - "type": "string", - "enum": [ - "Not Finished", - "Approved", - "Declined", - "In Review", - "Resub Requested" - ], - "description": "The check's status when the override was requested.", - "example": "In Review" - }, - "new_status": { + "action": { "type": "string", "enum": [ - "Approved", - "Declined", - "In Review" - ], - "description": "The status the override sets.", - "example": "Approved" + "approve", + "decline", + "escalate", + "request" + ] }, - "state": { + "category": { "type": "string", "enum": [ - "applied", - "pending_until_flow_finishes", - "cancelled" - ], - "description": "`applied`: the check has the new status. `pending_until_flow_finishes`: the override waits and applies when the person finishes the flow. `cancelled`: it waited and never applied (see `cancel_reason`).", - "example": "applied" - }, - "forced": { - "type": "boolean", - "description": "`true` when the override applied at once while the person was still in the flow.", - "example": false + "missing_context", + "needs_information", + "policy_differs", + "evidence_misread", + "other" + ] }, "reason": { "type": "string", - "nullable": true, - "description": "The `comment` sent with the request, or `null`.", - "example": "Document manually verified by compliance." + "minLength": 10, + "maxLength": 500 }, - "requested_by": { - "type": "object", - "nullable": true, - "description": "Who requested the override, or `null` when that is not known.", - "properties": { - "email": { - "type": "string", - "format": "email", - "nullable": true, - "description": "Email of the console user, or `null` for API keys and the system.", - "example": "reviewer@example.com" - }, - "name": { - "type": "string", - "nullable": true, - "description": "Display name of the requester, or `null`.", - "example": "Alex Reviewer" - }, - "type": { - "type": "string", - "enum": [ - "CONSOLE_USER", - "API_KEY", - "SYSTEM" - ], - "description": "Who made the request: a console user, an API key, or Didit itself.", - "example": "CONSOLE_USER" - } - } + "send_email": { + "type": "boolean", + "default": false, + "description": "Email the person about the decision." }, - "requested_at": { + "email_address": { "type": "string", - "format": "date-time", - "description": "When the override was requested.", - "example": "2026-10-13T09:15:00Z" + "format": "email", + "description": "Required when `send_email` is true." }, - "applied_at": { + "email_language": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the check took the new status, or `null` while it waits or once it is cancelled.", - "example": "2026-10-13T09:15:00Z" + "default": "en", + "maxLength": 16 + } + } + }, + "InvestigatorBatchAcceptRequest": { + "type": "object", + "required": [ + "run_ids" + ], + "properties": { + "run_ids": { + "type": "array", + "minItems": 1, + "maxItems": 50, + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, + "InvestigatorBatchAcceptResponse": { + "type": "object", + "properties": { + "accepted": { + "type": "integer" }, - "cancelled_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When a waiting override was cancelled, or `null`.", - "example": null + "skipped": { + "type": "integer" }, - "cancel_reason": { - "type": "string", - "nullable": true, - "enum": [ - "cancelled_by_reviewer", - "replaced", - "check_changed", - "session_closed", - null - ], - "description": "Why a waiting override never applied, or `null`. `cancelled_by_reviewer`: cancelled with the cancel endpoint. `replaced`: a newer override on the same check replaced it. `check_changed`: the person redid the check before finishing the flow. `session_closed`: the session left the flow before the person finished it (abandoned, expired, or decided mid-flow).", - "example": null + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "run_id": { + "type": "string", + "format": "uuid" + }, + "result": { + "type": "string", + "enum": [ + "accepted", + "skipped" + ] + }, + "reason": { + "type": "string", + "enum": [ + "not_found", + "forbidden", + "already_decided", + "not_ready", + "guardrail", + "invalid" + ] + }, + "detail": {}, + "action": { + "type": "string" + }, + "final_status": { + "type": "string" + } + } + } } } }, - "SandboxSimulateRequest": { + "InvestigatorSettings": { "type": "object", - "description": "Force a sandbox session's status. Every field is optional, but at least one of `new_status`, `scenario` or `risk` is required.", "properties": { - "new_status": { + "stage": { "type": "string", "enum": [ - "Approved", - "Declined", - "In Review", - "Expired", - "Abandoned" - ], - "description": "The status to set. When you leave it out, it defaults to the default status of the risk case (`risk`, or the first risk the scenario's magic values carry), else to the scenario's default status.", - "example": "Declined" - }, - "comment": { - "type": "string", - "maxLength": 500, - "description": "Note added to the activity entry the status change records.", - "example": "Testing the decline path" + "none", + "shadow", + "live" + ] }, - "scenario": { + "stage_changed_at": { "type": "string", - "maxLength": 100, - "description": "A scenario slug from the catalog (`GET /v1/sandbox/scenarios/`). It supplies the default status and, without `risk`, the warning its magic values carry. An unknown slug returns `400`.", - "example": "decline_aml_hit" + "format": "date-time", + "readOnly": true, + "nullable": true }, - "risk": { + "stage_changed_by": { "type": "string", - "maxLength": 128, - "description": "A risk case from the catalog. Its warning is added to the session, with a log type that follows `new_status`. An unknown value returns `400`.", - "example": "POSSIBLE_MATCH_FOUND" + "readOnly": true }, - "node_id": { + "monthly_spend_limit": { "type": "string", - "maxLength": 128, - "description": "Workflow node the risk warning is attached to. Defaults to the session's current node.", - "example": "feature_aml_1" + "format": "decimal", + "description": "Monthly limit in your billing currency, 0.01 to 1,000,000. Null turns it off.", + "nullable": true }, - "send_webhooks": { - "type": "boolean", - "default": true, - "description": "`true` sends exactly the webhooks a real status change sends to the sandbox application's destinations: `status.updated`, plus the `user.status.updated` / `user.data.updated` (or `business.status.updated` / `business.data.updated`) events the change causes, for destinations subscribed to them. `false` changes the status without logging or sending any webhook: the missed-webhook recovery never re-sends that decision, the console still updates live, and the next status change of the session sends webhooks as usual.", - "example": true + "spend_limit": { + "type": "object", + "readOnly": true, + "properties": { + "enabled": { + "type": "boolean" + }, + "limit": { + "type": "string", + "format": "decimal", + "nullable": true + }, + "spent": { + "type": "string", + "format": "decimal" + }, + "reviews": { + "type": "integer" + }, + "reserved": { + "type": "string", + "format": "decimal", + "description": "The price of every open live report, held back because accepting it charges it." + }, + "currency": { + "type": "string" + }, + "paused": { + "type": "boolean", + "description": "At the limit: no new review starts." + } + } } } }, - "SandboxSimulateResponse": { + "TravelRuleUtxoEntry": { "type": "object", + "description": "One input or output of a UTXO transaction, as the chain recorded it.", "required": [ - "session_id", - "previous_status", - "status", - "scenario", - "risk", - "send_webhooks" + "address" ], "properties": { - "session_id": { - "type": "string", - "format": "uuid", - "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" - }, - "previous_status": { - "type": "string", - "enum": [ - "Not Started", - "In Progress", - "Approved", - "Declined", - "In Review", - "Expired", - "Abandoned", - "Kyc Expired", - "Resubmitted", - "Awaiting User" - ], - "description": "The session's status before the simulation.", - "example": "In Progress" - }, - "status": { + "address": { "type": "string", - "enum": [ - "Approved", - "Declined", - "In Review", - "Expired", - "Abandoned" - ], - "description": "The status the simulation set.", - "example": "Declined" + "maxLength": 128 }, - "scenario": { + "amount": { "type": "string", "nullable": true, - "description": "The scenario slug you passed, or `null`.", - "example": "decline_aml_hit" + "description": "Decimal string in the coin's own unit (BTC, not satoshis). Optional.", + "example": "0.0125" }, - "risk": { + "txid": { "type": "string", - "nullable": true, - "description": "The risk case applied (`risk`, or the one taken from the scenario), or `null` when none.", - "example": "POSSIBLE_MATCH_FOUND" + "maxLength": 128, + "description": "Optional. The transaction an input spends." }, - "send_webhooks": { - "type": "boolean", - "description": "The `send_webhooks` value the simulation applied.", - "example": false + "vout": { + "type": "integer", + "nullable": true, + "minimum": 0, + "description": "Optional. The output index an input spends." } } }, - "CaseTeamSummary": { + "TravelRuleUtxo": { "type": "object", - "nullable": true, - "description": "The review team that owns the case, or null when no team owns it. Routing sets it when a routing rule places the case with one of its teams. Change or clear it with `PATCH .../cases/{case_uuid}/` (`team`).", + "description": "The inputs and outputs of a UTXO transfer (BTC, LTC, BCH, DOGE). Only accepted on those chains: on any other chain it is a `400`. From them Didit infers the originator wallet (the declared one, else the input address that contributed the most) and the beneficiary output (the declared one, else the only output that does not pay an input address back as change, else the one output paying the transfer amount). The result is on the transfer's `chain_details`.", + "required": [ + "outputs" + ], "properties": { - "uuid": { - "type": "string", - "format": "uuid" + "inputs": { + "type": "array", + "maxItems": 1000, + "items": { + "$ref": "#/components/schemas/TravelRuleUtxoEntry" + }, + "description": "Optional. Without inputs no originator is inferred and no change output is recognised." }, - "name": { - "type": "string" + "outputs": { + "type": "array", + "minItems": 1, + "maxItems": 1000, + "items": { + "$ref": "#/components/schemas/TravelRuleUtxoEntry" + } } } }, - "CaseChecker": { + "TravelRuleChainSide": { "type": "object", - "nullable": true, - "description": "The member named to approve or reject the pending resolution. Set only while a four-eyes resolution waits on a named checker. Null when nothing is pending, while the pending resolution waits on the checker queue, and once the resolution is approved, rejected, or returned for a new review because the evidence changed.", + "description": "One side's wallet as Didit resolved it from the chain data.", "properties": { - "member_uuid": { + "address": { "type": "string", - "format": "uuid", - "description": "The member's user uuid: the value you pass as `checker` when you resolve the case." + "description": "The wallet. On a memo network the classic address (an XRP X-address is split into its classic address and its tag); on Lightning the payee node id or Lightning Address." }, - "name": { + "memo": { "type": "string", - "nullable": true, - "description": "The member's full name, or null when it is not known." + "description": "The destination tag or memo that is part of the wallet; `\"\"` for none." }, - "email": { + "source": { "type": "string", - "format": "email" + "enum": [ + "declared", + "x_address", + "largest_input", + "only_non_change_output", + "amount_match", + "invoice_payee", + "updated" + ], + "description": "Where the wallet came from: `declared` (your request), `x_address` (split from an XRP X-address), `largest_input` (the UTXO input address that contributed the most), `only_non_change_output` (the only UTXO output that is not change), `amount_match` (the one UTXO output paying the transfer amount), `invoice_payee` (the payee a Lightning payment request names), `updated` (set later with `action: update_originator_wallet`)." } } }, - "ServiceStatusFeed": { + "TravelRuleChainDetails": { "type": "object", - "description": "Public service status: the state of each Didit service, the overall state, and the incidents that are ongoing or were resolved in the last 7 days.", - "required": [ - "status", - "updated_at", - "services", - "incidents" - ], + "description": "How the transfer's chain names its two wallets, when that is more than one address paying another. Empty (`{}`) for an account-chain transfer (EVM, Solana, Tron), where the two addresses are the wallets. Matching, routing and the address book read the wallets from here first.", "properties": { - "status": { + "chain": { "type": "string", - "enum": [ - "operational", - "degraded", - "down" - ], - "description": "The worst state of any service right now, decided by the ongoing incidents only.", - "example": "degraded" + "description": "Canonical chain, e.g. `BTC`, `XRP`, or `LIGHTNING` for a Lightning transfer." }, - "updated_at": { + "shape": { "type": "string", - "format": "date-time", - "description": "When Didit built this response (ISO 8601, UTC). Responses are cached for 30 seconds, so it can be up to 30 seconds old.", - "example": "2026-10-13T09:41:07.512345Z" + "enum": [ + "utxo", + "memo", + "lightning" + ] }, - "services": { - "type": "array", - "description": "One entry per service, every service always listed.", - "items": { - "$ref": "#/components/schemas/ServiceStatusService" + "originator": { + "$ref": "#/components/schemas/TravelRuleChainSide" + }, + "beneficiary": { + "$ref": "#/components/schemas/TravelRuleChainSide" + }, + "utxo": { + "type": "object", + "description": "On a UTXO transfer: the inputs and outputs as stored (amounts as decimal strings) and which outputs Didit read as what.", + "properties": { + "inputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TravelRuleUtxoEntry" + } + }, + "outputs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TravelRuleUtxoEntry" + } + }, + "change_output_indexes": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Outputs that pay an input address back." + }, + "beneficiary_output_index": { + "type": "integer", + "nullable": true, + "description": "The output that pays the beneficiary; null when none could be told apart." + } } }, - "incidents": { + "lightning": { + "type": "object", + "description": "On a Lightning transfer: what the payment request says. Always `kind` (`bolt11`, `bolt12_offer`, `bolt12_invoice`, `bolt12_invoice_request`, `lnurl`, `lightning_address`, `node_id` or `unknown`); a BOLT11 invoice adds `network`, `payee_node_id`, `payment_hash`, `amount_msat`, `created_at` and `expires_at`; a BOLT12 string `blinded_paths` and `payee_node_id`; an LNURL or a Lightning Address its `domain`. Nothing is resolved over the network: the request is decoded only.", + "additionalProperties": true + }, + "warnings": { "type": "array", - "description": "Newest `started_at` first. Every ongoing incident, plus the incidents resolved in the last 7 days (at most 50 resolved incidents). Empty when nothing happened in that time.", "items": { - "$ref": "#/components/schemas/ServiceStatusIncident" - } + "type": "string", + "enum": [ + "declared_originator_not_an_input", + "declared_beneficiary_not_an_output", + "beneficiary_output_ambiguous", + "beneficiary_output_amount_differs" + ] + }, + "description": "UTXO inconsistencies worth a look: the declared originator is not an input, the declared beneficiary is not an output, no single beneficiary output could be told apart, or the beneficiary output pays a different amount than the transaction states." + }, + "not_applicable_reason": { + "type": "string", + "enum": [ + "LIGHTNING_NO_PAYEE_IDENTIFIER", + "LIGHTNING_BOLT12_BLINDED_PAYEE", + "LIGHTNING_LNURL_NAMES_NO_PAYEE" + ], + "description": "On an outbound Lightning transfer whose payment request names no payee: why the transfer is `NOT_APPLICABLE`. `LIGHTNING_NO_PAYEE_IDENTIFIER` (the request names no payee node, or could not be decoded), `LIGHTNING_BOLT12_BLINDED_PAYEE` (the offer hides its payee behind blinded paths), `LIGHTNING_LNURL_NAMES_NO_PAYEE` (an LNURL names a service, not a payee). The same code opens the transfer's last `timeline` entry." } } }, - "ServiceStatusService": { + "WalletAddressImportRow": { "type": "object", - "required": [ - "key", - "name", - "status" - ], + "description": "One wallet to import: by its `address`, its `address_hash`, or both. The camelCase forms of these fields are accepted too, as are `walletAddress`, `walletAddressHash`, `destinationTag` and `externalUserId`.", "properties": { - "key": { + "address": { + "type": "string", + "maxLength": 128, + "description": "The wallet address. Alias: `walletAddress`." + }, + "address_hash": { + "type": "string", + "description": "SHA-256 of the lowercased address, as 64 hex characters or 44 base64 characters. Send it alone to register a wallet without disclosing its address; sent with `address`, it must be that address's hash. Alias: `walletAddressHash`." + }, + "chain": { + "type": "string", + "maxLength": 32 + }, + "memo": { + "type": "string", + "maxLength": 256, + "description": "The destination tag or memo. XRP: a destination tag, a whole number from 0 to 4294967295 (a JSON number is accepted). XLM: a text memo of up to 28 bytes, a 64-bit id or a 32-byte hash in hex. EOS: up to 256 bytes. ATOM: up to 256 characters. HBAR: up to 100 bytes. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin and Lightning wallets take no memo: one there is a `400`." + }, + "holder_name": { + "type": "string", + "maxLength": 255 + }, + "holder_vendor_data": { + "type": "string", + "maxLength": 255, + "description": "Your internal identifier for the holder. Alias: `externalUserId`." + }, + "entity_type": { "type": "string", "enum": [ - "service_id_verification", - "service_liveness_face_match", - "service_aml_screening", - "service_kyb_registries", - "service_database_validation", - "service_phone_delivery", - "service_email_delivery", - "service_transaction_monitoring" + "individual", + "company" ], - "description": "Stable service key. Match on this, never on the display name. `service_id_verification`: ID verification, `service_liveness_face_match`: Liveness and face match, `service_aml_screening`: AML screening, `service_kyb_registries`: KYB registries, `service_database_validation`: Database validation, `service_phone_delivery`: Phone verification delivery, `service_email_delivery`: Email verification delivery, `service_transaction_monitoring`: Transaction monitoring.", - "example": "service_database_validation" + "default": "individual" }, - "name": { + "label": { "type": "string", - "description": "English display name of the service.", - "example": "Database validation" + "maxLength": 255 }, - "status": { + "owner_type": { "type": "string", "enum": [ - "operational", - "degraded", - "down" + "customer", + "internal", + "vasp" ], - "description": "`operational` when no incident is ongoing for the service, otherwise the worst state of its ongoing incidents.", - "example": "degraded" + "default": "customer" + }, + "travel_address": { + "type": "string", + "maxLength": 512 + }, + "self_declared": { + "type": "boolean", + "default": false, + "description": "Create the entry already verified through a self-declaration, when your settings allow it." } } }, - "ServiceStatusIncident": { + "WalletAddressImportReport": { "type": "object", - "required": [ - "id", - "service", - "service_name", - "state", - "status", - "title", - "body", - "affected", - "country_name", - "started_at", - "resolved_at", - "duration_minutes" - ], + "description": "What happened to each row of an import, in the order sent.", "properties": { - "id": { - "type": "string", - "format": "uuid", - "description": "Incident ID.", - "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + "total": { + "type": "integer" }, - "service": { - "type": "string", - "enum": [ - "service_id_verification", - "service_liveness_face_match", - "service_aml_screening", - "service_kyb_registries", - "service_database_validation", - "service_phone_delivery", - "service_email_delivery", - "service_transaction_monitoring" - ], - "description": "Key of the affected service (see `services[].key`).", - "example": "service_database_validation" + "created": { + "type": "integer" }, - "service_name": { - "type": "string", - "description": "English display name of the affected service.", - "example": "Database validation" + "existing": { + "type": "integer" }, - "state": { + "duplicate": { + "type": "integer" + }, + "failed": { + "type": "integer" + }, + "rows": { + "type": "array", + "items": { + "type": "object", + "properties": { + "row": { + "type": "integer", + "description": "The row's number, from 1." + }, + "status": { + "type": "string", + "enum": [ + "created", + "existing", + "duplicate", + "failed" + ], + "description": "`created`: added to the book. `existing`: the wallet is already in the book and was left untouched. `duplicate`: repeats an earlier row of this import. `failed`: see `errors`." + }, + "entry_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "The address-book entry the row created or found." + }, + "errors": { + "type": "object", + "description": "Field errors of a `failed` row; empty otherwise." + }, + "duplicate_of_row": { + "type": "integer", + "nullable": true, + "description": "On a `duplicate` row, the row it repeats." + } + } + } + } + } + }, + "TravelRuleCounterpartyContact": { + "type": "object", + "description": "A compliance address the EMAIL rail writes to for one directory entry.", + "properties": { + "uuid": { "type": "string", - "enum": [ - "degraded", - "down" - ], - "description": "How the service is affected. A resolved incident keeps the last state it had.", - "example": "degraded" + "format": "uuid" }, - "status": { + "counterparty": { "type": "string", - "enum": [ - "ongoing", - "resolved" - ], - "description": "`ongoing` until the service recovers, then `resolved`.", - "example": "ongoing" + "format": "uuid", + "description": "The directory entry's `id`, as GET /v3/travel-rule/vasps/ shows it." }, - "title": { + "counterparty_name": { + "type": "string" + }, + "email": { "type": "string", - "description": "English headline. To translate it, build your own text from `service`, `state` and `country_name`.", - "example": "Database validation is degraded in Brazil." + "format": "email" }, - "body": { + "name": { "type": "string", - "description": "English detail line: since when checks may be slow or fail, or when it recovered.", - "example": "Checks against Brazil (CPF) may be slow or fail since 08:55 UTC." + "description": "Optional label, for example the team name." }, - "affected": { + "source": { "type": "string", - "description": "Countries or registries affected, for example `Brazil (CPF)`. Empty when the incident is not tied to a country or registry.", - "example": "Brazil (CPF)" + "enum": [ + "staff", + "application", + "learned" + ], + "description": "staff: curated by Didit. learned: an address at one of the VASP's own domains that answered a request through its response link. application: added by your application." }, - "country_name": { + "scope": { "type": "string", - "description": "Country affected, in English. Empty when the incident is not tied to a country.", - "example": "Brazil" + "enum": [ + "platform", + "application" + ], + "description": "platform: curated by Didit or learned from a verified answer, used for every Didit customer, read-only for you. application: private to your application." }, - "started_at": { + "created_by": { "type": "string", - "format": "date-time", - "description": "When the incident started (ISO 8601, UTC).", - "example": "2026-10-13T08:55:00Z" + "description": "Empty for platform contacts and for contacts an API key added." }, - "resolved_at": { + "verified_at": { "type": "string", "format": "date-time", "nullable": true, - "description": "When the service recovered (ISO 8601, UTC). `null` while the incident is ongoing." + "description": "When this address last answered a request through its response link." }, - "duration_minutes": { - "type": "integer", - "nullable": true, - "description": "Whole minutes from `started_at` to `resolved_at`. `null` while the incident is ongoing." - } - } - }, - "TravelRuleJoinInvitation": { - "type": "object", - "description": "What the join page shows before anything is typed.", - "properties": { - "email": { - "type": "string", - "format": "email", - "description": "The address the invitation went to." + "is_invalid": { + "type": "boolean", + "description": "true once the address bounced or complained; the EMAIL rail skips it." }, - "vasp_name": { - "type": "string" + "invalid_reason": { + "type": "string", + "enum": [ + "", + "hard_bounce", + "soft_bounce", + "spam_complaint", + "suppressed" + ] }, - "source": { + "invalid_detail": { "type": "string", - "description": "Where the invitation came from, for example `pickup`." + "description": "The receiving mail server's reason, when it gave one." }, - "expires_at": { + "invalid_at": { "type": "string", "format": "date-time", "nullable": true }, - "prefill": { - "type": "object", - "properties": { - "vasp_id": { - "type": "string", - "format": "uuid", - "nullable": true - }, - "legal_name": { - "type": "string" - }, - "lei": { - "type": "string" - }, - "jurisdiction": { - "type": "string" - }, - "domains": { - "type": "array", - "items": { - "type": "string" - } - } - } + "created_at": { + "type": "string", + "format": "date-time" } } }, - "TravelRuleJoinRegisterRequest": { + "TravelRuleCounterpartyContactCreate": { "type": "object", "required": [ - "email", - "password" + "counterparty", + "email" ], "properties": { - "email": { + "counterparty": { "type": "string", - "format": "email", - "maxLength": 254, - "description": "Must be the address the invitation went to." + "format": "uuid", + "description": "The directory entry's `id`." }, - "password": { - "type": "string", - "minLength": 8, - "maxLength": 128 - } - } - }, - "TravelRuleJoinVerifyRequest": { - "type": "object", - "required": [ - "email", - "code" - ], - "properties": { "email": { "type": "string", "format": "email", "maxLength": 254 }, - "code": { + "name": { "type": "string", - "minLength": 6, - "maxLength": 6, - "description": "The 6-character code emailed after registering." + "description": "Optional label.", + "maxLength": 255 } } }, - "TravelRuleJoinCredentials": { + "TravelRuleNameMatch": { "type": "object", - "description": "The new free organization and the credentials its application calls the API with.", + "nullable": true, + "description": "The name comparison that decided the transfer, or null until one ran. While the parties are masked, and on the other customer's copy of an INTERNAL exchange, `transfer_name`, `compared_name`, `matched_names` and `mismatched_names` are hidden. `score` and `matched` can disagree: `matched` follows the strictness, `score` is the similarity of the two full names.", "properties": { - "organization": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - } - } - }, - "application": { - "type": "object", - "properties": { - "uuid": { - "type": "string", - "format": "uuid" - } - } + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "description": "Similarity of the two full names, 0 to 100. 0 when either name is blank." }, - "client_id": { - "type": "string" + "matched": { + "type": "boolean", + "description": "Whether the names satisfy `strictness`. The transfer's outcome follows `data_match`, which compares every field, so a transfer can be COUNTERPARTY_MISMATCHED_DATA while this is true." }, - "api_key": { - "type": "string", - "description": "Send as the `x-api-key` header on the workspace endpoints." - } - } - }, - "TravelRuleWorkspaceClaimRequest": { - "type": "object", - "required": [ - "vasp_id" - ], - "properties": { - "vasp_id": { - "type": "string", - "format": "uuid", - "description": "The directory entry this workspace is. Read ids from `GET /v3/travel-rule/vasps/`." - } - } - }, - "TravelRuleWorkspaceDomainConfirmRequest": { - "type": "object", - "required": [ - "code" - ], - "properties": { - "code": { + "method": { "type": "string", - "minLength": 6, - "maxLength": 6 - } - } - }, - "TravelRuleWorkspaceBillingRequest": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true, - "description": "Only `true` is accepted: outbound billing cannot be turned back off through the API." - } - } - }, - "TravelRuleWorkspaceDomainCodeResponse": { - "type": "object", - "properties": { - "domain": { - "type": "string" + "enum": [ + "none", + "exact_token", + "token_subset", + "token_containment", + "sequence_ratio" + ], + "description": "How `matched` was decided: none (`NONE`), exact_token (`STRICT`), token_subset (`DEFAULT`), token_containment (`CONTAINS`) or sequence_ratio (`FUZZY`)." }, - "status": { + "strictness": { "type": "string", "enum": [ - "unverified", - "code_sent", - "verified" + "NONE", + "STRICT", + "CONTAINS", + "DEFAULT", + "FUZZY" ] }, - "txt": { - "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord" - } - } - }, - "TravelRuleWorkspaceTxtRecord": { - "type": "object", - "description": "The TXT record to publish for the DNS proof. Empty until a proof has been started.", - "properties": { - "host": { + "compared_with": { "type": "string", - "example": "didit-tr-verify.example.com" + "enum": [ + "wallet_holder", + "counterparty_vasp" + ], + "description": "wallet_holder: the holder recorded for the wallet. counterparty_vasp: the name the counterparty answered on the email response page, or the Didit Test VASP's answer in sandbox." }, - "value": { - "type": "string" + "transfer_name": { + "type": "string", + "description": "The name on the transfer." + }, + "compared_name": { + "type": "string", + "description": "The name it was compared with." + }, + "matched_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Words of `transfer_name` found in `compared_name`." + }, + "mismatched_names": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Words of `transfer_name` missing from `compared_name`, then words of `compared_name` missing from `transfer_name`." } } }, - "TravelRuleWorkspace": { + "TravelRuleTransferRow": { "type": "object", - "description": "The free Travel Rule workspace of an application that joined free.", + "description": "One Travel Rule transfer as the transfers list shows it: VASP names, wallets and memos only, never the originator or beneficiary person data.", "properties": { - "joined_free": { - "type": "boolean" - }, - "work_email": { + "id": { "type": "string", - "format": "email" + "format": "uuid", + "description": "The transfer's id." }, - "joined_at": { + "transaction_id": { "type": "string", - "format": "date-time", - "nullable": true - }, - "claim": { - "type": "object", - "properties": { - "status": { - "type": "string", - "enum": [ - "unclaimed", - "pending_review", - "claimed", - "rejected" - ] - }, - "proved_by_domain": { - "type": "boolean" - }, - "claimed_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "reviewed_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "review_note": { - "type": "string" - }, - "vasp_id": { - "type": "string", - "format": "uuid", - "nullable": true - }, - "vasp_name": { - "type": "string" - } - } - }, - "prefill": { - "type": "object", - "description": "Profile values taken from the directory entry: `vasp_id`, `legal_name`, `lei`, `jurisdiction`, `compliance_email`, `domains`. Nothing is written until the claim is made." - }, - "domain": { - "type": "object", - "properties": { - "domain": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "unverified", - "code_sent", - "verified" - ] - }, - "verified_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "txt": { - "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord" - } - } - }, - "billing_enabled": { - "type": "boolean", - "description": "Receiving Travel Rule data is free. Sending is billed only after billing is enabled." + "format": "uuid", + "description": "The Didit transaction the transfer belongs to." }, - "billing_enabled_at": { + "txn_id": { "type": "string", - "format": "date-time", - "nullable": true + "nullable": true, + "description": "Your own id for the transaction. Transfers Didit books for you, such as a Didit Test VASP inbound transfer, carry a generated one." }, - "didit_network": { - "type": "object", - "description": "Whether the Didit network lists this VASP and, when not, each condition it still misses." + "txn_date": { + "type": "string", + "format": "date-time" }, - "settings": { - "$ref": "#/components/schemas/TravelRuleSettingsDetail" - } - } - }, - "InvestigatorDecision": { - "type": "object", - "description": "How the item left the Investigator queue. `decided_by`, `original_outcome` and `overrides` are returned by the accept and override endpoints and the report; the `investigator` block of a session decision carries the other fields.", - "properties": { - "outcome": { + "kind": { "type": "string", "enum": [ - "accepted", - "edited", - "overridden", - "decided_elsewhere", - "automated" + "withdrawal", + "deposit", + "message" ], - "description": "`accepted` or `edited` took the recommendation (`edited` with a rewritten narrative), `overridden` took another action, `decided_elsewhere` is a decision taken outside the Investigator while the report was open, `automated` is a decision the Investigator took on its own." + "description": "withdrawal: outbound. message: an inbound transfer a rail created from a counterparty's message (a TRP inquiry, the INTERNAL inbound leg, or a GTR, VerifyVASP or Sygna Bridge message). deposit: any other inbound transfer." }, - "action": { + "direction": { "type": "string", "enum": [ - "approve", - "decline", - "escalate", - "request" + "INBOUND", + "OUTBOUND" ] }, - "actor_email": { + "status": { "type": "string", - "nullable": true + "enum": [ + "AWAITING_COUNTERPARTY", + "ON_HOLD", + "COMPLETED", + "FINISHED", + "CANCELLED", + "EXPIRED", + "COUNTERPARTY_MISMATCHED_DATA", + "COUNTERPARTY_VASP_NOT_FOUND", + "COUNTERPARTY_VASP_NOT_REACHABLE", + "UNCONFIRMED_OWNERSHIP", + "COUNTERPARTY_VASP_GENERAL_DECLINE", + "NOT_ENOUGH_COUNTERPARTY_DATA", + "NOT_APPLICABLE" + ] }, - "actor_name": { + "reason": { "type": "string", - "nullable": true + "description": "Why a `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE` transfer is stuck, the same value as the transfer's own `reason`, so the list tells a bounced compliance email from a counterparty with no route without opening each transfer. `\"\"` for any other status. See [Why a transfer is stuck](/transaction-monitoring/travel-rule#why-a-transfer-is-stuck)." }, - "override_category": { + "rail": { "type": "string", + "nullable": true, "enum": [ - "missing_context", - "needs_information", - "policy_differs", - "evidence_misread", - "other", - "" - ], - "nullable": true + "INTERNAL", + "TRP", + "GTR", + "TRUST", + "VERIFYVASP", + "SYGNA", + "EMAIL", + "TEST_VASP", + null + ] }, - "override_reason": { + "asset": { "type": "string", - "nullable": true + "description": "The transaction's currency." }, - "final_status": { + "amount": { "type": "string", - "description": "The item's status after the decision." + "description": "The amount as a plain decimal, for example \"1.25\"." }, - "agreed": { - "type": "boolean", - "description": "Whether the decision matched the recommendation.", - "nullable": true + "originator_vasp": { + "type": "string", + "description": "Outbound: your VASP's legal name. Inbound: the counterparty's name, from its directory entry, the Didit network member, the TRP sender, the Didit Test VASP, or the name the transfer declared. Empty when none is known." }, - "decided_at": { + "beneficiary_vasp": { "type": "string", - "format": "date-time" + "description": "Outbound: the counterparty's name, worked out the same way. Inbound: your VASP's legal name." }, - "billed": { - "type": "boolean", - "description": "The review was charged." + "originator_wallet": { + "type": "string" }, - "decided_by": { + "beneficiary_wallet": { + "type": "string" + }, + "originator_memo": { + "type": "string", + "description": "Memo or destination tag, empty on chains without one." + }, + "beneficiary_memo": { + "type": "string" + }, + "originator_wallet_type": { "type": "string", "enum": [ - "investigator", - "member" + "vasp", + "self_hosted", + "own" + ], + "description": "vasp, self_hosted (declared unhosted) or own (a wallet your address book records as yours). Your own side is always vasp." + }, + "beneficiary_wallet_type": { + "type": "string", + "enum": [ + "vasp", + "self_hosted", + "own" ] }, - "original_outcome": { + "matched_transaction_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "The other side of a deposit you matched to an announced transfer by hand." + }, + "deadline_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the transfer expires if it is still waiting on its counterparty. Set on every transfer you create with `POST /v3/transactions/` that needs an exchange, outbound or inbound. Null below the threshold, on a Lightning payment the Travel Rule does not apply to, and on inbound transfers Didit creates when a counterparty reaches you (an inbound TRP inquiry, a network message or the INTERNAL inbound leg)." + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "BankAccountCheckHolder": { + "description": "The name the account is checked against. Send exactly one of `full_name` and `business_name`.", + "oneOf": [ + { + "$ref": "#/components/schemas/BankAccountCheckPersonHolder" + }, + { + "$ref": "#/components/schemas/BankAccountCheckBusinessHolder" + } + ] + }, + "BankAccountCheckRequest": { + "type": "object", + "required": [ + "country", + "account", + "holder" + ], + "properties": { + "country": { + "type": "string", + "minLength": 3, + "maxLength": 3, + "description": "The account's country, as an ISO 3166-1 alpha-3 code, for example `GBR`. Lowercase is accepted.", + "example": "GBR" + }, + "account": { "type": "object", - "description": "The decision the Investigator took on its own, unchanged by later overrides. Null for a decision the team took.", + "description": "The account the way its country writes it: an `iban`, or an `account_number` with the bank or branch code the country needs (`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code` or `bic`). Mexico takes a `clabe` and Argentina a `cbu_cvu`, which already name the bank. A business account adds a `registration_id` where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a `400` that names it.", "properties": { - "action": { - "type": "string" + "iban": { + "type": "string", + "maxLength": 64, + "description": "The IBAN, in a country that uses IBANs. It must belong to `country`." }, - "final_status": { - "type": "string" + "account_number": { + "type": "string", + "maxLength": 64, + "description": "The account number, in a country that writes the account with a separate bank or branch code." }, - "decided_at": { + "sort_code": { "type": "string", - "format": "date-time" + "maxLength": 64, + "description": "United Kingdom: the 6-digit sort code." + }, + "routing_number": { + "type": "string", + "maxLength": 64, + "description": "United States: the 9-digit ABA routing number." + }, + "transit_institution": { + "type": "string", + "maxLength": 64, + "description": "Canada: the 8-digit transit and institution number." + }, + "bsb": { + "type": "string", + "maxLength": 64, + "description": "Australia: the 6-digit BSB." + }, + "ifsc": { + "type": "string", + "maxLength": 64, + "description": "India: the 11-character IFSC." + }, + "bank_code": { + "type": "string", + "maxLength": 64, + "description": "The bank's code, where the country needs one, for example in Nigeria." + }, + "bic": { + "type": "string", + "maxLength": 64, + "description": "The bank's BIC, where the country's check asks for one." + }, + "clabe": { + "type": "string", + "maxLength": 64, + "description": "Mexico: the 18-digit CLABE. It already names the bank." + }, + "cbu_cvu": { + "type": "string", + "maxLength": 64, + "description": "Argentina: the 22-digit CBU or CVU. It already names the bank." + }, + "registration_id": { + "type": "string", + "maxLength": 64, + "description": "A business account's registration number, where the country asks for one." } }, - "nullable": true - }, - "overrides": { - "type": "array", - "description": "Every override of a decision the Investigator took on its own, oldest first.", - "items": { - "type": "object", - "properties": { - "action": { - "type": "string" - }, - "actor_email": { - "type": "string", - "nullable": true - }, - "actor_name": { - "type": "string", - "nullable": true - }, - "override_category": { - "type": "string" - }, - "override_reason": { - "type": "string" - }, - "previous_status": { - "type": "string" - }, - "final_status": { - "type": "string" - }, - "agreed": { - "type": "boolean", - "nullable": true - }, - "overridden_at": { - "type": "string", - "format": "date-time" - } - } + "additionalProperties": { + "type": "string", + "maxLength": 64 + }, + "example": { + "sort_code": "20-45-67", + "account_number": "31926819" } + }, + "holder": { + "$ref": "#/components/schemas/BankAccountCheckHolder" + }, + "vendor_data": { + "type": "string", + "nullable": true, + "description": "Your own reference for this check, returned unchanged.", + "example": "payout_20481" + }, + "consent": { + "type": "boolean", + "default": false, + "description": "Set to `true` when the account holder has explicitly consented to this check. Required in the countries whose account check needs that consent: without it the check is refused with a `400` whose `field` is `consent` and whose `reason` is `required`, and nothing is billed. Elsewhere it is optional, and Didit records it with the check's charge when you send it.", + "example": true } } }, - "InvestigatorBlock": { + "BankAccountCheckResponse": { "type": "object", - "nullable": true, - "description": "The item's latest Investigator review, or null when it never had one. Carried by the V3 session and business session decision (and so by `status.updated` webhooks).", + "required": [ + "request_id", + "result", + "holder_name", + "account", + "vendor_data", + "created_at" + ], "properties": { - "run_id": { + "request_id": { "type": "string", - "format": "uuid" + "format": "uuid", + "description": "The ID of this check." }, - "status": { + "result": { "type": "string", "enum": [ - "running", - "completed", - "failed" - ] + "match", + "close_match", + "no_match", + "cannot_verify" + ], + "description": "`match`: the bank holds the account under the name you sent. `close_match`: under a close name, for example a missing middle name or a typo. `no_match`: under another name, or there is no such account. `cannot_verify`: the bank answered without comparing the name, for example for a blocked or closed account." }, - "stage": { + "holder_name": { "type": "string", - "enum": [ - "shadow", - "live" - ] + "nullable": true, + "description": "Only on a `close_match`, and only when the bank returned it: the name on the account, as the bank holds it. `null` otherwise." }, - "queue": { + "account": { "type": "string", - "enum": [ - "kyc", - "kyb", - "aml", - "transactions", - "cases" - ] - }, - "is_open": { - "type": "boolean" + "description": "The account, masked to its last 4 characters." }, - "recommendation": { + "vendor_data": { "type": "string", - "enum": [ - "approve", - "decline", - "escalate", - "request" - ], - "nullable": true + "nullable": true, + "description": "Your own reference, as you sent it." }, - "recommendation_detail": { + "created_at": { "type": "string", - "nullable": true - }, - "confidence": { + "format": "date-time", + "description": "When the check ran, in UTC." + } + } + }, + "BankAccountCheckError": { + "type": "object", + "required": [ + "detail" + ], + "properties": { + "detail": { "type": "string", - "enum": [ - "high", - "moderate", - "low" - ], - "nullable": true + "description": "What went wrong, in English." }, - "summary": { + "code": { "type": "string", - "nullable": true - }, - "ready_to_accept": { - "type": "boolean" + "description": "A stable code to branch on. Absent on `401` and `403`." }, - "prepared_at": { + "field": { "type": "string", - "format": "date-time", - "nullable": true - }, - "automated": { - "type": "boolean", - "description": "The Investigator decided on its own, even if the decision was later overridden." + "description": "`400` only: the body field to correct, as a dotted path, for example `account.sort_code`." }, - "decided_by": { + "reason": { "type": "string", "enum": [ - "investigator", - "member" - ], - "nullable": true - }, - "decision": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/InvestigatorDecision" - } + "required", + "length", + "format", + "checksum", + "country_mismatch", + "rejected" ], - "type": "object" + "description": "`400` only: why the field was refused. `required`, `length`, `format`, `checksum` and `country_mismatch` (an IBAN of another country) are Didit's own checks; `rejected` means the bank refused the account as sent." } } }, - "InvestigatorQueueRow": { + "BankVerificationResult": { "type": "object", + "description": "One Bank Verification step's result, for User and Business Verification. `method` says how the account was verified, and `none` that the person continued without a bank before any attempt was evaluated. `continued_without_bank` says the person continued without a bank, also after an evaluated attempt. See [Bank verification methods](/core-technology/bank-verification/verification-methods) and [When the person cannot verify their bank](/core-technology/bank-verification/fallbacks).", "properties": { - "run_id": { - "type": "string", - "format": "uuid" + "schema_version": { + "type": "integer", + "description": "Version of this result shape. `1` today." }, - "kind": { + "bank_verification_id": { "type": "string", - "enum": [ - "session", - "business_session", - "transaction", - "case" - ] + "format": "uuid", + "description": "The ID of this result." }, - "queue": { + "node_id": { "type": "string", - "enum": [ - "kyc", - "kyb", - "aml", - "transactions", - "cases" - ] + "description": "The workflow node this result belongs to." }, - "stage": { + "status": { "type": "string", "enum": [ - "shadow", - "live" - ] + "Not Finished", + "Approved", + "Declined", + "In Review", + "Expired" + ], + "description": "The step's verdict, after its actions and status rules." }, - "subject": { - "type": "object", - "description": "The item under review: `id`, `number`, `status`, `name` and, depending on the kind, `country`, `workflow`, `vendor_data`, `txn_id`, `amount`, `currency`, `direction`, `title` or `priority`.", - "additionalProperties": true + "original_status": { + "type": "string", + "nullable": true, + "description": "The first verdict the step reached, before any later change such as a manual review." }, - "recommendation": { + "method": { "type": "string", + "nullable": true, "enum": [ - "approve", - "decline", - "escalate", - "request" - ] + "open_banking", + "account_lookup", + "microdeposits", + "statement", + "none" + ], + "description": "How the account was verified: `open_banking` (bank sign-in: the person signed in at their bank), `account_lookup` (account check: the person typed the account details and the bank confirmed the name), `microdeposits` or `statement` (a statement upload). `none` when the person continued without a bank before any attempt was evaluated, so no account was verified. After an evaluated attempt, it stays the method of that attempt. `null` until an account is evaluated, and when the workflow narrows the data it returns. Workflow rules read the same value as `bank.method`." }, - "recommendation_detail": { - "type": "string" + "provider": { + "type": "string", + "nullable": true, + "description": "The key of the route that ran the connection. Read `method`, not this key, to tell how the account was verified." }, - "confidence": { + "credential_source": { "type": "string", + "nullable": true, "enum": [ - "high", - "moderate", - "low" - ] - }, - "summary": { - "type": "string" - }, - "sources_count": { - "type": "integer" - }, - "ready_to_accept": { - "type": "boolean" - }, - "guardrails": { - "description": "The locked guardrails that hold this item, if any." + "native", + "byok" + ], + "description": "`native`: Didit's own route, billed to your Didit balance. `byok`: a marketplace provider you connected with your own credentials." }, - "waiting_since": { - "type": "string", - "format": "date-time", - "nullable": true + "route": { + "type": "object", + "nullable": true, + "description": "The route chosen before consent. It never changes afterwards.", + "properties": { + "provider_key": { + "type": "string", + "nullable": true, + "description": "The route's key." + }, + "credential_source": { + "type": "string", + "enum": [ + "native", + "byok" + ] + }, + "is_fallback": { + "type": "boolean", + "description": "Whether Didit's own route stood in for a marketplace provider that could not connect." + }, + "provider_connection_id": { + "type": "string", + "nullable": true, + "description": "The marketplace connection used, for `byok`." + }, + "requested_scopes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The data the connection asked for, for example `ownership` or `balances`." + } + } }, - "due_at": { - "type": "string", - "format": "date-time", - "nullable": true + "connection": { + "type": "object", + "nullable": true, + "description": "The latest attempt's connection. `null` before the first attempt.", + "properties": { + "status": { + "type": "string", + "enum": [ + "pending", + "connected", + "cancelled", + "timeout", + "failed", + "unsupported", + "revoked", + "expired" + ] + }, + "institution_id": { + "type": "string", + "nullable": true, + "description": "The bank's ID. `null` for an account check, where no bank is picked." + }, + "institution_name": { + "type": "string", + "nullable": true, + "description": "The bank's name. `null` for an account check." + }, + "institution_country": { + "type": "string", + "nullable": true, + "description": "The account's country, ISO 3166-1 alpha-3." + }, + "oauth": { + "type": "boolean", + "nullable": true, + "description": "Whether the bank sign-in ran over OAuth or app-to-app. `null` for an account check." + }, + "connected_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the connection succeeded." + }, + "consent_expires_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the bank consent ends, for bank sign-in." + }, + "last_refreshed_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the financial data was last read again." + }, + "attempts": { + "type": "integer", + "description": "The attempts the person spent on this step, every method together." + }, + "reason_code": { + "type": "string", + "nullable": true, + "description": "Why the connection is not simply `connected`, for example `USER_CANCELLED`, `INSTITUTION_DOWN`, `ACCOUNT_NOT_FOUND`, `REFERENCE_IDENTITY_MISSING` or `VERIFICATION_COMPLETED`." + } + } }, - "prepared_at": { - "type": "string", - "format": "date-time", - "nullable": true - } - } - }, - "InvestigatorRunDetail": { - "allOf": [ - { - "$ref": "#/components/schemas/InvestigatorQueueRow" + "account": { + "type": "object", + "nullable": true, + "description": "The evaluated account. `null` until an account is evaluated.", + "properties": { + "account_id_masked": { + "type": "string", + "nullable": true, + "description": "The account number, masked." + }, + "iban_masked": { + "type": "string", + "nullable": true, + "description": "The IBAN, masked." + }, + "sort_code": { + "type": "string", + "nullable": true, + "description": "The sort code, in the United Kingdom." + }, + "routing_number_masked": { + "type": "string", + "nullable": true, + "description": "The routing number, masked." + }, + "type": { + "type": "string", + "nullable": true, + "enum": [ + "checking", + "current", + "savings", + "business", + "other" + ] + }, + "subtype": { + "type": "string", + "nullable": true, + "description": "The bank's own account subtype." + }, + "currency": { + "type": "string", + "nullable": true, + "description": "ISO 4217 currency of the account." + }, + "holder_type": { + "type": "string", + "nullable": true, + "enum": [ + "person", + "business", + "unknown" + ] + }, + "holders_count": { + "type": "integer", + "nullable": true + }, + "is_joint": { + "type": "boolean", + "nullable": true + }, + "is_business": { + "type": "boolean", + "nullable": true + } + } }, - { + "ownership": { "type": "object", + "nullable": true, + "description": "How the account holder compared with the verified identity. `null` until an account is evaluated.", "properties": { - "status": { - "type": "string" + "result": { + "type": "string", + "enum": [ + "match", + "partial_match", + "no_match", + "unknown", + "not_verifiable" + ], + "description": "`partial_match` is a close match. `not_verifiable`: the bank answered with no holder to compare. `unknown`: the evidence could not be read, or there was no identity to compare." }, - "is_open": { - "type": "boolean" + "reference_identity_source": { + "type": "string", + "nullable": true, + "description": "The step whose identity the holder was compared against: `kyc`, `database_validation`, `expected_details`, `questionnaire`, `document_ai` or `kyb`." }, - "lookups": { + "name_score": { "type": "integer", - "description": "How many sections and linked records it read." + "minimum": 0, + "maximum": 100, + "nullable": true, + "description": "Didit's holder name score." }, - "duration_ms": { + "provider_name_score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "nullable": true, + "description": "The bank's own holder name score, when it returned one." + }, + "address_score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "nullable": true, + "description": "The holder address score, when address matching ran." + }, + "email_score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "nullable": true, + "description": "The holder email score, when email matching ran." + }, + "phone_score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "nullable": true, + "description": "The holder phone score, when phone matching ran." + }, + "dob_score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "nullable": true, + "description": "The holder date of birth score, when the bank shared one." + }, + "close_match": { + "type": "boolean", + "nullable": true, + "description": "Whether the name landed in the close-match band." + }, + "holder_confirmation": { + "type": "string", + "nullable": true, + "enum": [ + "pending", + "confirmed", + "rejected" + ], + "description": "The person's answer when asked to confirm a close-match name. `null` when never asked." + }, + "method": { + "type": "string", + "nullable": true, + "enum": [ + "exact", + "token_set", + "nickname", + "transliteration", + "fuzzy", + "provider_only", + "microdeposits" + ], + "description": "Which name comparison produced the score. This is not the verification method: read the top-level `method` for that." + }, + "matched_holder_index": { "type": "integer", "nullable": true }, - "agent_version": { - "type": "string" + "holders": { + "type": "array", + "items": { + "type": "object" + }, + "description": "Each holder the bank listed, with its scores." }, - "prepared_before_opened": { + "owner_identity_available": { "type": "boolean", "nullable": true }, - "report": { + "evidence_freshness": { + "type": "string", + "nullable": true, + "enum": [ + "live", + "cached", + "refreshed" + ] + }, + "evaluated_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the verdict was computed." + } + } + }, + "financial_data": { + "type": "object", + "description": "The financial data the step read. Only bank sign-in reads it.", + "properties": { + "balances": { "type": "object", - "additionalProperties": true, - "description": "The report: reasoning, evidence points with their verdict (`ok`, `risk`, `look`, `explained`, `context`) and cited sources, screening hit verdicts (`same`, `not_same`, `unclear`) and suggested next steps." + "nullable": true, + "description": "With the `balances` scope." }, - "trail": { - "description": "What I checked: the overview, sections and records it read, in order." + "transactions": { + "type": "object", + "nullable": true, + "description": "With the `transactions` scope." }, - "decision": { + "income": { + "type": "object", "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/InvestigatorDecision" - } - ], - "type": "object" + "description": "With the `income` scope." }, - "autonomy": { + "categorization": { "type": "object", - "additionalProperties": true, - "description": "What autonomy made of the report (`result`, `reason`, `tier`, `policy_version`, `rule`, `agreement`, `decisions`, `threshold`, `at`). Null when the queue is not automated.", - "nullable": true + "nullable": true, + "description": "Didit's categorization of the transactions read. `null` without them." + }, + "not_collected": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "balances", + "income", + "transactions" + ] + }, + "description": "The data the step asked for that the method which verified the account does not collect. Balances, transactions and income come from bank sign-in only, so an account verified by account check lists them here. Never a failure. Empty otherwise." } } - } - ] - }, - "InvestigatorAcceptRequest": { - "type": "object", - "properties": { - "narrative": { - "type": "string", - "maxLength": 4000, - "description": "A rewritten narrative. Sending one records the decision as edited and accepted." }, - "send_email": { + "billing": { + "type": "object", + "nullable": true, + "properties": { + "route": { + "type": "string", + "enum": [ + "native", + "byok" + ] + }, + "billed": { + "type": "boolean" + }, + "marketplace_fee": { + "type": "string", + "nullable": true, + "description": "The marketplace platform fee charged, for `byok`." + }, + "usage_type": { + "type": "string", + "nullable": true, + "description": "The usage line the charge was booked on: `bank_verification` for a bank sign-in or an account check, `bank_statement_upload` for a statement upload with no charged bank attempt before it, and `bank_byok_fee` for the marketplace fee on your own provider. `null` when nothing was billed." + } + } + }, + "reference_identity": { + "type": "object", + "nullable": true, + "description": "The identity the holder was compared against, with its source." + }, + "signals": { + "type": "object", + "nullable": true, + "description": "Account signals read from the transaction history, when the step read one." + }, + "connection_abandoned": { "type": "boolean", - "default": false, - "description": "Email the person about the decision." + "nullable": true, + "description": "Whether the step ended without a match after the person left at their bank." }, - "email_address": { - "type": "string", - "format": "email", - "description": "Required when `send_email` is true." + "not_covered": { + "type": "boolean", + "nullable": true, + "description": "Whether the person's bank or country could not be reached on this step. Also `true` when the person continued without a bank because no method could verify their country or bank." }, - "email_language": { - "type": "string", - "default": "en", - "maxLength": 16 - } - } - }, - "InvestigatorOverrideRequest": { - "type": "object", - "required": [ - "action", - "category", - "reason" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "approve", - "decline", - "escalate", - "request" - ] + "continued_without_bank": { + "type": "boolean", + "description": "Whether the person left the step with **Continue without your bank**. `continuation` then says why. `method` is `none` when no attempt was evaluated before they continued. After an evaluated attempt, such as a holder that does not match, `method` stays the method of that attempt and its verdict and reason codes stand. Returned even when the workflow narrows the data it returns." }, - "category": { - "type": "string", - "enum": [ - "missing_context", - "needs_information", - "policy_differs", - "evidence_misread", - "other" - ] + "continuation": { + "type": "object", + "nullable": true, + "description": "How the person continued without a bank. `null` when they did not. When the workflow narrows the data it returns, `reason` is still returned and every other key is `null`.", + "properties": { + "reason": { + "type": "string", + "enum": [ + "no_route", + "institution_unsupported", + "attempts_exhausted", + "person_choice" + ], + "description": "Why, as Didit worked it out when the person continued: `no_route` (no bank sign-in or account check serves their country), `institution_unsupported` (the bank they picked cannot be used on this step), `attempts_exhausted` (every attempt was already spent and none was in progress), or `person_choice` (a way to verify was there and they chose to continue, also when their bank could not be reached right now). `no_route` and `institution_unsupported` follow `bank_unsupported_action`, `attempts_exhausted` follows `bank_attempts_exhausted_action`, and `person_choice` follows `bank_skipped_action`, unless an evaluated attempt already decided the step." + }, + "country": { + "type": "string", + "nullable": true, + "description": "The country the person was verifying in, ISO 3166-1 alpha-3. `null` when they continued before picking one." + }, + "offered": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "statement", + "microdeposits" + ] + }, + "nullable": true, + "description": "The other ways to verify that country offered the person when they continued, in the order it offered them: `statement` (a statement upload), then `microdeposits`. Empty when it offered none." + }, + "institution_id": { + "type": "string", + "nullable": true, + "description": "For `institution_unsupported`, the ID of the bank the person could not use: the bank they picked, or the bank their last attempt ended on. Didit takes it from its own list of banks, never from the person's device, so a bank that list does not have is `null`. `null` for every other reason." + }, + "institution_name": { + "type": "string", + "nullable": true, + "description": "For `institution_unsupported`, the name of that bank, from the same list as `institution_id`. `null` when that list does not have the bank, and for every other reason." + }, + "continued_at": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "When the person continued." + } + } }, - "reason": { + "evidence_purged_at": { "type": "string", - "minLength": 10, - "maxLength": 500 + "format": "date-time", + "nullable": true, + "description": "When the bank evidence was deleted under `bank_evidence_retention_days`. `null` otherwise." }, - "send_email": { - "type": "boolean", - "default": false, - "description": "Email the person about the decision." + "warnings": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Informational codes, for example `holder_declared`. A warning never changes the status on its own." }, - "email_address": { + "reason_codes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Why the verdict came out the way it did, for example `OWNER_NAME_PARTIAL`. Several may apply. `NOT_COVERED`: the person continued without a bank because no method could verify their country or bank. `SKIPPED`: the person chose to continue without a bank while a way to verify was there. Neither is added when an evaluated attempt already decided the step." + }, + "created_at": { "type": "string", - "format": "email", - "description": "Required when `send_email` is true." + "format": "date-time" }, - "email_language": { + "updated_at": { "type": "string", - "default": "en", - "maxLength": 16 + "format": "date-time" } } }, - "InvestigatorBatchAcceptRequest": { + "BankAccountCheckPersonHolder": { "type": "object", + "description": "The person who should hold the account.", "required": [ - "run_ids" + "full_name" ], "properties": { - "run_ids": { - "type": "array", - "minItems": 1, - "maxItems": 50, - "items": { - "type": "string", - "format": "uuid" - } + "full_name": { + "type": "string", + "maxLength": 255, + "description": "The full name of the person who should hold the account.", + "example": "Maria Oliveira" } } }, - "InvestigatorBatchAcceptResponse": { + "BankAccountCheckBusinessHolder": { "type": "object", + "description": "The company that should hold the account. Checks a business account.", + "required": [ + "business_name" + ], "properties": { - "accepted": { - "type": "integer" - }, - "skipped": { - "type": "integer" - }, - "results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "run_id": { - "type": "string", - "format": "uuid" - }, - "result": { - "type": "string", - "enum": [ - "accepted", - "skipped" - ] - }, - "reason": { - "type": "string", - "enum": [ - "not_found", - "forbidden", - "already_decided", - "not_ready", - "guardrail", - "invalid" - ] - }, - "detail": {}, - "action": { - "type": "string" - }, - "final_status": { - "type": "string" - } - } - } + "business_name": { + "type": "string", + "maxLength": 255, + "description": "The name of the company that should hold the account. Checks a business account." } } }, - "InvestigatorSettings": { + "BankVerificationPricing": { "type": "object", + "description": "Public Bank Verification list prices: the statement upload, the own provider key fee and each country's methods.", + "required": [ + "currency", + "statement_upload", + "own_provider_fee_usd", + "countries" + ], "properties": { - "stage": { + "currency": { "type": "string", "enum": [ - "none", - "shadow", - "live" - ] - }, - "stage_changed_at": { - "type": "string", - "format": "date-time", - "readOnly": true, - "nullable": true + "USD" + ], + "description": "Currency of every price in the response.", + "example": "USD" }, - "stage_changed_by": { - "type": "string", - "readOnly": true + "statement_upload": { + "$ref": "#/components/schemas/BankStatementUploadPricing" }, - "monthly_spend_limit": { + "own_provider_fee_usd": { "type": "string", - "format": "decimal", - "description": "Monthly limit in your billing currency, 0.01 to 1,000,000. Null turns it off.", - "nullable": true + "description": "Fee for each billable ownership check on a route that uses your own provider contract instead of Didit's, charged whatever the result. A cancelled, timed out or abandoned connection is not billed. Decimal string with 4 decimals, in USD.", + "example": "0.0200" }, - "spend_limit": { + "countries": { "type": "object", - "readOnly": true, - "properties": { - "enabled": { - "type": "boolean" - }, - "limit": { - "type": "string", - "format": "decimal", - "nullable": true - }, - "spent": { - "type": "string", - "format": "decimal" - }, - "reviews": { - "type": "integer" - }, - "reserved": { - "type": "string", - "format": "decimal", - "description": "The price of every open live report, held back because accepting it charges it." - }, - "currency": { - "type": "string" - }, - "paused": { - "type": "boolean", - "description": "At the limit: no new review starts." - } + "description": "Every country, keyed by ISO 3166-1 alpha-3 code.", + "additionalProperties": { + "$ref": "#/components/schemas/BankVerificationPricingCountry" } } } }, - "TravelRuleUtxoEntry": { + "BankStatementUploadPricing": { "type": "object", - "description": "One input or output of a UTXO transaction, as the chain recorded it.", + "description": "How the bank statement upload is priced.", "required": [ - "address" + "price_usd", + "included_after_charged_bank_attempt", + "standalone_available" ], "properties": { - "address": { - "type": "string", - "maxLength": 128 - }, - "amount": { + "price_usd": { "type": "string", - "nullable": true, - "description": "Decimal string in the coin's own unit (BTC, not satoshis). Optional.", - "example": "0.0125" + "description": "Price of a statement upload after a charged bank attempt. Decimal string with 4 decimals, in USD.", + "example": "0.0000" }, - "txid": { - "type": "string", - "maxLength": 128, - "description": "Optional. The transaction an input spends." + "included_after_charged_bank_attempt": { + "type": "boolean", + "description": "`true` when the upload is included at no extra charge after a charged bank attempt in the same session.", + "example": true }, - "vout": { - "type": "integer", - "nullable": true, - "minimum": 0, - "description": "Optional. The output index an input spends." + "standalone_available": { + "type": "boolean", + "description": "`true` when a statement upload can run on its own, with no bank attempt first. `false` in production; sandbox sessions can test it without billing.", + "example": false } } }, - "TravelRuleUtxo": { + "BankVerificationPricingCountry": { "type": "object", - "description": "The inputs and outputs of a UTXO transfer (BTC, LTC, BCH, DOGE). Only accepted on those chains: on any other chain it is a `400`. From them Didit infers the originator wallet (the declared one, else the input address that contributed the most) and the beneficiary output (the declared one, else the only output that does not pay an input address back as change, else the one output paying the transfer amount). The result is on the transfer's `chain_details`.", + "description": "One country's Bank Verification methods and their list prices.", "required": [ - "outputs" + "name", + "methods" ], "properties": { - "inputs": { - "type": "array", - "maxItems": 1000, - "items": { - "$ref": "#/components/schemas/TravelRuleUtxoEntry" - }, - "description": "Optional. Without inputs no originator is inferred and no change output is recognised." + "name": { + "type": "string", + "description": "Country name in English.", + "example": "United Kingdom" }, - "outputs": { - "type": "array", - "minItems": 1, - "maxItems": 1000, - "items": { - "$ref": "#/components/schemas/TravelRuleUtxoEntry" - } + "methods": { + "$ref": "#/components/schemas/BankVerificationPricingMethods" } } }, - "TravelRuleChainSide": { + "BankVerificationPricingMethods": { "type": "object", - "description": "One side's wallet as Didit resolved it from the chain data.", + "description": "The two Bank Verification methods in a country.", + "required": [ + "open_banking", + "account_lookup" + ], "properties": { - "address": { - "type": "string", - "description": "The wallet. On a memo network the classic address (an XRP X-address is split into its classic address and its tag); on Lightning the payee node id or Lightning Address." - }, - "memo": { - "type": "string", - "description": "The destination tag or memo that is part of the wallet; `\"\"` for none." + "open_banking": { + "$ref": "#/components/schemas/BankSignInPricing" }, - "source": { - "type": "string", - "enum": [ - "declared", - "x_address", - "largest_input", - "only_non_change_output", - "amount_match", - "invoice_payee", - "updated" - ], - "description": "Where the wallet came from: `declared` (your request), `x_address` (split from an XRP X-address), `largest_input` (the UTXO input address that contributed the most), `only_non_change_output` (the only UTXO output that is not change), `amount_match` (the one UTXO output paying the transfer amount), `invoice_payee` (the payee a Lightning payment request names), `updated` (set later with `action: update_originator_wallet`)." + "account_lookup": { + "$ref": "#/components/schemas/BankAccountCheckPricing" } } }, - "TravelRuleChainDetails": { + "BankSignInPricing": { "type": "object", - "description": "How the transfer's chain names its two wallets, when that is more than one address paying another. Empty (`{}`) for an account-chain transfer (EVM, Solana, Tron), where the two addresses are the wallets. Matching, routing and the address book read the wallets from here first.", + "description": "Bank sign-in: the person signs in to their bank. Priced by market, the same for every bank in it.", + "required": [ + "available", + "market", + "price_usd", + "add_ons" + ], "properties": { - "chain": { - "type": "string", - "description": "Canonical chain, e.g. `BTC`, `XRP`, or `LIGHTNING` for a Lightning transfer." + "available": { + "type": "boolean", + "description": "`true` only where Didit serves bank sign-in in this country in production.", + "example": true }, - "shape": { + "market": { "type": "string", - "enum": [ - "utxo", - "memo", - "lightning" - ] - }, - "originator": { - "$ref": "#/components/schemas/TravelRuleChainSide" + "nullable": true, + "description": "The market whose price applies. `null` when not available.", + "example": "UK and EEA" }, - "beneficiary": { - "$ref": "#/components/schemas/TravelRuleChainSide" + "price_usd": { + "type": "string", + "nullable": true, + "description": "List price of one bank sign-in. `null` when not available. Decimal string with 4 decimals, in USD.", + "example": "0.7900" }, - "utxo": { + "add_ons": { "type": "object", - "description": "On a UTXO transfer: the inputs and outputs as stored (amounts as decimal strings) and which outputs Didit read as what.", + "description": "Add-ons priced in this country, each a decimal string with 4 decimals in USD, added to the bank sign-in price. Only the add-ons the country offers are listed; empty when bank sign-in is not available.", "properties": { - "inputs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TravelRuleUtxoEntry" - } - }, - "outputs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TravelRuleUtxoEntry" - } - }, - "change_output_indexes": { - "type": "array", - "items": { - "type": "integer" - }, - "description": "Outputs that pay an input address back." + "balance": { + "type": "string", + "description": "Account balance add-on.", + "example": "0.3500" }, - "beneficiary_output_index": { - "type": "integer", - "nullable": true, - "description": "The output that pays the beneficiary; null when none could be told apart." + "transactions": { + "type": "string", + "description": "Transactions add-on.", + "example": "1.3000" } } - }, - "lightning": { - "type": "object", - "description": "On a Lightning transfer: what the payment request says. Always `kind` (`bolt11`, `bolt12_offer`, `bolt12_invoice`, `bolt12_invoice_request`, `lnurl`, `lightning_address`, `node_id` or `unknown`); a BOLT11 invoice adds `network`, `payee_node_id`, `payment_hash`, `amount_msat`, `created_at` and `expires_at`; a BOLT12 string `blinded_paths` and `payee_node_id`; an LNURL or a Lightning Address its `domain`. Nothing is resolved over the network: the request is decoded only.", - "additionalProperties": true - }, - "warnings": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "declared_originator_not_an_input", - "declared_beneficiary_not_an_output", - "beneficiary_output_ambiguous", - "beneficiary_output_amount_differs" - ] - }, - "description": "UTXO inconsistencies worth a look: the declared originator is not an input, the declared beneficiary is not an output, no single beneficiary output could be told apart, or the beneficiary output pays a different amount than the transaction states." - }, - "not_applicable_reason": { - "type": "string", - "enum": [ - "LIGHTNING_NO_PAYEE_IDENTIFIER", - "LIGHTNING_BOLT12_BLINDED_PAYEE", - "LIGHTNING_LNURL_NAMES_NO_PAYEE" - ], - "description": "On an outbound Lightning transfer whose payment request names no payee: why the transfer is `NOT_APPLICABLE`. `LIGHTNING_NO_PAYEE_IDENTIFIER` (the request names no payee node, or could not be decoded), `LIGHTNING_BOLT12_BLINDED_PAYEE` (the offer hides its payee behind blinded paths), `LIGHTNING_LNURL_NAMES_NO_PAYEE` (an LNURL names a service, not a payee). The same code opens the transfer's last `timeline` entry." } } }, - "WalletAddressImportRow": { + "BankAccountCheckPricing": { "type": "object", - "description": "One wallet to import: by its `address`, its `address_hash`, or both. The camelCase forms of these fields are accepted too, as are `walletAddress`, `walletAddressHash`, `destinationTag` and `externalUserId`.", + "description": "Account check: the person types their account number and Didit checks it with the bank. Priced per country.", + "required": [ + "available", + "price_usd" + ], "properties": { - "address": { - "type": "string", - "maxLength": 128, - "description": "The wallet address. Alias: `walletAddress`." - }, - "address_hash": { - "type": "string", - "description": "SHA-256 of the lowercased address, as 64 hex characters or 44 base64 characters. Send it alone to register a wallet without disclosing its address; sent with `address`, it must be that address's hash. Alias: `walletAddressHash`." - }, - "chain": { - "type": "string", - "maxLength": 32 - }, - "memo": { - "type": "string", - "maxLength": 256, - "description": "The destination tag or memo. XRP: a destination tag, a whole number from 0 to 4294967295 (a JSON number is accepted). XLM: a text memo of up to 28 bytes, a 64-bit id or a 32-byte hash in hex. EOS: up to 256 bytes. ATOM: up to 256 characters. HBAR: up to 100 bytes. Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin and Lightning wallets take no memo: one there is a `400`." - }, - "holder_name": { - "type": "string", - "maxLength": 255 - }, - "holder_vendor_data": { - "type": "string", - "maxLength": 255, - "description": "Your internal identifier for the holder. Alias: `externalUserId`." - }, - "entity_type": { - "type": "string", - "enum": [ - "individual", - "company" - ], - "default": "individual" - }, - "label": { - "type": "string", - "maxLength": 255 - }, - "owner_type": { - "type": "string", - "enum": [ - "customer", - "internal", - "vasp" - ], - "default": "customer" + "available": { + "type": "boolean", + "description": "`true` only where Didit serves the account check in this country in production.", + "example": true }, - "travel_address": { + "price_usd": { "type": "string", - "maxLength": 512 - }, - "self_declared": { - "type": "boolean", - "default": false, - "description": "Create the entry already verified through a self-declaration, when your settings allow it." + "nullable": true, + "description": "List price of one account check the bank answers. `null` when not available. Decimal string with 4 decimals, in USD.", + "example": "0.4000" } } }, - "WalletAddressImportReport": { + "ImportProvider": { "type": "object", - "description": "What happened to each row of an import, in the order sent.", "properties": { - "total": { - "type": "integer" - }, - "created": { - "type": "integer" + "key": { + "type": "string", + "enum": [ + "sumsub", + "jumio", + "veriff", + "onfido", + "persona", + "metamap", + "socure", + "idnow", + "shufti", + "idenfy", + "ondato", + "trulioo", + "au10tix", + "complycube", + "other" + ] }, - "existing": { - "type": "integer" + "name": { + "type": "string" }, - "duplicate": { - "type": "integer" + "mode": { + "type": "string", + "enum": [ + "api_list", + "api_ids", + "export_file" + ], + "description": "`api_list`: Didit lists records with the key. `api_ids`: upload the record IDs from an export. `export_file`: upload an export in Didit's format." }, - "failed": { - "type": "integer" + "record_noun": { + "type": "string" }, - "rows": { + "credential_fields": { "type": "array", "items": { "type": "object", "properties": { - "row": { - "type": "integer", - "description": "The row's number, from 1." - }, - "status": { - "type": "string", - "enum": [ - "created", - "existing", - "duplicate", - "failed" - ], - "description": "`created`: added to the book. `existing`: the wallet is already in the book and was left untouched. `duplicate`: repeats an earlier row of this import. `failed`: see `errors`." - }, - "entry_id": { - "type": "string", - "format": "uuid", - "nullable": true, - "description": "The address-book entry the row created or found." + "name": { + "type": "string" }, - "errors": { - "type": "object", - "description": "Field errors of a `failed` row; empty otherwise." + "label": { + "type": "string" }, - "duplicate_of_row": { - "type": "integer", - "nullable": true, - "description": "On a `duplicate` row, the row it repeats." + "secret": { + "type": "boolean" } } } + }, + "regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "required_permissions": { + "type": "array", + "items": { + "type": "string" + } + }, + "docs_url": { + "type": "string", + "nullable": true + }, + "status_mapping": { + "type": "object", + "additionalProperties": { + "type": "string", + "enum": [ + "Approved", + "Declined", + "In Review", + "Expired", + "Not Finished", + "Abandoned" + ] + } } } }, - "TravelRuleCounterpartyContact": { + "ImportJobSummary": { "type": "object", - "description": "A compliance address the EMAIL rail writes to for one directory entry.", + "description": "One import job of any kind, in the shape the console's Import jobs drawer reads.", "properties": { - "uuid": { + "id": { "type": "string", "format": "uuid" }, - "counterparty": { + "kind": { "type": "string", - "format": "uuid", - "description": "The directory entry's `id`, as GET /v3/travel-rule/vasps/ shows it." + "enum": [ + "sessions", + "businesses", + "users", + "status_rules", + "transactions" + ] }, - "counterparty_name": { - "type": "string" + "source": { + "type": "string", + "enum": [ + "file", + "api", + "provider" + ] }, - "email": { + "provider": { "type": "string", - "format": "email" + "nullable": true }, - "name": { + "provider_name": { "type": "string", - "description": "Optional label, for example the team name." + "nullable": true }, - "source": { + "filename": { "type": "string", - "enum": [ - "staff", - "application", - "learned" - ], - "description": "staff: curated by Didit. learned: an address at one of the VASP's own domains that answered a request through its response link. application: added by your application." + "nullable": true }, - "scope": { + "state": { "type": "string", "enum": [ - "platform", - "application" + "ready", + "queued", + "running", + "paused", + "completed", + "errors", + "failed", + "cancelled" ], - "description": "platform: curated by Didit or learned from a verified answer, used for every Didit customer, read-only for you. application: private to your application." + "description": "The job's state as the console shows it; `errors` is a completed job with rejected rows." }, - "created_by": { + "status": { + "type": "string" + }, + "is_dry_run": { + "type": "boolean" + }, + "credential_hint": { "type": "string", - "description": "Empty for platform contacts and for contacts an API key added." + "nullable": true }, - "verified_at": { + "resumes_at": { "type": "string", "format": "date-time", - "nullable": true, - "description": "When this address last answered a request through its response link." + "nullable": true }, - "is_invalid": { - "type": "boolean", - "description": "true once the address bounced or complained; the EMAIL rail skips it." + "last_error": { + "type": "string", + "nullable": true + }, + "started_by": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + }, + "email": { + "type": "string", + "nullable": true + } + } + }, + "progress": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int64" + }, + "processed": { + "type": "integer", + "format": "int64" + }, + "imported": { + "type": "integer", + "format": "int64" + }, + "updated": { + "type": "integer", + "format": "int64" + }, + "already_in_didit": { + "type": "integer", + "format": "int64" + }, + "failed": { + "type": "integer", + "format": "int64" + }, + "not_finished": { + "type": "integer", + "format": "int64" + }, + "same_person": { + "type": "integer", + "format": "int64" + } + } + }, + "face_templates": { + "type": "object", + "nullable": true, + "properties": { + "enabled": { + "type": "boolean" + }, + "built": { + "type": "integer", + "format": "int64" + }, + "duplicates": { + "type": "integer", + "format": "int64" + }, + "blocklisted": { + "type": "integer", + "format": "int64" + } + } }, - "invalid_reason": { - "type": "string", - "enum": [ - "", - "hard_bounce", - "soft_bounce", - "spam_complaint", - "suppressed" - ] + "eta_seconds": { + "type": "integer", + "nullable": true }, - "invalid_detail": { + "created_at": { "type": "string", - "description": "The receiving mail server's reason, when it gave one." + "format": "date-time" }, - "invalid_at": { + "started_at": { "type": "string", "format": "date-time", "nullable": true }, - "created_at": { + "completed_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "nullable": true } } }, - "TravelRuleCounterpartyContactCreate": { + "FiledRegulatoryReport": { "type": "object", + "description": "A finalized regulatory report that prevents the requested deletion.", "required": [ - "counterparty", - "email" + "uuid", + "report_number", + "report_type", + "case_uuid" ], "properties": { - "counterparty": { + "uuid": { "type": "string", "format": "uuid", - "description": "The directory entry's `id`." + "description": "Report UUID." }, - "email": { + "report_number": { "type": "string", - "format": "email", - "maxLength": 254 + "description": "Report number shown in the Console (for example, SAR-0001)." }, - "name": { + "report_type": { "type": "string", - "description": "Optional label.", - "maxLength": 255 + "enum": [ + "SAR", + "STR", + "CTR", + "TTR", + "UTR", + "IFT", + "CBR", + "TFR" + ], + "description": "Regulatory report type." + }, + "case_uuid": { + "type": "string", + "format": "uuid", + "description": "Case the report belongs to." } } }, - "TravelRuleNameMatch": { + "FiledReportTransaction": { "type": "object", - "nullable": true, - "description": "The name comparison that decided the transfer, or null until one ran. While the parties are masked, and on the other customer's copy of an INTERNAL exchange, `transfer_name`, `compared_name`, `matched_names` and `mismatched_names` are hidden. `score` and `matched` can disagree: `matched` follows the strictness, `score` is the similarity of the two full names.", + "description": "A transaction that cannot be deleted because a finalized regulatory report lists it.", + "required": [ + "uuid", + "transaction_id", + "reports" + ], "properties": { - "score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "description": "Similarity of the two full names, 0 to 100. 0 when either name is blank." - }, - "matched": { - "type": "boolean", - "description": "Whether the names satisfy `strictness`. The transfer's outcome follows `data_match`, which compares every field, so a transfer can be COUNTERPARTY_MISMATCHED_DATA while this is true." - }, - "method": { + "uuid": { "type": "string", - "enum": [ - "none", - "exact_token", - "token_subset", - "token_containment", - "sequence_ratio" - ], - "description": "How `matched` was decided: none (`NONE`), exact_token (`STRICT`), token_subset (`DEFAULT`), token_containment (`CONTAINS`) or sequence_ratio (`FUZZY`)." + "format": "uuid", + "description": "Didit transaction UUID." }, - "strictness": { + "transaction_id": { "type": "string", - "enum": [ - "NONE", - "STRICT", - "CONTAINS", - "DEFAULT", - "FUZZY" - ] + "description": "The transaction identifier supplied when the transaction was created." }, - "compared_with": { + "reports": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FiledRegulatoryReport" + }, + "description": "Finalized reports that list this transaction." + } + } + }, + "InFiledReportError": { + "type": "object", + "description": "The deletion is refused because the selected data is in a finalized regulatory report. Nothing is deleted. Delete the report, then repeat the request.", + "required": [ + "detail", + "code" + ], + "properties": { + "detail": { + "type": "string" + }, + "code": { "type": "string", "enum": [ - "wallet_holder", - "counterparty_vasp" + "in_filed_report" ], - "description": "wallet_holder: the holder recorded for the wallet. counterparty_vasp: the name the counterparty answered on the email response page, or the Didit Test VASP's answer in sandbox." - }, - "transfer_name": { - "type": "string", - "description": "The name on the transfer." - }, - "compared_name": { - "type": "string", - "description": "The name it was compared with." + "description": "Stable error code for a deletion blocked by a finalized regulatory report." }, - "matched_names": { + "reports": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/FiledRegulatoryReport" }, - "description": "Words of `transfer_name` found in `compared_name`." + "description": "Reports that block a person, company, case or session deletion." }, - "mismatched_names": { + "transactions": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/FiledReportTransaction" }, - "description": "Words of `transfer_name` missing from `compared_name`, then words of `compared_name` missing from `transfer_name`." + "description": "Transactions that block a transaction deletion, each with the reports that list it." } } }, - "TravelRuleTransferRow": { + "TravelRuleNetworkParticipantSummary": { "type": "object", - "description": "One Travel Rule transfer as the transfers list shows it: VASP names, wallets and memos only, never the originator or beneficiary person data.", + "nullable": true, + "description": "This application's own participant on the network, or null when it has none.", "properties": { - "id": { - "type": "string", - "format": "uuid", - "description": "The transfer's id." - }, - "transaction_id": { - "type": "string", - "format": "uuid", - "description": "The Didit transaction the transfer belongs to." - }, - "txn_id": { - "type": "string", - "nullable": true, - "description": "Your own id for the transaction. Transfers Didit books for you, such as a Didit Test VASP inbound transfer, carry a generated one." - }, - "txn_date": { + "mode": { "type": "string", - "format": "date-time" + "enum": [ + "platform", + "own" + ], + "description": "platform: carried by Didit's membership; own: onboarded under the application's own membership." }, - "kind": { + "status": { "type": "string", "enum": [ - "withdrawal", - "deposit", - "message" + "not_requested", + "questionnaire_pending", + "submitted_to_network", + "active", + "suspended", + "rejected" ], - "description": "withdrawal: outbound. message: an inbound transfer a rail created from a counterparty's message (a TRP inquiry, the INTERNAL inbound leg, or a GTR, VerifyVASP or Sygna Bridge message). deposit: any other inbound transfer." + "description": "not_requested: never requested, or the network refused the first request (see last_error); questionnaire_pending: waiting for the due-diligence questionnaire to be approved; submitted_to_network: handed to the network's onboarding; active: the network gave this application its own participant code; suspended / rejected: Didit suspended or rejected it." }, - "direction": { + "participant_code": { "type": "string", - "enum": [ - "INBOUND", - "OUTBOUND" - ] + "description": "The code the network gave this application (for GTR, its VASP code). Outbound messages carry this code, never Didit's own." }, - "status": { + "requested_at": { "type": "string", - "enum": [ - "AWAITING_COUNTERPARTY", - "ON_HOLD", - "COMPLETED", - "FINISHED", - "CANCELLED", - "EXPIRED", - "COUNTERPARTY_MISMATCHED_DATA", - "COUNTERPARTY_VASP_NOT_FOUND", - "COUNTERPARTY_VASP_NOT_REACHABLE", - "UNCONFIRMED_OWNERSHIP", - "COUNTERPARTY_VASP_GENERAL_DECLINE", - "NOT_ENOUGH_COUNTERPARTY_DATA", - "NOT_APPLICABLE" - ] + "format": "date-time", + "nullable": true }, - "reason": { + "activated_at": { "type": "string", - "description": "Why a `COUNTERPARTY_VASP_NOT_FOUND` or `COUNTERPARTY_VASP_NOT_REACHABLE` transfer is stuck, the same value as the transfer's own `reason`, so the list tells a bounced compliance email from a counterparty with no route without opening each transfer. `\"\"` for any other status. See [Why a transfer is stuck](/transaction-monitoring/travel-rule#why-a-transfer-is-stuck)." + "format": "date-time", + "nullable": true }, + "last_error": { + "type": "string", + "description": "The network's answer when it refused the registration; empty otherwise." + } + } + }, + "TravelRuleNetworkState": { + "type": "object", + "description": "How Travel Rule messages on one network would be sent for this application, and why they cannot be. Configuration status, not a live health or delivery check.", + "properties": { "rail": { "type": "string", - "nullable": true, "enum": [ - "INTERNAL", - "TRP", "GTR", "TRUST", "VERIFYVASP", - "SYGNA", - "EMAIL", - "TEST_VASP", - null + "SYGNA" ] }, - "asset": { - "type": "string", - "description": "The transaction's currency." - }, - "amount": { + "mode": { "type": "string", - "description": "The amount as a plain decimal, for example \"1.25\"." + "enum": [ + "own", + "didit", + "off", + "unavailable" + ], + "description": "own: the application's connected membership is used; didit: Didit's membership carries the application as its own active participant; off: platform routing disabled in disabled_networks with no own membership; unavailable: nothing can send on this network yet (see state and reason)." }, - "originator_vasp": { + "state": { "type": "string", - "description": "Outbound: your VASP's legal name. Inbound: the counterparty's name, from its directory entry, the Didit network member, the TRP sender, the Didit Test VASP, or the name the transfer declared. Empty when none is known." + "enum": [ + "own_membership", + "live_through_didit", + "off", + "didit_onboarding", + "questionnaire_needed", + "questionnaire_in_review", + "request_access", + "request_sent", + "unavailable", + "error" + ], + "description": "own_membership: your connected membership sends; live_through_didit: your own participant on Didit's membership sends; off: you switched platform routing off; didit_onboarding: Didit's own membership of this network is not live yet, so it cannot carry anyone; questionnaire_needed / questionnaire_in_review: the due-diligence questionnaire must be submitted or is with Didit; request_access: the questionnaire is approved, request the network; request_sent: your participant is being onboarded; unavailable: see reason; error: see reason." }, - "beneficiary_vasp": { + "reason": { "type": "string", - "description": "Outbound: the counterparty's name, worked out the same way. Inbound: your VASP's legal name." + "enum": [ + "own_membership_connected", + "platform_network_switched_off", + "own_membership_only", + "sandbox_application", + "didit_membership_not_live", + "participant_suspended", + "participant_rejected", + "questionnaire_not_submitted", + "questionnaire_submitted", + "questionnaire_changes_requested", + "questionnaire_rejected", + "participant_not_requested", + "participant_active", + "participant_key_missing", + "participant_key_unresolved", + "provisioning_failed", + "questionnaire_pending", + "submitted_to_network" + ], + "description": "Machine-readable detail of state. own_membership_only: Didit does not carry applications on this network (TRUST), connect your own membership; sandbox_application: sandbox transfers never reach a network; provisioning_failed: the network refused the registration, the participant's last_error says why and requesting the network again retries." }, - "originator_wallet": { - "type": "string" + "platform_available": { + "type": "boolean", + "description": "Whether Didit's own membership of this network is configured; not a live health check." }, - "beneficiary_wallet": { - "type": "string" + "connected": { + "type": "boolean", + "description": "Whether a connected customer membership exists. Credentials are validated locally; network validation occurs on a live exchange." }, - "originator_memo": { - "type": "string", - "description": "Memo or destination tag, empty on chains without one." + "participant": { + "$ref": "#/components/schemas/TravelRuleNetworkParticipantSummary" }, - "beneficiary_memo": { - "type": "string" + "vasps_reachable": { + "type": "integer", + "description": "Directory VASPs reachable on this network." }, - "originator_wallet_type": { + "routed_30d": { + "type": "integer", + "description": "This application's transfers carried on this network in the last 30 days." + } + } + }, + "TravelRuleNetworkQuestionnaireAnswers": { + "type": "object", + "description": "Didit's network due-diligence questionnaire. Saves are partial: a save keeps every answer it does not name. Submitting requires every field except lei and data_protection_contact_email, and the three attestations true.", + "properties": { + "legal_name": { "type": "string", - "enum": [ - "vasp", - "self_hosted", - "own" - ], - "description": "vasp, self_hosted (declared unhosted) or own (a wallet your address book records as yours). Your own side is always vasp." + "maxLength": 255 }, - "beneficiary_wallet_type": { + "registration_number": { "type": "string", - "enum": [ - "vasp", - "self_hosted", - "own" - ] + "maxLength": 255 }, - "matched_transaction_id": { + "incorporation_country": { "type": "string", - "format": "uuid", - "nullable": true, - "description": "The other side of a deposit you matched to an announced transfer by hand." + "minLength": 2, + "maxLength": 2, + "description": "ISO 3166-1 alpha-2 country code." }, - "deadline_at": { + "registered_address": { "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the transfer expires if it is still waiting on its counterparty. Set on every transfer you create with `POST /v3/transactions/` that needs an exchange, outbound or inbound. Null below the threshold, on a Lightning payment the Travel Rule does not apply to, and on inbound transfers Didit creates when a counterparty reaches you (an inbound TRP inquiry, a network message or the INTERNAL inbound leg)." + "maxLength": 1000 }, - "created_at": { + "website": { "type": "string", - "format": "date-time" - } - } - }, - "BankAccountCheckHolder": { - "description": "The name the account is checked against. Send exactly one of `full_name` and `business_name`.", - "oneOf": [ - { - "$ref": "#/components/schemas/BankAccountCheckPersonHolder" + "format": "uri", + "maxLength": 500 }, - { - "$ref": "#/components/schemas/BankAccountCheckBusinessHolder" - } - ] - }, - "BankAccountCheckRequest": { - "type": "object", - "required": [ - "country", - "account", - "holder" - ], - "properties": { - "country": { + "lei": { "type": "string", - "minLength": 3, - "maxLength": 3, - "description": "The account's country, as an ISO 3166-1 alpha-3 code, for example `GBR`. Lowercase is accepted.", - "example": "GBR" + "maxLength": 20, + "description": "Optional. A valid ISO 17442 LEI when given." }, - "account": { - "type": "object", - "description": "The account the way its country writes it: an `iban`, or an `account_number` with the bank or branch code the country needs (`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code` or `bic`). Mexico takes a `clabe` and Argentina a `cbu_cvu`, which already name the bank. A business account adds a `registration_id` where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a `400` that names it.", - "properties": { - "iban": { - "type": "string", - "maxLength": 64, - "description": "The IBAN, in a country that uses IBANs. It must belong to `country`." - }, - "account_number": { - "type": "string", - "maxLength": 64, - "description": "The account number, in a country that writes the account with a separate bank or branch code." - }, - "sort_code": { - "type": "string", - "maxLength": 64, - "description": "United Kingdom: the 6-digit sort code." - }, - "routing_number": { - "type": "string", - "maxLength": 64, - "description": "United States: the 9-digit ABA routing number." - }, - "transit_institution": { - "type": "string", - "maxLength": 64, - "description": "Canada: the 8-digit transit and institution number." - }, - "bsb": { - "type": "string", - "maxLength": 64, - "description": "Australia: the 6-digit BSB." - }, - "ifsc": { - "type": "string", - "maxLength": 64, - "description": "India: the 11-character IFSC." - }, - "bank_code": { - "type": "string", - "maxLength": 64, - "description": "The bank's code, where the country needs one, for example in Nigeria." - }, - "bic": { - "type": "string", - "maxLength": 64, - "description": "The bank's BIC, where the country's check asks for one." - }, - "clabe": { - "type": "string", - "maxLength": 64, - "description": "Mexico: the 18-digit CLABE. It already names the bank." - }, - "cbu_cvu": { - "type": "string", - "maxLength": 64, - "description": "Argentina: the 22-digit CBU or CVU. It already names the bank." - }, - "registration_id": { - "type": "string", - "maxLength": 64, - "description": "A business account's registration number, where the country asks for one." + "licences": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "regulator", + "jurisdiction", + "licence_type", + "licence_number" + ], + "properties": { + "regulator": { + "type": "string", + "maxLength": 255 + }, + "jurisdiction": { + "type": "string", + "minLength": 2, + "maxLength": 2, + "description": "ISO 3166-1 alpha-2 country code." + }, + "licence_type": { + "type": "string", + "maxLength": 255 + }, + "licence_number": { + "type": "string", + "maxLength": 255 + } } }, - "additionalProperties": { + "description": "Every licence or registration the VASP holds." + }, + "operating_jurisdictions": { + "type": "array", + "minItems": 1, + "maxItems": 250, + "items": { "type": "string", - "maxLength": 64 - }, - "example": { - "sort_code": "20-45-67", - "account_number": "31926819" + "minLength": 2, + "maxLength": 2, + "description": "ISO 3166-1 alpha-2 country code." } }, - "holder": { - "$ref": "#/components/schemas/BankAccountCheckHolder" + "compliance_officer_name": { + "type": "string", + "maxLength": 255 + }, + "compliance_officer_email": { + "type": "string", + "format": "email" + }, + "aml_ctf_policy_attested": { + "type": "boolean", + "description": "Must be true to submit." + }, + "sanctions_screening_attested": { + "type": "boolean", + "description": "Must be true to submit." }, - "vendor_data": { + "data_protection_attested": { + "type": "boolean", + "description": "Must be true to submit." + }, + "data_protection_contact_email": { "type": "string", - "nullable": true, - "description": "Your own reference for this check, returned unchanged.", - "example": "payout_20481" + "format": "email", + "description": "Optional." + }, + "expected_monthly_transfers": { + "type": "integer", + "minimum": 0 + }, + "expected_monthly_volume_usd": { + "type": "string", + "format": "decimal", + "description": "Expected monthly volume in USD, up to 2 decimal places. Returned as a string." + }, + "assets": { + "type": "array", + "minItems": 1, + "maxItems": 200, + "items": { + "type": "string", + "maxLength": 32 + }, + "description": "Asset tickers, stored upper-case, sorted and de-duplicated." } } }, - "BankAccountCheckResponse": { + "TravelRuleNetworkQuestionnaire": { "type": "object", - "required": [ - "request_id", - "result", - "holder_name", - "account", - "vendor_data", - "created_at" - ], "properties": { - "request_id": { - "type": "string", - "format": "uuid", - "description": "The ID of this check." - }, - "result": { + "status": { "type": "string", "enum": [ - "match", - "close_match", - "no_match", - "cannot_verify" + "draft", + "submitted", + "changes_requested", + "approved", + "rejected" ], - "description": "`match`: the bank holds the account under the name you sent. `close_match`: under a close name, for example a missing middle name or a typo. `no_match`: under another name, or there is no such account. `cannot_verify`: the bank answered without comparing the name, for example for a blocked or closed account." - }, - "holder_name": { - "type": "string", - "nullable": true, - "description": "Only on a `close_match`, and only when the bank returned it: the name on the account, as the bank holds it. `null` otherwise." + "description": "Answers can be saved while draft or changes_requested; submitted, approved and rejected are Didit's to move." }, - "account": { - "type": "string", - "description": "The account, masked to its last 4 characters." + "answers": { + "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers" }, - "vendor_data": { + "submitted_at": { "type": "string", - "nullable": true, - "description": "Your own reference, as you sent it." + "format": "date-time", + "nullable": true }, - "created_at": { + "reviewed_at": { "type": "string", "format": "date-time", - "description": "When the check ran, in UTC." - } - } - }, - "BankAccountCheckError": { - "type": "object", - "required": [ - "detail" - ], - "properties": { - "detail": { - "type": "string", - "description": "What went wrong, in English." + "nullable": true }, - "code": { + "review_note": { "type": "string", - "description": "A stable code to branch on. Absent on `401` and `403`." + "description": "Didit's note on its last decision, for example what to change." }, - "field": { - "type": "string", - "description": "`400` only: the body field to correct, as a dotted path, for example `account.sort_code`." + "history": { + "type": "array", + "readOnly": true, + "description": "Every status change, oldest first.", + "items": { + "type": "object", + "properties": { + "at": { + "type": "string", + "format": "date-time" + }, + "from": { + "type": "string" + }, + "to": { + "type": "string" + }, + "note": { + "type": "string", + "description": "Review note or the network's answer, when there is one." + } + } + } }, - "reason": { + "updated_at": { "type": "string", - "enum": [ - "required", - "length", - "format", - "checksum", - "country_mismatch", - "rejected" - ], - "description": "`400` only: why the field was refused. `required`, `length`, `format`, `checksum` and `country_mismatch` (an IBAN of another country) are Didit's own checks; `rejected` means the bank refused the account as sent." + "format": "date-time", + "nullable": true } } }, - "BankVerificationResult": { + "TravelRuleNetworkParticipant": { "type": "object", - "description": "One Bank Verification step's result, for User and Business Verification. `method` says how the account was verified, and `none` that the person continued without a bank before any attempt was evaluated. `continued_without_bank` says the person continued without a bank, also after an evaluated attempt. See [Bank verification methods](/core-technology/bank-verification/verification-methods) and [When the person cannot verify their bank](/core-technology/bank-verification/fallbacks).", + "description": "This application's own participant on one network.", "properties": { - "schema_version": { - "type": "integer", - "description": "Version of this result shape. `1` today." - }, - "bank_verification_id": { - "type": "string", - "format": "uuid", - "description": "The ID of this result." - }, - "node_id": { - "type": "string", - "description": "The workflow node this result belongs to." - }, - "status": { + "network": { "type": "string", "enum": [ - "Not Finished", - "Approved", - "Declined", - "In Review", - "Expired" - ], - "description": "The step's verdict, after its actions and status rules." - }, - "original_status": { - "type": "string", - "nullable": true, - "description": "The first verdict the step reached, before any later change such as a manual review." + "gtr", + "trust", + "verifyvasp", + "sygna" + ] }, - "method": { + "rail": { "type": "string", - "nullable": true, "enum": [ - "open_banking", - "account_lookup", - "microdeposits", - "statement", - "none" - ], - "description": "How the account was verified: `open_banking` (bank sign-in: the person signed in at their bank), `account_lookup` (account check: the person typed the account details and the bank confirmed the name), `microdeposits` or `statement` (a statement upload). `none` when the person continued without a bank before any attempt was evaluated, so no account was verified. After an evaluated attempt, it stays the method of that attempt. `null` until an account is evaluated, and when the workflow narrows the data it returns. Workflow rules read the same value as `bank.method`." + "GTR", + "TRUST", + "VERIFYVASP", + "SYGNA" + ] }, - "provider": { + "mode": { "type": "string", - "nullable": true, - "description": "The key of the route that ran the connection. Read `method`, not this key, to tell how the account was verified." + "enum": [ + "platform", + "own" + ] }, - "credential_source": { + "status": { "type": "string", - "nullable": true, "enum": [ - "native", - "byok" + "not_requested", + "questionnaire_pending", + "submitted_to_network", + "active", + "suspended", + "rejected" ], - "description": "`native`: Didit's own route, billed to your Didit balance. `byok`: a marketplace provider you connected with your own credentials." + "description": "not_requested: never requested, or the network refused the first request (see last_error); questionnaire_pending: waiting for the due-diligence questionnaire to be approved; submitted_to_network: handed to the network's onboarding; active: the network gave this application its own participant code; suspended / rejected: Didit suspended or rejected it." }, - "route": { - "type": "object", - "nullable": true, - "description": "The route chosen before consent. It never changes afterwards.", - "properties": { - "provider_key": { - "type": "string", - "nullable": true, - "description": "The route's key." - }, - "credential_source": { - "type": "string", - "enum": [ - "native", - "byok" - ] - }, - "is_fallback": { - "type": "boolean", - "description": "Whether Didit's own route stood in for a marketplace provider that could not connect." - }, - "provider_connection_id": { - "type": "string", - "nullable": true, - "description": "The marketplace connection used, for `byok`." - }, - "requested_scopes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "The data the connection asked for, for example `ownership` or `balances`." - } - } + "participant_code": { + "type": "string" }, - "connection": { - "type": "object", - "nullable": true, - "description": "The latest attempt's connection. `null` before the first attempt.", - "properties": { - "status": { - "type": "string", - "enum": [ - "pending", - "connected", - "cancelled", - "timeout", - "failed", - "unsupported", - "revoked", - "expired" - ] - }, - "institution_id": { - "type": "string", - "nullable": true, - "description": "The bank's ID. `null` for an account check, where no bank is picked." - }, - "institution_name": { - "type": "string", - "nullable": true, - "description": "The bank's name. `null` for an account check." - }, - "institution_country": { - "type": "string", - "nullable": true, - "description": "The account's country, ISO 3166-1 alpha-3." - }, - "oauth": { - "type": "boolean", - "nullable": true, - "description": "Whether the bank sign-in ran over OAuth or app-to-app. `null` for an account check." - }, - "connected_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the connection succeeded." - }, - "consent_expires_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the bank consent ends, for bank sign-in." - }, - "last_refreshed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the financial data was last read again." - }, - "attempts": { - "type": "integer", - "description": "The attempts the person spent on this step, every method together." - }, - "reason_code": { - "type": "string", - "nullable": true, - "description": "Why the connection is not simply `connected`, for example `USER_CANCELLED`, `INSTITUTION_DOWN`, `ACCOUNT_NOT_FOUND`, `REFERENCE_IDENTITY_MISSING` or `VERIFICATION_COMPLETED`." - } - } + "requested_at": { + "type": "string", + "format": "date-time", + "nullable": true }, - "account": { - "type": "object", - "nullable": true, - "description": "The evaluated account. `null` until an account is evaluated.", - "properties": { - "account_id_masked": { - "type": "string", - "nullable": true, - "description": "The account number, masked." - }, - "iban_masked": { - "type": "string", - "nullable": true, - "description": "The IBAN, masked." - }, - "sort_code": { - "type": "string", - "nullable": true, - "description": "The sort code, in the United Kingdom." - }, - "routing_number_masked": { - "type": "string", - "nullable": true, - "description": "The routing number, masked." - }, - "type": { - "type": "string", - "nullable": true, - "enum": [ - "checking", - "current", - "savings", - "business", - "other" - ] - }, - "subtype": { - "type": "string", - "nullable": true, - "description": "The bank's own account subtype." - }, - "currency": { - "type": "string", - "nullable": true, - "description": "ISO 4217 currency of the account." - }, - "holder_type": { - "type": "string", - "nullable": true, - "enum": [ - "person", - "business", - "unknown" - ] - }, - "holders_count": { - "type": "integer", - "nullable": true - }, - "is_joint": { - "type": "boolean", - "nullable": true - }, - "is_business": { - "type": "boolean", - "nullable": true - } - } + "submitted_at": { + "type": "string", + "format": "date-time", + "nullable": true }, - "ownership": { - "type": "object", - "nullable": true, - "description": "How the account holder compared with the verified identity. `null` until an account is evaluated.", - "properties": { - "result": { - "type": "string", - "enum": [ - "match", - "partial_match", - "no_match", - "unknown", - "not_verifiable" - ], - "description": "`partial_match` is a close match. `not_verifiable`: the bank answered with no holder to compare. `unknown`: the evidence could not be read, or there was no identity to compare." - }, - "reference_identity_source": { - "type": "string", - "nullable": true, - "description": "The step whose identity the holder was compared against: `kyc`, `database_validation`, `expected_details`, `questionnaire`, `document_ai` or `kyb`." - }, - "name_score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "nullable": true, - "description": "Didit's holder name score." - }, - "provider_name_score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "nullable": true, - "description": "The bank's own holder name score, when it returned one." - }, - "address_score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "nullable": true, - "description": "The holder address score, when address matching ran." - }, - "email_score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "nullable": true, - "description": "The holder email score, when email matching ran." - }, - "phone_score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "nullable": true, - "description": "The holder phone score, when phone matching ran." - }, - "dob_score": { - "type": "integer", - "minimum": 0, - "maximum": 100, - "nullable": true, - "description": "The holder date of birth score, when the bank shared one." - }, - "close_match": { - "type": "boolean", - "nullable": true, - "description": "Whether the name landed in the close-match band." - }, - "holder_confirmation": { - "type": "string", - "nullable": true, - "enum": [ - "pending", - "confirmed", - "rejected" - ], - "description": "The person's answer when asked to confirm a close-match name. `null` when never asked." - }, - "method": { - "type": "string", - "nullable": true, - "enum": [ - "exact", - "token_set", - "nickname", - "transliteration", - "fuzzy", - "provider_only", - "microdeposits" - ], - "description": "Which name comparison produced the score. This is not the verification method: read the top-level `method` for that." - }, - "matched_holder_index": { - "type": "integer", - "nullable": true - }, - "holders": { - "type": "array", - "items": { - "type": "object" - }, - "description": "Each holder the bank listed, with its scores." - }, - "owner_identity_available": { - "type": "boolean", - "nullable": true - }, - "evidence_freshness": { - "type": "string", - "nullable": true, - "enum": [ - "live", - "cached", - "refreshed" - ] - }, - "evaluated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "When the verdict was computed." - } - } + "activated_at": { + "type": "string", + "format": "date-time", + "nullable": true }, - "financial_data": { - "type": "object", - "description": "The financial data the step read. Only bank sign-in reads it.", - "properties": { - "balances": { - "type": "object", - "nullable": true, - "description": "With the `balances` scope." - }, - "transactions": { - "type": "object", - "nullable": true, - "description": "With the `transactions` scope." - }, - "income": { - "type": "object", - "nullable": true, - "description": "With the `income` scope." - }, - "categorization": { - "type": "object", - "nullable": true, - "description": "Didit's categorization of the transactions read. `null` without them." - }, - "not_collected": { - "type": "array", - "items": { + "suspended_at": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "last_error": { + "type": "string", + "description": "The network's answer when it refused the registration; empty otherwise." + }, + "history": { + "type": "array", + "readOnly": true, + "description": "Every status change, oldest first.", + "items": { + "type": "object", + "properties": { + "at": { "type": "string", - "enum": [ - "balances", - "income", - "transactions" - ] + "format": "date-time" }, - "description": "The data the step asked for that the method which verified the account does not collect. Balances, transactions and income come from bank sign-in only, so an account verified by account check lists them here. Never a failure. Empty otherwise." + "from": { + "type": "string" + }, + "to": { + "type": "string" + }, + "note": { + "type": "string", + "description": "Review note or the network's answer, when there is one." + } } } + } + } + }, + "TravelRuleNetworksOverview": { + "type": "object", + "properties": { + "platform_networks_enabled": { + "type": "boolean", + "description": "Whether network access through Didit's membership is open. While false, questionnaire saves, submissions and network requests answer 403." }, - "billing": { + "questionnaire": { + "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire" + }, + "participants": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TravelRuleNetworkParticipant" + } + }, + "networks": { "type": "object", - "nullable": true, + "readOnly": true, + "description": "Per network, how this application would send and why it cannot. No network, including GTR, is included by default: a network is reachable through your own connected membership, or through Didit's membership once Didit's membership of that network is live and your own participant on it is active. Not a live health or delivery check.", "properties": { - "route": { - "type": "string", - "enum": [ - "native", - "byok" - ] + "gtr": { + "$ref": "#/components/schemas/TravelRuleNetworkState" }, - "billed": { - "type": "boolean" + "trust": { + "$ref": "#/components/schemas/TravelRuleNetworkState" }, - "marketplace_fee": { - "type": "string", - "nullable": true, - "description": "The marketplace platform fee charged, for `byok`." + "verifyvasp": { + "$ref": "#/components/schemas/TravelRuleNetworkState" }, - "usage_type": { - "type": "string", - "nullable": true, - "description": "The usage line the charge was booked on: `bank_verification` for a bank sign-in or an account check, `bank_statement_upload` for a statement upload with no charged bank attempt before it, and `bank_byok_fee` for the marketplace fee on your own provider. `null` when nothing was billed." + "sygna": { + "$ref": "#/components/schemas/TravelRuleNetworkState" } } + } + } + }, + "AddressValidationResult": { + "type": "object", + "description": "The result of one Address Validation: whether the address exists, and its normalised form. It confirms the address only; it never links the address to a person.", + "required": [ + "status", + "verification_level", + "address", + "formatted_address", + "latitude", + "longitude" + ], + "properties": { + "status": { + "type": "string", + "enum": [ + "verified", + "partially_verified", + "not_verified", + "unavailable" + ], + "description": "`verified`: the address was confirmed down to the building (or the flat or PO box). `partially_verified`: it was confirmed only to the street, or to the most precise level the postal reference data holds for that place. `not_verified`: only the region or the city matched, or nothing did. `unavailable`: the validation could not run (for example the reference service did not answer); it is not charged and never affects a verification." }, - "reference_identity": { - "type": "object", - "nullable": true, - "description": "The identity the holder was compared against, with its source." - }, - "signals": { - "type": "object", - "nullable": true, - "description": "Account signals read from the transaction history, when the step read one." - }, - "connection_abandoned": { - "type": "boolean", - "nullable": true, - "description": "Whether the step ended without a match after the person left at their bank." - }, - "not_covered": { - "type": "boolean", + "verification_level": { + "type": "string", "nullable": true, - "description": "Whether the person's bank or country could not be reached on this step. Also `true` when the person continued without a bank because no method could verify their country or bank." - }, - "continued_without_bank": { - "type": "boolean", - "description": "Whether the person left the step with **Continue without your bank**. `continuation` then says why. `method` is `none` when no attempt was evaluated before they continued. After an evaluated attempt, such as a holder that does not match, `method` stays the method of that attempt and its verdict and reason codes stand. Returned even when the workflow narrows the data it returns." + "enum": [ + "administrative_area", + "locality", + "thoroughfare", + "premise", + "delivery_point", + null + ], + "description": "The most precise level the address was matched to. `null` when nothing matched or `status` is `unavailable`." }, - "continuation": { + "address": { "type": "object", "nullable": true, - "description": "How the person continued without a bank. `null` when they did not. When the workflow narrows the data it returns, `reason` is still returned and every other key is `null`.", + "description": "The normalised address. `null` when `status` is `unavailable`.", "properties": { - "reason": { + "address_line_1": { "type": "string", - "enum": [ - "no_route", - "institution_unsupported", - "attempts_exhausted", - "person_choice" - ], - "description": "Why, as Didit worked it out when the person continued: `no_route` (no bank sign-in or account check serves their country), `institution_unsupported` (the bank they picked cannot be used on this step), `attempts_exhausted` (every attempt was already spent and none was in progress), or `person_choice` (a way to verify was there and they chose to continue, also when their bank could not be reached right now). `no_route` and `institution_unsupported` follow `bank_unsupported_action`, `attempts_exhausted` follows `bank_attempts_exhausted_action`, and `person_choice` follows `bank_skipped_action`, unless an evaluated attempt already decided the step." + "nullable": true, + "description": "First delivery line, written the way the country writes it.", + "example": "1600 Amphitheatre Pkwy" }, - "country": { + "address_line_2": { "type": "string", "nullable": true, - "description": "The country the person was verifying in, ISO 3166-1 alpha-3. `null` when they continued before picking one." + "description": "Second delivery line (a flat, building or neighbourhood), when the address has one." }, - "offered": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "statement", - "microdeposits" - ] - }, + "city": { + "type": "string", "nullable": true, - "description": "The other ways to verify that country offered the person when they continued, in the order it offered them: `statement` (a statement upload), then `microdeposits`. Empty when it offered none." + "example": "Mountain View" }, - "institution_id": { + "region": { "type": "string", "nullable": true, - "description": "For `institution_unsupported`, the ID of the bank the person could not use: the bank they picked, or the bank their last attempt ended on. Didit takes it from its own list of banks, never from the person's device, so a bank that list does not have is `null`. `null` for every other reason." + "description": "State, province or region.", + "example": "CA" }, - "institution_name": { + "postal_code": { "type": "string", "nullable": true, - "description": "For `institution_unsupported`, the name of that bank, from the same list as `institution_id`. `null` when that list does not have the bank, and for every other reason." + "example": "94043-1351" }, - "continued_at": { + "country": { "type": "string", - "format": "date-time", "nullable": true, - "description": "When the person continued." + "description": "ISO 3166-1 alpha-2 country code.", + "example": "US" } } }, - "evidence_purged_at": { + "formatted_address": { "type": "string", - "format": "date-time", "nullable": true, - "description": "When the bank evidence was deleted under `bank_evidence_retention_days`. `null` otherwise." - }, - "warnings": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Informational codes, for example `holder_declared`. A warning never changes the status on its own." - }, - "reason_codes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Why the verdict came out the way it did, for example `OWNER_NAME_PARTIAL`. Several may apply. `NOT_COVERED`: the person continued without a bank because no method could verify their country or bank. `SKIPPED`: the person chose to continue without a bank while a way to verify was there. Neither is added when an evaluated attempt already decided the step." + "description": "The normalised address on one line.", + "example": "1600 Amphitheatre Pkwy, Mountain View CA 94043-1351" }, - "created_at": { - "type": "string", - "format": "date-time" + "latitude": { + "type": "number", + "nullable": true, + "example": 37.422022 }, - "updated_at": { - "type": "string", - "format": "date-time" + "longitude": { + "type": "number", + "nullable": true, + "example": -122.08429 } } }, - "BankAccountCheckPersonHolder": { + "AddressValidationRequest": { "type": "object", - "description": "The person who should hold the account.", "required": [ - "full_name" + "country" ], + "description": "One address: on one line (`address`) or as structured fields with at least `address_line_1`, never both.", "properties": { - "full_name": { + "address": { + "type": "string", + "maxLength": 500, + "description": "The whole address on one line.", + "example": "Paseo de la Castellana 259, 28046 Madrid" + }, + "address_line_1": { "type": "string", "maxLength": 255, - "description": "The full name of the person who should hold the account.", - "example": "Maria Oliveira" - } - } - }, - "BankAccountCheckBusinessHolder": { - "type": "object", - "description": "The company that should hold the account. Checks a business account.", - "required": [ - "business_name" - ], - "properties": { - "business_name": { + "description": "Street and number.", + "example": "1600 Amphitheatre Pkwy" + }, + "address_line_2": { "type": "string", "maxLength": 255, - "description": "The name of the company that should hold the account. Checks a business account." - } - } - }, - "BankVerificationPricing": { - "type": "object", - "description": "Public Bank Verification list prices: the statement upload, the own provider key fee and each country's methods.", - "required": [ - "currency", - "statement_upload", - "own_provider_fee_usd", - "countries" - ], - "properties": { - "currency": { + "description": "Apartment, suite, floor or building." + }, + "city": { "type": "string", - "enum": [ - "USD" - ], - "description": "Currency of every price in the response.", - "example": "USD" + "maxLength": 128, + "description": "City or locality.", + "example": "Mountain View" }, - "statement_upload": { - "$ref": "#/components/schemas/BankStatementUploadPricing" + "region": { + "type": "string", + "maxLength": 128, + "description": "State, province or region.", + "example": "CA" }, - "own_provider_fee_usd": { + "postal_code": { "type": "string", - "description": "Fee for each billable ownership check on a route that uses your own provider contract instead of Didit's, charged whatever the result. A cancelled, timed out or abandoned connection is not billed. Decimal string with 4 decimals, in USD.", - "example": "0.0200" + "maxLength": 32, + "example": "94043" }, - "countries": { - "type": "object", - "description": "Every country, keyed by ISO 3166-1 alpha-3 code.", - "additionalProperties": { - "$ref": "#/components/schemas/BankVerificationPricingCountry" - } + "country": { + "type": "string", + "maxLength": 3, + "description": "ISO 3166-1 alpha-2 or alpha-3 code of the address's country.", + "example": "US" } } }, - "BankStatementUploadPricing": { + "AddressValidationResponse": { "type": "object", - "description": "How the bank statement upload is priced.", "required": [ - "price_usd", - "included_after_charged_bank_attempt", - "standalone_available" + "request_id", + "address_validation", + "created_at" ], "properties": { - "price_usd": { + "request_id": { "type": "string", - "description": "Price of a statement upload after a charged bank attempt. Decimal string with 4 decimals, in USD.", - "example": "0.0000" + "format": "uuid", + "description": "Identifier of this request; quote it to support. No session is created." }, - "included_after_charged_bank_attempt": { - "type": "boolean", - "description": "`true` when the upload is included at no extra charge after a charged bank attempt in the same session.", - "example": true + "address_validation": { + "$ref": "#/components/schemas/AddressValidationResult" }, - "standalone_available": { - "type": "boolean", - "description": "`true` when a statement upload can run on its own, with no bank attempt first. `false` in production; sandbox sessions can test it without billing.", - "example": false - } - } - }, - "BankVerificationPricingCountry": { - "type": "object", - "description": "One country's Bank Verification methods and their list prices.", - "required": [ - "name", - "methods" - ], - "properties": { - "name": { + "created_at": { "type": "string", - "description": "Country name in English.", - "example": "United Kingdom" - }, - "methods": { - "$ref": "#/components/schemas/BankVerificationPricingMethods" + "format": "date-time" } } }, - "BankVerificationPricingMethods": { - "type": "object", - "description": "The two Bank Verification methods in a country.", - "required": [ - "open_banking", - "account_lookup" + "TravelRuleWalletProofFailureReason": { + "type": "string", + "enum": [ + "", + "SIGNATURE_INVALID", + "SIGNATURE_UNSUPPORTED_SCHEME", + "DEPOSIT_NOT_FOUND", + "DEPOSIT_UNCONFIRMED", + "DEPOSIT_LOOKUP_FAILED", + "DEPOSIT_MISMATCH", + "DEPOSIT_STALE", + "TXID_REUSED", + "CHAIN_UNSUPPORTED", + "WINDOW_EXPIRED", + "OWNERSHIP_CHANGED", + "METHOD_SWITCHED", + "REVIEW_REJECTED", + "ABANDONED" ], - "properties": { - "open_banking": { - "$ref": "#/components/schemas/BankSignInPricing" - }, - "account_lookup": { - "$ref": "#/components/schemas/BankAccountCheckPricing" - } - } + "description": "Why a wallet-ownership proof, or its last attempt, fell short of VERIFIED. Empty when nothing failed. A PENDING proof can carry one: the last attempt failed and the end user can try again. DEPOSIT_MISMATCH, DEPOSIT_STALE, TXID_REUSED and REVIEW_REJECTED close the proof as REJECTED. SIGNATURE_INVALID: the signature does not match the wallet and challenge. SIGNATURE_UNSUPPORTED_SCHEME: the wallet signed in a format Didit does not verify. DEPOSIT_NOT_FOUND, DEPOSIT_UNCONFIRMED, DEPOSIT_LOOKUP_FAILED: the test deposit is not readable or not confirmed yet; Didit keeps checking it until the test window closes. DEPOSIT_MISMATCH: the transaction does not send the expected amount from the wallet to the deposit address. DEPOSIT_STALE: the transaction predates the challenge. TXID_REUSED: the transaction already proved another wallet. CHAIN_UNSUPPORTED: the method is not available on this chain. WINDOW_EXPIRED: the test window closed. OWNERSHIP_CHANGED: the wallet's holder changed, or the wallet was deleted from your address book, after the widget session was minted. METHOD_SWITCHED: the end user picked another method before finishing this one. REVIEW_REJECTED: your reviewer rejected the screenshot. ABANDONED: the widget session lapsed before the end user finished." }, - "BankSignInPricing": { + "TravelRuleWidgetProofError": { "type": "object", - "description": "Bank sign-in: the person signs in to their bank. Priced by market, the same for every bank in it.", - "required": [ - "available", - "market", - "price_usd", - "add_ons" - ], "properties": { - "available": { - "type": "boolean", - "description": "`true` only where Didit serves bank sign-in in this country in production.", - "example": true + "detail": { + "type": "string", + "description": "Human-readable message in English." }, - "market": { + "code": { + "allOf": [ + { + "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason" + } + ], + "description": "Machine-readable reason, so a client can show its own translated message." + }, + "status": { "type": "string", - "nullable": true, - "description": "The market whose price applies. `null` when not available.", - "example": "UK and EEA" + "enum": [ + "PENDING", + "VERIFIED", + "REJECTED", + "EXPIRED" + ], + "description": "Present when the proof is closed: REJECTED by the deposit just submitted (400), or REJECTED or EXPIRED when evidence is sent to a proof that is already closed (409)." }, - "price_usd": { + "proof_id": { "type": "string", - "nullable": true, - "description": "List price of one bank sign-in. `null` when not available. Decimal string with 4 decimals, in USD.", - "example": "0.7900" + "format": "uuid", + "description": "Present with status: the closed proof." }, - "add_ons": { - "type": "object", - "description": "Add-ons priced in this country, each a decimal string with 4 decimals in USD, added to the bank sign-in price. Only the add-ons the country offers are listed; empty when bank sign-in is not available.", - "properties": { - "balance": { - "type": "string", - "description": "Account balance add-on.", - "example": "0.3500" - }, - "transactions": { - "type": "string", - "description": "Transactions add-on.", - "example": "1.3000" - } - } + "method": { + "type": "string", + "enum": [ + "MESSAGE_SIGNING", + "SATOSHI_TEST", + "SCREENSHOT", + "SELF_DECLARATION" + ], + "description": "Present with status: the closed proof's method." + }, + "max_attempts": { + "type": "integer", + "description": "Present with status: rejected wallet proofs this session allows." + }, + "attempts_used": { + "type": "integer", + "description": "Present with status: rejected proofs so far." + }, + "attempts_remaining": { + "type": "integer", + "description": "Present with status: when 0, starting another proof answers 409 and you mint a new widget session." } } }, - "BankAccountCheckPricing": { + "TravelRuleWidgetProofCreate": { "type": "object", - "description": "Account check: the person types their account number and Didit checks it with the bank. Priced per country.", "required": [ - "available", - "price_usd" + "method" ], "properties": { - "available": { - "type": "boolean", - "description": "`true` only where Didit serves the account check in this country in production.", - "example": true + "method": { + "type": "string", + "enum": [ + "MESSAGE_SIGNING", + "SATOSHI_TEST", + "SCREENSHOT", + "SELF_DECLARATION" + ], + "description": "The proof method the end user picked. It must be one of the context's allowed_methods." + }, + "wallet_address": { + "type": "string", + "maxLength": 128, + "description": "Defaults to the session's wallet_address. Must match the transfer's wallet when the session is linked to a transfer." }, - "price_usd": { + "chain": { "type": "string", - "nullable": true, - "description": "List price of one account check the bank answers. `null` when not available. Decimal string with 4 decimals, in USD.", - "example": "0.4000" + "maxLength": 32, + "description": "Defaults to the session's chain." } } }, - "ImportProvider": { + "TravelRuleWidgetProofVerifyResult": { "type": "object", "properties": { - "key": { + "proof_id": { + "type": "string", + "format": "uuid" + }, + "method": { "type": "string", "enum": [ - "sumsub", - "jumio", - "veriff", - "onfido", - "persona", - "metamap", - "socure", - "idnow", - "shufti", - "idenfy", - "ondato", - "trulioo", - "au10tix", - "complycube", - "other" + "MESSAGE_SIGNING", + "SATOSHI_TEST", + "SCREENSHOT", + "SELF_DECLARATION" ] }, - "name": { - "type": "string" - }, - "mode": { + "status": { "type": "string", "enum": [ - "api_list", - "api_ids", - "export_file" - ], - "description": "`api_list`: Didit lists records with the key. `api_ids`: upload the record IDs from an export. `export_file`: upload an export in Didit's format." - }, - "record_noun": { - "type": "string" - }, - "credential_fields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "label": { - "type": "string" - }, - "secret": { - "type": "boolean" - } - } - } + "PENDING", + "VERIFIED", + "REJECTED", + "EXPIRED" + ] }, - "regions": { - "type": "array", - "items": { - "type": "string" - } + "is_ownership_verified": { + "type": "boolean", + "description": "Present when the proof is VERIFIED: the address book entry is now ownership-verified." }, - "required_permissions": { - "type": "array", - "items": { - "type": "string" - } + "transfer_status": { + "type": "string", + "nullable": true, + "description": "Present when the proof is VERIFIED: the linked transfer's status, null without one." }, - "docs_url": { + "detail": { "type": "string", - "nullable": true + "description": "Present while the proof stays PENDING: a submitted screenshot awaiting review, or a test deposit that is not confirmed yet." }, - "status_mapping": { - "type": "object", - "additionalProperties": { - "type": "string", - "enum": [ - "Approved", - "Declined", - "In Review", - "Expired", - "Not Finished", - "Abandoned" - ] - } + "code": { + "allOf": [ + { + "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason" + } + ], + "description": "Present on a pending test deposit: why it is not confirmed yet." } } }, - "ImportJobSummary": { + "TravelRuleWalletProofReview": { "type": "object", - "description": "One import job of any kind, in the shape the console's Import jobs drawer reads.", "properties": { - "id": { + "proof_id": { "type": "string", "format": "uuid" }, - "kind": { + "method": { "type": "string", "enum": [ - "sessions", - "businesses", - "users", - "status_rules", - "transactions" + "SCREENSHOT" ] }, - "source": { + "status": { "type": "string", "enum": [ - "file", - "api", - "provider" + "PENDING", + "VERIFIED", + "REJECTED", + "EXPIRED" ] }, - "provider": { - "type": "string", - "nullable": true - }, - "provider_name": { - "type": "string", - "nullable": true - }, - "filename": { - "type": "string", - "nullable": true + "wallet_address": { + "type": "string" }, - "state": { + "chain": { "type": "string", - "enum": [ - "ready", - "queued", - "running", - "paused", - "completed", - "errors", - "failed", - "cancelled" - ], - "description": "The job's state as the console shows it; `errors` is a completed job with rejected rows." + "description": "Canonical chain identifier, e.g. ETH, BTC, SOL, TRX." }, - "status": { + "holder_name": { "type": "string" }, - "is_dry_run": { - "type": "boolean" + "is_ownership_verified": { + "type": "boolean", + "description": "Whether the address book entry is ownership-verified, by this proof or another one." }, - "credential_hint": { + "transaction_id": { "type": "string", - "nullable": true + "format": "uuid", + "nullable": true, + "description": "The transaction whose Travel Rule transfer the widget session was minted for. Null for a session minted without a transaction_id." }, - "resumes_at": { + "file_name": { "type": "string", - "format": "date-time", "nullable": true }, - "last_error": { + "content_type": { "type": "string", "nullable": true }, - "started_by": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true - }, - "email": { - "type": "string", - "nullable": true - } - } - }, - "progress": { - "type": "object", - "properties": { - "total": { - "type": "integer", - "format": "int64" - }, - "processed": { - "type": "integer", - "format": "int64" - }, - "imported": { - "type": "integer", - "format": "int64" - }, - "updated": { - "type": "integer", - "format": "int64" - }, - "already_in_didit": { - "type": "integer", - "format": "int64" - }, - "failed": { - "type": "integer", - "format": "int64" - }, - "not_finished": { - "type": "integer", - "format": "int64" - }, - "same_person": { - "type": "integer", - "format": "int64" - } - } - }, - "face_templates": { - "type": "object", + "screenshot_url": { + "type": "string", "nullable": true, - "properties": { - "enabled": { - "type": "boolean" - }, - "built": { - "type": "integer", - "format": "int64" - }, - "duplicates": { - "type": "integer", - "format": "int64" - }, - "blocklisted": { - "type": "integer", - "format": "int64" - } - } + "description": "Time-limited link to the uploaded screenshot. List the queue again for a fresh link." }, - "eta_seconds": { + "attempts": { "type": "integer", - "nullable": true + "description": "How many files the end user uploaded for this proof." }, - "created_at": { - "type": "string", - "format": "date-time" + "failure_reason": { + "allOf": [ + { + "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason" + } + ], + "description": "REVIEW_REJECTED after a rejection, OWNERSHIP_CHANGED when the wallet changed holder or was deleted before a decision. Empty otherwise." }, - "started_at": { + "method_chosen_at": { "type": "string", "format": "date-time", - "nullable": true + "nullable": true, + "description": "When the end user picked the screenshot method." }, - "completed_at": { + "decided_at": { "type": "string", "format": "date-time", "nullable": true - } - } - }, - "FiledRegulatoryReport": { - "type": "object", - "description": "A finalized regulatory report that prevents the requested deletion.", - "required": [ - "uuid", - "report_number", - "report_type", - "case_uuid" - ], - "properties": { - "uuid": { - "type": "string", - "format": "uuid", - "description": "Report UUID." }, - "report_number": { + "decided_by": { "type": "string", - "description": "Report number shown in the Console (for example, SAR-0001)." + "description": "Who closed the proof: review: for a console reviewer, review for an API-key decision, widget or sweeper when Didit closed it automatically. Empty while PENDING." }, - "report_type": { + "review_note": { "type": "string", - "enum": [ - "SAR", - "STR", - "CTR", - "TTR", - "UTR", - "IFT", - "CBR", - "TFR" - ], - "description": "Regulatory report type." + "description": "The note sent with the decision. Empty when none." }, - "case_uuid": { + "created_at": { "type": "string", - "format": "uuid", - "description": "Case the report belongs to." + "format": "date-time" } } }, - "FiledReportTransaction": { + "TravelRuleWalletProofDecision": { "type": "object", - "description": "A transaction that cannot be deleted because a finalized regulatory report lists it.", "required": [ - "uuid", - "transaction_id", - "reports" + "decision" ], "properties": { - "uuid": { + "decision": { "type": "string", - "format": "uuid", - "description": "Didit transaction UUID." + "enum": [ + "approve", + "reject" + ] }, - "transaction_id": { + "note": { "type": "string", - "description": "The transaction identifier supplied when the transaction was created." - }, - "reports": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FiledRegulatoryReport" - }, - "description": "Finalized reports that list this transaction." + "maxLength": 512, + "description": "Optional. Kept with the proof and returned as review_note." } } }, - "InFiledReportError": { + "DigitalIdWalletApiWalletDigitalCredentialsRequest": { "type": "object", - "description": "The deletion is refused because the selected data is in a finalized regulatory report. Nothing is deleted. Delete the report, then repeat the request.", - "required": [ - "detail", - "code" - ], "properties": { - "detail": { - "type": "string" - }, - "code": { + "protocol": { "type": "string", - "enum": [ - "in_filed_report" - ], - "description": "Stable error code for a deletion blocked by a finalized regulatory report." + "description": "openid4vp-v1-signed." }, - "reports": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FiledRegulatoryReport" - }, - "description": "Reports that block a person, company, case or session deletion." - }, - "transactions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FiledReportTransaction" - }, - "description": "Transactions that block a transaction deletion, each with the reports that list it." + "request": { + "type": "object", + "additionalProperties": {}, + "description": "Pass as is: navigator.credentials.get({digital: request}) in the browser, or JSON.stringify(request) as GetDigitalCredentialOption's requestJson on Android. Signed by Didit for your application." } - } + }, + "required": [ + "protocol", + "request" + ] }, - "TravelRuleNetworkParticipantSummary": { + "DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest": { "type": "object", - "nullable": true, - "description": "This application's own participant on the network, or null when it has none.", + "description": "Start a Google Wallet verification (USA, GBR, BRA, SGP, TWN).", "properties": { - "mode": { - "type": "string", - "enum": [ - "platform", - "own" - ], - "description": "platform: carried by Didit's membership; own: onboarded under the application's own membership." - }, - "status": { + "vendor_data": { "type": "string", - "enum": [ - "not_requested", - "questionnaire_pending", - "submitted_to_network", - "active", - "suspended", - "rejected" - ], - "description": "not_requested: never requested, or the network refused the first request (see last_error); questionnaire_pending: waiting for the due-diligence questionnaire to be approved; submitted_to_network: handed to the network's onboarding; active: the network gave this application its own participant code; suspended / rejected: Didit suspended or rejected it." + "nullable": true, + "description": "Your own reference for this verification (e.g. your user id). Returned in results and webhooks." }, - "participant_code": { - "type": "string", - "description": "The code the network gave this application (for GTR, its VASP code). Outbound messages carry this code, never Didit's own." + "metadata": { + "type": "object", + "additionalProperties": {}, + "nullable": true, + "description": "Optional JSON object stored with the verification and returned in results and webhooks." }, - "requested_at": { + "sandbox_scenario": { "type": "string", - "format": "date-time", - "nullable": true + "minLength": 1, + "description": "Sandbox applications only: the simulated outcome - 'wallet_cancelled', 'wallet_timeout' or 'wallet_provider_error'; any other scenario (or none) verifies. Rejected on live applications. The full catalog is available at GET /v1/sandbox/scenarios/." }, - "activated_at": { - "type": "string", - "format": "date-time", - "nullable": true + "country": { + "allOf": [ + { + "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum" + } + ], + "description": "ISO 3166-1 alpha-3 country of the Google Wallet identity.\n\n* `USA` - USA\n* `GBR` - GBR\n* `BRA` - BRA\n* `SGP` - SGP\n* `TWN` - TWN" }, - "last_error": { + "origin": { "type": "string", - "description": "The network's answer when it refused the registration; empty otherwise." + "minLength": 1, + "description": "Where your page or app will ask the wallet: the https origin of your page (its host must be in the application's allowed_return_hosts, or be its white-label domain), e.g. https://app.example.com, or android:apk-key-hash:. The wallet refuses the request anywhere else.", + "maxLength": 256 } - } + }, + "required": [ + "country", + "origin" + ] }, - "TravelRuleNetworkState": { + "DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum": { + "enum": [ + "USA", + "GBR", + "BRA", + "SGP", + "TWN" + ], + "type": "string", + "description": "* `USA` - USA\n* `GBR` - GBR\n* `BRA` - BRA\n* `SGP` - SGP\n* `TWN` - TWN" + }, + "DigitalIdWalletApiWalletDigitalCredentialResponseRequest": { "type": "object", - "description": "How Travel Rule messages on one network would be sent for this application, and why they cannot be. Configuration status, not a live health or delivery check.", + "description": "What the wallet answered your page or app, for a ``request_digital_credential`` verification.", "properties": { - "rail": { - "type": "string", - "enum": [ - "GTR", - "TRUST", - "VERIFYVASP", - "SYGNA" - ] - }, - "mode": { - "type": "string", - "enum": [ - "own", - "didit", - "off", - "unavailable" - ], - "description": "own: the application's connected membership is used; didit: Didit's membership carries the application as its own active participant; off: platform routing disabled in disabled_networks with no own membership; unavailable: nothing can send on this network yet (see state and reason)." - }, - "state": { - "type": "string", - "enum": [ - "own_membership", - "live_through_didit", - "off", - "didit_onboarding", - "questionnaire_needed", - "questionnaire_in_review", - "request_access", - "request_sent", - "unavailable", - "error" - ], - "description": "own_membership: your connected membership sends; live_through_didit: your own participant on Didit's membership sends; off: you switched platform routing off; didit_onboarding: Didit's own membership of this network is not live yet, so it cannot carry anyone; questionnaire_needed / questionnaire_in_review: the due-diligence questionnaire must be submitted or is with Didit; request_access: the questionnaire is approved, request the network; request_sent: your participant is being onboarded; unavailable: see reason; error: see reason." - }, - "reason": { + "response": { + "type": "object", + "additionalProperties": {}, + "description": "Exactly what the wallet returned: {protocol, data} of the DigitalCredential from navigator.credentials.get, or the parsed credentialJson of Android's DigitalCredential. Encrypted to Didit; do not alter it." + } + }, + "required": [ + "response" + ] + }, + "SessionFilesExport": { + "type": "object", + "description": "One ZIP with every file of a session, in original quality.", + "required": [ + "export_id", + "session_id", + "status", + "file_count", + "size_bytes", + "download_url", + "expires_at", + "error", + "created_at", + "completed_at" + ], + "properties": { + "export_id": { "type": "string", - "enum": [ - "own_membership_connected", - "platform_network_switched_off", - "own_membership_only", - "sandbox_application", - "didit_membership_not_live", - "participant_suspended", - "participant_rejected", - "questionnaire_not_submitted", - "questionnaire_submitted", - "questionnaire_changes_requested", - "questionnaire_rejected", - "participant_not_requested", - "participant_active", - "participant_key_missing", - "participant_key_unresolved", - "provisioning_failed", - "questionnaire_pending", - "submitted_to_network" - ], - "description": "Machine-readable detail of state. own_membership_only: Didit does not carry applications on this network (TRUST), connect your own membership; sandbox_application: sandbox transfers never reach a network; provisioning_failed: the network refused the registration, the participant's last_error says why and requesting the network again retries." - }, - "platform_available": { - "type": "boolean", - "description": "Whether Didit's own membership of this network is configured; not a live health check." + "format": "uuid", + "description": "ID of the export. Pass it to `GET /v3/session/{sessionId}/files-export/{exportId}/`." }, - "connected": { - "type": "boolean", - "description": "Whether a connected customer membership exists. Credentials are validated locally; network validation occurs on a live exchange." + "session_id": { + "type": "string", + "format": "uuid", + "description": "The session the files are from." }, - "participant": { - "$ref": "#/components/schemas/TravelRuleNetworkParticipantSummary" + "status": { + "type": "string", + "enum": [ + "PENDING", + "PROCESSING", + "READY", + "FAILED", + "EXPIRED" + ], + "description": "`PENDING` and `PROCESSING` while the ZIP is prepared, `READY` once it can be downloaded, `FAILED` when it could not be prepared (request a new export), `EXPIRED` once the ZIP was deleted." }, - "vasps_reachable": { + "file_count": { "type": "integer", - "description": "Directory VASPs reachable on this network." + "nullable": true, + "description": "Files in the ZIP. Set only while `status` is `READY`." }, - "routed_30d": { + "size_bytes": { "type": "integer", - "description": "This application's transfers carried on this network in the last 30 days." - } - } - }, - "TravelRuleNetworkQuestionnaireAnswers": { - "type": "object", - "description": "Didit's network due-diligence questionnaire. Saves are partial: a save keeps every answer it does not name. Submitting requires every field except lei and data_protection_contact_email, and the three attestations true.", - "properties": { - "legal_name": { - "type": "string", - "maxLength": 255 + "format": "int64", + "nullable": true, + "description": "Size of the ZIP in bytes. Set only while `status` is `READY`." }, - "registration_number": { + "download_url": { "type": "string", - "maxLength": 255 + "format": "uri", + "nullable": true, + "description": "Signed URL of the ZIP, valid for a short time. Set only while `status` is `READY`; read the export again for a new one." }, - "incorporation_country": { + "expires_at": { "type": "string", - "minLength": 2, - "maxLength": 2, - "description": "ISO 3166-1 alpha-2 country code." + "format": "date-time", + "nullable": true, + "description": "When the ZIP is deleted, 24 hours after it was ready. Set only while `status` is `READY`." }, - "registered_address": { + "error": { "type": "string", - "maxLength": 1000 + "nullable": true, + "description": "Why the export failed, when `status` is `FAILED`." }, - "website": { + "created_at": { "type": "string", - "format": "uri", - "maxLength": 500 + "format": "date-time", + "description": "When the export was requested." }, - "lei": { + "completed_at": { "type": "string", - "maxLength": 20, - "description": "Optional. A valid ISO 17442 LEI when given." + "format": "date-time", + "nullable": true, + "description": "When the ZIP was ready or the export failed." + } + } + }, + "TransactionRuleSuggestionsCreatedEvent": { + "description": "A transaction rule suggestion run proposed new rule changes for your application. Sent when the rule-suggestion settings have webhook notifications on. There is no top-level `status`.", + "allOf": [ + { + "$ref": "#/components/schemas/WebhookEventEnvelope" }, - "licences": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "required": [ - "regulator", - "jurisdiction", - "licence_type", - "licence_number" - ], - "properties": { - "regulator": { - "type": "string", - "maxLength": 255 - }, - "jurisdiction": { - "type": "string", - "minLength": 2, - "maxLength": 2, - "description": "ISO 3166-1 alpha-2 country code." - }, - "licence_type": { - "type": "string", - "maxLength": 255 - }, - "licence_number": { - "type": "string", - "maxLength": 255 + { + "type": "object", + "properties": { + "webhook_type": { + "type": "string", + "enum": [ + "transaction_rule_suggestions.created" + ], + "description": "Always `transaction_rule_suggestions.created`." + }, + "run_id": { + "type": "string", + "format": "uuid", + "description": "The suggestion run that produced the new suggestions." + }, + "open_count": { + "type": "integer", + "description": "Number of suggestions that are still open after this run, new ones included." + }, + "suggestions": { + "type": "array", + "description": "The suggestions this run created.", + "items": { + "type": "object", + "required": [ + "suggestion_id", + "kind", + "title", + "rule_id", + "expected_impact" + ], + "properties": { + "suggestion_id": { + "type": "string", + "format": "uuid" + }, + "kind": { + "type": "string", + "enum": [ + "ADD", + "TWEAK", + "DISABLE" + ], + "description": "`ADD` proposes a new rule, `TWEAK` changes an existing one, `DISABLE` turns one off." + }, + "title": { + "type": "string" + }, + "rule_id": { + "type": "string", + "format": "uuid", + "nullable": true, + "description": "The rule a `TWEAK` or `DISABLE` suggestion applies to; `null` for `ADD`." + }, + "expected_impact": { + "type": "object", + "additionalProperties": true, + "description": "What the change would do, as the suggestion shows it in the Console." + } + } } } }, - "description": "Every licence or registration the VASP holds." + "required": [ + "webhook_type", + "run_id", + "open_count", + "suggestions" + ] + } + ] + }, + "GeolocationCheck": { + "type": "object", + "description": "One Location verification result, the accepted attempt of one workflow node. Measurement, uncertainty and authenticity are separate keys, so a precise unattested fix reads differently from an imprecise attested one.", + "properties": { + "node_id": { + "type": "string", + "nullable": true, + "description": "Workflow node that produced this result, so a workflow with two Location verification steps stays readable." }, - "operating_jurisdictions": { - "type": "array", - "minItems": 1, - "maxItems": 250, - "items": { - "type": "string", - "minLength": 2, - "maxLength": 2, - "description": "ISO 3166-1 alpha-2 country code." - } + "status": { + "type": "string", + "enum": [ + "Not Finished", + "Approved", + "Declined", + "In Review", + "Resub Requested" + ], + "description": "Feature-level status of this Location verification step, resolved from its warnings. Independent of the session `status`." }, - "compliance_officer_name": { + "outcome": { "type": "string", - "maxLength": 255 + "nullable": true, + "description": "What happened on this attempt.", + "enum": [ + "verified", + "low_accuracy", + "accuracy_undetermined", + "stale", + "approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "mock_detected", + "outside_geofence", + "in_blocked_area", + "anonymizer_detected", + "skipped", + "replay_rejected", + "unsupported_client", + null + ] }, - "compliance_officer_email": { + "permission": { "type": "string", - "format": "email" + "nullable": true, + "description": "What the operating system or browser granted. `not_requested` means the step uses the connection's IP location only, so the person is never asked for a permission.", + "enum": [ + "granted_precise", + "granted_approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "dismissed", + "not_requested", + null + ] }, - "aml_ctf_policy_attested": { - "type": "boolean", - "description": "Must be true to submit." + "latitude": { + "type": "number", + "nullable": true, + "description": "WGS84 latitude of the fix. `null` when there is no fix.", + "format": "double" }, - "sanctions_screening_attested": { - "type": "boolean", - "description": "Must be true to submit." + "longitude": { + "type": "number", + "nullable": true, + "description": "WGS84 longitude of the fix. `null` when there is no fix.", + "format": "double" }, - "data_protection_attested": { - "type": "boolean", - "description": "Must be true to submit." + "accuracy_m": { + "type": "number", + "nullable": true, + "description": "Radius of uncertainty in metres, at the confidence level in `accuracy_confidence`.", + "format": "double" }, - "data_protection_contact_email": { + "accuracy_confidence": { "type": "string", - "format": "email", - "description": "Optional." + "nullable": true, + "description": "Confidence level the platform attaches to `accuracy_m`: `p95` (browsers), `p68` (Android) or `unspecified` (iOS).", + "enum": [ + "p95", + "p68", + "unspecified", + null + ] }, - "expected_monthly_transfers": { + "measured_at": { + "type": "string", + "nullable": true, + "description": "When the device took the fix, by its own clock.", + "format": "date-time" + }, + "age_seconds": { "type": "integer", - "minimum": 0 + "nullable": true, + "description": "Seconds between the device taking the fix and Didit receiving it." }, - "expected_monthly_volume_usd": { + "source": { "type": "string", - "format": "decimal", - "description": "Expected monthly volume in USD, up to 2 decimal places. Returned as a string." + "nullable": true, + "description": "Where the fix came from, when the platform says. `ip` means the position is the connection's IP location.", + "enum": [ + "gps", + "fused", + "network", + "wifi", + "cell", + "browser", + "unknown", + "ip", + null + ] }, - "assets": { - "type": "array", - "minItems": 1, - "maxItems": 200, - "items": { - "type": "string", - "maxLength": 32 - }, - "description": "Asset tickers, stored upper-case, sorted and de-duplicated." - } - } - }, - "TravelRuleNetworkQuestionnaire": { - "type": "object", - "properties": { - "status": { + "platform": { "type": "string", + "nullable": true, + "description": "The client that produced the fix.", "enum": [ - "draft", - "submitted", - "changes_requested", - "approved", - "rejected" - ], - "description": "Answers can be saved while draft or changes_requested; submitted, approved and rejected are Didit's to move." + "web", + "ios", + "android", + "react_native", + "flutter", + null + ] }, - "answers": { - "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers" + "sdk_version": { + "type": "string", + "nullable": true, + "description": "Version of the SDK that produced the fix." }, - "submitted_at": { + "is_mock": { + "type": "boolean", + "nullable": true, + "description": "`true` when the device says the fix came from a mock location provider or simulation software. `null` when the platform does not report it (browsers cannot tell); `null` is not `false`." + }, + "produced_by_accessory": { + "type": "boolean", + "nullable": true, + "description": "iOS only: `true` when the fix came from an external accessory. `null` elsewhere." + }, + "integrity": { "type": "string", - "format": "date-time", - "nullable": true + "enum": [ + "attested", + "not_attested", + "failed", + "unsupported", + "not_determined" + ], + "description": "Whether device attestation backs the fix. `unsupported` is what browsers report, because the web has no attestation mechanism; it is not a failure." }, - "reviewed_at": { + "country_code": { "type": "string", - "format": "date-time", - "nullable": true + "nullable": true, + "description": "ISO 3166-1 alpha-2 country the fix is in." }, - "review_note": { + "region_code": { "type": "string", - "description": "Didit's note on its last decision, for example what to change." + "nullable": true, + "description": "ISO 3166-2 subdivision the fix is in." }, - "history": { - "type": "array", - "readOnly": true, - "description": "Every status change, oldest first.", - "items": { - "type": "object", - "properties": { - "at": { - "type": "string", - "format": "date-time" - }, - "from": { - "type": "string" - }, - "to": { - "type": "string" - }, - "note": { - "type": "string", - "description": "Review note or the network's answer, when there is one." - } + "city": { + "type": "string", + "nullable": true, + "description": "Nearest populated place, a label for reviewers." + }, + "geofence": { + "type": "object", + "description": "Result of the country and area rules of the step.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether the step applies any country or area rule." + }, + "result": { + "type": "string", + "nullable": true, + "description": "Where the position sits relative to the rules. `undetermined` means the accuracy circle straddles the border or the position resolved to no country; it is not evidence of being outside.", + "enum": [ + "inside", + "outside", + "undetermined", + null + ] } } }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true - } - } - }, - "TravelRuleNetworkParticipant": { - "type": "object", - "description": "This application's own participant on one network.", - "properties": { - "network": { - "type": "string", - "enum": [ - "gtr", - "trust", - "verifyvasp", - "sygna" - ] + "inside_geofence": { + "type": "boolean", + "nullable": true, + "description": "`true` when `geofence.result` is `inside`, `false` when `outside`, `null` otherwise." }, - "rail": { + "geofence_basis": { "type": "string", + "nullable": true, + "description": "Which position the area result was judged from: the `device` fix, or the connection's `ip` location.", "enum": [ - "GTR", - "TRUST", - "VERIFYVASP", - "SYGNA" + "device", + "ip", + null ] }, - "mode": { + "inside_areas": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ids of the configured allowed areas the position is inside." + }, + "blocked_areas": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ids of the configured blocked areas the position is in." + }, + "position_source": { "type": "string", + "nullable": true, + "description": "Where the step takes the position from, as configured: the device checked against the IP location, the device only, or the IP location only.", "enum": [ - "platform", - "own" + "device_and_ip", + "device_only", + "ip_only", + null ] }, - "status": { - "type": "string", - "enum": [ - "not_requested", - "questionnaire_pending", - "submitted_to_network", - "active", - "suspended", - "rejected" - ], - "description": "not_requested: never requested, or the network refused the first request (see last_error); questionnaire_pending: waiting for the due-diligence questionnaire to be approved; submitted_to_network: handed to the network's onboarding; active: the network gave this application its own participant code; suspended / rejected: Didit suspended or rejected it." + "anonymizers": { + "type": "object", + "nullable": true, + "description": "What the connection and device look like, each `true`, `false` or `null` when the source cannot tell.", + "properties": { + "vpn": { + "type": "boolean", + "nullable": true + }, + "proxy": { + "type": "boolean", + "nullable": true + }, + "tor": { + "type": "boolean", + "nullable": true + }, + "spoofing": { + "type": "boolean", + "nullable": true + }, + "emulator": { + "type": "boolean", + "nullable": true + } + } }, - "participant_code": { - "type": "string" + "ip_distance_km": { + "type": "number", + "nullable": true, + "description": "Distance to the session's IP location after both uncertainty radii are subtracted; `0` when they overlap.", + "format": "double" }, - "requested_at": { - "type": "string", - "format": "date-time", - "nullable": true + "ip_distance_uncertainty_km": { + "type": "number", + "nullable": true, + "description": "Combined radius that was subtracted: the IP location's radius plus this fix's accuracy.", + "format": "double" }, - "submitted_at": { - "type": "string", - "format": "date-time", - "nullable": true + "ip_consistent": { + "type": "boolean", + "nullable": true, + "description": "Whether `ip_distance_km` is within the distance configured on the step. `null` when either side is unknown." }, - "activated_at": { - "type": "string", - "format": "date-time", - "nullable": true + "document_distance_km": { + "type": "number", + "nullable": true, + "description": "Distance to the geocoded address on the ID document or proof of address. `null` when no address is on file.", + "format": "double" }, - "suspended_at": { - "type": "string", - "format": "date-time", - "nullable": true + "travel_excused": { + "type": "boolean", + "nullable": true, + "description": "Whether the step's travel tolerance excused the distance from the address. `null` when tolerance is off." }, - "last_error": { - "type": "string", - "description": "The network's answer when it refused the registration; empty otherwise." + "consecutive_mismatches": { + "type": "integer", + "nullable": true, + "description": "On the final attempt: this check plus the same person's earlier mismatches in a row." }, - "history": { + "attempts": { + "type": "integer", + "description": "Number of this attempt within the node, starting at 1." + }, + "consent": { + "type": "object", + "nullable": true, + "description": "The consent the person gave before the system prompt, recorded with the wording version and language they saw.", + "properties": { + "accepted_at": { + "type": "string", + "format": "date-time" + }, + "version": { + "type": "string", + "nullable": true + }, + "locale": { + "type": "string", + "nullable": true + } + } + }, + "warnings": { "type": "array", - "readOnly": true, - "description": "Every status change, oldest first.", "items": { "type": "object", "properties": { - "at": { + "feature": { "type": "string", - "format": "date-time" + "enum": [ + "ID_VERIFICATION", + "NFC", + "LIVENESS", + "FACEMATCH", + "PROOF_OF_ADDRESS", + "PHONE", + "EMAIL", + "AML", + "LOCATION", + "DATABASE_VALIDATION", + "QUESTIONNAIRE", + "DOCUMENT_AI", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE" + ], + "description": "The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload." }, - "from": { + "risk": { "type": "string" }, - "to": { + "additional_data": { + "type": "object", + "nullable": true + }, + "log_type": { "type": "string" }, - "note": { + "short_description": { + "type": "string" + }, + "long_description": { + "type": "string" + }, + "node_id": { "type": "string", - "description": "Review note or the network's answer, when there is one." + "description": "The workflow graph node ID that generated this warning" } } - } - } - } - }, - "TravelRuleNetworksOverview": { - "type": "object", - "properties": { - "platform_networks_enabled": { - "type": "boolean", - "description": "Whether network access through Didit's membership is open. While false, questionnaire saves, submissions and network requests answer 403." - }, - "questionnaire": { - "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire" - }, - "participants": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TravelRuleNetworkParticipant" - } - }, - "networks": { - "type": "object", - "readOnly": true, - "description": "Per network, how this application would send and why it cannot. No network, including GTR, is included by default: a network is reachable through your own connected membership, or through Didit's membership once Didit's membership of that network is live and your own participant on it is active. Not a live health or delivery check.", - "properties": { - "gtr": { - "$ref": "#/components/schemas/TravelRuleNetworkState" - }, - "trust": { - "$ref": "#/components/schemas/TravelRuleNetworkState" - }, - "verifyvasp": { - "$ref": "#/components/schemas/TravelRuleNetworkState" - }, - "sygna": { - "$ref": "#/components/schemas/TravelRuleNetworkState" - } - } + }, + "description": "Warnings this Location verification step raised, with `feature` set to `GEOLOCATION`. Warning codes start with `LOCATION_`." } } }, - "AddressValidationResult": { + "GeolocationAttempt": { "type": "object", - "description": "The result of one Address Validation: whether the address exists, and its normalised form. It confirms the address only; it never links the address to a person.", - "required": [ - "status", - "verification_level", - "address", - "formatted_address", - "latitude", - "longitude" - ], + "description": "One attempt of a Location verification step: the same keys as `geolocation_checks[]` except `warnings`, plus when Didit received it.", "properties": { + "node_id": { + "type": "string", + "nullable": true, + "description": "Workflow node that produced this result, so a workflow with two Location verification steps stays readable." + }, "status": { "type": "string", "enum": [ - "verified", - "partially_verified", - "not_verified", - "unavailable" + "Not Finished", + "Approved", + "Declined", + "In Review", + "Resub Requested" ], - "description": "`verified`: the address was confirmed down to the building (or the flat or PO box). `partially_verified`: it was confirmed only to the street, or to the most precise level the postal reference data holds for that place. `not_verified`: only the region or the city matched, or nothing did. `unavailable`: the validation could not run (for example the reference service did not answer); it is not charged and never affects a verification." + "description": "Feature-level status of this Location verification step, resolved from its warnings. Independent of the session `status`." }, - "verification_level": { + "outcome": { "type": "string", "nullable": true, + "description": "What happened on this attempt.", "enum": [ - "administrative_area", - "locality", - "thoroughfare", - "premise", - "delivery_point", + "verified", + "low_accuracy", + "accuracy_undetermined", + "stale", + "approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "mock_detected", + "outside_geofence", + "in_blocked_area", + "anonymizer_detected", + "skipped", + "replay_rejected", + "unsupported_client", null - ], - "description": "The most precise level the address was matched to. `null` when nothing matched or `status` is `unavailable`." - }, - "address": { - "type": "object", - "nullable": true, - "description": "The normalised address. `null` when `status` is `unavailable`.", - "properties": { - "address_line_1": { - "type": "string", - "nullable": true, - "description": "First delivery line, written the way the country writes it.", - "example": "1600 Amphitheatre Pkwy" - }, - "address_line_2": { - "type": "string", - "nullable": true, - "description": "Second delivery line (a flat, building or neighbourhood), when the address has one." - }, - "city": { - "type": "string", - "nullable": true, - "example": "Mountain View" - }, - "region": { - "type": "string", - "nullable": true, - "description": "State, province or region.", - "example": "CA" - }, - "postal_code": { - "type": "string", - "nullable": true, - "example": "94043-1351" - }, - "country": { - "type": "string", - "nullable": true, - "description": "ISO 3166-1 alpha-2 country code.", - "example": "US" - } - } + ] }, - "formatted_address": { + "permission": { "type": "string", "nullable": true, - "description": "The normalised address on one line.", - "example": "1600 Amphitheatre Pkwy, Mountain View CA 94043-1351" + "description": "What the operating system or browser granted. `not_requested` means the step uses the connection's IP location only, so the person is never asked for a permission.", + "enum": [ + "granted_precise", + "granted_approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "dismissed", + "not_requested", + null + ] }, "latitude": { "type": "number", "nullable": true, - "example": 37.422022 + "description": "WGS84 latitude of the fix. `null` when there is no fix.", + "format": "double" }, "longitude": { "type": "number", "nullable": true, - "example": -122.08429 - } - } - }, - "AddressValidationRequest": { - "type": "object", - "required": [ - "country" - ], - "description": "One address: on one line (`address`) or as structured fields with at least `address_line_1`, never both.", - "properties": { - "address": { - "type": "string", - "maxLength": 500, - "description": "The whole address on one line.", - "example": "Paseo de la Castellana 259, 28046 Madrid" - }, - "address_line_1": { - "type": "string", - "maxLength": 255, - "description": "Street and number.", - "example": "1600 Amphitheatre Pkwy" - }, - "address_line_2": { - "type": "string", - "maxLength": 255, - "description": "Apartment, suite, floor or building." + "description": "WGS84 longitude of the fix. `null` when there is no fix.", + "format": "double" }, - "city": { - "type": "string", - "maxLength": 128, - "description": "City or locality.", - "example": "Mountain View" - }, - "region": { - "type": "string", - "maxLength": 128, - "description": "State, province or region.", - "example": "CA" - }, - "postal_code": { - "type": "string", - "maxLength": 32, - "example": "94043" + "accuracy_m": { + "type": "number", + "nullable": true, + "description": "Radius of uncertainty in metres, at the confidence level in `accuracy_confidence`.", + "format": "double" }, - "country": { - "type": "string", - "maxLength": 3, - "description": "ISO 3166-1 alpha-2 or alpha-3 code of the address's country.", - "example": "US" - } - } - }, - "AddressValidationResponse": { - "type": "object", - "required": [ - "request_id", - "address_validation", - "created_at" - ], - "properties": { - "request_id": { + "accuracy_confidence": { "type": "string", - "format": "uuid", - "description": "Identifier of this request; quote it to support. No session is created." - }, - "address_validation": { - "$ref": "#/components/schemas/AddressValidationResult" + "nullable": true, + "description": "Confidence level the platform attaches to `accuracy_m`: `p95` (browsers), `p68` (Android) or `unspecified` (iOS).", + "enum": [ + "p95", + "p68", + "unspecified", + null + ] }, - "created_at": { + "measured_at": { "type": "string", + "nullable": true, + "description": "When the device took the fix, by its own clock.", "format": "date-time" - } - } - }, - "TravelRuleWalletProofFailureReason": { - "type": "string", - "enum": [ - "", - "SIGNATURE_INVALID", - "SIGNATURE_UNSUPPORTED_SCHEME", - "DEPOSIT_NOT_FOUND", - "DEPOSIT_UNCONFIRMED", - "DEPOSIT_LOOKUP_FAILED", - "DEPOSIT_MISMATCH", - "DEPOSIT_STALE", - "TXID_REUSED", - "CHAIN_UNSUPPORTED", - "WINDOW_EXPIRED", - "OWNERSHIP_CHANGED", - "METHOD_SWITCHED", - "REVIEW_REJECTED", - "ABANDONED" - ], - "description": "Why a wallet-ownership proof, or its last attempt, fell short of VERIFIED. Empty when nothing failed. A PENDING proof can carry one: the last attempt failed and the end user can try again. DEPOSIT_MISMATCH, DEPOSIT_STALE, TXID_REUSED and REVIEW_REJECTED close the proof as REJECTED. SIGNATURE_INVALID: the signature does not match the wallet and challenge. SIGNATURE_UNSUPPORTED_SCHEME: the wallet signed in a format Didit does not verify. DEPOSIT_NOT_FOUND, DEPOSIT_UNCONFIRMED, DEPOSIT_LOOKUP_FAILED: the test deposit is not readable or not confirmed yet; Didit keeps checking it until the test window closes. DEPOSIT_MISMATCH: the transaction does not send the expected amount from the wallet to the deposit address. DEPOSIT_STALE: the transaction predates the challenge. TXID_REUSED: the transaction already proved another wallet. CHAIN_UNSUPPORTED: the method is not available on this chain. WINDOW_EXPIRED: the test window closed. OWNERSHIP_CHANGED: the wallet's holder changed, or the wallet was deleted from your address book, after the widget session was minted. METHOD_SWITCHED: the end user picked another method before finishing this one. REVIEW_REJECTED: your reviewer rejected the screenshot. ABANDONED: the widget session lapsed before the end user finished." - }, - "TravelRuleWidgetProofError": { - "type": "object", - "properties": { - "detail": { - "type": "string", - "description": "Human-readable message in English." }, - "code": { - "allOf": [ - { - "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason" - } - ], - "description": "Machine-readable reason, so a client can show its own translated message." + "age_seconds": { + "type": "integer", + "nullable": true, + "description": "Seconds between the device taking the fix and Didit receiving it." }, - "status": { + "source": { "type": "string", + "nullable": true, + "description": "Where the fix came from, when the platform says. `ip` means the position is the connection's IP location.", "enum": [ - "PENDING", - "VERIFIED", - "REJECTED", - "EXPIRED" - ], - "description": "Present when the proof is closed: REJECTED by the deposit just submitted (400), or REJECTED or EXPIRED when evidence is sent to a proof that is already closed (409)." + "gps", + "fused", + "network", + "wifi", + "cell", + "browser", + "unknown", + "ip", + null + ] }, - "proof_id": { + "platform": { "type": "string", - "format": "uuid", - "description": "Present with status: the closed proof." + "nullable": true, + "description": "The client that produced the fix.", + "enum": [ + "web", + "ios", + "android", + "react_native", + "flutter", + null + ] }, - "method": { + "sdk_version": { "type": "string", - "enum": [ - "MESSAGE_SIGNING", - "SATOSHI_TEST", - "SCREENSHOT", - "SELF_DECLARATION" - ], - "description": "Present with status: the closed proof's method." + "nullable": true, + "description": "Version of the SDK that produced the fix." }, - "max_attempts": { - "type": "integer", - "description": "Present with status: rejected wallet proofs this session allows." + "is_mock": { + "type": "boolean", + "nullable": true, + "description": "`true` when the device says the fix came from a mock location provider or simulation software. `null` when the platform does not report it (browsers cannot tell); `null` is not `false`." }, - "attempts_used": { - "type": "integer", - "description": "Present with status: rejected proofs so far." + "produced_by_accessory": { + "type": "boolean", + "nullable": true, + "description": "iOS only: `true` when the fix came from an external accessory. `null` elsewhere." }, - "attempts_remaining": { - "type": "integer", - "description": "Present with status: when 0, starting another proof answers 409 and you mint a new widget session." - } - } - }, - "TravelRuleWidgetProofCreate": { - "type": "object", - "required": [ - "method" - ], - "properties": { - "method": { + "integrity": { "type": "string", "enum": [ - "MESSAGE_SIGNING", - "SATOSHI_TEST", - "SCREENSHOT", - "SELF_DECLARATION" + "attested", + "not_attested", + "failed", + "unsupported", + "not_determined" ], - "description": "The proof method the end user picked. It must be one of the context's allowed_methods." + "description": "Whether device attestation backs the fix. `unsupported` is what browsers report, because the web has no attestation mechanism; it is not a failure." }, - "wallet_address": { + "country_code": { "type": "string", - "maxLength": 128, - "description": "Defaults to the session's wallet_address. Must match the transfer's wallet when the session is linked to a transfer." + "nullable": true, + "description": "ISO 3166-1 alpha-2 country the fix is in." }, - "chain": { - "type": "string", - "maxLength": 32, - "description": "Defaults to the session's chain." - } - } - }, - "TravelRuleWidgetProofVerifyResult": { - "type": "object", - "properties": { - "proof_id": { + "region_code": { "type": "string", - "format": "uuid" + "nullable": true, + "description": "ISO 3166-2 subdivision the fix is in." }, - "method": { + "city": { "type": "string", - "enum": [ - "MESSAGE_SIGNING", - "SATOSHI_TEST", - "SCREENSHOT", - "SELF_DECLARATION" - ] + "nullable": true, + "description": "Nearest populated place, a label for reviewers." }, - "status": { - "type": "string", - "enum": [ - "PENDING", - "VERIFIED", - "REJECTED", - "EXPIRED" - ] + "geofence": { + "type": "object", + "description": "Result of the country and area rules of the step.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether the step applies any country or area rule." + }, + "result": { + "type": "string", + "nullable": true, + "description": "Where the position sits relative to the rules. `undetermined` means the accuracy circle straddles the border or the position resolved to no country; it is not evidence of being outside.", + "enum": [ + "inside", + "outside", + "undetermined", + null + ] + } + } }, - "is_ownership_verified": { + "inside_geofence": { "type": "boolean", - "description": "Present when the proof is VERIFIED: the address book entry is now ownership-verified." - }, - "transfer_status": { - "type": "string", "nullable": true, - "description": "Present when the proof is VERIFIED: the linked transfer's status, null without one." - }, - "detail": { - "type": "string", - "description": "Present while the proof stays PENDING: a submitted screenshot awaiting review, or a test deposit that is not confirmed yet." - }, - "code": { - "allOf": [ - { - "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason" - } - ], - "description": "Present on a pending test deposit: why it is not confirmed yet." - } - } - }, - "TravelRuleWalletProofReview": { - "type": "object", - "properties": { - "proof_id": { - "type": "string", - "format": "uuid" + "description": "`true` when `geofence.result` is `inside`, `false` when `outside`, `null` otherwise." }, - "method": { + "geofence_basis": { "type": "string", + "nullable": true, + "description": "Which position the area result was judged from: the `device` fix, or the connection's `ip` location.", "enum": [ - "SCREENSHOT" + "device", + "ip", + null ] }, - "status": { + "inside_areas": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ids of the configured allowed areas the position is inside." + }, + "blocked_areas": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ids of the configured blocked areas the position is in." + }, + "position_source": { "type": "string", + "nullable": true, + "description": "Where the step takes the position from, as configured: the device checked against the IP location, the device only, or the IP location only.", "enum": [ - "PENDING", - "VERIFIED", - "REJECTED", - "EXPIRED" + "device_and_ip", + "device_only", + "ip_only", + null ] }, - "wallet_address": { - "type": "string" + "anonymizers": { + "type": "object", + "nullable": true, + "description": "What the connection and device look like, each `true`, `false` or `null` when the source cannot tell.", + "properties": { + "vpn": { + "type": "boolean", + "nullable": true + }, + "proxy": { + "type": "boolean", + "nullable": true + }, + "tor": { + "type": "boolean", + "nullable": true + }, + "spoofing": { + "type": "boolean", + "nullable": true + }, + "emulator": { + "type": "boolean", + "nullable": true + } + } }, - "chain": { - "type": "string", - "description": "Canonical chain identifier, e.g. ETH, BTC, SOL, TRX." + "ip_distance_km": { + "type": "number", + "nullable": true, + "description": "Distance to the session's IP location after both uncertainty radii are subtracted; `0` when they overlap.", + "format": "double" }, - "holder_name": { - "type": "string" + "ip_distance_uncertainty_km": { + "type": "number", + "nullable": true, + "description": "Combined radius that was subtracted: the IP location's radius plus this fix's accuracy.", + "format": "double" }, - "is_ownership_verified": { + "ip_consistent": { "type": "boolean", - "description": "Whether the address book entry is ownership-verified, by this proof or another one." - }, - "transaction_id": { - "type": "string", - "format": "uuid", "nullable": true, - "description": "The transaction whose Travel Rule transfer the widget session was minted for. Null for a session minted without a transaction_id." + "description": "Whether `ip_distance_km` is within the distance configured on the step. `null` when either side is unknown." }, - "file_name": { - "type": "string", - "nullable": true + "document_distance_km": { + "type": "number", + "nullable": true, + "description": "Distance to the geocoded address on the ID document or proof of address. `null` when no address is on file.", + "format": "double" }, - "content_type": { - "type": "string", - "nullable": true + "travel_excused": { + "type": "boolean", + "nullable": true, + "description": "Whether the step's travel tolerance excused the distance from the address. `null` when tolerance is off." }, - "screenshot_url": { - "type": "string", + "consecutive_mismatches": { + "type": "integer", "nullable": true, - "description": "Time-limited link to the uploaded screenshot. List the queue again for a fresh link." + "description": "On the final attempt: this check plus the same person's earlier mismatches in a row." }, "attempts": { "type": "integer", - "description": "How many files the end user uploaded for this proof." + "description": "Number of this attempt within the node, starting at 1." }, - "failure_reason": { - "allOf": [ - { - "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason" + "consent": { + "type": "object", + "nullable": true, + "description": "The consent the person gave before the system prompt, recorded with the wording version and language they saw.", + "properties": { + "accepted_at": { + "type": "string", + "format": "date-time" + }, + "version": { + "type": "string", + "nullable": true + }, + "locale": { + "type": "string", + "nullable": true } - ], - "description": "REVIEW_REJECTED after a rejection, OWNERSHIP_CHANGED when the wallet changed holder or was deleted before a decision. Empty otherwise." + } }, - "method_chosen_at": { + "received_at": { "type": "string", - "format": "date-time", "nullable": true, - "description": "When the end user picked the screenshot method." - }, - "decided_at": { - "type": "string", - "format": "date-time", - "nullable": true - }, - "decided_by": { - "type": "string", - "description": "Who closed the proof: review: for a console reviewer, review for an API-key decision, widget or sweeper when Didit closed it automatically. Empty while PENDING." - }, - "review_note": { - "type": "string", - "description": "The note sent with the decision. Empty when none." + "description": "When Didit received the attempt.", + "format": "date-time" }, "created_at": { "type": "string", @@ -108859,23 +127272,54 @@ } } }, - "TravelRuleWalletProofDecision": { + "BiometricRetention": { "type": "object", + "description": "When the live biometric data of this session is deleted.", "required": [ - "decision" + "jurisdictions", + "deletes_at" ], "properties": { - "decision": { - "type": "string", - "enum": [ - "approve", - "reject" - ] + "jurisdictions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Codes of the US states whose biometric rules set a deletion limit for this person (`US` when the state is unknown). Empty when none applies." }, - "note": { + "deletes_at": { "type": "string", - "maxLength": 512, - "description": "Optional. Kept with the proof and returned as review_note." + "format": "date-time", + "nullable": true, + "description": "The date the live biometric data (face images and templates) of this session is deleted, from your application's retention setting and, where one applies, the legal limit for the person's jurisdiction. `null` when no date applies yet." + } + } + }, + "TravelRuleManualMatchRequest": { + "type": "object", + "required": [ + "transaction_id" + ], + "properties": { + "transaction_id": { + "type": "string", + "format": "uuid", + "description": "The `transaction_id` of the received Travel Rule message (a row with `kind: message`)." + } + } + }, + "TravelRuleManualMatchResponse": { + "type": "object", + "required": [ + "deposit", + "message" + ], + "properties": { + "deposit": { + "$ref": "#/components/schemas/TravelRuleTransferRow" + }, + "message": { + "$ref": "#/components/schemas/TravelRuleTransferRow" } } } @@ -108885,7 +127329,7 @@ "type": "apiKey", "in": "header", "name": "x-api-key", - "description": "Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is missing, wrong, revoked or expired; 403 means the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys." + "description": "Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is wrong, revoked or expired; 403 means no key was sent, the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys." }, "TransactionTokenAuth": { "type": "apiKey", @@ -109601,6 +128045,44 @@ } } } + }, + "transaction_rule_suggestions.created": { + "post": { + "summary": "Transaction rule suggestions created", + "description": "A transaction rule suggestion run proposed new rule changes for your application. Sent when the rule-suggestion settings have webhook notifications on. There is no top-level `status`.", + "tags": [ + "Webhook" + ], + "parameters": [ + { + "$ref": "#/components/parameters/WebhookSignature" + }, + { + "$ref": "#/components/parameters/WebhookSignatureV2" + }, + { + "$ref": "#/components/parameters/WebhookSignatureSimple" + }, + { + "$ref": "#/components/parameters/WebhookTimestamp" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent" + } + } + } + }, + "responses": { + "2XX": { + "description": "Any 2xx response acknowledges the delivery. Other responses and timeouts are retried; see https://docs.didit.me/integration/webhooks." + } + } + } } } } diff --git a/src/didit/resources/analytics.py b/src/didit/resources/analytics.py index 527e3cb..e385115 100644 --- a/src/didit/resources/analytics.py +++ b/src/didit/resources/analytics.py @@ -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, ) @@ -35,7 +36,7 @@ class Analytics(SyncAPIResource): """The ``analytics`` resource of the Didit API. - Methods: ``retrieve``. + Methods: ``retrieve``, ``retrieve_today``. """ @cached_property @@ -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 @@ -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) diff --git a/src/didit/resources/bank.py b/src/didit/resources/bank.py index cddba2b..c360d77 100644 --- a/src/didit/resources/bank.py +++ b/src/didit/resources/bank.py @@ -53,6 +53,7 @@ def account_check( account: BankAccountCheckParamsAccount, holder: BankAccountCheckHolder, vendor_data: str | None | NotGiven = NOT_GIVEN, + consent: bool | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -60,6 +61,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. @@ -70,7 +73,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. @@ -81,6 +84,7 @@ def account_check( account: The account the way its country writes it: an `iban`, or an `account_number` with the bank or branch code the country needs (`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code` or `bic`). Mexico takes a `clabe` and Argentina a `cbu_cvu`, which already name the bank. A business account adds a `registration_id` where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a `400` that names it. holder: The name the account is checked against. Send exactly one of `full_name` and `business_name`. vendor_data: Your own reference for this check, returned unchanged. + consent: Set to `true` when the account holder has explicitly consented to this check. Required in the countries whose account check needs that consent: without it the check is refused with a `400` whose `field` is `consent` and whose `reason` is `required`, and nothing is billed. Elsewhere it is optional, and Didit records it with the check's charge when you send it. 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. @@ -98,6 +102,7 @@ def account_check( "account": account, "holder": holder, "vendor_data": vendor_data, + "consent": consent, }, extra_headers=extra_headers, extra_query=extra_query, @@ -130,6 +135,7 @@ async def account_check( account: BankAccountCheckParamsAccount, holder: BankAccountCheckHolder, vendor_data: str | None | NotGiven = NOT_GIVEN, + consent: bool | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -137,6 +143,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. @@ -147,7 +155,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. @@ -158,6 +166,7 @@ async def account_check( account: The account the way its country writes it: an `iban`, or an `account_number` with the bank or branch code the country needs (`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code` or `bic`). Mexico takes a `clabe` and Argentina a `cbu_cvu`, which already name the bank. A business account adds a `registration_id` where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a `400` that names it. holder: The name the account is checked against. Send exactly one of `full_name` and `business_name`. vendor_data: Your own reference for this check, returned unchanged. + consent: Set to `true` when the account holder has explicitly consented to this check. Required in the countries whose account check needs that consent: without it the check is refused with a `400` whose `field` is `consent` and whose `reason` is `required`, and nothing is billed. Elsewhere it is optional, and Didit records it with the check's charge when you send it. 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. @@ -175,6 +184,7 @@ async def account_check( "account": account, "holder": holder, "vendor_data": vendor_data, + "consent": consent, }, extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/didit/resources/database_validation.py b/src/didit/resources/database_validation.py index e6952f3..f5b26fd 100644 --- a/src/didit/resources/database_validation.py +++ b/src/didit/resources/database_validation.py @@ -110,6 +110,22 @@ def validate( emission_number: str | NotGiven = NOT_GIVEN, bvn: str | NotGiven = NOT_GIVEN, bank_card_number: str | NotGiven = NOT_GIVEN, + company_registration_number: str | NotGiven = NOT_GIVEN, + company_name: str | NotGiven = NOT_GIVEN, + initials: str | NotGiven = NOT_GIVEN, + licence_number: str | NotGiven = NOT_GIVEN, + refugee_file_number: str | NotGiven = NOT_GIVEN, + bank_name: str | NotGiven = NOT_GIVEN, + bank_account_number: str | NotGiven = NOT_GIVEN, + account_type: str | NotGiven = NOT_GIVEN, + phone_number: str | NotGiven = NOT_GIVEN, + right_thumb: str | NotGiven = NOT_GIVEN, + left_thumb: str | NotGiven = NOT_GIVEN, + score_level: int | NotGiven = NOT_GIVEN, + max_matches: int | NotGiven = NOT_GIVEN, + vehicle_register_number: str | NotGiven = NOT_GIVEN, + vehicle_licence_plate: str | NotGiven = NOT_GIVEN, + vin: str | NotGiven = NOT_GIVEN, ssn: str | NotGiven = NOT_GIVEN, phone: str | NotGiven = NOT_GIVEN, landline: str | NotGiven = NOT_GIVEN, @@ -204,6 +220,22 @@ def validate( emission_number: Mexican INE Número de Emisión. Used with `voter_number` for legacy IFE models (A/B/C) in `mex_ine_vigencia`. bvn: Nigerian Bank Verification Number. bank_card_number: Bank card number (CHN bank-card verification). + company_registration_number: Company registration number as issued by the companies register: the CNPJ in Brazil (e.g. `11222333000181`), the registration number in South Africa (e.g. `1936/007721/06`). Required by the company registry and company directors services (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`). + company_name: Registered company name, cross-checked against the register entry. Optional for `zaf_company_registry`. + initials: The person's initials as printed on the document. Required by `zaf_drivers_license`; accepted by `zaf_bank_account_holder`. + licence_number: Driving licence number as printed on the card, for `zaf_drivers_license`. When omitted, `document_number` is used. + refugee_file_number: Refugee file number issued by South Africa's Department of Home Affairs. Required by `zaf_refugee`. + bank_name: Name of the bank that holds the account. Required by `zaf_bank_account_holder`. + bank_account_number: Bank account number. Required by `zaf_bank_account_holder`; accepted by `zaf_fraud_prevention`. + account_type: Bank account type for `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare` or `notKnown`, case-insensitive. Any other value returns `400`. Omit it when you do not know the type: the account-type cross-check is then reported as not confirmed. + phone_number: Contact mobile number, for the services that cross-check contactability (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`). + right_thumb: Base64-encoded right thumb fingerprint for `zaf_dha_fingerprint_match`, with `left_thumb` or on its own. + left_thumb: Base64-encoded left thumb fingerprint for `zaf_dha_fingerprint_match`, with `right_thumb` or on its own. + score_level: Minimum biometric score level for `zaf_criminal_face_screening`. Defaults to `3`. + max_matches: Maximum number of candidate matches `zaf_criminal_face_screening` returns. Defaults to `1`. + vehicle_register_number: Vehicle register number. Required, with `vehicle_licence_plate` and `vin`, by `zaf_vehicle_ownership`. + vehicle_licence_plate: Vehicle licence plate number. Required, with `vehicle_register_number` and `vin`, by `zaf_vehicle_ownership`. + vin: Vehicle Identification Number (VIN or chassis number). Required, with `vehicle_register_number` and `vehicle_licence_plate`, by `zaf_vehicle_ownership`. ssn: Social Security Number (USA). phone: Phone number for phone-verification services. landline: Landline number for phone-verification services. @@ -283,6 +315,22 @@ def validate( "emission_number": emission_number, "bvn": bvn, "bank_card_number": bank_card_number, + "company_registration_number": company_registration_number, + "company_name": company_name, + "initials": initials, + "licence_number": licence_number, + "refugee_file_number": refugee_file_number, + "bank_name": bank_name, + "bank_account_number": bank_account_number, + "account_type": account_type, + "phone_number": phone_number, + "right_thumb": right_thumb, + "left_thumb": left_thumb, + "score_level": score_level, + "max_matches": max_matches, + "vehicle_register_number": vehicle_register_number, + "vehicle_licence_plate": vehicle_licence_plate, + "vin": vin, "ssn": ssn, "phone": phone, "landline": landline, @@ -383,6 +431,22 @@ async def validate( emission_number: str | NotGiven = NOT_GIVEN, bvn: str | NotGiven = NOT_GIVEN, bank_card_number: str | NotGiven = NOT_GIVEN, + company_registration_number: str | NotGiven = NOT_GIVEN, + company_name: str | NotGiven = NOT_GIVEN, + initials: str | NotGiven = NOT_GIVEN, + licence_number: str | NotGiven = NOT_GIVEN, + refugee_file_number: str | NotGiven = NOT_GIVEN, + bank_name: str | NotGiven = NOT_GIVEN, + bank_account_number: str | NotGiven = NOT_GIVEN, + account_type: str | NotGiven = NOT_GIVEN, + phone_number: str | NotGiven = NOT_GIVEN, + right_thumb: str | NotGiven = NOT_GIVEN, + left_thumb: str | NotGiven = NOT_GIVEN, + score_level: int | NotGiven = NOT_GIVEN, + max_matches: int | NotGiven = NOT_GIVEN, + vehicle_register_number: str | NotGiven = NOT_GIVEN, + vehicle_licence_plate: str | NotGiven = NOT_GIVEN, + vin: str | NotGiven = NOT_GIVEN, ssn: str | NotGiven = NOT_GIVEN, phone: str | NotGiven = NOT_GIVEN, landline: str | NotGiven = NOT_GIVEN, @@ -477,6 +541,22 @@ async def validate( emission_number: Mexican INE Número de Emisión. Used with `voter_number` for legacy IFE models (A/B/C) in `mex_ine_vigencia`. bvn: Nigerian Bank Verification Number. bank_card_number: Bank card number (CHN bank-card verification). + company_registration_number: Company registration number as issued by the companies register: the CNPJ in Brazil (e.g. `11222333000181`), the registration number in South Africa (e.g. `1936/007721/06`). Required by the company registry and company directors services (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`). + company_name: Registered company name, cross-checked against the register entry. Optional for `zaf_company_registry`. + initials: The person's initials as printed on the document. Required by `zaf_drivers_license`; accepted by `zaf_bank_account_holder`. + licence_number: Driving licence number as printed on the card, for `zaf_drivers_license`. When omitted, `document_number` is used. + refugee_file_number: Refugee file number issued by South Africa's Department of Home Affairs. Required by `zaf_refugee`. + bank_name: Name of the bank that holds the account. Required by `zaf_bank_account_holder`. + bank_account_number: Bank account number. Required by `zaf_bank_account_holder`; accepted by `zaf_fraud_prevention`. + account_type: Bank account type for `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare` or `notKnown`, case-insensitive. Any other value returns `400`. Omit it when you do not know the type: the account-type cross-check is then reported as not confirmed. + phone_number: Contact mobile number, for the services that cross-check contactability (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`). + right_thumb: Base64-encoded right thumb fingerprint for `zaf_dha_fingerprint_match`, with `left_thumb` or on its own. + left_thumb: Base64-encoded left thumb fingerprint for `zaf_dha_fingerprint_match`, with `right_thumb` or on its own. + score_level: Minimum biometric score level for `zaf_criminal_face_screening`. Defaults to `3`. + max_matches: Maximum number of candidate matches `zaf_criminal_face_screening` returns. Defaults to `1`. + vehicle_register_number: Vehicle register number. Required, with `vehicle_licence_plate` and `vin`, by `zaf_vehicle_ownership`. + vehicle_licence_plate: Vehicle licence plate number. Required, with `vehicle_register_number` and `vin`, by `zaf_vehicle_ownership`. + vin: Vehicle Identification Number (VIN or chassis number). Required, with `vehicle_register_number` and `vehicle_licence_plate`, by `zaf_vehicle_ownership`. ssn: Social Security Number (USA). phone: Phone number for phone-verification services. landline: Landline number for phone-verification services. @@ -556,6 +636,22 @@ async def validate( "emission_number": emission_number, "bvn": bvn, "bank_card_number": bank_card_number, + "company_registration_number": company_registration_number, + "company_name": company_name, + "initials": initials, + "licence_number": licence_number, + "refugee_file_number": refugee_file_number, + "bank_name": bank_name, + "bank_account_number": bank_account_number, + "account_type": account_type, + "phone_number": phone_number, + "right_thumb": right_thumb, + "left_thumb": left_thumb, + "score_level": score_level, + "max_matches": max_matches, + "vehicle_register_number": vehicle_register_number, + "vehicle_licence_plate": vehicle_licence_plate, + "vin": vin, "ssn": ssn, "phone": phone, "landline": landline, diff --git a/src/didit/resources/email.py b/src/didit/resources/email.py index cf04546..074a55f 100644 --- a/src/didit/resources/email.py +++ b/src/didit/resources/email.py @@ -194,6 +194,12 @@ def check_code( duplicated_email_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, breached_email_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, disposable_email_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + enable_enrichment: bool | NotGiven = NOT_GIVEN, + email_intelligence_score_action: Literal["NO_ACTION", "DECLINE"] + | str + | NotGiven = NOT_GIVEN, + recent_email_breach_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + frequent_email_breach_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, enable_social: bool | NotGiven = NOT_GIVEN, email_no_social_presence_action: Literal["NO_ACTION", "DECLINE"] | str @@ -235,6 +241,10 @@ def check_code( duplicated_email_action: What to do when the same address was already used and approved by a different user (only previously Approved verifications count) (different `vendor_data`) of your application. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings` and fills `email.matches`. breached_email_action: What to do when the address appears in known data breaches (`email.is_breached`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings`. disposable_email_action: What to do when the domain belongs to a disposable/temporary-mail provider (`email.is_disposable`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings`. + enable_enrichment: When `true`, also run email intelligence on the address: a risk score and its breach history. Billed as one `email_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it. + email_intelligence_score_action: Action when the email intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + recent_email_breach_action: Action when the address appears in a recent known data breach. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + frequent_email_breach_action: Action when the address appears in many known data breaches. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. enable_social: When true, also look up the social footprint of the address - the email, social, professional, e-commerce and entertainment platforms it is registered on. Billed as one `email_social` unit per request in addition to this endpoint's own price. email_no_social_presence_action: Action when the social footprint check finds the address registered on none of the platforms it covers. Only NO_ACTION and DECLINE are accepted on this endpoint; REVIEW is available on the workflow configuration key of the same name. extra_headers: Headers to add to (or, with ``None``, remove from) this request. @@ -255,6 +265,10 @@ def check_code( "duplicated_email_action": duplicated_email_action, "breached_email_action": breached_email_action, "disposable_email_action": disposable_email_action, + "enable_enrichment": enable_enrichment, + "email_intelligence_score_action": email_intelligence_score_action, + "recent_email_breach_action": recent_email_breach_action, + "frequent_email_breach_action": frequent_email_breach_action, "enable_social": enable_social, "email_no_social_presence_action": email_no_social_presence_action, }, @@ -425,6 +439,12 @@ async def check_code( duplicated_email_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, breached_email_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, disposable_email_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + enable_enrichment: bool | NotGiven = NOT_GIVEN, + email_intelligence_score_action: Literal["NO_ACTION", "DECLINE"] + | str + | NotGiven = NOT_GIVEN, + recent_email_breach_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + frequent_email_breach_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, enable_social: bool | NotGiven = NOT_GIVEN, email_no_social_presence_action: Literal["NO_ACTION", "DECLINE"] | str @@ -466,6 +486,10 @@ async def check_code( duplicated_email_action: What to do when the same address was already used and approved by a different user (only previously Approved verifications count) (different `vendor_data`) of your application. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings` and fills `email.matches`. breached_email_action: What to do when the address appears in known data breaches (`email.is_breached`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings`. disposable_email_action: What to do when the domain belongs to a disposable/temporary-mail provider (`email.is_disposable`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings`. + enable_enrichment: When `true`, also run email intelligence on the address: a risk score and its breach history. Billed as one `email_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it. + email_intelligence_score_action: Action when the email intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + recent_email_breach_action: Action when the address appears in a recent known data breach. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + frequent_email_breach_action: Action when the address appears in many known data breaches. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. enable_social: When true, also look up the social footprint of the address - the email, social, professional, e-commerce and entertainment platforms it is registered on. Billed as one `email_social` unit per request in addition to this endpoint's own price. email_no_social_presence_action: Action when the social footprint check finds the address registered on none of the platforms it covers. Only NO_ACTION and DECLINE are accepted on this endpoint; REVIEW is available on the workflow configuration key of the same name. extra_headers: Headers to add to (or, with ``None``, remove from) this request. @@ -486,6 +510,10 @@ async def check_code( "duplicated_email_action": duplicated_email_action, "breached_email_action": breached_email_action, "disposable_email_action": disposable_email_action, + "enable_enrichment": enable_enrichment, + "email_intelligence_score_action": email_intelligence_score_action, + "recent_email_breach_action": recent_email_breach_action, + "frequent_email_breach_action": frequent_email_breach_action, "enable_social": enable_social, "email_no_social_presence_action": email_no_social_presence_action, }, diff --git a/src/didit/resources/id_verification.py b/src/didit/resources/id_verification.py index 896a728..75011ac 100644 --- a/src/didit/resources/id_verification.py +++ b/src/didit/resources/id_verification.py @@ -79,7 +79,7 @@ def verify( **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. @@ -202,7 +202,7 @@ async def verify( **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. diff --git a/src/didit/resources/id_wallets.py b/src/didit/resources/id_wallets.py index 50495bd..ca137ef 100644 --- a/src/didit/resources/id_wallets.py +++ b/src/didit/resources/id_wallets.py @@ -50,6 +50,9 @@ from didit.types.components.digital_id_wallet_api_ftn_wallet_verification_start_country_enum import ( DigitalIdWalletApiFtnWalletVerificationStartCountryEnum, ) +from didit.types.components.digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum import ( + DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum, +) from didit.types.components.digital_id_wallet_api_govbr_wallet_verification_start_country_enum import ( DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum, ) @@ -97,7 +100,7 @@ class IdWallets(SyncAPIResource): """The ``id_wallets`` resource of the Didit API. - Methods: ``cancel_verification``, ``list``, ``poll_verification``, ``retrieve_verification``, ``start_audkenni``, ``start_bankid_cz``, ``start_bankid_no``, ``start_bankid_se``, ``start_buypass``, ``start_connectid``, ``start_diia``, ``start_eparaksts_mobile``, ``start_eudi``, ``start_franceconnect``, ``start_frejaid``, ``start_ftn``, ``start_govbr``, ``start_govuk_wallet``, ``start_idcard_ee``, ``start_idin``, ``start_itsme``, ``start_mitid``, ``start_mobile_id``, ``start_mojeid``, ``start_oneid``, ``start_personalausweis``, ``start_smart_id``, ``start_uae_pass``, ``start_vipps``. + Methods: ``cancel_verification``, ``list``, ``poll_verification``, ``retrieve_verification``, ``start_audkenni``, ``start_bankid_cz``, ``start_bankid_no``, ``start_bankid_se``, ``start_buypass``, ``start_connectid``, ``start_diia``, ``start_eparaksts_mobile``, ``start_eudi``, ``start_franceconnect``, ``start_frejaid``, ``start_ftn``, ``start_google_wallet``, ``start_govbr``, ``start_govuk_wallet``, ``start_idcard_ee``, ``start_idin``, ``start_itsme``, ``start_mitid``, ``start_mobile_id``, ``start_mojeid``, ``start_oneid``, ``start_personalausweis``, ``start_smart_id``, ``start_uae_pass``, ``start_vipps``, ``submit_verification_response``. """ @cached_property @@ -1686,11 +1689,105 @@ def start_eudi( ), ) + def submit_verification_response( + self, + request_id: str, + *, + response: Mapping[str, object], + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> DigitalIdWalletApiWalletVerificationResponse: + """Submit a wallet response. + + Digital Credentials API wallets (Google Wallet): send what the wallet returned to your page or app for a verification whose next_action is request_digital_credential. Didit decrypts it, checks the issuer's signature against the trusted issuer roots, every returned value against its signed digest, and the device signature over your origin and this request, then decides the verification: verified (billed once) or declined with the error code. Single use: a second submit returns the decided verification. + + ``POST /v3/id-verification/wallets/verifications/{request_id}/response/`` + + Args: + request_id: The request_id the start endpoint returned. + response: Exactly what the wallet returned: {protocol, data} of the DigitalCredential from navigator.credentials.get, or the parsed credentialJson of Android's DigitalCredential. Encrypted to Didit; do not alter it. + 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( + "DigitalIdWalletApiWalletVerificationResponse", + self._client.request( + "post", + "/v3/id-verification/wallets/verifications/{request_id}/response/", + cast_to=DigitalIdWalletApiWalletVerificationResponse, + path_params={"request_id": request_id}, + auth="api_key", + body={"response": response}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + def start_google_wallet( + self, + *, + country: DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum, + origin: str, + vendor_data: str | None | NotGiven = NOT_GIVEN, + metadata: Mapping[str, object] | None | NotGiven = NOT_GIVEN, + sandbox_scenario: str | NotGiven = NOT_GIVEN, + idempotency_key: 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, + ) -> DigitalIdWalletApiWalletVerificationResponse: + """Start Google Wallet verification. + + Start a Google Wallet sign-in (Google Wallet (ID pass) and US state issuers (mobile driving licence); USA, GBR, BRA, SGP, TWN) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=request_digital_credential with a request Didit signed for your application, usable only from origin. In a user gesture there, pass next_action.digital_credentials.request to navigator.credentials.get({digital: ...}) (or to Android Credential Manager as GetDigitalCredentialOption requestJson), then POST what the wallet returns to /v3/id-verification/wallets/verifications/{request_id}/response/. The browser offers its own QR code when the wallet is on another device. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider. + + ``POST /v3/id-verification/wallets/google-wallet/`` + + Args: + country: ISO 3166-1 alpha-3 country of the Google Wallet identity. * `USA` - USA * `GBR` - GBR * `BRA` - BRA * `SGP` - SGP * `TWN` - TWN + origin: Where your page or app will ask the wallet: the https origin of your page (its host must be in the application's allowed_return_hosts, or be its white-label domain), e.g. https://app.example.com, or android:apk-key-hash:. The wallet refuses the request anywhere else. + vendor_data: Your own reference for this verification (e.g. your user id). Returned in results and webhooks. + metadata: Optional JSON object stored with the verification and returned in results and webhooks. + sandbox_scenario: Sandbox applications only: the simulated outcome - 'wallet_cancelled', 'wallet_timeout' or 'wallet_provider_error'; any other scenario (or none) verifies. Rejected on live applications. The full catalog is available at GET /v1/sandbox/scenarios/. + idempotency_key: Sent as the ``Idempotency-Key`` header; a retry with the same key returns the first result instead of acting twice. + 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( + "DigitalIdWalletApiWalletVerificationResponse", + self._client.request( + "post", + "/v3/id-verification/wallets/google-wallet/", + cast_to=DigitalIdWalletApiWalletVerificationResponse, + auth="api_key", + body={ + "country": country, + "origin": origin, + "vendor_data": vendor_data, + "metadata": metadata, + "sandbox_scenario": sandbox_scenario, + }, + headers={"Idempotency-Key": idempotency_key}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + class AsyncIdWallets(AsyncAPIResource): """The ``id_wallets`` resource of the Didit API. - Methods: ``cancel_verification``, ``list``, ``poll_verification``, ``retrieve_verification``, ``start_audkenni``, ``start_bankid_cz``, ``start_bankid_no``, ``start_bankid_se``, ``start_buypass``, ``start_connectid``, ``start_diia``, ``start_eparaksts_mobile``, ``start_eudi``, ``start_franceconnect``, ``start_frejaid``, ``start_ftn``, ``start_govbr``, ``start_govuk_wallet``, ``start_idcard_ee``, ``start_idin``, ``start_itsme``, ``start_mitid``, ``start_mobile_id``, ``start_mojeid``, ``start_oneid``, ``start_personalausweis``, ``start_smart_id``, ``start_uae_pass``, ``start_vipps``. + Methods: ``cancel_verification``, ``list``, ``poll_verification``, ``retrieve_verification``, ``start_audkenni``, ``start_bankid_cz``, ``start_bankid_no``, ``start_bankid_se``, ``start_buypass``, ``start_connectid``, ``start_diia``, ``start_eparaksts_mobile``, ``start_eudi``, ``start_franceconnect``, ``start_frejaid``, ``start_ftn``, ``start_google_wallet``, ``start_govbr``, ``start_govuk_wallet``, ``start_idcard_ee``, ``start_idin``, ``start_itsme``, ``start_mitid``, ``start_mobile_id``, ``start_mojeid``, ``start_oneid``, ``start_personalausweis``, ``start_smart_id``, ``start_uae_pass``, ``start_vipps``, ``submit_verification_response``. """ @cached_property @@ -3279,6 +3376,100 @@ async def start_eudi( ), ) + async def submit_verification_response( + self, + request_id: str, + *, + response: Mapping[str, object], + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> DigitalIdWalletApiWalletVerificationResponse: + """Submit a wallet response. + + Digital Credentials API wallets (Google Wallet): send what the wallet returned to your page or app for a verification whose next_action is request_digital_credential. Didit decrypts it, checks the issuer's signature against the trusted issuer roots, every returned value against its signed digest, and the device signature over your origin and this request, then decides the verification: verified (billed once) or declined with the error code. Single use: a second submit returns the decided verification. + + ``POST /v3/id-verification/wallets/verifications/{request_id}/response/`` + + Args: + request_id: The request_id the start endpoint returned. + response: Exactly what the wallet returned: {protocol, data} of the DigitalCredential from navigator.credentials.get, or the parsed credentialJson of Android's DigitalCredential. Encrypted to Didit; do not alter it. + 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( + "DigitalIdWalletApiWalletVerificationResponse", + await self._client.request( + "post", + "/v3/id-verification/wallets/verifications/{request_id}/response/", + cast_to=DigitalIdWalletApiWalletVerificationResponse, + path_params={"request_id": request_id}, + auth="api_key", + body={"response": response}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def start_google_wallet( + self, + *, + country: DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum, + origin: str, + vendor_data: str | None | NotGiven = NOT_GIVEN, + metadata: Mapping[str, object] | None | NotGiven = NOT_GIVEN, + sandbox_scenario: str | NotGiven = NOT_GIVEN, + idempotency_key: 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, + ) -> DigitalIdWalletApiWalletVerificationResponse: + """Start Google Wallet verification. + + Start a Google Wallet sign-in (Google Wallet (ID pass) and US state issuers (mobile driving licence); USA, GBR, BRA, SGP, TWN) without any workflow. Billed once, only when the identity is verified. The response carries next_action.type=request_digital_credential with a request Didit signed for your application, usable only from origin. In a user gesture there, pass next_action.digital_credentials.request to navigator.credentials.get({digital: ...}) (or to Android Credential Manager as GetDigitalCredentialOption requestJson), then POST what the wallet returns to /v3/id-verification/wallets/verifications/{request_id}/response/. The browser offers its own QR code when the wallet is on another device. Sandbox applications get a deterministic simulation (simulated: true) that never contacts the provider. + + ``POST /v3/id-verification/wallets/google-wallet/`` + + Args: + country: ISO 3166-1 alpha-3 country of the Google Wallet identity. * `USA` - USA * `GBR` - GBR * `BRA` - BRA * `SGP` - SGP * `TWN` - TWN + origin: Where your page or app will ask the wallet: the https origin of your page (its host must be in the application's allowed_return_hosts, or be its white-label domain), e.g. https://app.example.com, or android:apk-key-hash:. The wallet refuses the request anywhere else. + vendor_data: Your own reference for this verification (e.g. your user id). Returned in results and webhooks. + metadata: Optional JSON object stored with the verification and returned in results and webhooks. + sandbox_scenario: Sandbox applications only: the simulated outcome - 'wallet_cancelled', 'wallet_timeout' or 'wallet_provider_error'; any other scenario (or none) verifies. Rejected on live applications. The full catalog is available at GET /v1/sandbox/scenarios/. + idempotency_key: Sent as the ``Idempotency-Key`` header; a retry with the same key returns the first result instead of acting twice. + 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( + "DigitalIdWalletApiWalletVerificationResponse", + await self._client.request( + "post", + "/v3/id-verification/wallets/google-wallet/", + cast_to=DigitalIdWalletApiWalletVerificationResponse, + auth="api_key", + body={ + "country": country, + "origin": origin, + "vendor_data": vendor_data, + "metadata": metadata, + "sandbox_scenario": sandbox_scenario, + }, + headers={"Idempotency-Key": idempotency_key}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + class IdWalletsWithRawResponse: def __init__(self, resource: IdWallets) -> None: @@ -3312,6 +3503,10 @@ def __init__(self, resource: IdWallets) -> None: self.start_audkenni = to_raw_response_wrapper(resource.start_audkenni) self.start_connectid = to_raw_response_wrapper(resource.start_connectid) self.start_eudi = to_raw_response_wrapper(resource.start_eudi) + self.submit_verification_response = to_raw_response_wrapper( + resource.submit_verification_response + ) + self.start_google_wallet = to_raw_response_wrapper(resource.start_google_wallet) class AsyncIdWalletsWithRawResponse: @@ -3346,6 +3541,10 @@ def __init__(self, resource: AsyncIdWallets) -> None: self.start_audkenni = async_to_raw_response_wrapper(resource.start_audkenni) self.start_connectid = async_to_raw_response_wrapper(resource.start_connectid) self.start_eudi = async_to_raw_response_wrapper(resource.start_eudi) + self.submit_verification_response = async_to_raw_response_wrapper( + resource.submit_verification_response + ) + self.start_google_wallet = async_to_raw_response_wrapper(resource.start_google_wallet) class IdWalletsWithStreamingResponse: @@ -3380,6 +3579,10 @@ def __init__(self, resource: IdWallets) -> None: self.start_audkenni = to_streamed_response_wrapper(resource.start_audkenni) self.start_connectid = to_streamed_response_wrapper(resource.start_connectid) self.start_eudi = to_streamed_response_wrapper(resource.start_eudi) + self.submit_verification_response = to_streamed_response_wrapper( + resource.submit_verification_response + ) + self.start_google_wallet = to_streamed_response_wrapper(resource.start_google_wallet) class AsyncIdWalletsWithStreamingResponse: @@ -3420,3 +3623,7 @@ def __init__(self, resource: AsyncIdWallets) -> None: self.start_audkenni = async_to_streamed_response_wrapper(resource.start_audkenni) self.start_connectid = async_to_streamed_response_wrapper(resource.start_connectid) self.start_eudi = async_to_streamed_response_wrapper(resource.start_eudi) + self.submit_verification_response = async_to_streamed_response_wrapper( + resource.submit_verification_response + ) + self.start_google_wallet = async_to_streamed_response_wrapper(resource.start_google_wallet) diff --git a/src/didit/resources/kyb.py b/src/didit/resources/kyb.py index 0c3a86e..ba9e004 100644 --- a/src/didit/resources/kyb.py +++ b/src/didit/resources/kyb.py @@ -151,7 +151,7 @@ def select( ``POST /v3/kyb/select/`` Args: - kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it. + kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length. vendor_data: Your identifier for this company; echoed back and stored with the business session. metadata: Free-form JSON stored with the business session and echoed back. save_api_request: Must be `true` (the default). KYB registry selects are always persisted so billing and retrieval can be tracked; `false` returns `400`. @@ -196,7 +196,7 @@ def list_shareholders( Retrieve the Lite profile **plus the direct shareholders** (natural persons and corporate entities, with their ownership bands) of one candidate returned by `POST /v3/kyb/search/`. - **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. The search runs on the Lite registry chain; when the country's ownership data lives at another registry Didit re-finds the company there by registration number, at no extra cost. + **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. Search at the tier you intend to buy (`tier` on `POST /v3/kyb/search/`), because the search runs on the registry chain that serves that tier and an empty Lite search is not proof that the registry does not hold the company. When the country's ownership data lives at another registry, Didit re-finds the company there by registration number, at no extra cost. **Billing.** Billed at the country's Shareholders price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). When the registry holds no shareholder record for the company (or the country offers no ownership data at all) the Lite profile is delivered and billed instead: read `registry_tier_delivered` and `registry_ownership_status`. The balance is checked against the Shareholders price before any registry call (`403` when short). @@ -207,7 +207,7 @@ def list_shareholders( ``POST /v3/kyb/shareholders/`` Args: - kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it. + kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length. vendor_data: Your identifier for this company; echoed back and stored with the business session. metadata: Free-form JSON stored with the business session and echoed back. save_api_request: Must be `true` (the default). KYB registry selects are always persisted so billing and retrieval can be tracked; `false` returns `400`. @@ -252,7 +252,7 @@ def list_ubos( Retrieve the Lite profile, the direct shareholders **and the ultimate beneficial owners** resolved through the ownership chain (`registry_data.ubo_resolution` carries the corporate parent chain) of one candidate returned by `POST /v3/kyb/search/`. - **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. The search runs on the Lite registry chain; when the country's ownership data lives at another registry Didit re-finds the company there by registration number, at no extra cost. + **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. Search at the tier you intend to buy (`tier` on `POST /v3/kyb/search/`), because the search runs on the registry chain that serves that tier and an empty Lite search is not proof that the registry does not hold the company. When the country's ownership data lives at another registry, Didit re-finds the company there by registration number, at no extra cost. **Billing.** Billed at the country's UBO price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). The tier delivered is the highest the country and the registry can serve: Shareholders when the resolved report names no natural person as a beneficial owner, Lite when there is no ownership record at all; `registry_tier_delivered` names what was billed. The balance is checked against the UBO price before any registry call (`403` when short). @@ -263,7 +263,7 @@ def list_ubos( ``POST /v3/kyb/ubo/`` Args: - kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it. + kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length. vendor_data: Your identifier for this company; echoed back and stored with the business session. metadata: Free-form JSON stored with the business session and echoed back. save_api_request: Must be `true` (the default). KYB registry selects are always persisted so billing and retrieval can be tracked; `false` returns `400`. @@ -410,7 +410,7 @@ async def select( ``POST /v3/kyb/select/`` Args: - kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it. + kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length. vendor_data: Your identifier for this company; echoed back and stored with the business session. metadata: Free-form JSON stored with the business session and echoed back. save_api_request: Must be `true` (the default). KYB registry selects are always persisted so billing and retrieval can be tracked; `false` returns `400`. @@ -455,7 +455,7 @@ async def list_shareholders( Retrieve the Lite profile **plus the direct shareholders** (natural persons and corporate entities, with their ownership bands) of one candidate returned by `POST /v3/kyb/search/`. - **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. The search runs on the Lite registry chain; when the country's ownership data lives at another registry Didit re-finds the company there by registration number, at no extra cost. + **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. Search at the tier you intend to buy (`tier` on `POST /v3/kyb/search/`), because the search runs on the registry chain that serves that tier and an empty Lite search is not proof that the registry does not hold the company. When the country's ownership data lives at another registry, Didit re-finds the company there by registration number, at no extra cost. **Billing.** Billed at the country's Shareholders price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). When the registry holds no shareholder record for the company (or the country offers no ownership data at all) the Lite profile is delivered and billed instead: read `registry_tier_delivered` and `registry_ownership_status`. The balance is checked against the Shareholders price before any registry call (`403` when short). @@ -466,7 +466,7 @@ async def list_shareholders( ``POST /v3/kyb/shareholders/`` Args: - kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it. + kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length. vendor_data: Your identifier for this company; echoed back and stored with the business session. metadata: Free-form JSON stored with the business session and echoed back. save_api_request: Must be `true` (the default). KYB registry selects are always persisted so billing and retrieval can be tracked; `false` returns `400`. @@ -511,7 +511,7 @@ async def list_ubos( Retrieve the Lite profile, the direct shareholders **and the ultimate beneficial owners** resolved through the ownership chain (`registry_data.ubo_resolution` carries the corporate parent chain) of one candidate returned by `POST /v3/kyb/search/`. - **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. The search runs on the Lite registry chain; when the country's ownership data lives at another registry Didit re-finds the company there by registration number, at no extra cost. + **Pairing with search.** Pass the candidate's `kyb_response_id` exactly as returned by a search of the same application. Search at the tier you intend to buy (`tier` on `POST /v3/kyb/search/`), because the search runs on the registry chain that serves that tier and an empty Lite search is not proof that the registry does not hold the company. When the country's ownership data lives at another registry, Didit re-finds the company there by registration number, at no extra cost. **Billing.** Billed at the country's UBO price - see [KYB registry pricing](/getting-started/kyb-registry-pricing). The tier delivered is the highest the country and the registry can serve: Shareholders when the resolved report names no natural person as a beneficial owner, Lite when there is no ownership record at all; `registry_tier_delivered` names what was billed. The balance is checked against the UBO price before any registry call (`403` when short). @@ -522,7 +522,7 @@ async def list_ubos( ``POST /v3/kyb/ubo/`` Args: - kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it. + kyb_response_id: Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length. vendor_data: Your identifier for this company; echoed back and stored with the business session. metadata: Free-form JSON stored with the business session and echoed back. save_api_request: Must be `true` (the default). KYB registry selects are always persisted so billing and retrieval can be tracked; `false` returns `400`. diff --git a/src/didit/resources/phone.py b/src/didit/resources/phone.py index 6121460..d5996d7 100644 --- a/src/didit/resources/phone.py +++ b/src/didit/resources/phone.py @@ -198,6 +198,13 @@ def check_code( | NotGiven = NOT_GIVEN, disposable_number_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, voip_number_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + enable_enrichment: bool | NotGiven = NOT_GIVEN, + phone_intelligence_score_action: Literal["NO_ACTION", "DECLINE"] + | str + | NotGiven = NOT_GIVEN, + phone_type_risk_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + recent_port_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + low_phone_trust_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, enable_social: bool | NotGiven = NOT_GIVEN, phone_no_social_presence_action: Literal["NO_ACTION", "DECLINE"] | str @@ -239,6 +246,11 @@ def check_code( duplicated_phone_number_action: What to do when the same number was already used by a different user (different `vendor_data`) of your application. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings` and fills `phone.matches`. disposable_number_action: What to do when the carrier lookup flags the number as a temporary/burner line (`phone.is_disposable`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings`. voip_number_action: What to do when the carrier lookup reports a virtual line type - `voip`, `isp`, or `vpn` (`phone.is_virtual`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings`. + enable_enrichment: When `true`, also run phone intelligence on the number: a risk score, the line type, whether it was recently ported and a trust index. Billed as one `phone_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it. + phone_intelligence_score_action: Action when the phone intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + phone_type_risk_action: Action when the number is a high-risk line type. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + recent_port_action: Action when the number was ported to another carrier recently. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + low_phone_trust_action: Action when the phone intelligence trust index is at or below the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. enable_social: When true, also look up the social footprint of the number - the messaging, social, e-commerce and professional platforms it is registered on. Billed as one `phone_social` unit per request in addition to this endpoint's own price. phone_no_social_presence_action: Action when the social footprint check finds the number registered on none of the platforms it covers. Only NO_ACTION and DECLINE are accepted on this endpoint; REVIEW is available on the workflow configuration key of the same name. extra_headers: Headers to add to (or, with ``None``, remove from) this request. @@ -259,6 +271,11 @@ def check_code( "duplicated_phone_number_action": duplicated_phone_number_action, "disposable_number_action": disposable_number_action, "voip_number_action": voip_number_action, + "enable_enrichment": enable_enrichment, + "phone_intelligence_score_action": phone_intelligence_score_action, + "phone_type_risk_action": phone_type_risk_action, + "recent_port_action": recent_port_action, + "low_phone_trust_action": low_phone_trust_action, "enable_social": enable_social, "phone_no_social_presence_action": phone_no_social_presence_action, }, @@ -433,6 +450,13 @@ async def check_code( | NotGiven = NOT_GIVEN, disposable_number_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, voip_number_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + enable_enrichment: bool | NotGiven = NOT_GIVEN, + phone_intelligence_score_action: Literal["NO_ACTION", "DECLINE"] + | str + | NotGiven = NOT_GIVEN, + phone_type_risk_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + recent_port_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, + low_phone_trust_action: Literal["NO_ACTION", "DECLINE"] | str | NotGiven = NOT_GIVEN, enable_social: bool | NotGiven = NOT_GIVEN, phone_no_social_presence_action: Literal["NO_ACTION", "DECLINE"] | str @@ -474,6 +498,11 @@ async def check_code( duplicated_phone_number_action: What to do when the same number was already used by a different user (different `vendor_data`) of your application. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings` and fills `phone.matches`. disposable_number_action: What to do when the carrier lookup flags the number as a temporary/burner line (`phone.is_disposable`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings`. voip_number_action: What to do when the carrier lookup reports a virtual line type - `voip`, `isp`, or `vpn` (`phone.is_virtual`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings`. + enable_enrichment: When `true`, also run phone intelligence on the number: a risk score, the line type, whether it was recently ported and a trust index. Billed as one `phone_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it. + phone_intelligence_score_action: Action when the phone intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + phone_type_risk_action: Action when the number is a high-risk line type. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + recent_port_action: Action when the number was ported to another carrier recently. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. + low_phone_trust_action: Action when the phone intelligence trust index is at or below the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`. enable_social: When true, also look up the social footprint of the number - the messaging, social, e-commerce and professional platforms it is registered on. Billed as one `phone_social` unit per request in addition to this endpoint's own price. phone_no_social_presence_action: Action when the social footprint check finds the number registered on none of the platforms it covers. Only NO_ACTION and DECLINE are accepted on this endpoint; REVIEW is available on the workflow configuration key of the same name. extra_headers: Headers to add to (or, with ``None``, remove from) this request. @@ -494,6 +523,11 @@ async def check_code( "duplicated_phone_number_action": duplicated_phone_number_action, "disposable_number_action": disposable_number_action, "voip_number_action": voip_number_action, + "enable_enrichment": enable_enrichment, + "phone_intelligence_score_action": phone_intelligence_score_action, + "phone_type_risk_action": phone_type_risk_action, + "recent_port_action": recent_port_action, + "low_phone_trust_action": low_phone_trust_action, "enable_social": enable_social, "phone_no_social_presence_action": phone_no_social_presence_action, }, diff --git a/src/didit/resources/pricing.py b/src/didit/resources/pricing.py index a87cb35..714241a 100644 --- a/src/didit/resources/pricing.py +++ b/src/didit/resources/pricing.py @@ -54,7 +54,7 @@ def bank_verification( ) -> BankVerificationPricing: """Get bank verification prices (public, unauthenticated). - Returns the list price of each Bank Verification method in every country: bank sign-in with its balance and transactions add-ons, and the account check. Use it to quote a bank step before you build a workflow, or to show bank prices in your own product. + Returns the list price of each Bank Verification method in every country: bank sign-in with its balance and transactions add-ons, and the account check. Bank Verification is not enabled in production yet, so a bank step is refused on production workflows until it is; treat these prices as a list price, not as an offer you can buy today. Use it to quote a bank step before you build a workflow, or to show bank prices in your own product. Public: send no auth header. The response contains no organization data and is the same for every caller. It is cached publicly for one hour and carries an `ETag`, so send `If-None-Match` to get a `304 Not Modified` when nothing changed. @@ -111,7 +111,7 @@ async def bank_verification( ) -> BankVerificationPricing: """Get bank verification prices (public, unauthenticated). - Returns the list price of each Bank Verification method in every country: bank sign-in with its balance and transactions add-ons, and the account check. Use it to quote a bank step before you build a workflow, or to show bank prices in your own product. + Returns the list price of each Bank Verification method in every country: bank sign-in with its balance and transactions add-ons, and the account check. Bank Verification is not enabled in production yet, so a bank step is refused on production workflows until it is; treat these prices as a list price, not as an offer you can buy today. Use it to quote a bank step before you build a workflow, or to show bank prices in your own product. Public: send no auth header. The response contains no organization data and is the same for every caller. It is cached publicly for one hour and carries an `ETag`, so send `If-None-Match` to get a `304 Not Modified` when nothing changed. diff --git a/src/didit/resources/sessions/__init__.py b/src/didit/resources/sessions/__init__.py index 54cf1e4..7bbe79c 100644 --- a/src/didit/resources/sessions/__init__.py +++ b/src/didit/resources/sessions/__init__.py @@ -27,6 +27,7 @@ from didit.types.components.session_decision import SessionDecision from didit.types.components.session_deletion_job import SessionDeletionJob from didit.types.components.session_event import SessionEvent +from didit.types.components.session_files_export import SessionFilesExport from didit.types.components.user_session_list_item import UserSessionListItem from didit.types.sessions.add_images_response import SessionsAddImagesResponse from didit.types.sessions.batch_delete_response import SessionsBatchDeleteResponse @@ -36,6 +37,7 @@ from didit.types.sessions.bulk_update_aml_hit_status_response import ( SessionsBulkUpdateAmlHitStatusResponse, ) +from didit.types.sessions.create_kyb_party_draft_response import SessionsCreateKybPartyDraftResponse from didit.types.sessions.create_params import ( SessionsCreateParamsBiometricConsent, SessionsCreateParamsContactDetails, @@ -51,6 +53,10 @@ from didit.types.sessions.list_feature_overrides_response import ( SessionsListFeatureOverridesResponse, ) +from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponse, +) +from didit.types.sessions.list_kyb_party_drafts_response import SessionsListKybPartyDraftsResponse from didit.types.sessions.list_response import SessionsListResponse from didit.types.sessions.preview_decision_email_response import ( SessionsPreviewDecisionEmailResponse, @@ -60,6 +66,7 @@ ) from didit.types.sessions.preview_resubmission_response import SessionsPreviewResubmissionResponse from didit.types.sessions.share_response import SessionsShareResponse +from didit.types.sessions.submit_kyb_parties_response import SessionsSubmitKybPartiesResponse from didit.types.sessions.update_aml_hit_status_response import SessionsUpdateAmlHitStatusResponse from didit.types.sessions.update_aml_status_response import SessionsUpdateAmlStatusResponse from didit.types.sessions.update_data_params import SessionsUpdateDataParamsParsedAddress @@ -71,11 +78,13 @@ from didit.types.sessions.update_kyb_company_data_response import ( SessionsUpdateKybCompanyDataResponse, ) +from didit.types.sessions.update_kyb_party_draft_response import SessionsUpdateKybPartyDraftResponse from didit.types.sessions.update_kyb_party_response import SessionsUpdateKybPartyResponse from didit.types.sessions.update_poa_data_params import SessionsUpdatePoaDataParamsPoaParsedAddress from didit.types.sessions.update_poa_data_response import SessionsUpdatePoaDataResponse from didit.types.sessions.update_status_params import SessionsUpdateStatusParamsNodesToResubmit from didit.types.sessions.update_status_response import SessionsUpdateStatusResponse +from didit.types.sessions.upload_kyb_documents_response import SessionsUploadKybDocumentsResponse if TYPE_CHECKING: from didit.resources.sessions.imports import ( @@ -124,7 +133,7 @@ class Sessions(SyncAPIResource): """The ``sessions`` resource of the Didit API. - Methods: ``add_images``, ``batch_delete``, ``bulk_update_aml_hit_status``, ``cancel_feature_override``, ``create``, ``delete``, ``export_aml_screening_history``, ``generate_pdf``, ``import_shared``, ``list``, ``list_aml_screening_history``, ``list_events``, ``list_feature_overrides``, ``list_networks``, ``preview_decision_email``, ``preview_resubmission``, ``regenerate_kyb_party``, ``retrieve_decision``, ``retrieve_deletion_job``, ``share``, ``simulate``, ``update_aml_hit_status``, ``update_aml_status``, ``update_data``, ``update_document_ai_data``, ``update_feature_status``, ``update_kyb_company_data``, ``update_kyb_party``, ``update_poa_data``, ``update_status``. + Methods: ``add_images``, ``batch_delete``, ``bulk_update_aml_hit_status``, ``cancel_feature_override``, ``create``, ``create_kyb_party_draft``, ``delete``, ``delete_kyb_party_draft``, ``export_aml_screening_history``, ``export_files``, ``generate_pdf``, ``get_files_export``, ``import_shared``, ``list``, ``list_aml_screening_history``, ``list_events``, ``list_feature_overrides``, ``list_kyb_extracted_parties``, ``list_kyb_party_drafts``, ``list_networks``, ``preview_decision_email``, ``preview_resubmission``, ``regenerate_kyb_party``, ``retrieve_decision``, ``retrieve_deletion_job``, ``share``, ``simulate``, ``submit_kyb_parties``, ``update_aml_hit_status``, ``update_aml_status``, ``update_data``, ``update_document_ai_data``, ``update_feature_status``, ``update_kyb_company_data``, ``update_kyb_party``, ``update_kyb_party_draft``, ``update_poa_data``, ``update_status``, ``upload_kyb_documents``. Nested resources: ``imports``, ``reviews``, ``signatures``, ``webhooks``. """ @@ -168,6 +177,7 @@ def create( *, workflow_id: str, vendor_data: str | NotGiven = NOT_GIVEN, + multi_account_segment: str | NotGiven = NOT_GIVEN, callback: str | NotGiven = NOT_GIVEN, callback_method: Literal["initiator", "completer", "both"] | str | NotGiven = NOT_GIVEN, metadata: object | NotGiven = NOT_GIVEN, @@ -257,6 +267,7 @@ def create( Args: workflow_id: Stable identifier of the workflow that defines which verification steps the session will run. Workflows are created and managed in the [Workflows](/console/workflows) page of the Console. The `workflow_id` also implicitly selects whether the session is KYC or KYB. vendor_data: A unique identifier for the user being verified, such as a UUID, email, or internal user ID. This field is used for: (1) **User grouping** - sessions with the same vendor_data are linked to the same user profile in the Users tab. (2) **Cross-session duplicate detection** - when checking for duplicated faces, documents, phone numbers, emails, IP addresses, or device fingerprints, sessions with the same vendor_data are treated as the same user and excluded from matches. Without vendor_data, every session is treated as a unique user and all potential duplicates are surfaced. We strongly recommend always providing a vendor_data to reduce noise in duplicate detection. + multi_account_segment: Optional duplicate-detection realm inside your organization. Duplicate face checks compare this session only with other sessions that carry the same segment, so separate account bases (personal and business accounts, or one per B2B sub-client) do not flag a person who legitimately holds one account in each. Omit it to use the single default realm, which is what every session uses today. Blocklist and allowlist matching ignore this field. callback: URL to redirect the user to after verification completes. Didit automatically appends `verificationSessionId` and `status` (Approved, Declined, In Review) as query parameters. Custom URL schemes (e.g. `myapp://`) are supported for mobile callbacks. If omitted, the workflow's default `callback_url` is used. When the application has allowed domains (`allowed_domains` on `PATCH /v3/webhook/`), an `http` or `https` callback must be on one of those origins (same scheme, host and port), otherwise the request fails with 400 on `callback`: `callback must be on one of the application's allowed domains: https://app.example.com`. Custom URL schemes are always accepted. callback_method: Determines which device should handle the redirect to the provided callback URL. Use `initiator` to redirect only the device that started the flow, `completer` for the device that finishes it, or `both` to allow either device to trigger the callback. If you ever notice the callback not triggering reliably, we recommend setting this value to `both`. metadata: Arbitrary JSON stored with the session and echoed back in the response and webhooks. Any JSON value is accepted (object, string, number, array), but a JSON object of key/value pairs is recommended. Not shown to the end user. Use it to pass your own correlation ids, A/B variants, or business context. @@ -266,7 +277,7 @@ def create( expected_details: Expected user details used to cross-validate against the data extracted from the user's ID document, Proof of Address, and other verification steps. Mismatches are surfaced as warnings on the decision; some fields (e.g. `id_country`, `expected_document_types`) also alter the user-facing flow. For Business Verification (KYB) workflows only the business fields (`company_name`, `registry_country`, `registration_number`) are used - they pre-fill the company registry search for the user - and all person-level fields are ignored. portrait_image: Base64-encoded portrait image of the end user's face (max 2MB; JPEG, PNG, WebP, or TIFF). Used as the reference image to match against the liveness capture when the workflow is a `Biometric Authentication` workflow with Face Match enabled, or any graph workflow where Face Match runs before ID Verification (OCR). Optional when the `vendor_data` user already has a stored face image: Didit reuses it automatically, resolved in priority order: approved liveness face, ePassport chip photo, ID document portrait, manually enrolled profile face (only faces from approved sessions or faces you enrolled yourself are reused). When provided, `portrait_image` always takes precedence over the stored face. If omitted and no stored face exists (or `vendor_data` is not sent), session creation fails with `400`. Ignored for other workflow types. sandbox_scenario: Sandbox-only scenario slug. Only accepted when the API key belongs to a sandbox-mode application; rejected on live applications. When set, the create flow expands the scenario's bundled magic values onto the session's input fields (contact_details, expected_details) so the mocked providers reproduce the scenario's outcome through the real workflow pipeline. See the scenario catalog at GET /v1/sandbox/scenarios/ or [Sandbox & Test Data](/integration/sandbox-testing). You can also arm (or re-arm) a scenario after create via POST /v3/session/{sessionId}/sandbox/arm/, as long as the session is still `Not Started`. For non-doc lookup, use `lookup_partial_match`, `lookup_no_match`, or `lookup_provider_error` to test the configured attempt budget and fallback. For identity wallets, use `wallet_cancelled`, `wallet_timeout`, or `wallet_provider_error`; `approve` simulates a verified wallet. All catalog wallets can be tested in sandbox, including schemes unavailable on live applications. Simulated attempts are not charged. - sign: Electronic Signature input for this session. `documents` are the documents to sign, for a workflow whose Electronic Signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [Electronic signature documents](/sessions-api/create-session#electronic-signature-documents). + sign: E-signature input for this session. `documents` are the documents to sign, for a workflow whose E-signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [E-signature documents](/sessions-api/create-session#e-signature-documents). user_state: Where the person lives, when you know it: an ISO 3166-2 subdivision code (`US-IL`, `ES-M`) or a US state code or name (`IL`, `Illinois`). A state whose law requires explicit biometric consent (Illinois, Texas, Colorado) makes the verification flow ask for it before capturing a face, with trigger `declared_state`. An unrecognized value returns `400`. See [Biometric consent](/getting-started/biometric-consent). biometric_consent: Explicit biometric consent you already collected from the person. It satisfies the requirement, so the verification flow does not ask again, and the decision records it as `status: "given"` with trigger `customer_collected`. An answer the person already gave in the flow is never replaced. See [Biometric consent](/getting-started/biometric-consent). extra_headers: Headers to add to (or, with ``None``, remove from) this request. @@ -284,6 +295,7 @@ def create( body={ "workflow_id": workflow_id, "vendor_data": vendor_data, + "multi_account_segment": multi_account_segment, "callback": callback, "callback_method": callback_method, "metadata": metadata, @@ -320,7 +332,7 @@ def retrieve_decision( Retrieve the complete decision report for a verification session - the rolled-up session `status` plus one report per verification feature the workflow executed. This is the canonical read endpoint for both User Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level `session_kind` discriminator tells you which shape you received (`"user"` or `"business"`). - **Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` - never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. Electronic Signature results are in `signatures`, which is present only when the workflow has an Electronic Signature step. + **Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` - never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. E-signature results are in `signatures`, which is present only when the workflow has an E-signature step. **When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to fetch the full report. Polling also works - the endpoint can be called at any point in the session lifecycle and returns the data produced so far - but webhook-then-fetch is cheaper and faster. Media URLs in the response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request the decision to get fresh ones, and do not persist them as long-term references. @@ -378,7 +390,7 @@ def delete( **What is deleted:** - The session and every verification attempt it holds, including results that a resubmission replaced: the decision, extracted data, all related feature records (ID verification, face, liveness, face match, AML, registry checks, IP analysis, and so on), its reviews and its activity log. - - All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded files (KYC); uploaded company documents and extra files (KYB). Electronic Signature documents, signed PDFs, evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media URLs (`https:///...`) stop resolving. + - All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded files (KYC); uploaded company documents and extra files (KYB). E-signature documents, signed PDFs, evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media URLs (`https:///...`) stop resolving. - The session's face data. Its face embedding is deleted too, unless you choose to keep an image-free template (see **Face biometric data**). - Webhook deliveries still queued for the session, and their retries. Webhooks already delivered are not affected. - For a Business Verification (KYB) session: the verifications it created for its key people (KYC) and its corporate owners (KYB), recursively, reported as `deleted_child_verifications`. A verification it only links to, such as an existing approved KYC it reused, is not deleted. @@ -582,6 +594,9 @@ def list( workflow_id: str | NotGiven = NOT_GIVEN, date_from: str | _dt.date | NotGiven = NOT_GIVEN, date_to: str | _dt.date | NotGiven = NOT_GIVEN, + tags: str | NotGiven = NOT_GIVEN, + decided_from: str | _dt.datetime | NotGiven = NOT_GIVEN, + decided_to: str | _dt.datetime | NotGiven = NOT_GIVEN, country: str | NotGiven = NOT_GIVEN, document_type: str | NotGiven = NOT_GIVEN, document_name: str | NotGiven = NOT_GIVEN, @@ -649,6 +664,9 @@ def list( workflow_id: Comma-separated workflow UUIDs (find them on the Workflows page in the Console). Malformed UUIDs in the list are ignored; if none are valid the result is empty. date_from: Only sessions created on or after this date (UTC), format `YYYY-MM-DD`. Malformed dates return `400`. date_to: Only sessions created up to this date (UTC), format `YYYY-MM-DD`. For KYC rows the entire day is included; for KYB rows the comparison is `created_at <= date_to` (midnight), so use the next day's date to include a full day of KYB sessions. + tags: Comma-separated tag ids (`tags` of your application). Returns the sessions that carry any of them. Ids that are not valid UUIDs are ignored, and when none is valid the list is empty. + decided_from: ISO 8601 datetime. Returns the sessions whose status last changed at or after it. It filters on the time of the last status change, not on creation time. + decided_to: ISO 8601 datetime. Returns the sessions whose status last changed before it. Combine with `decided_from` for a half-open window. country: Comma-separated country filter. For KYC rows: ISO 3166-1 alpha-3 codes of the ID document's issuing state (e.g. `ESP,USA`), which may differ from nationality. For KYB rows: the registry company's country code. document_type: Comma-separated ID-document type codes verified in the session (KYC rows only): `P` (Passport), `ID` (Identity Card), `DL` (Driver's License), `RP` (Residence Permit), `SSC` (Social Security Card), `HIC` (Health Insurance Card), `WP` (Work Permit), `TC` (Tax Card), `VISA`, `PSC` (Public Service Card), `BC` (Birth Certificate), `OTHER`. Note the response field `document_type` contains the display name, not the code. document_name: Exact document names; multiple names can be passed comma-separated, but the value is only split on commas when it contains more than one ` - ` separator (a lone name with an embedded comma is matched whole). Names are as recognized by document verification (front or back side), e.g. `Spain - Id Card (2021)`. KYC rows only. @@ -685,6 +703,9 @@ def list( "workflow_id": workflow_id, "date_from": date_from, "date_to": date_to, + "tags": tags, + "decided_from": decided_from, + "decided_to": decided_to, "country": country, "document_type": document_type, "document_name": document_name, @@ -1204,7 +1225,7 @@ def update_aml_hit_status( ) -> SessionsUpdateAmlHitStatusResponse: """Update an AML hit review status. - Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match) returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id` (the `id` of an entry in the AML check's `hits` array - see the session decision). + Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match) returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id` (the `id` of an entry in the AML check's `hits` array - see the session decision). A hit id returned in the earlier format is still accepted; the response always names the hit by its current `id`. `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. Reviewer decisions are preserved across ongoing-monitoring updates, so a hit you mark `False Positive` stays that way when the provider re-screens. @@ -1216,7 +1237,7 @@ def update_aml_hit_status( Args: session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. - hit_id: The `id` of the hit in the AML check's `hits` array. + hit_id: The `id` of the hit in the AML check's `hits` array (`hit_...`). A hit id returned in the earlier format is still accepted. review_status: The new review status for the hit. node_id: Optional graph node ID. Use it (here or as a query parameter) when the session has multiple AML checks. node_id_query: Workflow graph node ID. Required only when the session has multiple AML checks (one per node); omit it for single-AML sessions. @@ -1797,6 +1818,7 @@ def list_aml_screening_history( session_id: str, *, node_id: str | NotGiven = NOT_GIVEN, + month: str | NotGiven = NOT_GIVEN, limit: int | NotGiven = NOT_GIVEN, offset: int | NotGiven = NOT_GIVEN, ordering: str | NotGiven = NOT_GIVEN, @@ -1807,13 +1829,14 @@ def list_aml_screening_history( ) -> SyncPage[AMLScreeningRun]: """List AML screening history. - List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`, including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves, so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed (the first screening is part of the session decision) and runs from before this history existed are not reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and capped at 100 above that, so follow `next` until it is `null`. A scoped API key needs `decisions: read`; see [Continuous AML monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening). + List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`, including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves, so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed (the first screening is part of the session decision) and runs from before this history existed are not reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and capped at 100 above that, so follow `next` until it is `null`. Pass `month` to read one calendar month at a time. A scoped API key needs `decisions: read`; see [Continuous AML monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening). ``GET /v3/session/{sessionId}/aml-screening-history/`` Args: session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. node_id: Workflow graph node ID of the AML check. Needed only when the session ran more than one AML step; without it the most recent AML check is used. An unknown node returns `404`. + month: A UTC calendar month as `YYYY-MM`. Only screenings completed in that month are returned; without it every month is returned. A malformed month returns `400`. limit: Maximum number of screening runs per page. Defaults to 50. A value below 1 or a non-numeric value falls back to 50; a value above 1,000,000 returns `400`. offset: Number of results to skip before the first returned one. Defaults to 0; a negative or non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and `previous` URLs. ordering: Optional sort override. The default order is `-completed_at`. Pass a result field name (for example `completed_at`, `started_at`, `outcome` or `score`) to sort ascending, prefix it with `-` to sort descending, and separate several fields with commas. Unknown fields are ignored. @@ -1831,7 +1854,13 @@ def list_aml_screening_history( item_type=AMLScreeningRun, path_params={"sessionId": session_id}, auth="api_key", - query={"node_id": node_id, "limit": limit, "offset": offset, "ordering": ordering}, + query={ + "node_id": node_id, + "month": month, + "limit": limit, + "offset": offset, + "ordering": ordering, + }, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -1844,6 +1873,7 @@ def export_aml_screening_history( session_id: str, *, node_id: str | NotGiven = NOT_GIVEN, + month: str | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -1851,13 +1881,14 @@ def export_aml_screening_history( ) -> bytes: """Export AML screening history as CSV. - Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated, and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Errors are returned as JSON, not CSV. A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media: read` gets `403`. + Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated, and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Pass `month` to export one calendar month. Errors are returned as JSON, not CSV. A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media: read` gets `403`. ``GET /v3/session/{sessionId}/aml-screening-history/export/`` Args: session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. node_id: Workflow graph node ID of the AML check. Needed only when the session ran more than one AML step; without it the most recent AML check is used. An unknown node returns `404`. + month: A UTC calendar month as `YYYY-MM`. Only screenings completed in that month are returned; without it every month is returned. A malformed month returns `400`. 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. @@ -1871,7 +1902,7 @@ def export_aml_screening_history( cast_to=bytes, path_params={"sessionId": session_id}, auth="api_key", - query={"node_id": node_id}, + query={"node_id": node_id, "month": month}, accept="text/csv, application/json", extra_headers=extra_headers, extra_query=extra_query, @@ -2169,183 +2200,62 @@ def preview_decision_email( ), ) - -class AsyncSessions(AsyncAPIResource): - """The ``sessions`` resource of the Didit API. - - Methods: ``add_images``, ``batch_delete``, ``bulk_update_aml_hit_status``, ``cancel_feature_override``, ``create``, ``delete``, ``export_aml_screening_history``, ``generate_pdf``, ``import_shared``, ``list``, ``list_aml_screening_history``, ``list_events``, ``list_feature_overrides``, ``list_networks``, ``preview_decision_email``, ``preview_resubmission``, ``regenerate_kyb_party``, ``retrieve_decision``, ``retrieve_deletion_job``, ``share``, ``simulate``, ``update_aml_hit_status``, ``update_aml_status``, ``update_data``, ``update_document_ai_data``, ``update_feature_status``, ``update_kyb_company_data``, ``update_kyb_party``, ``update_poa_data``, ``update_status``. - - Nested resources: ``imports``, ``reviews``, ``signatures``, ``webhooks``. - """ - - @cached_property - def imports(self) -> AsyncSessionsImports: - from didit.resources.sessions.imports import AsyncSessionsImports - - return AsyncSessionsImports(self._client) - - @cached_property - def reviews(self) -> AsyncSessionsReviews: - from didit.resources.sessions.reviews import AsyncSessionsReviews - - return AsyncSessionsReviews(self._client) - - @cached_property - def signatures(self) -> AsyncSessionsSignatures: - from didit.resources.sessions.signatures import AsyncSessionsSignatures - - return AsyncSessionsSignatures(self._client) - - @cached_property - def webhooks(self) -> AsyncSessionsWebhooks: - from didit.resources.sessions.webhooks import AsyncSessionsWebhooks - - return AsyncSessionsWebhooks(self._client) - - @cached_property - def with_raw_response(self) -> AsyncSessionsWithRawResponse: - """Every method of this resource, returning the raw HTTP response.""" - return AsyncSessionsWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncSessionsWithStreamingResponse: - """Every method of this resource, returning the HTTP response before reading its body.""" - return AsyncSessionsWithStreamingResponse(self) - - async def create( + def upload_kyb_documents( self, + session_id: str, *, - workflow_id: str, - vendor_data: str | NotGiven = NOT_GIVEN, - callback: str | NotGiven = NOT_GIVEN, - callback_method: Literal["initiator", "completer", "both"] | str | NotGiven = NOT_GIVEN, - metadata: object | NotGiven = NOT_GIVEN, - tags: Sequence[str] | NotGiven = NOT_GIVEN, - language: Literal[ - "en", - "ar", - "bg", - "bn", - "bs", - "ca", - "cnr", - "cs", - "da", - "de", - "el", - "es", - "et", - "fa", - "fi", - "fr", - "he", - "hi", - "hr", - "hu", - "hy", - "id", - "it", - "ja", - "ka", - "kk", - "ko", - "ky", - "lt", - "lv", - "mk", - "mn", - "ms", - "nl", - "no", - "pl", - "pt-BR", - "pt", - "ro", - "ru", - "sk", - "sl", - "so", - "sq", - "sr", - "sv", - "th", - "tr", - "uk", - "uz", - "vi", - "zh-CN", - "zh-TW", - "zh", + documents: Sequence[FileTypes], + document_passwords: Sequence[str] | NotGiven = NOT_GIVEN, + document_group: Literal[ + "LEGAL_PRESENCE", + "COMPANY_DETAILS", + "OWNERSHIP_STRUCTURE", + "REPRESENTATIVES_AUTHORIZATION", ] | str | NotGiven = NOT_GIVEN, - contact_details: SessionsCreateParamsContactDetails | NotGiven = NOT_GIVEN, - expected_details: SessionsCreateParamsExpectedDetails | NotGiven = NOT_GIVEN, - portrait_image: str | NotGiven = NOT_GIVEN, - sandbox_scenario: str | NotGiven = NOT_GIVEN, - sign: SessionsCreateParamsSign | NotGiven = NOT_GIVEN, - user_state: str | NotGiven = NOT_GIVEN, - biometric_consent: SessionsCreateParamsBiometricConsent | NotGiven = NOT_GIVEN, + locale: str | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionsCreateResponse: - """Create a verification session. - - Create a User Verification (KYC) or Business Verification (KYB) session and receive a hosted verification `url` plus a `session_token` to redirect or embed for your end user. The `workflow_id` selects which verification steps run and whether the session is KYC or KYB. - - Call this from your backend (never the browser - the API key is a secret) whenever a user or business needs to be verified: at signup, before a sensitive action, or when re-verification is required. Prerequisites: a published workflow (created in the Console [Workflows](https://docs.didit.me/console/workflows) page) and an application API key with available credits. Sandbox applications bypass the credit check. - - **Idempotency:** when `vendor_data` is provided and an unfinished session (`Not Started`, `In Progress`, `Resubmitted`, or `Awaiting User`) with the same `vendor_data` already exists on the workflow's **current latest published version** (and that session already has a hosted verification URL), the existing session is returned (still `201`) instead of creating a duplicate - with its `callback` and `metadata` updated to the newly provided values. An unfinished session created on an older version of the workflow (one that has since been republished) is **not** reused; a new session pinned to the latest published version is created instead. Sessions in `Approved`, `Declined`, `In Review`, `Expired`, `Abandoned`, or `Kyc Expired` are never reused. + ) -> SessionsUploadKybDocumentsResponse: + """Upload KYB documents to a session. - **Side effects:** the hosted verification URL is generated and stored; if `contact_details.send_notification_emails` is `true` and an email is provided, a verification invite email is sent. The session expires after the workflow's configured session expiration time. For KYB workflows, `contact_details.phone` and `expected_details` are ignored. + Upload one or more corporate documents (articles of incorporation, shareholder register, certificate of incorporation, ...) to the KYB Documents step of a Business Verification session, from your own server instead of the hosted page. Didit runs the hosted pipeline: compression, OCR, tampering and cross-document checks, document grouping, and advances the session when the required document groups are satisfied. The step costs one flat fee however many files you send. The session must be open and on the KYB Documents step, and the company chosen at the registry step must exist. Read the people the documents name with `GET /v3/session/{sessionId}/kyb/extracted-parties/`. Requires `write:businesses`. - ``POST /v3/session/`` + ``POST /v3/session/{sessionId}/kyb/documents/`` Args: - workflow_id: Stable identifier of the workflow that defines which verification steps the session will run. Workflows are created and managed in the [Workflows](/console/workflows) page of the Console. The `workflow_id` also implicitly selects whether the session is KYC or KYB. - vendor_data: A unique identifier for the user being verified, such as a UUID, email, or internal user ID. This field is used for: (1) **User grouping** - sessions with the same vendor_data are linked to the same user profile in the Users tab. (2) **Cross-session duplicate detection** - when checking for duplicated faces, documents, phone numbers, emails, IP addresses, or device fingerprints, sessions with the same vendor_data are treated as the same user and excluded from matches. Without vendor_data, every session is treated as a unique user and all potential duplicates are surfaced. We strongly recommend always providing a vendor_data to reduce noise in duplicate detection. - callback: URL to redirect the user to after verification completes. Didit automatically appends `verificationSessionId` and `status` (Approved, Declined, In Review) as query parameters. Custom URL schemes (e.g. `myapp://`) are supported for mobile callbacks. If omitted, the workflow's default `callback_url` is used. When the application has allowed domains (`allowed_domains` on `PATCH /v3/webhook/`), an `http` or `https` callback must be on one of those origins (same scheme, host and port), otherwise the request fails with 400 on `callback`: `callback must be on one of the application's allowed domains: https://app.example.com`. Custom URL schemes are always accepted. - callback_method: Determines which device should handle the redirect to the provided callback URL. Use `initiator` to redirect only the device that started the flow, `completer` for the device that finishes it, or `both` to allow either device to trigger the callback. If you ever notice the callback not triggering reliably, we recommend setting this value to `both`. - metadata: Arbitrary JSON stored with the session and echoed back in the response and webhooks. Any JSON value is accepted (object, string, number, array), but a JSON object of key/value pairs is recommended. Not shown to the end user. Use it to pass your own correlation ids, A/B variants, or business context. - tags: Tags added to the session when it is created, by name. Up to 10, each up to 50 characters. Names are case-insensitive and stored in upper case. A name that does not exist yet in the application is created as a new tag. The tags show on the session in the console, where you can filter by them. - language: Language code (ISO 639-1) for the verification process interface. Controls the language displayed to the end user during verification. If not provided, the browser's language will be automatically detected and used. Check all the supported languages [here](/integration/supported-languages). - contact_details: User contact information that can be used for notifications, prefilling verification forms, and phone verification. This includes email address, preferred language for communications, and phone number. - expected_details: Expected user details used to cross-validate against the data extracted from the user's ID document, Proof of Address, and other verification steps. Mismatches are surfaced as warnings on the decision; some fields (e.g. `id_country`, `expected_document_types`) also alter the user-facing flow. For Business Verification (KYB) workflows only the business fields (`company_name`, `registry_country`, `registration_number`) are used - they pre-fill the company registry search for the user - and all person-level fields are ignored. - portrait_image: Base64-encoded portrait image of the end user's face (max 2MB; JPEG, PNG, WebP, or TIFF). Used as the reference image to match against the liveness capture when the workflow is a `Biometric Authentication` workflow with Face Match enabled, or any graph workflow where Face Match runs before ID Verification (OCR). Optional when the `vendor_data` user already has a stored face image: Didit reuses it automatically, resolved in priority order: approved liveness face, ePassport chip photo, ID document portrait, manually enrolled profile face (only faces from approved sessions or faces you enrolled yourself are reused). When provided, `portrait_image` always takes precedence over the stored face. If omitted and no stored face exists (or `vendor_data` is not sent), session creation fails with `400`. Ignored for other workflow types. - sandbox_scenario: Sandbox-only scenario slug. Only accepted when the API key belongs to a sandbox-mode application; rejected on live applications. When set, the create flow expands the scenario's bundled magic values onto the session's input fields (contact_details, expected_details) so the mocked providers reproduce the scenario's outcome through the real workflow pipeline. See the scenario catalog at GET /v1/sandbox/scenarios/ or [Sandbox & Test Data](/integration/sandbox-testing). You can also arm (or re-arm) a scenario after create via POST /v3/session/{sessionId}/sandbox/arm/, as long as the session is still `Not Started`. For non-doc lookup, use `lookup_partial_match`, `lookup_no_match`, or `lookup_provider_error` to test the configured attempt budget and fallback. For identity wallets, use `wallet_cancelled`, `wallet_timeout`, or `wallet_provider_error`; `approve` simulates a verified wallet. All catalog wallets can be tested in sandbox, including schemes unavailable on live applications. Simulated attempts are not charged. - sign: Electronic Signature input for this session. `documents` are the documents to sign, for a workflow whose Electronic Signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [Electronic signature documents](/sessions-api/create-session#electronic-signature-documents). - user_state: Where the person lives, when you know it: an ISO 3166-2 subdivision code (`US-IL`, `ES-M`) or a US state code or name (`IL`, `Illinois`). A state whose law requires explicit biometric consent (Illinois, Texas, Colorado) makes the verification flow ask for it before capturing a face, with trigger `declared_state`. An unrecognized value returns `400`. See [Biometric consent](/getting-started/biometric-consent). - biometric_consent: Explicit biometric consent you already collected from the person. It satisfies the requirement, so the verification flow does not ask again, and the decision records it as `status: "given"` with trigger `customer_collected`. An answer the person already gave in the flow is never replaced. See [Biometric consent](/getting-started/biometric-consent). + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + documents: Files to upload: JPG, JPEG, PNG, TIFF, WEBP, PDF or ZIP archives of them. PDFs up to 50 MB, photos up to 6 MB before compression. + document_passwords: One entry per file in `documents`, in the same order: the password of a protected PDF, empty for any other file. + document_group: Required document group this upload answers. + locale: Locale used to translate the response of the next step. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsCreateResponse", - await self._client.request( + "SessionsUploadKybDocumentsResponse", + self._client.request( "post", - "/v3/session/", - cast_to=SessionsCreateResponse, + "/v3/session/{sessionId}/kyb/documents/", + cast_to=SessionsUploadKybDocumentsResponse, + path_params={"sessionId": session_id}, auth="api_key", + query={"node_id": node_id}, body={ - "workflow_id": workflow_id, - "vendor_data": vendor_data, - "callback": callback, - "callback_method": callback_method, - "metadata": metadata, - "tags": tags, - "language": language, - "contact_details": contact_details, - "expected_details": expected_details, - "portrait_image": portrait_image, - "sandbox_scenario": sandbox_scenario, - "sign": sign, - "user_state": user_state, - "biometric_consent": biometric_consent, + "documents": documents, + "document_passwords": document_passwords, + "document_group": document_group, + "locale": locale, }, + multipart=True, + file_fields=("documents",), extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2353,51 +2263,39 @@ async def create( ), ) - async def retrieve_decision( + def list_kyb_extracted_parties( self, session_id: str, *, - include: Literal["events", "resubmissions", "events,resubmissions"] - | str - | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionDecision: - """Retrieve the full decision for a verification session. - - Retrieve the complete decision report for a verification session - the rolled-up session `status` plus one report per verification feature the workflow executed. This is the canonical read endpoint for both User Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level `session_kind` discriminator tells you which shape you received (`"user"` or `"business"`). - - **Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` - never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. Electronic Signature results are in `signatures`, which is present only when the workflow has an Electronic Signature step. + ) -> SessionsListKybExtractedPartiesResponse: + """List the parties named by the uploaded documents. - **When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to fetch the full report. Polling also works - the endpoint can be called at any point in the session lifecycle and returns the data produced so far - but webhook-then-fetch is cheaper and faster. Media URLs in the response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request the decision to get fresh ones, and do not persist them as long-term references. - - **Statuses.** The top-level `status` is the session lifecycle status (`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Each feature item additionally carries its own feature-level `status` (`Not Finished`, `Approved`, `Declined`, `In Review`, ...). A session can be `Approved` overall while an individual feature is `In Review`, depending on the workflow's decision rules. - - **Authentication and visibility.** Authenticate with the application API key in the `x-api-key` header (a console user Bearer token with the `read:sessions` permission also works). Only sessions owned by the authenticated application are visible. If your workflow restricts response attributes, non-allowed fields inside feature items are returned as `null` while `status`, `warnings`, and `node_id` are always preserved. - - **Rate limits.** GET requests are limited to 600 per minute per API key. Exceeding the limit returns `429` with `Retry-After` and `X-RateLimit-*` headers. + Return the shareholders and directors that the documents uploaded to this KYB session name, merged per person and attributed to the documents that named them. Show them to your applicant to confirm, then declare them with the party draft endpoints. A range stays a range: `ownership_percent.text` keeps the verbatim figure and `min` / `max` the numbers read from it. Nobody is labelled a UBO here; that is decided when the parties are submitted, from the role settings and ownership thresholds of the workflow. The same list is in the session decision as `document_verifications[].extracted_parties`. Requires `read:businesses` or `read:sessions`. - ``GET /v3/session/{sessionId}/decision/`` + ``GET /v3/session/{sessionId}/kyb/extracted-parties/`` Args: - session_id: UUID of the verification session whose decision you want to retrieve. This is the `session_id` returned by `POST /v3/session/`. The same path works for both User Verification (KYC) and Business Verification (KYB) sessions - the server resolves the id against both session types. **Must be a valid UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router before any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}` envelope shown below. Validate the UUID format client-side so you can distinguish an input error from a genuine missing-session `404`. - include: Comma-separated list of extra payload sections. Supported values: `events` and `resubmissions`, alone or together (`events,resubmissions`). When `include=events` is passed, the response additionally contains the session event timeline (`events`, including the `WORKFLOW_BRANCH_EVALUATED` / `WORKFLOW_STATUS_NODE_REACHED` routing events described on the Retrieve Session page), the full activity log (`activity_reviews`), blocklist flags (`blocklisted`), a per-session `cost_breakdown`, workflow metadata (`workflow_type`, `workflow_version`, `workflow_version_id`, and `workflow_terminal_node_id` - the last recorded workflow status node that set a session status, or `null` if none has been recorded; historical provenance that is not cleared by manual approvals, declines or resubmissions, and is replaced by a later workflow status node), and session metadata (`api_service` - string or `null`, set only for standalone-API sessions; `session_type` - `API`, `HOSTED`, or `MIGRATED`; `has_device_nfc_support` - boolean). Two fields change relative to the plain shape: the top-level `session_kind` discriminator is **omitted** (the events shape only exists for user sessions), and the `features` array switches from plain strings to `{feature, node_id}` objects - where the email feature is reported as `EMAIL` instead of `EMAIL_VERIFICATION`. This expanded shape is primarily used by the Didit Console; most API integrations should omit the parameter. **KYB limitation:** `include=events` only applies to user (KYC) sessions. Business sessions (`session_kind = "business"`) always return the standard business decision shape - `events`, `activity_reviews`, `blocklisted`, `cost_breakdown` and the extra `workflow_*`/session metadata are never returned for business sessions, and their `features` array stays a plain string array. With `include=resubmissions` (user and business sessions alike) the response also contains `resubmissions`: one entry per resubmission request, oldest first, each with `number`, `created_at`, `previous_status`, `nodes`, `reasons`, `requested_by` and `results` (what the resubmitted steps returned before the request, under the same keys and in the same shape as the current results). Each `cost_breakdown` item carries `usage_type`, `price`, `details` and `created_at`: a resubmitted step that runs again is billed as a new item. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionDecision", - await self._client.request( + "SessionsListKybExtractedPartiesResponse", + self._client.request( "get", - "/v3/session/{sessionId}/decision/", - cast_to=SessionDecision, + "/v3/session/{sessionId}/kyb/extracted-parties/", + cast_to=SessionsListKybExtractedPartiesResponse, path_params={"sessionId": session_id}, auth="api_key", - query={"include": include}, + query={"node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2405,84 +2303,39 @@ async def retrieve_decision( ), ) - async def delete( + def list_kyb_party_drafts( self, session_id: str, *, - retain_face_embeddings: bool | None | NotGiven = NOT_GIVEN, - face_retention_days: int | NotGiven = NOT_GIVEN, - face_retention_deadline: str | _dt.datetime | NotGiven = NOT_GIVEN, - deletion_instruction: Literal["operational_session_delete", "privacy_erasure"] - | str - | NotGiven = NOT_GIVEN, - instruction_id: str | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionsDeleteResponse: - """Delete a verification session (KYC or KYB). - - Delete a single verification session, User Verification (KYC) or Business Verification (KYB), by its `session_id`. The id is resolved against KYC sessions first, then KYB sessions, so both kinds are deleted through this one URL. - - **What is deleted:** - - The session and every verification attempt it holds, including results that a resubmission replaced: the decision, extracted data, all related feature records (ID verification, face, liveness, face match, AML, registry checks, IP analysis, and so on), its reviews and its activity log. - - All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded files (KYC); uploaded company documents and extra files (KYB). Electronic Signature documents, signed PDFs, evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media URLs (`https:///...`) stop resolving. - - The session's face data. Its face embedding is deleted too, unless you choose to keep an image-free template (see **Face biometric data**). - - Webhook deliveries still queued for the session, and their retries. Webhooks already delivered are not affected. - - For a Business Verification (KYB) session: the verifications it created for its key people (KYC) and its corporate owners (KYB), recursively, reported as `deleted_child_verifications`. A verification it only links to, such as an existing approved KYC it reused, is not deleted. - - The session disappears from every read endpoint immediately: `GET /v3/session/{sessionId}/decision/` returns `404` and `GET /v3/sessions/` stops listing it. Ongoing AML monitoring and KYB registry monitoring started by the deleted verifications stop. - - **What is not affected:** blocklist entries created from this session (face or document) are **not** removed; manage those with the blocklist endpoints. Share tokens issued for the session are not revoked, but there is nothing left for them to import: an import with one returns `400` with `{"share_token": ["Original session does not exist."]}`. Credits already consumed are **not** refunded. The parent User or Business entity is **not** deleted; use `POST /v3/users/delete/` or `POST /v3/businesses/delete/` for those. If the User's profile portrait came from this session, the portrait is removed with it. - - **Face biometric data:** by default the session's face embedding is deleted with the session (`face_retention_outcome: deleted`). An application that opted in to biometric-template retention (`face_retention_policy: retain_until_user_deleted` on `PATCH /v3/webhook/`), or a request with `retain_face_embeddings: true`, keeps one separately managed, image-free face biometric template anchored to the session's User (`retained_with_user`) so that duplicate detection, Face Search, and biometric authentication keep working. The template never contains the face image, media, identity fields, the decision, or the deleted session's id; it is biometric data deleted at `biometric_template_expires_at`, or earlier on User deletion, privacy erasure, or an explicit purge through `/v3/biometric-templates/`. A session without a linked User cannot retain a template (`ineligible_no_vendor_user`). Send `deletion_instruction: privacy_erasure` for data-subject requests: it purges every retained template for that User and never retains a new one. - - **Irreversible:** deletion is permanent and there is no restore endpoint. Export anything you need (for example a decision PDF) before you call it. - - **Side effects:** no webhook is emitted for deletions. - - **Response:** `200 OK` once the deletion has completed, with a JSON body reporting the `face_retention_outcome`, the retained template's expiry and, for a KYB session, `deleted_child_verifications`. Earlier versions of this endpoint returned `204 No Content`; update clients that assert on `204`. Keep your `instruction_id` in your own erasure log. + ) -> SessionsListKybPartyDraftsResponse: + """List the KYB party drafts. - **Idempotency:** not idempotent at the HTTP level: the first call returns `200`; repeating it returns `404` because the session no longer resolves. After a `503` the session is still in place; repeat the same request to finish deleting it. - - **Authentication:** send your application's API key in the `x-api-key` header; the session must belong to that application. Console user access tokens (`Authorization: Bearer ...`) may also call this endpoint when they carry the `delete:sessions` permission. Authentication and permission failures both return `403`; this API never returns `401`. - - **Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`. - - To bulk-delete KYC sessions by their numeric `session_number`, use `POST /v3/sessions/delete/` instead. - - **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request. + List the parties you are preparing for this KYB session, oldest first. A draft is not a declared party: it does not appear in the decision or the console and creates no verification session until you submit it with `POST /v3/session/{sessionId}/kyb/parties/submit/`. Requires `write:businesses`. - ``DELETE /v3/session/{sessionId}/delete/`` + ``GET /v3/session/{sessionId}/kyb/parties/drafts/`` Args: - session_id: UUID (`session_id`) of the User Verification (KYC) or Business Verification (KYB) session to delete, as returned when the session was created. Must be a canonical hyphenated UUID - a non-UUID value does not match the route and returns `404`. - retain_face_embeddings: Override the application's `face_retention_policy` for this deletion. `true` keeps one image-free face biometric template anchored to the session's User after the session is deleted; `false` deletes the face embedding with the session; omit or `null` to follow the application policy. Ignored for KYB sessions and for sessions without a face embedding. - face_retention_days: Finite retention duration, in days, for a retained template. Required when a template is retained unless the application already sets `face_retention_days`. The template's `expires_at` is the earliest of this duration, the application's general data-retention window, and `face_retention_deadline`. - face_retention_deadline: Optional hard expiry for a retained template. Must be in the future. - deletion_instruction: The class of instruction you are giving. `operational_session_delete` deletes the session and retains a template only when the policy or `retain_face_embeddings` says so. `privacy_erasure` purges every retained biometric template anchored to the session's User before deleting the session, cannot be overridden by the application policy, and cannot be combined with `retain_face_embeddings: true` (`400`). - instruction_id: Your durable reference for this deletion instruction (for example an erasure-ticket id). Recorded on the audit trail and on any retained template. Generated by Didit when omitted. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsDeleteResponse", - await self._client.request( - "delete", - "/v3/session/{sessionId}/delete/", - cast_to=SessionsDeleteResponse, + "SessionsListKybPartyDraftsResponse", + self._client.request( + "get", + "/v3/session/{sessionId}/kyb/parties/drafts/", + cast_to=SessionsListKybPartyDraftsResponse, path_params={"sessionId": session_id}, auth="api_key", - body={ - "retain_face_embeddings": retain_face_embeddings, - "face_retention_days": face_retention_days, - "face_retention_deadline": face_retention_deadline, - "deletion_instruction": deletion_instruction, - "instruction_id": instruction_id, - }, + query={"node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2490,59 +2343,131 @@ async def delete( ), ) - async def generate_pdf( + def create_kyb_party_draft( self, session_id: str, *, + entity_type: Literal["person", "company"] | str, + nationality: str, + full_name: str | NotGiven = NOT_GIVEN, + first_name: str | NotGiven = NOT_GIVEN, + last_name: str | NotGiven = NOT_GIVEN, + role: Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + | NotGiven = NOT_GIVEN, + roles: Sequence[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | NotGiven = NOT_GIVEN, + position: str | NotGiven = NOT_GIVEN, + date_of_birth: str | _dt.date | None | NotGiven = NOT_GIVEN, + company_name: str | NotGiven = NOT_GIVEN, + registration_number: str | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, + ownership_percent: float | None | NotGiven = NOT_GIVEN, + phone_number: str | NotGiven = NOT_GIVEN, + custom_fields: Mapping[str, object] | NotGiven = NOT_GIVEN, + skip_verification: bool | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> bytes: - """Download a PDF report for a verification session. - - Render and download a compliance-ready PDF report for a finished verification session. The same path serves both User Verification (KYC) and Business Verification (KYB) sessions - the server resolves the `sessionId` against both session types and picks the matching report template. - - **Eligible statuses.** The session must already carry a final or reviewable status: - - - KYC sessions: `Approved`, `Declined`, `In Review`, or `Kyc Expired`. - - KYB sessions: `Approved`, `Declined`, or `In Review`. - - Any other status (`Not Started`, `In Progress`, `Expired`, `Abandoned`, …) returns `403` with an explanatory `detail` string - see the `403` response below. - - **What the report contains.** The PDF mirrors the console session view at the moment of the request: - - - **KYC** - rolled-up session status, the warnings list, and one section per executed feature: ID Verification (document images plus extracted fields), NFC, Liveness, Face Match, Email Verification, Phone Verification, Proof of Address, Questionnaire answers, Database Validation, AML Screening, and IP Analysis - followed by session tags, console review activity (comments and status changes), and the session event timeline. - - **KYB** - registry checks (company data), AML screenings, business document verifications, key-people checks, questionnaire responses, phone/email verifications, IP analyses, and the session event timeline, followed by tags and review activity. - - **Branding.** If your application has white-label customization, the report is rendered with your logo and links to your privacy-policy URL; otherwise it carries Didit branding. Reports are rendered in English - there is no language parameter. - - **No caching.** Every call re-renders the PDF from the current session data, so a report generated after a manual review reflects the reviewer’s decision. Two calls for the same session can produce byte-different files - archive the downloaded file if you need an immutable copy. - - **Latency.** Rendering downloads every stored image (document sides, selfies, extra files) before composing the PDF, so media-heavy sessions can take several seconds. Use a generous client read timeout (60 s recommended) and stream the body to disk. + ) -> SessionsCreateKybPartyDraftResponse: + """Create a KYB party draft. - **Trailing slash.** The canonical route ends with a trailing slash (`…/generate-pdf/`). A request without it is served directly with the same response - there is no `301` redirect, so no client has to follow redirects and `curl` does not need `-L`. Use the slashed URL as in the samples. - - If you need the underlying data as JSON instead of a rendered report, use `GET /v3/session/{sessionId}/decision/`. For every reportable session of one user in a single document, use `GET /v3/users/{vendor_data}/generate-pdf/`. + Add a party (a person or a company) to the list you are preparing for this KYB session. The same fields and rules as the hosted Key People screen apply: a person needs `full_name` or `first_name` and `last_name`, at least one role and a nationality; a company needs `company_name` and the country of incorporation in `nationality`. Nothing is declared or billed until `POST /v3/session/{sessionId}/kyb/parties/submit/`. Requires `write:businesses`. - ``GET /v3/session/{sessionId}/generate-pdf/`` + ``POST /v3/session/{sessionId}/kyb/parties/drafts/`` Args: - session_id: UUID of the User Verification (KYC) or Business Verification (KYB) session to render - the `session_id` returned by `POST /v3/session/`. The same path works for both session kinds; use the `Content-Disposition` filename on the response to tell which report type you received. **Must be a well-formed, lowercase UUID.** The route only matches valid UUIDs, so a malformed value is rejected by the URL router before any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}` envelope shown below. The route's UUID converter only matches the canonical lowercase form - uppercase-hex UUIDs are rejected with the HTML 404. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + entity_type: Whether the party is an individual or a company. + nationality: Nationality of a person, or country of incorporation of a company. Required for every party. + full_name: Full name of a person. Send it, or `first_name` and `last_name`. + first_name + last_name + role: Role the party holds. Interchangeable with `roles`; when both are sent they are merged. + roles: Every role the party holds. A person needs at least one role (here or in `role`). + position: Job title of a person. + date_of_birth + company_name: Name of a company party. Required when `entity_type` is `company`. + registration_number: Registration number of a company party. + email: Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow. + ownership_percent: Share of the company the party owns. + phone_number + custom_fields: Workflow-defined extra fields. + skip_verification: Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "bytes", - await self._client.request( - "get", - "/v3/session/{sessionId}/generate-pdf/", - cast_to=bytes, + "SessionsCreateKybPartyDraftResponse", + self._client.request( + "post", + "/v3/session/{sessionId}/kyb/parties/drafts/", + cast_to=SessionsCreateKybPartyDraftResponse, path_params={"sessionId": session_id}, auth="api_key", - accept="application/pdf, application/json", + query={"node_id": node_id}, + body={ + "entity_type": entity_type, + "nationality": nationality, + "full_name": full_name, + "first_name": first_name, + "last_name": last_name, + "role": role, + "roles": roles, + "position": position, + "date_of_birth": date_of_birth, + "company_name": company_name, + "registration_number": registration_number, + "email": email, + "ownership_percent": ownership_percent, + "phone_number": phone_number, + "custom_fields": custom_fields, + "skip_verification": skip_verification, + }, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2550,68 +2475,41 @@ async def generate_pdf( ), ) - async def update_status( + def delete_kyb_party_draft( self, session_id: str, + draft_id: str, *, - new_status: Literal["Approved", "Declined", "Resubmitted"] | str, - comment: str | NotGiven = NOT_GIVEN, - nodes_to_resubmit: Sequence[SessionsUpdateStatusParamsNodesToResubmit] - | NotGiven = NOT_GIVEN, - send_email: bool | NotGiven = NOT_GIVEN, - email_address: str | NotGiven = NOT_GIVEN, - email_language: str | NotGiven = NOT_GIVEN, - email_preview_token: str | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionsUpdateStatusResponse: - """Approve, decline, or request resubmission for a verification session. - - Manually override the final decision of a KYC or KYB verification session. Set `new_status` to `Approved` or `Declined` to record a manual decision, or to `Resubmitted` to clear specific verification steps and let the user redo them through the same verification URL. The endpoint accepts both user (KYC) and business (KYB) session IDs. - - Call it once a session has reached a reviewable state: the current status must be `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned`, or `Resubmitted`. Sessions that are still `Not Started`, `In Progress`, or `Awaiting User`, or that ended as `Expired`, return `400`. Your API key needs the `write:sessions` permission (a scoped API key needs write access to decisions). The eligible-state check runs before body validation, so an ineligible session returns the `Wrong Current Status` error even when the payload is also invalid. - - For `Resubmitted`, pass `nodes_to_resubmit` to choose which workflow steps the user must redo, or omit it to auto-select existing feature attempts in a resubmittable state (`Declined`, `In Review`, `Not Finished`, `Expired`). Never-attempted features are not auto-selected: list them explicitly in `nodes_to_resubmit`, or the request returns `400` when no recorded attempt needs resubmission. The selected steps' previous results move to the resubmission's history (returned by Get Decision with `include=resubmissions`), the steps are reordered to match the workflow graph, the session's expiration window restarts, and the original verification URL becomes usable again. Backend-only steps (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) at the head of the list run immediately without user interaction; if every resubmitted step is backend-only, the session re-finalizes within the same request. `KYB_REGISTRY` and `KYB_KEY_PEOPLE` cannot be resubmitted directly: resubmit the relevant child KYC sessions instead and the parent business session recomputes automatically. - - Every call that changes the status fires the `status.updated` [webhook](/integration/webhooks) once the change commits and appends an activity entry (with actor attribution and your `comment`) to the session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and in the console activity timeline. The user-profile aggregates linked to the session's `vendor_data` update as well. Declining disables ongoing AML monitoring for the session; re-approving re-enables it (from `Resubmitted`, `Declined`, or `Kyc Expired`) when the workflow has monitoring turned on. Approving or declining a child KYC that belongs to a KYB key-people check recomputes the parent business session's status. Set `send_email: true` (with `email_address`) to notify the user: a status notice for `Approved`/`Declined`, or a resubmission email containing the verification link and per-step reasons for `Resubmitted`. To check the email first, preview it with [Preview Decision Email](/sessions-api/preview-decision-email) (`Approved`, `Declined`) or [Preview Resubmission Email](/sessions-api/preview-resubmission) (`Resubmitted`) and pass its `preview_token` as `email_preview_token`: the update then sends exactly the previewed email, or returns `409` before changing anything when the email or the session changed since the preview or the receipt is older than 15 minutes. + ) -> None: + """Delete a KYB party draft. - Repeating `Approved` or `Declined` on a session that already has that status changes nothing and returns `200`: no webhook, no activity entry and no email. Repeating `Resubmitted` returns `400` (`The new status is the same as the current status.`). Missing or invalid credentials and missing permissions return `403`; an expired scoped API key returns `401`. + Drop one party draft. Declared parties are not affected. Requires `write:businesses`. - ``PATCH /v3/session/{sessionId}/update-status/`` + ``DELETE /v3/session/{sessionId}/kyb/parties/drafts/{draftId}/`` Args: - session_id: UUID of the verification session to update. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. - new_status: Target status. `Approved` and `Declined` record a final manual decision (each can also overturn the other). `Resubmitted` clears the selected steps and sends the session back to the user. Any other value returns `400`. - comment: Free-text reason for the change, stored on the session's review trail and returned in the `reviews` array of [Get Decision](#get-/v3/session/-sessionId-/decision/). For example `Duplicated user`. - nodes_to_resubmit: Workflow steps the user must redo. Only acted on when `new_status` is `Resubmitted`. For `Approved`/`Declined` the entries are still schema-validated (an invalid `feature` value returns `400`) but schema-valid entries are semantically ignored. If omitted, the server auto-selects existing OCR, Liveness, Face Match, POA, Phone, Email, AML, Database Validation, and Questionnaire attempts whose status is `Declined`, `In Review`, `Not Finished`, or `Expired` (NFC, IP analysis, age estimation, face search, and KYB document attempts are never auto-selected; non-face-match face attempts are selected as `LIVENESS`) - features the user never attempted (no recorded attempt) are NOT selected, so a session with zero attempts returns `400` ("No features found that need resubmission") even though nothing was approved; pass `nodes_to_resubmit` explicitly in that case. Steps are executed in workflow-graph order regardless of the order you send them. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, and the `KYB` alias are rejected with `400` - those parent checks recompute from their child KYC sessions. - send_email: Whether to email the user about the change. Requires `email_address`. For `Approved`/`Declined` the user receives a status notice; for `Resubmitted` the email includes the verification link and the per-step resubmission reasons. - email_address: Recipient for the notification email. **Required when `send_email` is `true`** - omitting it returns `400`. - email_language: Language for the notification email. Accepts any string at schema level; unsupported codes silently fall back to English (`en`). - email_preview_token: Optional receipt from [Preview Decision Email](/sessions-api/preview-decision-email) (for `Approved` and `Declined`) or [Preview Resubmission Email](/sessions-api/preview-resubmission) (for `Resubmitted`): its `preview_token`. Valid only with `send_email: true`; without it the request returns `400`. The recipient, language, session status, sender and email (and, for a resubmission, the selected steps) must still match the preview, and the receipt expires after 15 minutes. Otherwise the request returns `409` before the session changes or an email is sent. Existing integrations may omit this field. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + draft_id: UUID of the party draft (`draft_id` returned when it was created). + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsUpdateStatusResponse", - await self._client.request( - "patch", - "/v3/session/{sessionId}/update-status/", - cast_to=SessionsUpdateStatusResponse, - path_params={"sessionId": session_id}, + "None", + self._client.request( + "delete", + "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/", + cast_to=None, + path_params={"sessionId": session_id, "draftId": draft_id}, auth="api_key", - body={ - "new_status": new_status, - "comment": comment, - "nodes_to_resubmit": nodes_to_resubmit, - "send_email": send_email, - "email_address": email_address, - "email_language": email_language, - "email_preview_token": email_preview_token, - }, + query={"node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2619,134 +2517,132 @@ async def update_status( ), ) - def list( + def update_kyb_party_draft( self, + session_id: str, + draft_id: str, *, - session_kind: Literal["user", "business", "all"] | str | NotGiven = NOT_GIVEN, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - status: str | NotGiven = NOT_GIVEN, - vendor_data: str | NotGiven = NOT_GIVEN, - search: str | NotGiven = NOT_GIVEN, - workflow_id: str | NotGiven = NOT_GIVEN, - date_from: str | _dt.date | NotGiven = NOT_GIVEN, - date_to: str | _dt.date | NotGiven = NOT_GIVEN, - country: str | NotGiven = NOT_GIVEN, - document_type: str | NotGiven = NOT_GIVEN, - document_name: str | NotGiven = NOT_GIVEN, - region: str | NotGiven = NOT_GIVEN, - didit_internal_id: str | NotGiven = NOT_GIVEN, - session_type: str | NotGiven = NOT_GIVEN, - api_service: Literal[ - "ID_VERIFICATION", - "FACE_MATCH", - "AGE_ESTIMATION", - "FACE_SEARCH", - "POA", - "AML", - "KYB_REGISTRY", - "PASSIVE_LIVENESS", - "DATABASE_VALIDATION", - "PHONE_VERIFICATION", - "EMAIL_VERIFICATION", + entity_type: Literal["person", "company"] | str | NotGiven = NOT_GIVEN, + full_name: str | NotGiven = NOT_GIVEN, + first_name: str | NotGiven = NOT_GIVEN, + last_name: str | NotGiven = NOT_GIVEN, + role: Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", ] | str | NotGiven = NOT_GIVEN, - screened_full_name: str | NotGiven = NOT_GIVEN, - warning: str | NotGiven = NOT_GIVEN, - status_initialized_as_in_review: bool | NotGiven = NOT_GIVEN, - is_kyc_to_be_reviewed: bool | NotGiven = NOT_GIVEN, - euuid: str | NotGiven = NOT_GIVEN, - organization_name: str | NotGiven = NOT_GIVEN, + roles: Sequence[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | NotGiven = NOT_GIVEN, + position: str | NotGiven = NOT_GIVEN, + date_of_birth: str | _dt.date | None | NotGiven = NOT_GIVEN, + company_name: str | NotGiven = NOT_GIVEN, + registration_number: str | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, + ownership_percent: float | None | NotGiven = NOT_GIVEN, + nationality: str | NotGiven = NOT_GIVEN, + phone_number: str | NotGiven = NOT_GIVEN, + custom_fields: Mapping[str, object] | NotGiven = NOT_GIVEN, + skip_verification: bool | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> AsyncPaginator[UserSessionListItem | BusinessSessionListItem]: - """List verification sessions (KYC and/or KYB) with filters and pagination. - - Returns a paginated list of verification sessions for the application identified by your API key, newest first (descending `session_number`). - - **Canonical URL:** the route is `/v3/sessions/` (trailing slash). Requests to `/v3/sessions` without the slash receive a `301` redirect to the slashed URL with the query string preserved; most HTTP clients follow it transparently on GET. - - **When to use this endpoint vs webhooks.** Use this endpoint for dashboards, back-office search, reconciliation, and batch exports. Do not poll it to track the progress of individual verifications - configure [webhooks](/integration/webhooks) instead, which push `status.updated` events the moment a session changes. For one session's full result, call `GET /v3/session/{sessionId}/decision/`. - - **KYC and KYB sessions.** `session_kind` selects which kinds are listed: - - `user` (default) - User Verification (KYC) sessions only. Backward-compatible behavior. - - `business` - Business Verification (KYB) sessions only. Rows have a different, smaller shape (see the response schema). - - `all` - both kinds in one response: the KYC page and the KYB page for the same `limit`/`offset` are concatenated in `results` (KYC rows first), so a page can contain up to `2 x limit` rows. `count` is the sum of both kinds and `next`/`previous` reflect the KYC-side pagination. For strict pagination of mixed data, call `user` and `business` separately. - - Every row carries a `session_kind` discriminator (`"user"` or `"business"`). + ) -> SessionsUpdateKybPartyDraftResponse: + """Edit a KYB party draft. - **Pagination.** Standard limit/offset: `limit` (default 50) and `offset` (default 0), with `next`/`previous` ready-made page URLs. For KYC rows `count` is exact. For KYB rows `count` is computed with a bounded scan and is capped at 100 - when there are more than 100 matches it stays at 100, so iterate using `next` (or by checking whether a full page came back) rather than computing total pages from `count`. - - **Filter semantics.** All filters combine with AND and apply to KYC rows. When `session_kind` is `business` or `all`, the KYB side honors the shared parameters `vendor_data`, `status`, `workflow_id`, `country` (registry-company country code), `date_from`, `date_to`, `search` (company name, registration number - type registration numbers without separators, e.g. `DPC001` not `DPC-001` - vendor_data, session number, or session UUID), `warning`, and `organization_name`; the remaining KYC-only filters are ignored for KYB rows. Comma-separated parameters (`status`, `country`, `document_type`, `region`, `workflow_id`, `document_name`, `warning`, `organization_name`, `session_type`) match any of the listed values (OR within the parameter). `vendor_data` is an exact match - use `search` for partial matching. Unknown values in list filters simply return no rows (no error); malformed typed values (`date_from`, `date_to`, `didit_internal_id`, `api_service`, `session_kind`) return `400` with a per-field error object. - - **Search.** `search` adapts to the input: a full UUID looks up `session_id`; digits (with optional `+ - . space`) match session-number prefix, document/personal numbers, phone-number prefix, or `vendor_data`; values containing `@` match email prefixes; any other text matches names (accent-insensitive) and `vendor_data`. - - No fixed per-endpoint rate limit is enforced, but keep list polling infrequent and rely on webhooks for real-time updates. + Change fields of one party draft. The edit is merged into the stored draft and the merged party is validated as a whole, so an edit that would leave the party incomplete is rejected. Changing `first_name` or `last_name` replaces the stored full name. Requires `write:businesses`. - ``GET /v3/sessions/`` + ``PATCH /v3/session/{sessionId}/kyb/parties/drafts/{draftId}/`` Args: - session_kind: Which kind of sessions to list: `user` (KYC only, default), `business` (KYB only), or `all` (both, concatenated - see the description for merged-pagination semantics). Matching is case-insensitive (`BUSINESS` works); any value other than a case variant of `user`/`business`/`all` returns `400`. - limit: Maximum number of rows per page (per kind when `session_kind=all`). Defaults to 50. - offset: Number of rows to skip before the first returned row. Defaults to 0. Prefer following the `next`/`previous` URLs from the response. - status: Comma-separated list of session statuses to include, e.g. `Approved,In Review`. Values are case-sensitive; see [Verification Statuses](/integration/verification-statuses). Unknown values match nothing. - vendor_data: Exact-match filter on the `vendor_data` you sent at session creation (your own user/business identifier). For partial matches use `search` instead. - search: A complete displayed reference such as `S-0001` (user) or `B-0001` (business) matches only that session number and kind; leading zeros and letter case do not affect matching. Smart free-text search. A full UUID matches `session_id`; numeric input matches session-number prefix, document/personal numbers, phone prefix, or `vendor_data`; input containing `@` matches email prefixes; other text matches names (accent-insensitive) and `vendor_data`. Free text containing digits additionally matches document/personal-number search fields and session-number prefixes. - workflow_id: Comma-separated workflow UUIDs (find them on the Workflows page in the Console). Malformed UUIDs in the list are ignored; if none are valid the result is empty. - date_from: Only sessions created on or after this date (UTC), format `YYYY-MM-DD`. Malformed dates return `400`. - date_to: Only sessions created up to this date (UTC), format `YYYY-MM-DD`. For KYC rows the entire day is included; for KYB rows the comparison is `created_at <= date_to` (midnight), so use the next day's date to include a full day of KYB sessions. - country: Comma-separated country filter. For KYC rows: ISO 3166-1 alpha-3 codes of the ID document's issuing state (e.g. `ESP,USA`), which may differ from nationality. For KYB rows: the registry company's country code. - document_type: Comma-separated ID-document type codes verified in the session (KYC rows only): `P` (Passport), `ID` (Identity Card), `DL` (Driver's License), `RP` (Residence Permit), `SSC` (Social Security Card), `HIC` (Health Insurance Card), `WP` (Work Permit), `TC` (Tax Card), `VISA`, `PSC` (Public Service Card), `BC` (Birth Certificate), `OTHER`. Note the response field `document_type` contains the display name, not the code. - document_name: Exact document names; multiple names can be passed comma-separated, but the value is only split on commas when it contains more than one ` - ` separator (a lone name with an embedded comma is matched whole). Names are as recognized by document verification (front or back side), e.g. `Spain - Id Card (2021)`. KYC rows only. - region: Comma-separated document region/state values (for documents issued per region, such as US driver's licenses). KYC rows only. - didit_internal_id: Filter by Didit's internal user identifier (the `didit_internal_id` response field) to list all sessions of one verified user. Must be a valid UUID; malformed values return `400`. KYC rows only. - session_type: Comma-separated session creation channels: `API`, `HOSTED`, `MIGRATED`. The special value `ALL` (or omitting the parameter) disables the filter. KYC rows only. - api_service: Filter standalone API sessions by service. Invalid values return `400`. KYC rows only. - screened_full_name: Accent-insensitive name search inside AML and database-validation screened data. When combined with `api_service=AML` or `api_service=DATABASE_VALIDATION`, the search is restricted to that feature's screened data. KYC rows only. - warning: Comma-separated warning risk codes; returns sessions that raised any of them (e.g. `POSSIBLE_FRAUD`). Risk codes are listed per feature in the [warnings documentation](/integration/webhooks). Applies to KYC rows and, with business warning codes, to KYB rows. - status_initialized_as_in_review: When `true`, only sessions whose decision initially landed in `In Review` (useful to audit manual-review volume). KYC rows only. - is_kyc_to_be_reviewed: `true` returns sessions whose document verification is flagged for manual review; `false` returns sessions with document verification explicitly not flagged. Omit to disable. KYC rows only. - euuid: Filter by the end user's euuid (UUID assigned to the verifying user, used by Console deep links). Must be a valid UUID; malformed values return a 400 field error. KYC rows only. - organization_name: Comma-separated organization names. Console-oriented; with an API key (already scoped to one application) it only matches your own organization's name. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + draft_id: UUID of the party draft (`draft_id` returned when it was created). + entity_type: Whether the party is an individual or a company. + full_name: Full name of a person. Send it, or `first_name` and `last_name`. + first_name + last_name + role: Role the party holds. Interchangeable with `roles`; when both are sent they are merged. + roles: Every role the party holds. A person needs at least one role (here or in `role`). + position: Job title of a person. + date_of_birth + company_name: Name of a company party. Required when `entity_type` is `company`. + registration_number: Registration number of a company party. + email: Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow. + ownership_percent: Share of the company the party owns. + nationality: Nationality of a person, or country of incorporation of a company. Required for every party. + phone_number + custom_fields: Workflow-defined extra fields. + skip_verification: Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "AsyncPaginator[UserSessionListItem | BusinessSessionListItem]", - self._client.request_page( - "get", - "/v3/sessions/", - cast_to=SessionsListResponse, - item_type=UserSessionListItem | BusinessSessionListItem, + "SessionsUpdateKybPartyDraftResponse", + self._client.request( + "patch", + "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/", + cast_to=SessionsUpdateKybPartyDraftResponse, + path_params={"sessionId": session_id, "draftId": draft_id}, auth="api_key", - query={ - "session_kind": session_kind, - "limit": limit, - "offset": offset, - "status": status, - "vendor_data": vendor_data, - "search": search, - "workflow_id": workflow_id, - "date_from": date_from, - "date_to": date_to, - "country": country, - "document_type": document_type, - "document_name": document_name, - "region": region, - "didit_internal_id": didit_internal_id, - "session_type": session_type, - "api_service": api_service, - "screened_full_name": screened_full_name, - "warning": warning, - "status_initialized_as_in_review": status_initialized_as_in_review, - "is_kyc_to_be_reviewed": is_kyc_to_be_reviewed, - "euuid": euuid, - "organization_name": organization_name, + query={"node_id": node_id}, + body={ + "entity_type": entity_type, + "full_name": full_name, + "first_name": first_name, + "last_name": last_name, + "role": role, + "roles": roles, + "position": position, + "date_of_birth": date_of_birth, + "company_name": company_name, + "registration_number": registration_number, + "email": email, + "ownership_percent": ownership_percent, + "nationality": nationality, + "phone_number": phone_number, + "custom_fields": custom_fields, + "skip_verification": skip_verification, }, extra_headers=extra_headers, extra_query=extra_query, @@ -2755,41 +2651,42 @@ def list( ), ) - async def share( + def submit_kyb_parties( self, session_id: str, *, - for_application_id: str, - ttl_in_seconds: int | NotGiven = NOT_GIVEN, + locale: str | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionsShareResponse: - """Mint a share token for a finished verification session. + ) -> SessionsSubmitKybPartiesResponse: + """Submit the KYB party drafts. - Mint a short-lived JWT that lets a specific Didit application import this finished session. Pair with `POST /v3/session/import-shared/`. + Declare the stored drafts as the company's key people. This is the hosted Key People step under your API key: Didit decides from the role settings and ownership thresholds of the workflow which parties must be verified, creates one individual KYC session (or a KYB sub-session for a corporate owner) for each of them, sends the emails the workflow asks for, and advances the session. Each child session is billed like in the hosted flow. The drafts are consumed. Repeating the call after a successful submit changes nothing and answers `200` with `already_submitted: true` and the parties that already exist. The session must be on the Key People step. Send each person's `kyc_session_url` to them, or embed it. Requires `write:businesses`. - ``POST /v3/session/{sessionId}/share/`` + ``POST /v3/session/{sessionId}/kyb/parties/submit/`` Args: - session_id: UUID of the source verification session to mint a token for. - for_application_id: UUID of the Didit application that will redeem the token. Must exist, must not be deleted, and must differ from the calling application. Find it in the Business Console under **Settings → Application**. - ttl_in_seconds: Token lifetime, in seconds. Minimum `60`, maximum `86400` (24 h). Defaults to `3600` (1 h). + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + locale: Locale used to translate the response of the step the session advances to. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsShareResponse", - await self._client.request( + "SessionsSubmitKybPartiesResponse", + self._client.request( "post", - "/v3/session/{sessionId}/share/", - cast_to=SessionsShareResponse, + "/v3/session/{sessionId}/kyb/parties/submit/", + cast_to=SessionsSubmitKybPartiesResponse, path_params={"sessionId": session_id}, auth="api_key", - body={"for_application_id": for_application_id, "ttl_in_seconds": ttl_in_seconds}, + query={"node_id": node_id}, + body={"locale": locale}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2797,47 +2694,38 @@ async def share( ), ) - async def import_shared( + def export_files( self, + session_id: str, *, - share_token: str, - trust_review: bool, - workflow_id: str, - vendor_data: str | None | 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, - ) -> SessionDecision: - """Redeem a share token to clone a verification session into your application. + ) -> SessionFilesExport: + """Export every file of a session. - Redeem a share token to clone a KYC or KYB session into the calling application with a fresh `session_id`. Not idempotent - a token redeems once per receiver. + Start preparing one ZIP with every image, video and document of a User Verification (KYC) or Business Verification (KYB) session, in original quality: the files are stored in the ZIP as they were captured, never recompressed. Answers `202` with the export; read it with `GET /v3/session/{sessionId}/files-export/{exportId}/` until `status` is `READY`, then download `download_url`. While an export of the same session is still being prepared, that export is returned instead of a new one. - ``POST /v3/session/import-shared/`` + The ZIP is deleted 24 hours after it is ready, and at once when the session is deleted. A deleted session cannot be exported. Every export and every download link handed out is written to the session's audit log. A scoped API key needs `media: read` and `decisions: read`; a console user needs the privilege to read sessions. + + ``POST /v3/session/{sessionId}/files-export/`` Args: - share_token: JWT share token issued by [`POST /v3/session/{sessionId}/share/`](/sessions-api/share-session). - trust_review: If `true`, the cloned session keeps the source's final `status`. If `false`, it is forced into `In Review`. - workflow_id: UUID of a workflow in the calling application. Cross-application IDs are rejected with `404`. - vendor_data: Optional override for the cloned session's `vendor_data`. + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs. A deleted session returns `404`. 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( - "SessionDecision", - await self._client.request( + "SessionFilesExport", + self._client.request( "post", - "/v3/session/import-shared/", - cast_to=SessionDecision, + "/v3/session/{sessionId}/files-export/", + cast_to=SessionFilesExport, + path_params={"sessionId": session_id}, auth="api_key", - body={ - "share_token": share_token, - "trust_review": trust_review, - "workflow_id": workflow_id, - "vendor_data": vendor_data, - }, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2845,147 +2733,1499 @@ async def import_shared( ), ) - async def batch_delete( + def get_files_export( self, + session_id: str, + export_id: str, *, - session_numbers: Sequence[str] | NotGiven = NOT_GIVEN, - delete_all: bool | NotGiven = NOT_GIVEN, - retain_face_embeddings: bool | None | NotGiven = NOT_GIVEN, - face_retention_days: int | NotGiven = NOT_GIVEN, - face_retention_deadline: str | _dt.datetime | NotGiven = NOT_GIVEN, - deletion_instruction: Literal["operational_session_delete", "privacy_erasure"] - | str - | NotGiven = NOT_GIVEN, - instruction_id: str | NotGiven = NOT_GIVEN, - filter_status: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_vendor_data: str | NotGiven = NOT_GIVEN, - filter_search: str | NotGiven = NOT_GIVEN, - filter_workflow_id: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_date_from: str | _dt.date | NotGiven = NOT_GIVEN, - filter_date_to: str | _dt.date | NotGiven = NOT_GIVEN, - filter_country: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_document_type: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_document_name: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_region: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_didit_internal_id: str | NotGiven = NOT_GIVEN, - filter_session_type: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_api_service: str | NotGiven = NOT_GIVEN, - filter_screened_full_name: str | NotGiven = NOT_GIVEN, - filter_warning: str | Sequence[str] | NotGiven = NOT_GIVEN, - filter_status_initialized_as_in_review: bool | NotGiven = NOT_GIVEN, - filter_is_kyc_to_be_reviewed: bool | NotGiven = NOT_GIVEN, - filter_euuid: str | NotGiven = NOT_GIVEN, - filter_organization_name: str | Sequence[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, - ) -> SessionsBatchDeleteResponse | SessionDeletionJob: - """Bulk delete KYC sessions by session_number. + ) -> SessionFilesExport: + """Get a session files export. - Bulk delete User Verification (KYC) sessions by their numeric `session_number`, or every KYC session in your application with `delete_all: true`. + Progress of an export started with `POST /v3/session/{sessionId}/files-export/`. Once `status` is `READY`, `download_url` is a signed URL of the ZIP that stays valid for a short time; read the export again for a new one until `expires_at`. Each read that hands out a download link is written to the session's audit log. An export of a deleted session returns `404`. - `session_number` is the human-friendly incrementing counter shown in the Console session list and returned as `session_number` by the create-session and decision endpoints; it is **not** the `session_id` UUID. To delete a session by UUID, or to delete a Business Verification (KYB) session, which this endpoint never touches, use `DELETE /v3/session/{sessionId}/delete/` instead. + ``GET /v3/session/{sessionId}/files-export/{exportId}/`` - **Up to 20 sessions are deleted in the request, more run as a job.** The number of matching sessions decides, whether they are selected by `session_numbers` or with `delete_all`: - - Up to 20 matching sessions: they are deleted before the response, which is `200` with one entry per session in `results[]`. - - More than 20: the response is `202` with a deletion job, and the sessions are deleted in the background. Poll `GET /v3/sessions/delete/{job_id}/` until `status` is `COMPLETED` or `FAILED`. A job reports counts per outcome, never which sessions it deleted. A `delete_all` job deletes only the sessions created before the request; sessions started while it runs are not deleted. + Args: + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs. A deleted session returns `404`. + export_id: The `export_id` returned by `POST /v3/session/{sessionId}/files-export/`. + 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( + "SessionFilesExport", + self._client.request( + "get", + "/v3/session/{sessionId}/files-export/{exportId}/", + cast_to=SessionFilesExport, + path_params={"sessionId": session_id, "exportId": export_id}, + auth="api_key", + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) - Each deleted session gets exactly the same treatment as the single-session delete endpoint: the session, every verification attempt it holds, its decision and extracted data, its related feature records (ID verification, face, liveness, face match, and so on) and all of its stored files are deleted, it disappears from every read endpoint, and previously issued media URLs stop resolving. Webhook deliveries still queued for a deleted session, and their retries, are dropped; webhooks already delivered are not affected. Blocklist entries are **not** removed, credits already consumed are **not** refunded, and the parent User entities are **not** deleted (use `POST /v3/users/delete/` for those); no webhook is emitted for the deletion. Deletion is permanent and irreversible. - **Selection semantics:** - - With `delete_all: true` you can narrow the selection with the filters of `GET /v3/sessions/`, each prefixed with `filter_` (for example `filter_status`, `filter_workflow_id`, `filter_date_from`). Filters that take several values in List Sessions (`status`, `workflow_id`, `country`, `region`, `document_type`, `document_name`, `session_type`, `warning`, `organization_name`) accept a comma-separated string or an array; the others take one value. An empty value is ignored. Filters apply only together with `delete_all`, and a deletion job applies the same filters. - - An unknown `filter_*` key, or a filter value that cannot be read, rejects the whole request with `400` before anything is deleted, so a mistyped filter never widens the deletion to every session. - - Entries in `session_numbers` that do not match a live KYC session in your application (unknown numbers, already-deleted sessions, or sessions owned by another application) are **silently skipped**: they do not appear in `results` and are not counted in a job's `total`. - - Validation failures (a non-numeric entry, an empty list, neither `session_numbers` nor `delete_all` provided, or a template retention the application cannot honour) reject the **whole request** with `400` and delete nothing. - - Sessions are deleted in groups. If a group cannot be deleted (for example because a storage service is unavailable), every session in that group is reported as `face_retention_outcome: failed_retryable` and stays in place; the other groups are unaffected. Repeat the request for those sessions. A job retries such a group by itself. - - There is no documented cap on the list length; the shared write rate limit (below) is the practical bound. +class AsyncSessions(AsyncAPIResource): + """The ``sessions`` resource of the Didit API. - **Face biometric data:** the optional `retain_face_embeddings`, `face_retention_days`, `face_retention_deadline`, `deletion_instruction`, and `instruction_id` fields have the same meaning as on `DELETE /v3/session/{sessionId}/delete/` and apply to every matched session. Each result reports its own `face_retention_outcome`. + Methods: ``add_images``, ``batch_delete``, ``bulk_update_aml_hit_status``, ``cancel_feature_override``, ``create``, ``create_kyb_party_draft``, ``delete``, ``delete_kyb_party_draft``, ``export_aml_screening_history``, ``export_files``, ``generate_pdf``, ``get_files_export``, ``import_shared``, ``list``, ``list_aml_screening_history``, ``list_events``, ``list_feature_overrides``, ``list_kyb_extracted_parties``, ``list_kyb_party_drafts``, ``list_networks``, ``preview_decision_email``, ``preview_resubmission``, ``regenerate_kyb_party``, ``retrieve_decision``, ``retrieve_deletion_job``, ``share``, ``simulate``, ``submit_kyb_parties``, ``update_aml_hit_status``, ``update_aml_status``, ``update_data``, ``update_document_ai_data``, ``update_feature_status``, ``update_kyb_company_data``, ``update_kyb_party``, ``update_kyb_party_draft``, ``update_poa_data``, ``update_status``, ``upload_kyb_documents``. - **Response:** `200 OK` with `results[]` for up to 20 matching sessions, or `202 Accepted` with a deletion job for more. Every result confirms deletion except `face_retention_outcome: failed_retryable`, which reports a session that was NOT deleted and should be retried. Earlier versions of this endpoint returned `204 No Content`; update clients that assert on `204`. + Nested resources: ``imports``, ``reviews``, ``signatures``, ``webhooks``. + """ - **Idempotency:** repeating the same request deletes nothing more: numbers that no longer match a session are skipped. + @cached_property + def imports(self) -> AsyncSessionsImports: + from didit.resources.sessions.imports import AsyncSessionsImports - **`delete_all: true` (destructive):** deletes **every** remaining KYC session in the application; `session_numbers` is ignored when set. There is no confirmation step and no undo. + return AsyncSessionsImports(self._client) - **Authentication:** API key in the `x-api-key` header. Missing or invalid credentials return `403` (`{"detail": "You do not have permission to perform this action."}`); this API never returns `401`. + @cached_property + def reviews(self) -> AsyncSessionsReviews: + from didit.resources.sessions.reviews import AsyncSessionsReviews - **Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`. + return AsyncSessionsReviews(self._client) - This endpoint accepts API keys only. Business Console user Bearer tokens are rejected with `403` (unlike the single-session delete, which accepts both). + @cached_property + def signatures(self) -> AsyncSessionsSignatures: + from didit.resources.sessions.signatures import AsyncSessionsSignatures - **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request. + return AsyncSessionsSignatures(self._client) - ``POST /v3/sessions/delete/`` + @cached_property + def webhooks(self) -> AsyncSessionsWebhooks: + from didit.resources.sessions.webhooks import AsyncSessionsWebhooks + + return AsyncSessionsWebhooks(self._client) + + @cached_property + def with_raw_response(self) -> AsyncSessionsWithRawResponse: + """Every method of this resource, returning the raw HTTP response.""" + return AsyncSessionsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSessionsWithStreamingResponse: + """Every method of this resource, returning the HTTP response before reading its body.""" + return AsyncSessionsWithStreamingResponse(self) + + async def create( + self, + *, + workflow_id: str, + vendor_data: str | NotGiven = NOT_GIVEN, + multi_account_segment: str | NotGiven = NOT_GIVEN, + callback: str | NotGiven = NOT_GIVEN, + callback_method: Literal["initiator", "completer", "both"] | str | NotGiven = NOT_GIVEN, + metadata: object | NotGiven = NOT_GIVEN, + tags: Sequence[str] | NotGiven = NOT_GIVEN, + language: Literal[ + "en", + "ar", + "bg", + "bn", + "bs", + "ca", + "cnr", + "cs", + "da", + "de", + "el", + "es", + "et", + "fa", + "fi", + "fr", + "he", + "hi", + "hr", + "hu", + "hy", + "id", + "it", + "ja", + "ka", + "kk", + "ko", + "ky", + "lt", + "lv", + "mk", + "mn", + "ms", + "nl", + "no", + "pl", + "pt-BR", + "pt", + "ro", + "ru", + "sk", + "sl", + "so", + "sq", + "sr", + "sv", + "th", + "tr", + "uk", + "uz", + "vi", + "zh-CN", + "zh-TW", + "zh", + ] + | str + | NotGiven = NOT_GIVEN, + contact_details: SessionsCreateParamsContactDetails | NotGiven = NOT_GIVEN, + expected_details: SessionsCreateParamsExpectedDetails | NotGiven = NOT_GIVEN, + portrait_image: str | NotGiven = NOT_GIVEN, + sandbox_scenario: str | NotGiven = NOT_GIVEN, + sign: SessionsCreateParamsSign | NotGiven = NOT_GIVEN, + user_state: str | NotGiven = NOT_GIVEN, + biometric_consent: SessionsCreateParamsBiometricConsent | 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, + ) -> SessionsCreateResponse: + """Create a verification session. + + Create a User Verification (KYC) or Business Verification (KYB) session and receive a hosted verification `url` plus a `session_token` to redirect or embed for your end user. The `workflow_id` selects which verification steps run and whether the session is KYC or KYB. + + Call this from your backend (never the browser - the API key is a secret) whenever a user or business needs to be verified: at signup, before a sensitive action, or when re-verification is required. Prerequisites: a published workflow (created in the Console [Workflows](https://docs.didit.me/console/workflows) page) and an application API key with available credits. Sandbox applications bypass the credit check. + + **Idempotency:** when `vendor_data` is provided and an unfinished session (`Not Started`, `In Progress`, `Resubmitted`, or `Awaiting User`) with the same `vendor_data` already exists on the workflow's **current latest published version** (and that session already has a hosted verification URL), the existing session is returned (still `201`) instead of creating a duplicate - with its `callback` and `metadata` updated to the newly provided values. An unfinished session created on an older version of the workflow (one that has since been republished) is **not** reused; a new session pinned to the latest published version is created instead. Sessions in `Approved`, `Declined`, `In Review`, `Expired`, `Abandoned`, or `Kyc Expired` are never reused. + + **Side effects:** the hosted verification URL is generated and stored; if `contact_details.send_notification_emails` is `true` and an email is provided, a verification invite email is sent. The session expires after the workflow's configured session expiration time. For KYB workflows, `contact_details.phone` and `expected_details` are ignored. + + ``POST /v3/session/`` Args: - session_numbers: Numeric `session_number` values of the KYC sessions to delete, as digit-only strings (JSON numbers are also accepted and coerced). Required unless `delete_all` is `true`; an empty list returns `400`. Any non-digit entry rejects the whole request with `400` (unless `delete_all` is `true`, in which case validation is skipped and the entries are ignored). Numbers that do not match a live session in your application are silently skipped. - delete_all: When `true`, every remaining KYC session in the calling application is deleted and `session_numbers` is ignored, unless you narrow the selection with `filter_*` keys. More than 20 matching sessions run as a deletion job (`202`) that covers only the sessions created before the request. Defaults to `false`. Irreversible; there is no confirmation step. - retain_face_embeddings: Override the application's `face_retention_policy` for this deletion. `true` keeps one image-free face biometric template anchored to the session's User after the session is deleted; `false` deletes the face embedding with the session; omit or `null` to follow the application policy. Ignored for KYB sessions and for sessions without a face embedding. - face_retention_days: Finite retention duration, in days, for a retained template. Required when a template is retained unless the application already sets `face_retention_days`. The template's `expires_at` is the earliest of this duration, the application's general data-retention window, and `face_retention_deadline`. - face_retention_deadline: Optional hard expiry for a retained template. Must be in the future. - deletion_instruction: The class of instruction you are giving. `operational_session_delete` deletes the session and retains a template only when the policy or `retain_face_embeddings` says so. `privacy_erasure` purges every retained biometric template anchored to the session's User before deleting the session, cannot be overridden by the application policy, and cannot be combined with `retain_face_embeddings: true` (`400`). - instruction_id: Your durable reference for this deletion instruction (for example an erasure-ticket id). Recorded on the audit trail and on any retained template. Generated by Didit when omitted. - filter_status: Narrows a `delete_all` to the sessions that match the `status` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_vendor_data: Narrows a `delete_all` to the sessions that match the `vendor_data` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_search: Narrows a `delete_all` to the sessions that match the `search` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_workflow_id: Narrows a `delete_all` to the sessions that match the `workflow_id` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_date_from: Narrows a `delete_all` to the sessions that match the `date_from` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_date_to: Narrows a `delete_all` to the sessions that match the `date_to` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_country: Narrows a `delete_all` to the sessions that match the `country` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_document_type: Narrows a `delete_all` to the sessions that match the `document_type` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_document_name: Narrows a `delete_all` to the sessions that match the `document_name` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_region: Narrows a `delete_all` to the sessions that match the `region` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_didit_internal_id: Narrows a `delete_all` to the sessions that match the `didit_internal_id` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_session_type: Narrows a `delete_all` to the sessions that match the `session_type` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_api_service: Narrows a `delete_all` to the sessions that match the `api_service` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_screened_full_name: Narrows a `delete_all` to the sessions that match the `screened_full_name` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_warning: Narrows a `delete_all` to the sessions that match the `warning` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_status_initialized_as_in_review: Narrows a `delete_all` to the sessions that match the `status_initialized_as_in_review` filter of [List Sessions](/sessions-api/list-sessions), with the same values. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_is_kyc_to_be_reviewed: Narrows a `delete_all` to the sessions that match the `is_kyc_to_be_reviewed` filter of [List Sessions](/sessions-api/list-sessions), with the same values. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_euuid: Narrows a `delete_all` to the sessions that match the `euuid` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. - filter_organization_name: Narrows a `delete_all` to the sessions that match the `organization_name` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. With an API key it can only match your own organization's name, so it selects all of your sessions or none. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + workflow_id: Stable identifier of the workflow that defines which verification steps the session will run. Workflows are created and managed in the [Workflows](/console/workflows) page of the Console. The `workflow_id` also implicitly selects whether the session is KYC or KYB. + vendor_data: A unique identifier for the user being verified, such as a UUID, email, or internal user ID. This field is used for: (1) **User grouping** - sessions with the same vendor_data are linked to the same user profile in the Users tab. (2) **Cross-session duplicate detection** - when checking for duplicated faces, documents, phone numbers, emails, IP addresses, or device fingerprints, sessions with the same vendor_data are treated as the same user and excluded from matches. Without vendor_data, every session is treated as a unique user and all potential duplicates are surfaced. We strongly recommend always providing a vendor_data to reduce noise in duplicate detection. + multi_account_segment: Optional duplicate-detection realm inside your organization. Duplicate face checks compare this session only with other sessions that carry the same segment, so separate account bases (personal and business accounts, or one per B2B sub-client) do not flag a person who legitimately holds one account in each. Omit it to use the single default realm, which is what every session uses today. Blocklist and allowlist matching ignore this field. + callback: URL to redirect the user to after verification completes. Didit automatically appends `verificationSessionId` and `status` (Approved, Declined, In Review) as query parameters. Custom URL schemes (e.g. `myapp://`) are supported for mobile callbacks. If omitted, the workflow's default `callback_url` is used. When the application has allowed domains (`allowed_domains` on `PATCH /v3/webhook/`), an `http` or `https` callback must be on one of those origins (same scheme, host and port), otherwise the request fails with 400 on `callback`: `callback must be on one of the application's allowed domains: https://app.example.com`. Custom URL schemes are always accepted. + callback_method: Determines which device should handle the redirect to the provided callback URL. Use `initiator` to redirect only the device that started the flow, `completer` for the device that finishes it, or `both` to allow either device to trigger the callback. If you ever notice the callback not triggering reliably, we recommend setting this value to `both`. + metadata: Arbitrary JSON stored with the session and echoed back in the response and webhooks. Any JSON value is accepted (object, string, number, array), but a JSON object of key/value pairs is recommended. Not shown to the end user. Use it to pass your own correlation ids, A/B variants, or business context. + tags: Tags added to the session when it is created, by name. Up to 10, each up to 50 characters. Names are case-insensitive and stored in upper case. A name that does not exist yet in the application is created as a new tag. The tags show on the session in the console, where you can filter by them. + language: Language code (ISO 639-1) for the verification process interface. Controls the language displayed to the end user during verification. If not provided, the browser's language will be automatically detected and used. Check all the supported languages [here](/integration/supported-languages). + contact_details: User contact information that can be used for notifications, prefilling verification forms, and phone verification. This includes email address, preferred language for communications, and phone number. + expected_details: Expected user details used to cross-validate against the data extracted from the user's ID document, Proof of Address, and other verification steps. Mismatches are surfaced as warnings on the decision; some fields (e.g. `id_country`, `expected_document_types`) also alter the user-facing flow. For Business Verification (KYB) workflows only the business fields (`company_name`, `registry_country`, `registration_number`) are used - they pre-fill the company registry search for the user - and all person-level fields are ignored. + portrait_image: Base64-encoded portrait image of the end user's face (max 2MB; JPEG, PNG, WebP, or TIFF). Used as the reference image to match against the liveness capture when the workflow is a `Biometric Authentication` workflow with Face Match enabled, or any graph workflow where Face Match runs before ID Verification (OCR). Optional when the `vendor_data` user already has a stored face image: Didit reuses it automatically, resolved in priority order: approved liveness face, ePassport chip photo, ID document portrait, manually enrolled profile face (only faces from approved sessions or faces you enrolled yourself are reused). When provided, `portrait_image` always takes precedence over the stored face. If omitted and no stored face exists (or `vendor_data` is not sent), session creation fails with `400`. Ignored for other workflow types. + sandbox_scenario: Sandbox-only scenario slug. Only accepted when the API key belongs to a sandbox-mode application; rejected on live applications. When set, the create flow expands the scenario's bundled magic values onto the session's input fields (contact_details, expected_details) so the mocked providers reproduce the scenario's outcome through the real workflow pipeline. See the scenario catalog at GET /v1/sandbox/scenarios/ or [Sandbox & Test Data](/integration/sandbox-testing). You can also arm (or re-arm) a scenario after create via POST /v3/session/{sessionId}/sandbox/arm/, as long as the session is still `Not Started`. For non-doc lookup, use `lookup_partial_match`, `lookup_no_match`, or `lookup_provider_error` to test the configured attempt budget and fallback. For identity wallets, use `wallet_cancelled`, `wallet_timeout`, or `wallet_provider_error`; `approve` simulates a verified wallet. All catalog wallets can be tested in sandbox, including schemes unavailable on live applications. Simulated attempts are not charged. + sign: E-signature input for this session. `documents` are the documents to sign, for a workflow whose E-signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [E-signature documents](/sessions-api/create-session#e-signature-documents). + user_state: Where the person lives, when you know it: an ISO 3166-2 subdivision code (`US-IL`, `ES-M`) or a US state code or name (`IL`, `Illinois`). A state whose law requires explicit biometric consent (Illinois, Texas, Colorado) makes the verification flow ask for it before capturing a face, with trigger `declared_state`. An unrecognized value returns `400`. See [Biometric consent](/getting-started/biometric-consent). + biometric_consent: Explicit biometric consent you already collected from the person. It satisfies the requirement, so the verification flow does not ask again, and the decision records it as `status: "given"` with trigger `customer_collected`. An answer the person already gave in the flow is never replaced. See [Biometric consent](/getting-started/biometric-consent). + 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( + "SessionsCreateResponse", + await self._client.request( + "post", + "/v3/session/", + cast_to=SessionsCreateResponse, + auth="api_key", + body={ + "workflow_id": workflow_id, + "vendor_data": vendor_data, + "multi_account_segment": multi_account_segment, + "callback": callback, + "callback_method": callback_method, + "metadata": metadata, + "tags": tags, + "language": language, + "contact_details": contact_details, + "expected_details": expected_details, + "portrait_image": portrait_image, + "sandbox_scenario": sandbox_scenario, + "sign": sign, + "user_state": user_state, + "biometric_consent": biometric_consent, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def retrieve_decision( + self, + session_id: str, + *, + include: Literal["events", "resubmissions", "events,resubmissions"] + | 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, + ) -> SessionDecision: + """Retrieve the full decision for a verification session. + + Retrieve the complete decision report for a verification session - the rolled-up session `status` plus one report per verification feature the workflow executed. This is the canonical read endpoint for both User Verification (KYC) and Business Verification (KYB) sessions: the same path serves both, and the top-level `session_kind` discriminator tells you which shape you received (`"user"` or `"business"`). + + **Every feature report is a plural array.** V3 workflows are graphs that can run the same feature more than once, so each block (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) is a JSON array whose items each carry a `node_id` identifying the workflow graph node that produced them. Read NFC as `response.nfc_verifications[0]` - never as a singular `nfc` field. A block is `null` until the workflow has run that feature at least once; features the workflow does not include never appear with data. E-signature results are in `signatures`, which is present only when the workflow has an E-signature step. + + **When to call.** The recommended pattern is event-driven: wait for the `status.updated` webhook that fires when the session reaches a decision (`Approved`, `Declined`, `In Review`), then call this endpoint once to fetch the full report. Polling also works - the endpoint can be called at any point in the session lifecycle and returns the data produced so far - but webhook-then-fetch is cheaper and faster. Media URLs in the response (document images, videos, PDFs) are short-lived presigned links: fetch them promptly or re-request the decision to get fresh ones, and do not persist them as long-term references. + + **Statuses.** The top-level `status` is the session lifecycle status (`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Each feature item additionally carries its own feature-level `status` (`Not Finished`, `Approved`, `Declined`, `In Review`, ...). A session can be `Approved` overall while an individual feature is `In Review`, depending on the workflow's decision rules. + + **Authentication and visibility.** Authenticate with the application API key in the `x-api-key` header (a console user Bearer token with the `read:sessions` permission also works). Only sessions owned by the authenticated application are visible. If your workflow restricts response attributes, non-allowed fields inside feature items are returned as `null` while `status`, `warnings`, and `node_id` are always preserved. + + **Rate limits.** GET requests are limited to 600 per minute per API key. Exceeding the limit returns `429` with `Retry-After` and `X-RateLimit-*` headers. + + ``GET /v3/session/{sessionId}/decision/`` + + Args: + session_id: UUID of the verification session whose decision you want to retrieve. This is the `session_id` returned by `POST /v3/session/`. The same path works for both User Verification (KYC) and Business Verification (KYB) sessions - the server resolves the id against both session types. **Must be a valid UUID.** The route only matches well-formed UUIDs, so a malformed value is rejected by the URL router before any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}` envelope shown below. Validate the UUID format client-side so you can distinguish an input error from a genuine missing-session `404`. + include: Comma-separated list of extra payload sections. Supported values: `events` and `resubmissions`, alone or together (`events,resubmissions`). When `include=events` is passed, the response additionally contains the session event timeline (`events`, including the `WORKFLOW_BRANCH_EVALUATED` / `WORKFLOW_STATUS_NODE_REACHED` routing events described on the Retrieve Session page), the full activity log (`activity_reviews`), blocklist flags (`blocklisted`), a per-session `cost_breakdown`, workflow metadata (`workflow_type`, `workflow_version`, `workflow_version_id`, and `workflow_terminal_node_id` - the last recorded workflow status node that set a session status, or `null` if none has been recorded; historical provenance that is not cleared by manual approvals, declines or resubmissions, and is replaced by a later workflow status node), and session metadata (`api_service` - string or `null`, set only for standalone-API sessions; `session_type` - `API`, `HOSTED`, or `MIGRATED`; `has_device_nfc_support` - boolean). Two fields change relative to the plain shape: the top-level `session_kind` discriminator is **omitted** (the events shape only exists for user sessions), and the `features` array switches from plain strings to `{feature, node_id}` objects - where the email feature is reported as `EMAIL` instead of `EMAIL_VERIFICATION`. This expanded shape is primarily used by the Didit Console; most API integrations should omit the parameter. **KYB limitation:** `include=events` only applies to user (KYC) sessions. Business sessions (`session_kind = "business"`) always return the standard business decision shape - `events`, `activity_reviews`, `blocklisted`, `cost_breakdown` and the extra `workflow_*`/session metadata are never returned for business sessions, and their `features` array stays a plain string array. With `include=resubmissions` (user and business sessions alike) the response also contains `resubmissions`: one entry per resubmission request, oldest first, each with `number`, `created_at`, `previous_status`, `nodes`, `reasons`, `requested_by` and `results` (what the resubmitted steps returned before the request, under the same keys and in the same shape as the current results). Each `cost_breakdown` item carries `usage_type`, `price`, `details` and `created_at`: a resubmitted step that runs again is billed as a new item. + 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( + "SessionDecision", + await self._client.request( + "get", + "/v3/session/{sessionId}/decision/", + cast_to=SessionDecision, + path_params={"sessionId": session_id}, + auth="api_key", + query={"include": include}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def delete( + self, + session_id: str, + *, + retain_face_embeddings: bool | None | NotGiven = NOT_GIVEN, + face_retention_days: int | NotGiven = NOT_GIVEN, + face_retention_deadline: str | _dt.datetime | NotGiven = NOT_GIVEN, + deletion_instruction: Literal["operational_session_delete", "privacy_erasure"] + | str + | NotGiven = NOT_GIVEN, + instruction_id: 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, + ) -> SessionsDeleteResponse: + """Delete a verification session (KYC or KYB). + + Delete a single verification session, User Verification (KYC) or Business Verification (KYB), by its `session_id`. The id is resolved against KYC sessions first, then KYB sessions, so both kinds are deleted through this one URL. + + **What is deleted:** + - The session and every verification attempt it holds, including results that a resubmission replaced: the decision, extracted data, all related feature records (ID verification, face, liveness, face match, AML, registry checks, IP analysis, and so on), its reviews and its activity log. + - All stored files owned by the session: document front/back photos (full, cropped, and privacy-blurred variants), document-capture videos, portrait crops, NFC chip portrait and signature images, face reference images, liveness videos, face-match source/target images, Proof of Address documents, and any extra uploaded files (KYC); uploaded company documents and extra files (KYB). E-signature documents, signed PDFs, evidence PDFs and signature images (KYC and KYB): their download paths stop working. Previously issued media URLs (`https:///...`) stop resolving. + - The session's face data. Its face embedding is deleted too, unless you choose to keep an image-free template (see **Face biometric data**). + - Webhook deliveries still queued for the session, and their retries. Webhooks already delivered are not affected. + - For a Business Verification (KYB) session: the verifications it created for its key people (KYC) and its corporate owners (KYB), recursively, reported as `deleted_child_verifications`. A verification it only links to, such as an existing approved KYC it reused, is not deleted. + + The session disappears from every read endpoint immediately: `GET /v3/session/{sessionId}/decision/` returns `404` and `GET /v3/sessions/` stops listing it. Ongoing AML monitoring and KYB registry monitoring started by the deleted verifications stop. + + **What is not affected:** blocklist entries created from this session (face or document) are **not** removed; manage those with the blocklist endpoints. Share tokens issued for the session are not revoked, but there is nothing left for them to import: an import with one returns `400` with `{"share_token": ["Original session does not exist."]}`. Credits already consumed are **not** refunded. The parent User or Business entity is **not** deleted; use `POST /v3/users/delete/` or `POST /v3/businesses/delete/` for those. If the User's profile portrait came from this session, the portrait is removed with it. + + **Face biometric data:** by default the session's face embedding is deleted with the session (`face_retention_outcome: deleted`). An application that opted in to biometric-template retention (`face_retention_policy: retain_until_user_deleted` on `PATCH /v3/webhook/`), or a request with `retain_face_embeddings: true`, keeps one separately managed, image-free face biometric template anchored to the session's User (`retained_with_user`) so that duplicate detection, Face Search, and biometric authentication keep working. The template never contains the face image, media, identity fields, the decision, or the deleted session's id; it is biometric data deleted at `biometric_template_expires_at`, or earlier on User deletion, privacy erasure, or an explicit purge through `/v3/biometric-templates/`. A session without a linked User cannot retain a template (`ineligible_no_vendor_user`). Send `deletion_instruction: privacy_erasure` for data-subject requests: it purges every retained template for that User and never retains a new one. + + **Irreversible:** deletion is permanent and there is no restore endpoint. Export anything you need (for example a decision PDF) before you call it. + + **Side effects:** no webhook is emitted for deletions. + + **Response:** `200 OK` once the deletion has completed, with a JSON body reporting the `face_retention_outcome`, the retained template's expiry and, for a KYB session, `deleted_child_verifications`. Earlier versions of this endpoint returned `204 No Content`; update clients that assert on `204`. Keep your `instruction_id` in your own erasure log. + + **Idempotency:** not idempotent at the HTTP level: the first call returns `200`; repeating it returns `404` because the session no longer resolves. After a `503` the session is still in place; repeat the same request to finish deleting it. + + **Authentication:** send your application's API key in the `x-api-key` header; the session must belong to that application. Console user access tokens (`Authorization: Bearer ...`) may also call this endpoint when they carry the `delete:sessions` permission. Authentication and permission failures both return `403`; this API never returns `401`. + + **Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`. + + To bulk-delete KYC sessions by their numeric `session_number`, use `POST /v3/sessions/delete/` instead. + + **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request. + + ``DELETE /v3/session/{sessionId}/delete/`` + + Args: + session_id: UUID (`session_id`) of the User Verification (KYC) or Business Verification (KYB) session to delete, as returned when the session was created. Must be a canonical hyphenated UUID - a non-UUID value does not match the route and returns `404`. + retain_face_embeddings: Override the application's `face_retention_policy` for this deletion. `true` keeps one image-free face biometric template anchored to the session's User after the session is deleted; `false` deletes the face embedding with the session; omit or `null` to follow the application policy. Ignored for KYB sessions and for sessions without a face embedding. + face_retention_days: Finite retention duration, in days, for a retained template. Required when a template is retained unless the application already sets `face_retention_days`. The template's `expires_at` is the earliest of this duration, the application's general data-retention window, and `face_retention_deadline`. + face_retention_deadline: Optional hard expiry for a retained template. Must be in the future. + deletion_instruction: The class of instruction you are giving. `operational_session_delete` deletes the session and retains a template only when the policy or `retain_face_embeddings` says so. `privacy_erasure` purges every retained biometric template anchored to the session's User before deleting the session, cannot be overridden by the application policy, and cannot be combined with `retain_face_embeddings: true` (`400`). + instruction_id: Your durable reference for this deletion instruction (for example an erasure-ticket id). Recorded on the audit trail and on any retained template. Generated by Didit when omitted. + 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( + "SessionsDeleteResponse", + await self._client.request( + "delete", + "/v3/session/{sessionId}/delete/", + cast_to=SessionsDeleteResponse, + path_params={"sessionId": session_id}, + auth="api_key", + body={ + "retain_face_embeddings": retain_face_embeddings, + "face_retention_days": face_retention_days, + "face_retention_deadline": face_retention_deadline, + "deletion_instruction": deletion_instruction, + "instruction_id": instruction_id, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def generate_pdf( + self, + session_id: str, + *, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> bytes: + """Download a PDF report for a verification session. + + Render and download a compliance-ready PDF report for a finished verification session. The same path serves both User Verification (KYC) and Business Verification (KYB) sessions - the server resolves the `sessionId` against both session types and picks the matching report template. + + **Eligible statuses.** The session must already carry a final or reviewable status: + + - KYC sessions: `Approved`, `Declined`, `In Review`, or `Kyc Expired`. + - KYB sessions: `Approved`, `Declined`, or `In Review`. + + Any other status (`Not Started`, `In Progress`, `Expired`, `Abandoned`, …) returns `403` with an explanatory `detail` string - see the `403` response below. + + **What the report contains.** The PDF mirrors the console session view at the moment of the request: + + - **KYC** - rolled-up session status, the warnings list, and one section per executed feature: ID Verification (document images plus extracted fields), NFC, Liveness, Face Match, Email Verification, Phone Verification, Proof of Address, Questionnaire answers, Database Validation, AML Screening, and IP Analysis - followed by session tags, console review activity (comments and status changes), and the session event timeline. + - **KYB** - registry checks (company data), AML screenings, business document verifications, key-people checks, questionnaire responses, phone/email verifications, IP analyses, and the session event timeline, followed by tags and review activity. + + **Branding.** If your application has white-label customization, the report is rendered with your logo and links to your privacy-policy URL; otherwise it carries Didit branding. Reports are rendered in English - there is no language parameter. + + **No caching.** Every call re-renders the PDF from the current session data, so a report generated after a manual review reflects the reviewer’s decision. Two calls for the same session can produce byte-different files - archive the downloaded file if you need an immutable copy. + + **Latency.** Rendering downloads every stored image (document sides, selfies, extra files) before composing the PDF, so media-heavy sessions can take several seconds. Use a generous client read timeout (60 s recommended) and stream the body to disk. + + **Trailing slash.** The canonical route ends with a trailing slash (`…/generate-pdf/`). A request without it is served directly with the same response - there is no `301` redirect, so no client has to follow redirects and `curl` does not need `-L`. Use the slashed URL as in the samples. + + If you need the underlying data as JSON instead of a rendered report, use `GET /v3/session/{sessionId}/decision/`. For every reportable session of one user in a single document, use `GET /v3/users/{vendor_data}/generate-pdf/`. + + ``GET /v3/session/{sessionId}/generate-pdf/`` + + Args: + session_id: UUID of the User Verification (KYC) or Business Verification (KYB) session to render - the `session_id` returned by `POST /v3/session/`. The same path works for both session kinds; use the `Content-Disposition` filename on the response to tell which report type you received. **Must be a well-formed, lowercase UUID.** The route only matches valid UUIDs, so a malformed value is rejected by the URL router before any application code runs and the response is a `404` **HTML** page rather than the JSON `{"detail": ...}` envelope shown below. The route's UUID converter only matches the canonical lowercase form - uppercase-hex UUIDs are rejected with the HTML 404. + 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( + "bytes", + await self._client.request( + "get", + "/v3/session/{sessionId}/generate-pdf/", + cast_to=bytes, + path_params={"sessionId": session_id}, + auth="api_key", + accept="application/pdf, application/json", + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_status( + self, + session_id: str, + *, + new_status: Literal["Approved", "Declined", "Resubmitted"] | str, + comment: str | NotGiven = NOT_GIVEN, + nodes_to_resubmit: Sequence[SessionsUpdateStatusParamsNodesToResubmit] + | NotGiven = NOT_GIVEN, + send_email: bool | NotGiven = NOT_GIVEN, + email_address: str | NotGiven = NOT_GIVEN, + email_language: str | NotGiven = NOT_GIVEN, + email_preview_token: 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, + ) -> SessionsUpdateStatusResponse: + """Approve, decline, or request resubmission for a verification session. + + Manually override the final decision of a KYC or KYB verification session. Set `new_status` to `Approved` or `Declined` to record a manual decision, or to `Resubmitted` to clear specific verification steps and let the user redo them through the same verification URL. The endpoint accepts both user (KYC) and business (KYB) session IDs. + + Call it once a session has reached a reviewable state: the current status must be `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned`, or `Resubmitted`. Sessions that are still `Not Started`, `In Progress`, or `Awaiting User`, or that ended as `Expired`, return `400`. Your API key needs the `write:sessions` permission (a scoped API key needs write access to decisions). The eligible-state check runs before body validation, so an ineligible session returns the `Wrong Current Status` error even when the payload is also invalid. + + For `Resubmitted`, pass `nodes_to_resubmit` to choose which workflow steps the user must redo, or omit it to auto-select existing feature attempts in a resubmittable state (`Declined`, `In Review`, `Not Finished`, `Expired`). Never-attempted features are not auto-selected: list them explicitly in `nodes_to_resubmit`, or the request returns `400` when no recorded attempt needs resubmission. The selected steps' previous results move to the resubmission's history (returned by Get Decision with `include=resubmissions`), the steps are reordered to match the workflow graph, the session's expiration window restarts, and the original verification URL becomes usable again. Backend-only steps (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) at the head of the list run immediately without user interaction; if every resubmitted step is backend-only, the session re-finalizes within the same request. `KYB_REGISTRY` and `KYB_KEY_PEOPLE` cannot be resubmitted directly: resubmit the relevant child KYC sessions instead and the parent business session recomputes automatically. + + Every call that changes the status fires the `status.updated` [webhook](/integration/webhooks) once the change commits and appends an activity entry (with actor attribution and your `comment`) to the session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and in the console activity timeline. The user-profile aggregates linked to the session's `vendor_data` update as well. Declining disables ongoing AML monitoring for the session; re-approving re-enables it (from `Resubmitted`, `Declined`, or `Kyc Expired`) when the workflow has monitoring turned on. Approving or declining a child KYC that belongs to a KYB key-people check recomputes the parent business session's status. Set `send_email: true` (with `email_address`) to notify the user: a status notice for `Approved`/`Declined`, or a resubmission email containing the verification link and per-step reasons for `Resubmitted`. To check the email first, preview it with [Preview Decision Email](/sessions-api/preview-decision-email) (`Approved`, `Declined`) or [Preview Resubmission Email](/sessions-api/preview-resubmission) (`Resubmitted`) and pass its `preview_token` as `email_preview_token`: the update then sends exactly the previewed email, or returns `409` before changing anything when the email or the session changed since the preview or the receipt is older than 15 minutes. + + Repeating `Approved` or `Declined` on a session that already has that status changes nothing and returns `200`: no webhook, no activity entry and no email. Repeating `Resubmitted` returns `400` (`The new status is the same as the current status.`). Missing or invalid credentials and missing permissions return `403`; an expired scoped API key returns `401`. + + ``PATCH /v3/session/{sessionId}/update-status/`` + + Args: + session_id: UUID of the verification session to update. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. + new_status: Target status. `Approved` and `Declined` record a final manual decision (each can also overturn the other). `Resubmitted` clears the selected steps and sends the session back to the user. Any other value returns `400`. + comment: Free-text reason for the change, stored on the session's review trail and returned in the `reviews` array of [Get Decision](#get-/v3/session/-sessionId-/decision/). For example `Duplicated user`. + nodes_to_resubmit: Workflow steps the user must redo. Only acted on when `new_status` is `Resubmitted`. For `Approved`/`Declined` the entries are still schema-validated (an invalid `feature` value returns `400`) but schema-valid entries are semantically ignored. If omitted, the server auto-selects existing OCR, Liveness, Face Match, POA, Phone, Email, AML, Database Validation, and Questionnaire attempts whose status is `Declined`, `In Review`, `Not Finished`, or `Expired` (NFC, IP analysis, age estimation, face search, and KYB document attempts are never auto-selected; non-face-match face attempts are selected as `LIVENESS`) - features the user never attempted (no recorded attempt) are NOT selected, so a session with zero attempts returns `400` ("No features found that need resubmission") even though nothing was approved; pass `nodes_to_resubmit` explicitly in that case. Steps are executed in workflow-graph order regardless of the order you send them. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, and the `KYB` alias are rejected with `400` - those parent checks recompute from their child KYC sessions. + send_email: Whether to email the user about the change. Requires `email_address`. For `Approved`/`Declined` the user receives a status notice; for `Resubmitted` the email includes the verification link and the per-step resubmission reasons. + email_address: Recipient for the notification email. **Required when `send_email` is `true`** - omitting it returns `400`. + email_language: Language for the notification email. Accepts any string at schema level; unsupported codes silently fall back to English (`en`). + email_preview_token: Optional receipt from [Preview Decision Email](/sessions-api/preview-decision-email) (for `Approved` and `Declined`) or [Preview Resubmission Email](/sessions-api/preview-resubmission) (for `Resubmitted`): its `preview_token`. Valid only with `send_email: true`; without it the request returns `400`. The recipient, language, session status, sender and email (and, for a resubmission, the selected steps) must still match the preview, and the receipt expires after 15 minutes. Otherwise the request returns `409` before the session changes or an email is sent. Existing integrations may omit this field. + 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( + "SessionsUpdateStatusResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/update-status/", + cast_to=SessionsUpdateStatusResponse, + path_params={"sessionId": session_id}, + auth="api_key", + body={ + "new_status": new_status, + "comment": comment, + "nodes_to_resubmit": nodes_to_resubmit, + "send_email": send_email, + "email_address": email_address, + "email_language": email_language, + "email_preview_token": email_preview_token, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + def list( + self, + *, + session_kind: Literal["user", "business", "all"] | str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | NotGiven = NOT_GIVEN, + status: str | NotGiven = NOT_GIVEN, + vendor_data: str | NotGiven = NOT_GIVEN, + search: str | NotGiven = NOT_GIVEN, + workflow_id: str | NotGiven = NOT_GIVEN, + date_from: str | _dt.date | NotGiven = NOT_GIVEN, + date_to: str | _dt.date | NotGiven = NOT_GIVEN, + tags: str | NotGiven = NOT_GIVEN, + decided_from: str | _dt.datetime | NotGiven = NOT_GIVEN, + decided_to: str | _dt.datetime | NotGiven = NOT_GIVEN, + country: str | NotGiven = NOT_GIVEN, + document_type: str | NotGiven = NOT_GIVEN, + document_name: str | NotGiven = NOT_GIVEN, + region: str | NotGiven = NOT_GIVEN, + didit_internal_id: str | NotGiven = NOT_GIVEN, + session_type: str | NotGiven = NOT_GIVEN, + api_service: Literal[ + "ID_VERIFICATION", + "FACE_MATCH", + "AGE_ESTIMATION", + "FACE_SEARCH", + "POA", + "AML", + "KYB_REGISTRY", + "PASSIVE_LIVENESS", + "DATABASE_VALIDATION", + "PHONE_VERIFICATION", + "EMAIL_VERIFICATION", + ] + | str + | NotGiven = NOT_GIVEN, + screened_full_name: str | NotGiven = NOT_GIVEN, + warning: str | NotGiven = NOT_GIVEN, + status_initialized_as_in_review: bool | NotGiven = NOT_GIVEN, + is_kyc_to_be_reviewed: bool | NotGiven = NOT_GIVEN, + euuid: str | NotGiven = NOT_GIVEN, + organization_name: 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, + ) -> AsyncPaginator[UserSessionListItem | BusinessSessionListItem]: + """List verification sessions (KYC and/or KYB) with filters and pagination. + + Returns a paginated list of verification sessions for the application identified by your API key, newest first (descending `session_number`). + + **Canonical URL:** the route is `/v3/sessions/` (trailing slash). Requests to `/v3/sessions` without the slash receive a `301` redirect to the slashed URL with the query string preserved; most HTTP clients follow it transparently on GET. + + **When to use this endpoint vs webhooks.** Use this endpoint for dashboards, back-office search, reconciliation, and batch exports. Do not poll it to track the progress of individual verifications - configure [webhooks](/integration/webhooks) instead, which push `status.updated` events the moment a session changes. For one session's full result, call `GET /v3/session/{sessionId}/decision/`. + + **KYC and KYB sessions.** `session_kind` selects which kinds are listed: + - `user` (default) - User Verification (KYC) sessions only. Backward-compatible behavior. + - `business` - Business Verification (KYB) sessions only. Rows have a different, smaller shape (see the response schema). + - `all` - both kinds in one response: the KYC page and the KYB page for the same `limit`/`offset` are concatenated in `results` (KYC rows first), so a page can contain up to `2 x limit` rows. `count` is the sum of both kinds and `next`/`previous` reflect the KYC-side pagination. For strict pagination of mixed data, call `user` and `business` separately. + + Every row carries a `session_kind` discriminator (`"user"` or `"business"`). + + **Pagination.** Standard limit/offset: `limit` (default 50) and `offset` (default 0), with `next`/`previous` ready-made page URLs. For KYC rows `count` is exact. For KYB rows `count` is computed with a bounded scan and is capped at 100 - when there are more than 100 matches it stays at 100, so iterate using `next` (or by checking whether a full page came back) rather than computing total pages from `count`. + + **Filter semantics.** All filters combine with AND and apply to KYC rows. When `session_kind` is `business` or `all`, the KYB side honors the shared parameters `vendor_data`, `status`, `workflow_id`, `country` (registry-company country code), `date_from`, `date_to`, `search` (company name, registration number - type registration numbers without separators, e.g. `DPC001` not `DPC-001` - vendor_data, session number, or session UUID), `warning`, and `organization_name`; the remaining KYC-only filters are ignored for KYB rows. Comma-separated parameters (`status`, `country`, `document_type`, `region`, `workflow_id`, `document_name`, `warning`, `organization_name`, `session_type`) match any of the listed values (OR within the parameter). `vendor_data` is an exact match - use `search` for partial matching. Unknown values in list filters simply return no rows (no error); malformed typed values (`date_from`, `date_to`, `didit_internal_id`, `api_service`, `session_kind`) return `400` with a per-field error object. + + **Search.** `search` adapts to the input: a full UUID looks up `session_id`; digits (with optional `+ - . space`) match session-number prefix, document/personal numbers, phone-number prefix, or `vendor_data`; values containing `@` match email prefixes; any other text matches names (accent-insensitive) and `vendor_data`. + + No fixed per-endpoint rate limit is enforced, but keep list polling infrequent and rely on webhooks for real-time updates. + + ``GET /v3/sessions/`` + + Args: + session_kind: Which kind of sessions to list: `user` (KYC only, default), `business` (KYB only), or `all` (both, concatenated - see the description for merged-pagination semantics). Matching is case-insensitive (`BUSINESS` works); any value other than a case variant of `user`/`business`/`all` returns `400`. + limit: Maximum number of rows per page (per kind when `session_kind=all`). Defaults to 50. + offset: Number of rows to skip before the first returned row. Defaults to 0. Prefer following the `next`/`previous` URLs from the response. + status: Comma-separated list of session statuses to include, e.g. `Approved,In Review`. Values are case-sensitive; see [Verification Statuses](/integration/verification-statuses). Unknown values match nothing. + vendor_data: Exact-match filter on the `vendor_data` you sent at session creation (your own user/business identifier). For partial matches use `search` instead. + search: A complete displayed reference such as `S-0001` (user) or `B-0001` (business) matches only that session number and kind; leading zeros and letter case do not affect matching. Smart free-text search. A full UUID matches `session_id`; numeric input matches session-number prefix, document/personal numbers, phone prefix, or `vendor_data`; input containing `@` matches email prefixes; other text matches names (accent-insensitive) and `vendor_data`. Free text containing digits additionally matches document/personal-number search fields and session-number prefixes. + workflow_id: Comma-separated workflow UUIDs (find them on the Workflows page in the Console). Malformed UUIDs in the list are ignored; if none are valid the result is empty. + date_from: Only sessions created on or after this date (UTC), format `YYYY-MM-DD`. Malformed dates return `400`. + date_to: Only sessions created up to this date (UTC), format `YYYY-MM-DD`. For KYC rows the entire day is included; for KYB rows the comparison is `created_at <= date_to` (midnight), so use the next day's date to include a full day of KYB sessions. + tags: Comma-separated tag ids (`tags` of your application). Returns the sessions that carry any of them. Ids that are not valid UUIDs are ignored, and when none is valid the list is empty. + decided_from: ISO 8601 datetime. Returns the sessions whose status last changed at or after it. It filters on the time of the last status change, not on creation time. + decided_to: ISO 8601 datetime. Returns the sessions whose status last changed before it. Combine with `decided_from` for a half-open window. + country: Comma-separated country filter. For KYC rows: ISO 3166-1 alpha-3 codes of the ID document's issuing state (e.g. `ESP,USA`), which may differ from nationality. For KYB rows: the registry company's country code. + document_type: Comma-separated ID-document type codes verified in the session (KYC rows only): `P` (Passport), `ID` (Identity Card), `DL` (Driver's License), `RP` (Residence Permit), `SSC` (Social Security Card), `HIC` (Health Insurance Card), `WP` (Work Permit), `TC` (Tax Card), `VISA`, `PSC` (Public Service Card), `BC` (Birth Certificate), `OTHER`. Note the response field `document_type` contains the display name, not the code. + document_name: Exact document names; multiple names can be passed comma-separated, but the value is only split on commas when it contains more than one ` - ` separator (a lone name with an embedded comma is matched whole). Names are as recognized by document verification (front or back side), e.g. `Spain - Id Card (2021)`. KYC rows only. + region: Comma-separated document region/state values (for documents issued per region, such as US driver's licenses). KYC rows only. + didit_internal_id: Filter by Didit's internal user identifier (the `didit_internal_id` response field) to list all sessions of one verified user. Must be a valid UUID; malformed values return `400`. KYC rows only. + session_type: Comma-separated session creation channels: `API`, `HOSTED`, `MIGRATED`. The special value `ALL` (or omitting the parameter) disables the filter. KYC rows only. + api_service: Filter standalone API sessions by service. Invalid values return `400`. KYC rows only. + screened_full_name: Accent-insensitive name search inside AML and database-validation screened data. When combined with `api_service=AML` or `api_service=DATABASE_VALIDATION`, the search is restricted to that feature's screened data. KYC rows only. + warning: Comma-separated warning risk codes; returns sessions that raised any of them (e.g. `POSSIBLE_FRAUD`). Risk codes are listed per feature in the [warnings documentation](/integration/webhooks). Applies to KYC rows and, with business warning codes, to KYB rows. + status_initialized_as_in_review: When `true`, only sessions whose decision initially landed in `In Review` (useful to audit manual-review volume). KYC rows only. + is_kyc_to_be_reviewed: `true` returns sessions whose document verification is flagged for manual review; `false` returns sessions with document verification explicitly not flagged. Omit to disable. KYC rows only. + euuid: Filter by the end user's euuid (UUID assigned to the verifying user, used by Console deep links). Must be a valid UUID; malformed values return a 400 field error. KYC rows only. + organization_name: Comma-separated organization names. Console-oriented; with an API key (already scoped to one application) it only matches your own organization's name. + 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( + "AsyncPaginator[UserSessionListItem | BusinessSessionListItem]", + self._client.request_page( + "get", + "/v3/sessions/", + cast_to=SessionsListResponse, + item_type=UserSessionListItem | BusinessSessionListItem, + auth="api_key", + query={ + "session_kind": session_kind, + "limit": limit, + "offset": offset, + "status": status, + "vendor_data": vendor_data, + "search": search, + "workflow_id": workflow_id, + "date_from": date_from, + "date_to": date_to, + "tags": tags, + "decided_from": decided_from, + "decided_to": decided_to, + "country": country, + "document_type": document_type, + "document_name": document_name, + "region": region, + "didit_internal_id": didit_internal_id, + "session_type": session_type, + "api_service": api_service, + "screened_full_name": screened_full_name, + "warning": warning, + "status_initialized_as_in_review": status_initialized_as_in_review, + "is_kyc_to_be_reviewed": is_kyc_to_be_reviewed, + "euuid": euuid, + "organization_name": organization_name, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def share( + self, + session_id: str, + *, + for_application_id: str, + ttl_in_seconds: int | 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, + ) -> SessionsShareResponse: + """Mint a share token for a finished verification session. + + Mint a short-lived JWT that lets a specific Didit application import this finished session. Pair with `POST /v3/session/import-shared/`. + + ``POST /v3/session/{sessionId}/share/`` + + Args: + session_id: UUID of the source verification session to mint a token for. + for_application_id: UUID of the Didit application that will redeem the token. Must exist, must not be deleted, and must differ from the calling application. Find it in the Business Console under **Settings → Application**. + ttl_in_seconds: Token lifetime, in seconds. Minimum `60`, maximum `86400` (24 h). Defaults to `3600` (1 h). + 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( + "SessionsShareResponse", + await self._client.request( + "post", + "/v3/session/{sessionId}/share/", + cast_to=SessionsShareResponse, + path_params={"sessionId": session_id}, + auth="api_key", + body={"for_application_id": for_application_id, "ttl_in_seconds": ttl_in_seconds}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def import_shared( + self, + *, + share_token: str, + trust_review: bool, + workflow_id: str, + vendor_data: str | None | 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, + ) -> SessionDecision: + """Redeem a share token to clone a verification session into your application. + + Redeem a share token to clone a KYC or KYB session into the calling application with a fresh `session_id`. Not idempotent - a token redeems once per receiver. + + ``POST /v3/session/import-shared/`` + + Args: + share_token: JWT share token issued by [`POST /v3/session/{sessionId}/share/`](/sessions-api/share-session). + trust_review: If `true`, the cloned session keeps the source's final `status`. If `false`, it is forced into `In Review`. + workflow_id: UUID of a workflow in the calling application. Cross-application IDs are rejected with `404`. + vendor_data: Optional override for the cloned session's `vendor_data`. + 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( + "SessionDecision", + await self._client.request( + "post", + "/v3/session/import-shared/", + cast_to=SessionDecision, + auth="api_key", + body={ + "share_token": share_token, + "trust_review": trust_review, + "workflow_id": workflow_id, + "vendor_data": vendor_data, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def batch_delete( + self, + *, + session_numbers: Sequence[str] | NotGiven = NOT_GIVEN, + delete_all: bool | NotGiven = NOT_GIVEN, + retain_face_embeddings: bool | None | NotGiven = NOT_GIVEN, + face_retention_days: int | NotGiven = NOT_GIVEN, + face_retention_deadline: str | _dt.datetime | NotGiven = NOT_GIVEN, + deletion_instruction: Literal["operational_session_delete", "privacy_erasure"] + | str + | NotGiven = NOT_GIVEN, + instruction_id: str | NotGiven = NOT_GIVEN, + filter_status: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_vendor_data: str | NotGiven = NOT_GIVEN, + filter_search: str | NotGiven = NOT_GIVEN, + filter_workflow_id: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_date_from: str | _dt.date | NotGiven = NOT_GIVEN, + filter_date_to: str | _dt.date | NotGiven = NOT_GIVEN, + filter_country: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_document_type: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_document_name: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_region: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_didit_internal_id: str | NotGiven = NOT_GIVEN, + filter_session_type: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_api_service: str | NotGiven = NOT_GIVEN, + filter_screened_full_name: str | NotGiven = NOT_GIVEN, + filter_warning: str | Sequence[str] | NotGiven = NOT_GIVEN, + filter_status_initialized_as_in_review: bool | NotGiven = NOT_GIVEN, + filter_is_kyc_to_be_reviewed: bool | NotGiven = NOT_GIVEN, + filter_euuid: str | NotGiven = NOT_GIVEN, + filter_organization_name: str | Sequence[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, + ) -> SessionsBatchDeleteResponse | SessionDeletionJob: + """Bulk delete KYC sessions by session_number. + + Bulk delete User Verification (KYC) sessions by their numeric `session_number`, or every KYC session in your application with `delete_all: true`. + + `session_number` is the human-friendly incrementing counter shown in the Console session list and returned as `session_number` by the create-session and decision endpoints; it is **not** the `session_id` UUID. To delete a session by UUID, or to delete a Business Verification (KYB) session, which this endpoint never touches, use `DELETE /v3/session/{sessionId}/delete/` instead. + + **Up to 20 sessions are deleted in the request, more run as a job.** The number of matching sessions decides, whether they are selected by `session_numbers` or with `delete_all`: + - Up to 20 matching sessions: they are deleted before the response, which is `200` with one entry per session in `results[]`. + - More than 20: the response is `202` with a deletion job, and the sessions are deleted in the background. Poll `GET /v3/sessions/delete/{job_id}/` until `status` is `COMPLETED` or `FAILED`. A job reports counts per outcome, never which sessions it deleted. A `delete_all` job deletes only the sessions created before the request; sessions started while it runs are not deleted. + + Each deleted session gets exactly the same treatment as the single-session delete endpoint: the session, every verification attempt it holds, its decision and extracted data, its related feature records (ID verification, face, liveness, face match, and so on) and all of its stored files are deleted, it disappears from every read endpoint, and previously issued media URLs stop resolving. Webhook deliveries still queued for a deleted session, and their retries, are dropped; webhooks already delivered are not affected. Blocklist entries are **not** removed, credits already consumed are **not** refunded, and the parent User entities are **not** deleted (use `POST /v3/users/delete/` for those); no webhook is emitted for the deletion. Deletion is permanent and irreversible. + + **Selection semantics:** + - With `delete_all: true` you can narrow the selection with the filters of `GET /v3/sessions/`, each prefixed with `filter_` (for example `filter_status`, `filter_workflow_id`, `filter_date_from`). Filters that take several values in List Sessions (`status`, `workflow_id`, `country`, `region`, `document_type`, `document_name`, `session_type`, `warning`, `organization_name`) accept a comma-separated string or an array; the others take one value. An empty value is ignored. Filters apply only together with `delete_all`, and a deletion job applies the same filters. + - An unknown `filter_*` key, or a filter value that cannot be read, rejects the whole request with `400` before anything is deleted, so a mistyped filter never widens the deletion to every session. + - Entries in `session_numbers` that do not match a live KYC session in your application (unknown numbers, already-deleted sessions, or sessions owned by another application) are **silently skipped**: they do not appear in `results` and are not counted in a job's `total`. + - Validation failures (a non-numeric entry, an empty list, neither `session_numbers` nor `delete_all` provided, or a template retention the application cannot honour) reject the **whole request** with `400` and delete nothing. + - Sessions are deleted in groups. If a group cannot be deleted (for example because a storage service is unavailable), every session in that group is reported as `face_retention_outcome: failed_retryable` and stays in place; the other groups are unaffected. Repeat the request for those sessions. A job retries such a group by itself. + - There is no documented cap on the list length; the shared write rate limit (below) is the practical bound. + + **Face biometric data:** the optional `retain_face_embeddings`, `face_retention_days`, `face_retention_deadline`, `deletion_instruction`, and `instruction_id` fields have the same meaning as on `DELETE /v3/session/{sessionId}/delete/` and apply to every matched session. Each result reports its own `face_retention_outcome`. + + **Response:** `200 OK` with `results[]` for up to 20 matching sessions, or `202 Accepted` with a deletion job for more. Every result confirms deletion except `face_retention_outcome: failed_retryable`, which reports a session that was NOT deleted and should be retried. Earlier versions of this endpoint returned `204 No Content`; update clients that assert on `204`. + + **Idempotency:** repeating the same request deletes nothing more: numbers that no longer match a session are skipped. + + **`delete_all: true` (destructive):** deletes **every** remaining KYC session in the application; `session_numbers` is ignored when set. There is no confirmation step and no undo. + + **Authentication:** API key in the `x-api-key` header. Missing or invalid credentials return `403` (`{"detail": "You do not have permission to perform this action."}`); this API never returns `401`. + + **Rate limit:** shared write budget of 300 requests/min per API key across all POST/PATCH/DELETE endpoints; exceeding it returns `429`. + + This endpoint accepts API keys only. Business Console user Bearer tokens are rejected with `403` (unlike the single-session delete, which accepts both). + + **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request. + + ``POST /v3/sessions/delete/`` + + Args: + session_numbers: Numeric `session_number` values of the KYC sessions to delete, as digit-only strings (JSON numbers are also accepted and coerced). Required unless `delete_all` is `true`; an empty list returns `400`. Any non-digit entry rejects the whole request with `400` (unless `delete_all` is `true`, in which case validation is skipped and the entries are ignored). Numbers that do not match a live session in your application are silently skipped. + delete_all: When `true`, every remaining KYC session in the calling application is deleted and `session_numbers` is ignored, unless you narrow the selection with `filter_*` keys. More than 20 matching sessions run as a deletion job (`202`) that covers only the sessions created before the request. Defaults to `false`. Irreversible; there is no confirmation step. + retain_face_embeddings: Override the application's `face_retention_policy` for this deletion. `true` keeps one image-free face biometric template anchored to the session's User after the session is deleted; `false` deletes the face embedding with the session; omit or `null` to follow the application policy. Ignored for KYB sessions and for sessions without a face embedding. + face_retention_days: Finite retention duration, in days, for a retained template. Required when a template is retained unless the application already sets `face_retention_days`. The template's `expires_at` is the earliest of this duration, the application's general data-retention window, and `face_retention_deadline`. + face_retention_deadline: Optional hard expiry for a retained template. Must be in the future. + deletion_instruction: The class of instruction you are giving. `operational_session_delete` deletes the session and retains a template only when the policy or `retain_face_embeddings` says so. `privacy_erasure` purges every retained biometric template anchored to the session's User before deleting the session, cannot be overridden by the application policy, and cannot be combined with `retain_face_embeddings: true` (`400`). + instruction_id: Your durable reference for this deletion instruction (for example an erasure-ticket id). Recorded on the audit trail and on any retained template. Generated by Didit when omitted. + filter_status: Narrows a `delete_all` to the sessions that match the `status` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_vendor_data: Narrows a `delete_all` to the sessions that match the `vendor_data` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_search: Narrows a `delete_all` to the sessions that match the `search` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_workflow_id: Narrows a `delete_all` to the sessions that match the `workflow_id` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_date_from: Narrows a `delete_all` to the sessions that match the `date_from` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_date_to: Narrows a `delete_all` to the sessions that match the `date_to` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_country: Narrows a `delete_all` to the sessions that match the `country` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_document_type: Narrows a `delete_all` to the sessions that match the `document_type` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_document_name: Narrows a `delete_all` to the sessions that match the `document_name` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_region: Narrows a `delete_all` to the sessions that match the `region` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_didit_internal_id: Narrows a `delete_all` to the sessions that match the `didit_internal_id` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_session_type: Narrows a `delete_all` to the sessions that match the `session_type` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_api_service: Narrows a `delete_all` to the sessions that match the `api_service` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_screened_full_name: Narrows a `delete_all` to the sessions that match the `screened_full_name` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated text, so several values are not matched as alternatives. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_warning: Narrows a `delete_all` to the sessions that match the `warning` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_status_initialized_as_in_review: Narrows a `delete_all` to the sessions that match the `status_initialized_as_in_review` filter of [List Sessions](/sessions-api/list-sessions), with the same values. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_is_kyc_to_be_reviewed: Narrows a `delete_all` to the sessions that match the `is_kyc_to_be_reviewed` filter of [List Sessions](/sessions-api/list-sessions), with the same values. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_euuid: Narrows a `delete_all` to the sessions that match the `euuid` filter of [List Sessions](/sessions-api/list-sessions), with the same value. One value, not a list: an array is joined into one comma-separated value, so several values are refused with `400`. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + filter_organization_name: Narrows a `delete_all` to the sessions that match the `organization_name` filter of [List Sessions](/sessions-api/list-sessions), with the same values. A comma-separated string or an array. With an API key it can only match your own organization's name, so it selects all of your sessions or none. Ignored without `delete_all`. An empty value is ignored and does not narrow the selection. + 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( + "SessionsBatchDeleteResponse | SessionDeletionJob", + await self._client.request( + "post", + "/v3/sessions/delete/", + cast_to={200: SessionsBatchDeleteResponse, 202: SessionDeletionJob}, + auth="api_key", + body={ + "session_numbers": session_numbers, + "delete_all": delete_all, + "retain_face_embeddings": retain_face_embeddings, + "face_retention_days": face_retention_days, + "face_retention_deadline": face_retention_deadline, + "deletion_instruction": deletion_instruction, + "instruction_id": instruction_id, + "filter_status": filter_status, + "filter_vendor_data": filter_vendor_data, + "filter_search": filter_search, + "filter_workflow_id": filter_workflow_id, + "filter_date_from": filter_date_from, + "filter_date_to": filter_date_to, + "filter_country": filter_country, + "filter_document_type": filter_document_type, + "filter_document_name": filter_document_name, + "filter_region": filter_region, + "filter_didit_internal_id": filter_didit_internal_id, + "filter_session_type": filter_session_type, + "filter_api_service": filter_api_service, + "filter_screened_full_name": filter_screened_full_name, + "filter_warning": filter_warning, + "filter_status_initialized_as_in_review": filter_status_initialized_as_in_review, + "filter_is_kyc_to_be_reviewed": filter_is_kyc_to_be_reviewed, + "filter_euuid": filter_euuid, + "filter_organization_name": filter_organization_name, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def retrieve_deletion_job( + self, + job_id: str, + *, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SessionDeletionJob: + """Get a bulk session deletion job. + + Progress of a bulk session deletion that `POST /v3/sessions/delete/` answered with `202` (more than 20 matching sessions, selected by `session_numbers` or with `delete_all`). Poll every few seconds while `status` is `PENDING` or `PROCESSING`; stop when it is `COMPLETED` or `FAILED`. + + The job reports how many sessions ended in each outcome and how many it has processed, never which sessions it deleted. A `FAILED` job carries the reason in `error`; the sessions it had not reached are still in place, so repeat the deletion request to delete them. + + **Authentication:** API key in the `x-api-key` header. A job is only visible to the application that created it; any other `job_id` returns `404`. Missing or invalid credentials return `403`; this API never returns `401`. + + ``GET /v3/sessions/delete/{job_id}/`` + + Args: + job_id: The `job_id` returned with the `202` from `POST /v3/sessions/delete/`. + 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( + "SessionDeletionJob", + await self._client.request( + "get", + "/v3/sessions/delete/{job_id}/", + cast_to=SessionDeletionJob, + path_params={"job_id": job_id}, + auth="api_key", + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_data( + self, + session_id: str, + *, + document_type: Literal[ + "P", "DL", "ID", "RP", "SSC", "HIC", "WP", "TC", "VISA", "PSC", "BC", "OTHER" + ] + | str + | None + | NotGiven = NOT_GIVEN, + document_subtype: str | None | NotGiven = NOT_GIVEN, + document_number: str | None | NotGiven = NOT_GIVEN, + personal_number: str | None | NotGiven = NOT_GIVEN, + date_of_birth: str | _dt.date | None | NotGiven = NOT_GIVEN, + date_of_issue: str | _dt.date | None | NotGiven = NOT_GIVEN, + expiration_date: str | _dt.date | None | NotGiven = NOT_GIVEN, + issuing_state: str | None | NotGiven = NOT_GIVEN, + first_name: str | None | NotGiven = NOT_GIVEN, + last_name: str | None | NotGiven = NOT_GIVEN, + gender: Literal["M", "F", "U"] | str | None | NotGiven = NOT_GIVEN, + address: str | None | NotGiven = NOT_GIVEN, + place_of_birth: str | None | NotGiven = NOT_GIVEN, + nationality: str | None | NotGiven = NOT_GIVEN, + marital_status: Literal["SINGLE", "MARRIED", "DIVORCED", "WIDOWED", "UNKNOWN"] + | str + | NotGiven = NOT_GIVEN, + extra_fields: Mapping[str, object] | None | NotGiven = NOT_GIVEN, + parsed_address: SessionsUpdateDataParamsParsedAddress | None | NotGiven = NOT_GIVEN, + node_id: 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, + ) -> SessionsUpdateDataResponse: + """Update KYC data extracted from the ID document on a verification session. + + Correct the identity fields that were extracted (OCR / NFC) from the user's ID document - misread names, dates, document numbers, and so on - after the verification has finished. Typical callers are a compliance analyst working from your own back office, or an automated reconciliation job. Every field in the body is optional: only the keys you send are written, everything else is left untouched (`PATCH` semantics). + + The session must belong to your application and be in `Approved`, `Declined`, `In Review`, or `Kyc Expired` status. Sessions in any other state (e.g. still `In Progress`) return `404` with `"No Session matches the given query."` - distinct from the `"Not found."` returned for an unknown or deleted `sessionId`. The session must also carry an ID-verification (KYC) record: sessions whose workflow never ran an ID-verification step return `404` (`"The session does not have a KYC."`). For graph workflows with multiple ID-verification steps, target a specific step with `node_id` (query parameter or body field); when omitted, the most recent KYC record is patched. + + Two derived fields are recomputed on every call: `full_name` (from `first_name` + `last_name`) and `issuing_state_name` (from `issuing_state`). If the free-text `address` changes, the server may also re-geocode it and refresh `parsed_address` (skipped for sandbox sessions). `extra_fields` and `parsed_address` are merged key-by-key rather than replaced - see the per-field descriptions for the `null`-to-delete semantics. + + Submitting at least one valid field fires the `data.updated` [webhook](/integration/webhooks) (trigger `manual_review`) - even when the submitted values equal the stored ones. When values actually change, a `KYC_DATA_UPDATED` activity entry recording the changed fields with previous and new values is appended to the session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and the console activity timeline. The session's status and decision are **not** re-evaluated - use [Update Status](#patch-/v3/session/-sessionId-/update-status/) to change the outcome. An empty JSON body (`{}`) is accepted and simply returns the current KYC data without firing the webhook. + + Accepts an API key or a console user token; either way the credential needs the `write:sessions` permission. Authentication and permission failures both return `403` - this API never responds `401`. Note that the session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing credentials. This endpoint has a dedicated rate limit of 10 requests per minute per API key (invalid requests count too); the shared write budget of 300 requests per minute also applies. + + ``PATCH /v3/session/{sessionId}/update-data/`` + + Args: + session_id: UUID of the User Verification (KYC) session whose extracted document data you are correcting. Business (KYB) session IDs are not valid here - for company data use [Update KYB Company Data](#patch-/v3/session/-sessionId-/kyb/-companyUuid-/update-data/). + document_type: Document type code. Accepts the short codes listed in the enum, plus six long-form aliases normalized server-side before validation: `Passport` → `P`, `Identity Card` → `ID`, `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`. Any other value (including `PASSPORT` in caps) returns `400`. + document_subtype: Document subtype from the document registry, including the region prefix when the registry distinguishes regional variants. + document_number: Document number as printed on the ID. + personal_number: Personal / national identification number where the document carries one (e.g. Spanish DNI on a passport). + date_of_birth: Date of birth in `YYYY-MM-DD`. Any other format returns `400`. + date_of_issue: Issue date of the document in `YYYY-MM-DD`. + expiration_date: Expiration date of the document in `YYYY-MM-DD`. + issuing_state: Issuing country as an ISO 3166-1 alpha-3 code. Case-insensitive (`esp` is stored as `ESP`); the human-readable `issuing_state_name` shown in [Get Decision](#get-/v3/session/-sessionId-/decision/) is recomputed from this value. Invalid codes return `400`. + first_name: Given name(s). The stored `full_name` is recomputed as `first_name + ' ' + last_name` on every call to this endpoint. + last_name: Family name(s). Also feeds the recomputed `full_name`. + gender: Sex as printed on the document: `M` (male), `F` (female), or `U` (unknown). Any other value - including `X` - returns `400`. + address: Free-text address as printed on the document. When this value changes (non-sandbox sessions only) and the structured address is still missing or incomplete, the server re-geocodes it synchronously before responding - the 200 body already reflects the refreshed `parsed_address`. The re-geocode also requires `issuing_state` to be present on the KYC record. + place_of_birth: Place of birth as printed on the document. + nationality: Nationality as printed on the document. Free text up to 32 characters - typically an ISO 3166-1 alpha-3 code (e.g. `ESP`), but not validated as one. + marital_status: Marital status where the document carries it. Any other value returns `400`. + extra_fields: Per-key overrides for document-specific extra fields (e.g. `blood_group`, `dl_categories`, `mrz_string`). Keys are merged into the existing override map: send a key with a value to set it, or with `null` / `""` to remove that key from the merged view. Send the whole field as `null` to clear all previously applied overrides. Must be a JSON object, otherwise `400`. The response always returns the merged view (OCR-extracted values with your overrides applied). + parsed_address: Structured address. Only these nested keys are accepted: `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` - any other key returns `400`. Per-key semantics: a value sets the key, `null` removes it. `formatted_address` is recomputed server-side by joining `street_1`, `street_2`, `city`, `region`, `postal_code`, and `country` and is returned in the response - you cannot set it directly. + node_id: Workflow graph node whose KYC record to patch, for graph workflows with multiple ID-verification steps (also accepted as a `node_id` body field). When omitted, the most recent KYC record on the session is patched. If no KYC exists for the given node, the call returns `404` (`"The session does not have a KYC for node ''."`). + 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( + "SessionsUpdateDataResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/update-data/", + cast_to=SessionsUpdateDataResponse, + path_params={"sessionId": session_id}, + auth="api_key", + query={"node_id": node_id}, + body={ + "document_type": document_type, + "document_subtype": document_subtype, + "document_number": document_number, + "personal_number": personal_number, + "date_of_birth": date_of_birth, + "date_of_issue": date_of_issue, + "expiration_date": expiration_date, + "issuing_state": issuing_state, + "first_name": first_name, + "last_name": last_name, + "gender": gender, + "address": address, + "place_of_birth": place_of_birth, + "nationality": nationality, + "marital_status": marital_status, + "extra_fields": extra_fields, + "parsed_address": parsed_address, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_feature_status( + self, + session_id: str, + node_id: str, + *, + new_status: Literal["Approved", "Declined", "In Review"] | str, + comment: str | NotGiven = NOT_GIVEN, + feature_type: Literal[ + "ID_VERIFICATION", + "OCR", + "OCR_BACK", + "NFC", + "LIVENESS", + "FACE", + "AGE_ESTIMATION", + "AGE_VERIFICATION", + "FACE_SEARCH", + "FACE_MATCH", + "IP_ANALYSIS", + "AML", + "PHONE", + "PHONE_VERIFICATION", + "EMAIL", + "EMAIL_VERIFICATION", + "POA", + "PROOF_OF_ADDRESS", + "DATABASE_VALIDATION", + "DATA_VALIDATION", + "QUESTIONNAIRE", + "DOCUMENT_AI", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "BANK_VERIFICATION", + "GEOLOCATION", + ] + | str + | NotGiven = NOT_GIVEN, + defer_until_flow_finishes: bool | 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, + ) -> SessionsUpdateFeatureStatusResponse: + """Update an individual feature (step) status. + + Set the status of a single verification feature (step) within a session. Target the feature by its workflow graph `nodeId`. On non-graph workflows, whose steps have no node, use `default` and also pass `feature_type` to say which step you mean. + + Works for both User Verification (KYC) and Business Verification (KYB) sessions and every step type: ID/OCR, Liveness, Face Match, NFC, AML, Proof of Address, Phone, Email, Database Validation, Questionnaire, and the KYB registry / documents / key-people checks. This endpoint is **not** available for standalone API sessions (`session_type = API`). + + `new_status` must be one of `Approved`, `Declined`, or `In Review`, and must differ from the feature's current status. + + **When the override applies.** Without `defer_until_flow_finishes` (or with `false`) the override applies at once, as it always did; when the person is still in the flow it is recorded as `forced`. With `defer_until_flow_finishes: true` while the person is still in the flow (the session is `Not Started`, `In Progress` or `Resubmitted` and has not finished), the override is stored as `pending_until_flow_finishes` and applies when the flow finishes, after the flow reaches its own decision. On a session whose flow already ended it applies at once either way. A waiting override is cancelled instead when the person redoes its step before finishing, when a newer override on the same check replaces it, when the session leaves the flow unfinished (abandoned, expired, or decided mid-flow), or when you cancel it with `POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`. List a session's overrides with `GET /v3/session/{sessionId}/features/overrides/`. + + **Effect on the session.** A session that already has a decision keeps it: only the check changes. When the session has no decision yet and its workflow is waiting on exactly this step, applying the override completes the step: the workflow moves on, later steps run, and a status node can set the session decision and fire `status.updated`. + + **Webhooks and activity.** A `data.updated` webhook fires when the override applies (at once, or when the flow finishes), never while it waits or when it is cancelled. Every override is recorded in the session's activity as `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` or `FEATURE_OVERRIDE_CANCELLED`, with who made it; the request's entry carries your `comment`. + + Authenticate with your API key (`x-api-key`) or a user authorization header carrying the `write:sessions` privilege; a scoped API key needs write access to decisions. + + ``PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`` + + Args: + session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. + node_id: Workflow graph node ID of the feature to update (for example `feature_ocr_1`). Use the literal value `default` for non-graph (single-step) workflows where the feature has no node ID. + new_status: Target status for this feature. Must differ from the current value. + comment: Optional free-text note recorded on the session's review trail for this feature change. + feature_type: Which kind of step to target. Needed on non-graph workflows (`nodeId` = `default`), where every step shares no node; optional otherwise. An unknown value returns `400`. + defer_until_flow_finishes: While the person is still in the flow, store the override as `pending_until_flow_finishes` and apply it when the flow finishes, instead of at once. Omitted or `false`, the override applies at once. On a session whose flow already ended it applies at once either way. + 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( + "SessionsUpdateFeatureStatusResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/features/{nodeId}/update-status/", + cast_to=SessionsUpdateFeatureStatusResponse, + path_params={"sessionId": session_id, "nodeId": node_id}, + auth="api_key", + body={ + "new_status": new_status, + "comment": comment, + "feature_type": feature_type, + "defer_until_flow_finishes": defer_until_flow_finishes, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_aml_hit_status( + self, + session_id: str, + *, + hit_id: str, + review_status: Literal["Unreviewed", "Confirmed Match", "False Positive", "Inconclusive"] + | str, + node_id: str | NotGiven = NOT_GIVEN, + node_id_query: 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, + ) -> SessionsUpdateAmlHitStatusResponse: + """Update an AML hit review status. + + Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match) returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id` (the `id` of an entry in the AML check's `hits` array - see the session decision). A hit id returned in the earlier format is still accepted; the response always names the hit by its current `id`. + + `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. Reviewer decisions are preserved across ongoing-monitoring updates, so a hit you mark `False Positive` stays that way when the provider re-screens. + + A successful call fires a `data.updated` webhook and appends an activity entry (with actor attribution) to the session's review trail. For graph workflows with multiple AML checks, pass `node_id` to target a specific check. + + Authenticate with your API key (`x-api-key`) or a user authorization header - either must carry the `write:sessions` privilege. + + ``PATCH /v3/session/{sessionId}/update-aml-hit-status/`` + + Args: + session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. + hit_id: The `id` of the hit in the AML check's `hits` array (`hit_...`). A hit id returned in the earlier format is still accepted. + review_status: The new review status for the hit. + node_id: Optional graph node ID. Use it (here or as a query parameter) when the session has multiple AML checks. + node_id_query: Workflow graph node ID. Required only when the session has multiple AML checks (one per node); omit it for single-AML sessions. + 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( + "SessionsUpdateAmlHitStatusResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/update-aml-hit-status/", + cast_to=SessionsUpdateAmlHitStatusResponse, + path_params={"sessionId": session_id}, + auth="api_key", + query={"node_id": node_id_query}, + body={"hit_id": hit_id, "review_status": review_status, "node_id": node_id}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def bulk_update_aml_hit_status( + self, + session_id: str, + *, + hit_updates: Sequence[SessionsBulkUpdateAmlHitStatusParamsHitUpdates], + node_id: str | NotGiven = NOT_GIVEN, + node_id_query: 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, + ) -> SessionsBulkUpdateAmlHitStatusResponse: + """Bulk update AML hit review statuses. + + Update the review status of **multiple AML hits** in one call. Provide `hit_updates`, a list of `{ hit_id, review_status }` pairs. `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. + + The update is all-or-nothing: if any `hit_id` is not found in the AML check, the request returns `404` and no hit is changed. A successful call fires a single `data.updated` webhook and records one activity entry covering all changes. For graph workflows with multiple AML checks, pass `node_id` to target a specific check. + + Authenticate with your API key (`x-api-key`) or a user authorization header - either must carry the `write:sessions` privilege. + + ``PATCH /v3/session/{sessionId}/bulk-update-aml-hit-status/`` + + Args: + session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. + hit_updates: Non-empty list of hit updates. + node_id: Optional graph node ID. Use it (here or as a query parameter) when the session has multiple AML checks. + node_id_query: Workflow graph node ID. Required only when the session has multiple AML checks (one per node); omit it for single-AML sessions. + 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( + "SessionsBulkUpdateAmlHitStatusResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/bulk-update-aml-hit-status/", + cast_to=SessionsBulkUpdateAmlHitStatusResponse, + path_params={"sessionId": session_id}, + auth="api_key", + query={"node_id": node_id_query}, + body={"hit_updates": hit_updates, "node_id": node_id}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_poa_data( + self, + session_id: str, + *, + issuing_state: str | None | NotGiven = NOT_GIVEN, + document_type: Literal[ + "UTILITY_BILL", + "BANK_STATEMENT", + "GOVERNMENT_ISSUED_DOCUMENT", + "OTHER_POA_DOCUMENT", + "UNKNOWN", + ] + | str + | NotGiven = NOT_GIVEN, + document_language: str | None | NotGiven = NOT_GIVEN, + issuer: str | None | NotGiven = NOT_GIVEN, + issue_date: str | _dt.date | None | NotGiven = NOT_GIVEN, + poa_address: str | None | NotGiven = NOT_GIVEN, + name_on_document: str | None | NotGiven = NOT_GIVEN, + extra_fields: Mapping[str, object] | None | NotGiven = NOT_GIVEN, + poa_parsed_address: SessionsUpdatePoaDataParamsPoaParsedAddress + | None + | NotGiven = NOT_GIVEN, + node_id: 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, + ) -> SessionsUpdatePoaDataResponse: + """Update Proof of Address data extracted from the POA document on a verification session. + + Correct the fields extracted from the user's Proof of Address document - utility bill, bank statement, or other address evidence - after the verification has finished: issuer, dates, the printed name, the address itself, and banking details. Every field in the body is optional: only the keys you send are written, everything else is left untouched (`PATCH` semantics). + + The session must belong to your application and be in `Approved`, `Declined`, `In Review`, or `Kyc Expired` status. Sessions in any other state (e.g. still `In Progress`) return `404` with `"No Session matches the given query."` - distinct from the `"Not found."` returned for an unknown or deleted `sessionId`. The session must also carry a POA record: sessions whose workflow never ran a Proof of Address step return `404` (`"The session does not have a POA."`). For graph workflows with multiple POA steps, target a specific step with `node_id` (query parameter or body field); when omitted, the most recent POA record is patched. + + `extra_fields` is merged key-by-key: nine known keys (`bank_iban`, `additional_names`, …) write through to dedicated POA columns, any other key is kept as a custom extra, and `null` / `""` deletes a key. `poa_parsed_address` accepts only the seven documented keys and recomputes `formatted_address` / `poa_formatted_address` after every edit. If the free-text `poa_address` changes, the server may also re-geocode it and refresh the structured address (skipped for sandbox sessions). + + Unlike the KYC variant of this endpoint, the `data.updated` [webhook](/integration/webhooks) (trigger `manual_review`) fires only when at least one stored value **actually changed** - re-sending identical values is a silent no-op. When values change, a `POA_DATA_UPDATED` activity entry recording the changed fields with previous and new values is appended to the session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and the console activity timeline. The session's status and decision are **not** re-evaluated - use [Update Status](#patch-/v3/session/-sessionId-/update-status/) to change the outcome. + + Accepts an API key or a console user token; either way the credential needs the `write:sessions` permission. Authentication and permission failures both return `403` - this API never responds `401`. Note that the session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing credentials. This endpoint has a dedicated rate limit of 10 requests per minute per API key (invalid requests count too); the shared write budget of 300 requests per minute also applies. + + An empty JSON body `{}` is a no-op: it returns `200` echoing the current POA record without firing the webhook (`has_changes` stays false). + + ``PATCH /v3/session/{sessionId}/update-poa-data/`` + + Args: + session_id: UUID of the User Verification (KYC) session whose attached POA record you are correcting. + issuing_state: Country that issued the POA document, ISO 3166-1 alpha-3. Case-insensitive (normalized to uppercase); invalid codes return `400`. + document_type: POA document category. Values are uppercase - lowercase variants like `utility_bill` return `400`. + document_language: Language of the document, typically an ISO 639-1 code (e.g. `es`). Free text - not validated as a language code. + issuer: Organization that issued the document (utility company, bank, government agency). + issue_date: Issue date of the POA document in `YYYY-MM-DD`. Any other format returns `400`. + poa_address: Free-text address as printed on the document. When this value changes (non-sandbox sessions only) and the structured address is still missing or incomplete, the server re-geocodes it in the background of the same request and may overwrite `poa_parsed_address` / `poa_formatted_address` with the geocoder result. The re-geocode also requires `issuing_state` to be present on the POA record. + name_on_document: Recipient name as printed on the document. + extra_fields: Document-specific extras, merged key-by-key. Nine keys map to dedicated POA columns: `bank_account_number`, `bank_iban`, `bank_sort_code`, `bank_routing_number`, `bank_swift_bic`, `bank_branch_name`, `bank_branch_address`, `document_phone_number`, and `additional_names` (must be a list of strings or `null`, otherwise `400`). Any other key is stored as a custom extra field. Per-key semantics: a value sets the key; `null` or `""` deletes it. Must be a JSON object, otherwise `400`. + poa_parsed_address: Structured address. Only these nested keys are accepted: `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` - any other key returns `400`. Per-key semantics: a value sets the key, `null` removes it. `formatted_address` (and the top-level `poa_formatted_address`) is recomputed server-side by joining `street_1`, `street_2`, `city`, `region`, `postal_code`, and `country` - you cannot set it directly. + node_id: Workflow graph node whose POA record to patch, for graph workflows with multiple Proof of Address steps (also accepted as a `node_id` body field). When omitted, the most recent POA record on the session is patched. If no POA exists for the given node, the call returns `404` (`"The session does not have a POA for node ''."`). + 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( + "SessionsUpdatePoaDataResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/update-poa-data/", + cast_to=SessionsUpdatePoaDataResponse, + path_params={"sessionId": session_id}, + auth="api_key", + query={"node_id": node_id}, + body={ + "issuing_state": issuing_state, + "document_type": document_type, + "document_language": document_language, + "issuer": issuer, + "issue_date": issue_date, + "poa_address": poa_address, + "name_on_document": name_on_document, + "extra_fields": extra_fields, + "poa_parsed_address": poa_parsed_address, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_kyb_company_data( + self, + session_id: str, + company_uuid: str, + *, + company_name: str | NotGiven = NOT_GIVEN, + registration_number: str | NotGiven = NOT_GIVEN, + country_code: str | NotGiven = NOT_GIVEN, + region: str | None | NotGiven = NOT_GIVEN, + incorporation_date: str | _dt.date | NotGiven = NOT_GIVEN, + registration_date: str | _dt.date | None | NotGiven = NOT_GIVEN, + dissolution_date: str | _dt.date | None | NotGiven = NOT_GIVEN, + tax_number: str | NotGiven = NOT_GIVEN, + legal_address: str | NotGiven = NOT_GIVEN, + company_type: str | NotGiven = NOT_GIVEN, + registry_status: Literal[ + "active", + "dissolved", + "deregistered", + "see full details", + "authorised", + "appointed representative", + "unauthorised", + "inactive", + "no longer authorised", + "closed", + "struck off", + ] + | str + | None + | NotGiven = NOT_GIVEN, + verification_status: Literal["verified", "failed", "unknown"] + | str + | None + | NotGiven = NOT_GIVEN, + alternative_names: str | NotGiven = NOT_GIVEN, + nature_of_business: str | NotGiven = NOT_GIVEN, + registered_capital: str | NotGiven = NOT_GIVEN, + registered_capital_amount: float | None | NotGiven = NOT_GIVEN, + registered_capital_currency: str | None | NotGiven = NOT_GIVEN, + website: str | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, + phone: str | NotGiven = NOT_GIVEN, + legal_entity_identifier: str | NotGiven = NOT_GIVEN, + location_of_registration: str | NotGiven = NOT_GIVEN, + vat_number: str | NotGiven = NOT_GIVEN, + control_scheme: 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, + ) -> SessionsUpdateKybCompanyDataResponse: + """Update registry-extracted company data on a Business Verification (KYB) session. + + Correct the registry-extracted company data on a Business Verification (KYB) session - company name, registration number, addresses, status, contact details - identified by `companyUuid`. Typical callers are a compliance analyst fixing a registry misread, or your back office syncing corrected company data. Every field in the body is optional (`PATCH` semantics); an empty JSON body (`{}`) is a no-op that simply echoes the current company record. + + Edits are written in two places at once: fields with a canonical company column (name, registration number, country, incorporation date, tax number, type, statuses, capital fields (`registered_capital`, `registered_capital_amount`, `registered_capital_currency`), alternative names, nature of business, website, email, phone, LEI, location, and `legal_address` → `registered_address`) update that column, and **every** submitted key is also merged into the `registry_data` snapshot (dates as ISO strings) so the "extracted from registry" view reflects the correction. Fields without a column - `region`, `registration_date`, `dissolution_date`, `control_scheme` - land in `registry_data` only. `user_provided_data` (what the end user confirmed in the hosted flow) is never touched, and `last_console_edit_at` is stamped on every non-empty PATCH. + + Unlike the KYC/POA update endpoints, there is **no session-status gate**: the company can be edited at any point in the business session's lifecycle. The company must belong to the session in the path (`404` with `"KYB company does not belong to the given session."` otherwise) and to your application. Every non-empty PATCH fires the `data.updated` [webhook](/integration/webhooks) on the business session (trigger `console_registry_edit`) - even when the submitted values equal the stored ones. The session's status and decision are **not** re-evaluated, and no review/audit entry is recorded. + + Accepts an API key or a console user token; either way the credential needs the `write:businesses` permission. Authentication and permission failures both return `403` - this API never responds `401`. Note that the session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing credentials. The shared write budget of 300 requests per minute per API key applies. + + For User Verification sessions, the KYC counterpart is `PATCH /v3/session/{sessionId}/update-data/`; to change the session decision itself use `PATCH /v3/session/{sessionId}/update-status/`. + + ``PATCH /v3/session/{sessionId}/kyb/{companyUuid}/update-data/`` + + Args: + session_id: UUID of the parent Business Verification (KYB) session. + company_uuid: UUID of the company record to update (`registry_checks[].company.uuid` on the business session decision). Must belong to the session referenced by `sessionId`. + company_name: Legal name of the company. Written to the canonical column and the registry snapshot. + registration_number: Official registration number with the company registry. + country_code: Country of incorporation, ISO 3166-1 alpha-2. Case-insensitive (`us` is stored as `US`). Alpha-3 codes fail the 2-character limit with `400`. + region: Subdivision / region tag where the registry has one (e.g. US state). Stored in the registry snapshot only - it has no canonical column. + incorporation_date: Incorporation date in `YYYY-MM-DD`. Optional like every other field - the `PATCH` is partial. Any other date format returns `400`. + registration_date: Registration date where the registry distinguishes it from incorporation. Stored in the registry snapshot only. + dissolution_date: Dissolution date for companies that are no longer active. Stored in the registry snapshot only. + tax_number: Tax identification number. + legal_address: Legal / registered address. Aliased server-side to the canonical `registered_address` column - the response returns it under `registered_address`, while the registry snapshot keeps the `legal_address` key you sent. + company_type: Legal entity type (e.g. `Limited Liability Company`, `PLC`, `GmbH`). + registry_status: Registry-reported company status. Lowercase, some values contain spaces (e.g. `struck off`, `no longer authorised`). Any other value returns `400`. + verification_status: Outcome of the registry verification. Any other value returns `400`. + alternative_names: Trade names, former legal names, DBA names (free text). + nature_of_business: Short description of the company's activity. + registered_capital: Human-readable registered capital (e.g. `USD 50000`). Use `registered_capital_amount` + `registered_capital_currency` for structured values, or this field for free-form text. + registered_capital_amount: Numeric registered-capital amount (up to 20 digits, 2 decimal places). Sets the `registered_capital_amount` column and is mirrored into `registry_data` as a decimal string; the response echoes it as a decimal string (e.g. `"1500000.50"`). + registered_capital_currency: ISO 4217 currency code for `registered_capital_amount`. Case-insensitive (`usd` is stored as `USD`); values that are not exactly 3 letters return `400` with the ISO 4217 message. Sets the canonical `registered_capital_currency` column and is mirrored into `registry_data`. + website: Company website. Bare domains are accepted and normalized with an `https://` prefix (`docsprobe.example.com` is stored as `https://docsprobe.example.com`); values that still fail URL validation return `400`. + email: Contact email on file with the registry. + phone: Contact phone. Must match `+`, digits, spaces, dashes, dots, or parentheses, with 7-15 digits total - otherwise `400`. + legal_entity_identifier: LEI, where the company has one. + location_of_registration: City / subdivision of the registry of record. + vat_number: EU VAT number. Merged into the `registry_data` snapshot only - editing it here does not re-run VAT and tax ID validation, so `vat_validation_status` and the other `vat_*` result fields are unchanged. + control_scheme: Control / governance scheme when the registry exposes it. Stored in the registry snapshot only. + 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( + "SessionsUpdateKybCompanyDataResponse", + await self._client.request( + "patch", + "/v3/session/{sessionId}/kyb/{companyUuid}/update-data/", + cast_to=SessionsUpdateKybCompanyDataResponse, + path_params={"sessionId": session_id, "companyUuid": company_uuid}, + auth="api_key", + body={ + "company_name": company_name, + "registration_number": registration_number, + "country_code": country_code, + "region": region, + "incorporation_date": incorporation_date, + "registration_date": registration_date, + "dissolution_date": dissolution_date, + "tax_number": tax_number, + "legal_address": legal_address, + "company_type": company_type, + "registry_status": registry_status, + "verification_status": verification_status, + "alternative_names": alternative_names, + "nature_of_business": nature_of_business, + "registered_capital": registered_capital, + "registered_capital_amount": registered_capital_amount, + "registered_capital_currency": registered_capital_currency, + "website": website, + "email": email, + "phone": phone, + "legal_entity_identifier": legal_entity_identifier, + "location_of_registration": location_of_registration, + "vat_number": vat_number, + "control_scheme": control_scheme, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def update_kyb_party( + self, + session_id: str, + party_uuid: str, + *, + is_skipped: bool, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SessionsUpdateKybPartyResponse: + """Skip (or re-require) a Key People party on a Business Verification (KYB) session. + + Exempt a Key People party from verification, or put it back in scope. This is the operator escape hatch for a party that can never finish its own check - most often because the individual KYC session handed to a UBO or director was deleted, which freezes that child's status and leaves the KYB parked in `Awaiting User` with nothing left that could move it. + + Setting `is_skipped: true` drops the party out of the Key People aggregation and immediately recomputes the `KYBKeyPeopleCheck` and the parent session status, so the business session can settle and then be approved or declined. Sending `is_skipped: false` puts the party back in scope and the check goes back to waiting on it. + + Unlike the applicant-facing skip in the hosted Key People screen, this endpoint is **not** gated by the role's `allow_skip` setting - that flag limits what the applicant may decide, not what your analyst may override. `requires_verification` is deliberately left untouched, so an overridden party reads as `requires_verification: true` **and** `is_skipped: true` and the record still shows what the rules asked for. + + The party must belong to the session in the path (`404` with `"Party does not belong to the given session."` otherwise) and to your application. A PATCH that actually changes the flag fires the `data.updated` [webhook](/integration/webhooks) on the business session with trigger `console_key_people_skip`; a PATCH that sets the flag to its current value is a no-op that echoes the party back. + + Accepts an API key or a console user token; either way the credential needs the `write:businesses` permission. + + ``PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/`` + + Args: + session_id: UUID of the parent Business Verification (KYB) session. + party_uuid: UUID of the Key People party to update (`key_people_checks[].submitted.parties[].uuid` on the business session decision). Must belong to the session referenced by `sessionId`. + is_skipped: `true` exempts the party from verification so the Key People check can settle without it; `false` puts it back in scope. 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( - "SessionsBatchDeleteResponse | SessionDeletionJob", + "SessionsUpdateKybPartyResponse", await self._client.request( - "post", - "/v3/sessions/delete/", - cast_to={200: SessionsBatchDeleteResponse, 202: SessionDeletionJob}, + "patch", + "/v3/session/{sessionId}/kyb/parties/{partyUuid}/", + cast_to=SessionsUpdateKybPartyResponse, + path_params={"sessionId": session_id, "partyUuid": party_uuid}, auth="api_key", - body={ - "session_numbers": session_numbers, - "delete_all": delete_all, - "retain_face_embeddings": retain_face_embeddings, - "face_retention_days": face_retention_days, - "face_retention_deadline": face_retention_deadline, - "deletion_instruction": deletion_instruction, - "instruction_id": instruction_id, - "filter_status": filter_status, - "filter_vendor_data": filter_vendor_data, - "filter_search": filter_search, - "filter_workflow_id": filter_workflow_id, - "filter_date_from": filter_date_from, - "filter_date_to": filter_date_to, - "filter_country": filter_country, - "filter_document_type": filter_document_type, - "filter_document_name": filter_document_name, - "filter_region": filter_region, - "filter_didit_internal_id": filter_didit_internal_id, - "filter_session_type": filter_session_type, - "filter_api_service": filter_api_service, - "filter_screened_full_name": filter_screened_full_name, - "filter_warning": filter_warning, - "filter_status_initialized_as_in_review": filter_status_initialized_as_in_review, - "filter_is_kyc_to_be_reviewed": filter_is_kyc_to_be_reviewed, - "filter_euuid": filter_euuid, - "filter_organization_name": filter_organization_name, - }, + body={"is_skipped": is_skipped}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -2993,39 +4233,36 @@ async def batch_delete( ), ) - async def retrieve_deletion_job( + async def list_networks( self, - job_id: str, + session_id: str, *, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> SessionDeletionJob: - """Get a bulk session deletion job. - - Progress of a bulk session deletion that `POST /v3/sessions/delete/` answered with `202` (more than 20 matching sessions, selected by `session_numbers` or with `delete_all`). Poll every few seconds while `status` is `PENDING` or `PROCESSING`; stop when it is `COMPLETED` or `FAILED`. - - The job reports how many sessions ended in each outcome and how many it has processed, never which sessions it deleted. A `FAILED` job carries the reason in `error`; the sessions it had not reached are still in place, so repeat the deletion request to delete them. + ) -> EntityNetworkMembershipList: + """List networks for a session. - **Authentication:** API key in the `x-api-key` header. A job is only visible to the application that created it; any other `job_id` returns `404`. Missing or invalid credentials return `403`; this API never returns `401`. + List the networks the session's vendor user belongs to. Resolves through the session's vendor_data-linked user. - ``GET /v3/sessions/delete/{job_id}/`` + ``GET /v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/`` Args: - job_id: The `job_id` returned with the `202` from `POST /v3/sessions/delete/`. + session_id: Session UUID. 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( - "SessionDeletionJob", + "EntityNetworkMembershipList", await self._client.request( "get", - "/v3/sessions/delete/{job_id}/", - cast_to=SessionDeletionJob, - path_params={"job_id": job_id}, + "/v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/", + cast_to=EntityNetworkMembershipList, + path_params={"session_id": session_id}, + scope="application", auth="api_key", extra_headers=extra_headers, extra_query=extra_query, @@ -3034,106 +4271,53 @@ async def retrieve_deletion_job( ), ) - async def update_data( + async def preview_resubmission( self, session_id: str, *, - document_type: Literal[ - "P", "DL", "ID", "RP", "SSC", "HIC", "WP", "TC", "VISA", "PSC", "BC", "OTHER" - ] - | str - | None - | NotGiven = NOT_GIVEN, - document_subtype: str | None | NotGiven = NOT_GIVEN, - document_number: str | None | NotGiven = NOT_GIVEN, - personal_number: str | None | NotGiven = NOT_GIVEN, - date_of_birth: str | _dt.date | None | NotGiven = NOT_GIVEN, - date_of_issue: str | _dt.date | None | NotGiven = NOT_GIVEN, - expiration_date: str | _dt.date | None | NotGiven = NOT_GIVEN, - issuing_state: str | None | NotGiven = NOT_GIVEN, - first_name: str | None | NotGiven = NOT_GIVEN, - last_name: str | None | NotGiven = NOT_GIVEN, - gender: Literal["M", "F", "U"] | str | None | NotGiven = NOT_GIVEN, - address: str | None | NotGiven = NOT_GIVEN, - place_of_birth: str | None | NotGiven = NOT_GIVEN, - nationality: str | None | NotGiven = NOT_GIVEN, - marital_status: Literal["SINGLE", "MARRIED", "DIVORCED", "WIDOWED", "UNKNOWN"] - | str + nodes_to_resubmit: Sequence[SessionsPreviewResubmissionParamsNodesToResubmit] | NotGiven = NOT_GIVEN, - extra_fields: Mapping[str, object] | None | NotGiven = NOT_GIVEN, - parsed_address: SessionsUpdateDataParamsParsedAddress | None | NotGiven = NOT_GIVEN, - node_id: str | NotGiven = NOT_GIVEN, + email_address: str | NotGiven = NOT_GIVEN, + email_language: 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, - ) -> SessionsUpdateDataResponse: - """Update KYC data extracted from the ID document on a verification session. - - Correct the identity fields that were extracted (OCR / NFC) from the user's ID document - misread names, dates, document numbers, and so on - after the verification has finished. Typical callers are a compliance analyst working from your own back office, or an automated reconciliation job. Every field in the body is optional: only the keys you send are written, everything else is left untouched (`PATCH` semantics). + ) -> SessionsPreviewResubmissionResponse: + """Preview a resubmission email. - The session must belong to your application and be in `Approved`, `Declined`, `In Review`, or `Kyc Expired` status. Sessions in any other state (e.g. still `In Progress`) return `404` with `"No Session matches the given query."` - distinct from the `"Not found."` returned for an unknown or deleted `sessionId`. The session must also carry an ID-verification (KYC) record: sessions whose workflow never ran an ID-verification step return `404` (`"The session does not have a KYC."`). For graph workflows with multiple ID-verification steps, target a specific step with `node_id` (query parameter or body field); when omitted, the most recent KYC record is patched. + Render the email that would accompany a KYC or KYB resubmission without changing the session, resetting checks, extending its expiry, running checks or sending mail. Requires the `write:sessions` privilege (a scoped API key needs write access to decisions) and a session in `Approved`, `Declined`, `In Review`, `Kyc Expired` or `Abandoned` status. The server validates the selected workflow steps and renders its fixed translated template with the applicable verified white-label sender and branding. The request cannot set a subject, message body or action URL. - Two derived fields are recomputed on every call: `full_name` (from `first_name` + `last_name`) and `issuing_state_name` (from `issuing_state`). If the free-text `address` changes, the server may also re-geocode it and refresh `parsed_address` (skipped for sandbox sessions). `extra_fields` and `parsed_address` are merged key-by-key rather than replaced - see the per-field descriptions for the `null`-to-delete semantics. + `email_address` is optional. Without it, the email goes to the person's own address: the one they verified in an email verification step of the flow, else the one given in `contact_details` when the session was created. An address you pass wins (`recipient_source: request`). When no address is known and you pass none, `recipient` and `preview_token` are empty strings and no email can be sent. - Submitting at least one valid field fires the `data.updated` [webhook](/integration/webhooks) (trigger `manual_review`) - even when the submitted values equal the stored ones. When values actually change, a `KYC_DATA_UPDATED` activity entry recording the changed fields with previous and new values is appended to the session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and the console activity timeline. The session's status and decision are **not** re-evaluated - use [Update Status](#patch-/v3/session/-sessionId-/update-status/) to change the outcome. An empty JSON body (`{}`) is accepted and simply returns the current KYC data without firing the webhook. + The response includes the recipient and where it comes from, the sender, subject, HTML, language, resolved steps, whether confirming sends the email (`will_be_sent`, `not_sent_reason`) and a signed `preview_token`. `requires_user_action` is `false` when every selected step runs without the person: the resubmission then finishes on its own and no email goes out (`not_sent_reason: no_user_action`). - Accepts an API key or a console user token; either way the credential needs the `write:sessions` permission. Authentication and permission failures both return `403` - this API never responds `401`. Note that the session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing credentials. This endpoint has a dedicated rate limit of 10 requests per minute per API key (invalid requests count too); the shared write budget of 300 requests per minute also applies. + This preview does not reserve session state or authorize delivery. After reviewing it, call [Update Session Status](/sessions-api/update-status) with `new_status: Resubmitted`, the same `nodes_to_resubmit` and `email_language` you previewed, `send_email: true`, `email_address` set to `recipient` and `email_preview_token` set to `preview_token`. The receipt expires after 15 minutes. When a receipt is supplied, changed inputs, message content, sender or session state return `409` before any mutation or send. Existing integrations may omit the receipt. Regenerate the preview after a conflict. Treat the response as sensitive verification content; responses use `Cache-Control: no-store`. Render HTML in a sandboxed frame, never directly in your application DOM. - ``PATCH /v3/session/{sessionId}/update-data/`` + ``POST /v3/session/{sessionId}/resubmission-preview/`` Args: - session_id: UUID of the User Verification (KYC) session whose extracted document data you are correcting. Business (KYB) session IDs are not valid here - for company data use [Update KYB Company Data](#patch-/v3/session/-sessionId-/kyb/-companyUuid-/update-data/). - document_type: Document type code. Accepts the short codes listed in the enum, plus six long-form aliases normalized server-side before validation: `Passport` → `P`, `Identity Card` → `ID`, `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`. Any other value (including `PASSPORT` in caps) returns `400`. - document_subtype: Document subtype from the document registry, including the region prefix when the registry distinguishes regional variants. - document_number: Document number as printed on the ID. - personal_number: Personal / national identification number where the document carries one (e.g. Spanish DNI on a passport). - date_of_birth: Date of birth in `YYYY-MM-DD`. Any other format returns `400`. - date_of_issue: Issue date of the document in `YYYY-MM-DD`. - expiration_date: Expiration date of the document in `YYYY-MM-DD`. - issuing_state: Issuing country as an ISO 3166-1 alpha-3 code. Case-insensitive (`esp` is stored as `ESP`); the human-readable `issuing_state_name` shown in [Get Decision](#get-/v3/session/-sessionId-/decision/) is recomputed from this value. Invalid codes return `400`. - first_name: Given name(s). The stored `full_name` is recomputed as `first_name + ' ' + last_name` on every call to this endpoint. - last_name: Family name(s). Also feeds the recomputed `full_name`. - gender: Sex as printed on the document: `M` (male), `F` (female), or `U` (unknown). Any other value - including `X` - returns `400`. - address: Free-text address as printed on the document. When this value changes (non-sandbox sessions only) and the structured address is still missing or incomplete, the server re-geocodes it synchronously before responding - the 200 body already reflects the refreshed `parsed_address`. The re-geocode also requires `issuing_state` to be present on the KYC record. - place_of_birth: Place of birth as printed on the document. - nationality: Nationality as printed on the document. Free text up to 32 characters - typically an ISO 3166-1 alpha-3 code (e.g. `ESP`), but not validated as one. - marital_status: Marital status where the document carries it. Any other value returns `400`. - extra_fields: Per-key overrides for document-specific extra fields (e.g. `blood_group`, `dl_categories`, `mrz_string`). Keys are merged into the existing override map: send a key with a value to set it, or with `null` / `""` to remove that key from the merged view. Send the whole field as `null` to clear all previously applied overrides. Must be a JSON object, otherwise `400`. The response always returns the merged view (OCR-extracted values with your overrides applied). - parsed_address: Structured address. Only these nested keys are accepted: `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` - any other key returns `400`. Per-key semantics: a value sets the key, `null` removes it. `formatted_address` is recomputed server-side by joining `street_1`, `street_2`, `city`, `region`, `postal_code`, and `country` and is returned in the response - you cannot set it directly. - node_id: Workflow graph node whose KYC record to patch, for graph workflows with multiple ID-verification steps (also accepted as a `node_id` body field). When omitted, the most recent KYC record on the session is patched. If no KYC exists for the given node, the call returns `404` (`"The session does not have a KYC for node ''."`). + session_id: UUID of the verification session to update. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. + nodes_to_resubmit: Steps to preview, using the same validation, selection and workflow ordering as a resubmission. Omit to auto-select recorded attempts needing resubmission. + email_address: Optional. Send the email to this address instead of the person's own. Without it, the recipient is the address the person verified in the flow, else the one given in `contact_details`. No email is sent by this call. + email_language: Language for the notification email. Accepts any string at schema level; unsupported codes silently fall back to English (`en`). 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( - "SessionsUpdateDataResponse", + "SessionsPreviewResubmissionResponse", await self._client.request( - "patch", - "/v3/session/{sessionId}/update-data/", - cast_to=SessionsUpdateDataResponse, + "post", + "/v3/session/{sessionId}/resubmission-preview/", + cast_to=SessionsPreviewResubmissionResponse, path_params={"sessionId": session_id}, auth="api_key", - query={"node_id": node_id}, body={ - "document_type": document_type, - "document_subtype": document_subtype, - "document_number": document_number, - "personal_number": personal_number, - "date_of_birth": date_of_birth, - "date_of_issue": date_of_issue, - "expiration_date": expiration_date, - "issuing_state": issuing_state, - "first_name": first_name, - "last_name": last_name, - "gender": gender, - "address": address, - "place_of_birth": place_of_birth, - "nationality": nationality, - "marital_status": marital_status, - "extra_fields": extra_fields, - "parsed_address": parsed_address, + "nodes_to_resubmit": nodes_to_resubmit, + "email_address": email_address, + "email_language": email_language, }, extra_headers=extra_headers, extra_query=extra_query, @@ -3142,94 +4326,45 @@ async def update_data( ), ) - async def update_feature_status( + async def update_document_ai_data( self, session_id: str, - node_id: str, + document_uuid: str, *, - new_status: Literal["Approved", "Declined", "In Review"] | str, - comment: str | NotGiven = NOT_GIVEN, - feature_type: Literal[ - "ID_VERIFICATION", - "OCR", - "OCR_BACK", - "NFC", - "LIVENESS", - "FACE", - "AGE_ESTIMATION", - "AGE_VERIFICATION", - "FACE_SEARCH", - "FACE_MATCH", - "IP_ANALYSIS", - "AML", - "PHONE", - "PHONE_VERIFICATION", - "EMAIL", - "EMAIL_VERIFICATION", - "POA", - "PROOF_OF_ADDRESS", - "DATABASE_VALIDATION", - "DATA_VALIDATION", - "QUESTIONNAIRE", - "DOCUMENT_AI", - "KYB_REGISTRY", - "KYB_DOCUMENTS", - "KYB_KEY_PEOPLE", - "BANK_VERIFICATION", - "GEOLOCATION", - ] + extracted_data: Mapping[str, object] | NotGiven = NOT_GIVEN, + status: Literal["Approved", "Declined", "In Review", "Not Finished"] | str | NotGiven = NOT_GIVEN, - defer_until_flow_finishes: bool | 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, - ) -> SessionsUpdateFeatureStatusResponse: - """Update an individual feature (step) status. - - Set the status of a single verification feature (step) within a session. Target the feature by its workflow graph `nodeId`. On non-graph workflows, whose steps have no node, use `default` and also pass `feature_type` to say which step you mean. - - Works for both User Verification (KYC) and Business Verification (KYB) sessions and every step type: ID/OCR, Liveness, Face Match, NFC, AML, Proof of Address, Phone, Email, Database Validation, Questionnaire, and the KYB registry / documents / key-people checks. This endpoint is **not** available for standalone API sessions (`session_type = API`). - - `new_status` must be one of `Approved`, `Declined`, or `In Review`, and must differ from the feature's current status. - - **When the override applies.** Without `defer_until_flow_finishes` (or with `false`) the override applies at once, as it always did; when the person is still in the flow it is recorded as `forced`. With `defer_until_flow_finishes: true` while the person is still in the flow (the session is `Not Started`, `In Progress` or `Resubmitted` and has not finished), the override is stored as `pending_until_flow_finishes` and applies when the flow finishes, after the flow reaches its own decision. On a session whose flow already ended it applies at once either way. A waiting override is cancelled instead when the person redoes its step before finishing, when a newer override on the same check replaces it, when the session leaves the flow unfinished (abandoned, expired, or decided mid-flow), or when you cancel it with `POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`. List a session's overrides with `GET /v3/session/{sessionId}/features/overrides/`. - - **Effect on the session.** A session that already has a decision keeps it: only the check changes. When the session has no decision yet and its workflow is waiting on exactly this step, applying the override completes the step: the workflow moves on, later steps run, and a status node can set the session decision and fire `status.updated`. - - **Webhooks and activity.** A `data.updated` webhook fires when the override applies (at once, or when the flow finishes), never while it waits or when it is cancelled. Every override is recorded in the session's activity as `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` or `FEATURE_OVERRIDE_CANCELLED`, with who made it; the request's entry carries your `comment`. + ) -> SessionsUpdateDocumentAiDataResponse: + """Update a Document AI document. - Authenticate with your API key (`x-api-key`) or a user authorization header carrying the `write:sessions` privilege; a scoped API key needs write access to decisions. + Correct the fields Document AI extracted from one uploaded document, set its review status, or both, on a KYC or KYB session. `extracted_data` must be a JSON object and is merged key by key: a key you send replaces the stored value (a key sent as `null` is stored as `null`) and keys you leave out keep their values. The document status feeds the Document AI result of its workflow node in the session decision; the session status itself is not recomputed. Every successful call, including one that changes nothing, sends a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) with trigger `manual_review`. A scoped API key needs `decisions: write`; see [Document AI](https://docs.didit.me/core-technology/document-ai/overview). - ``PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`` + ``PATCH /v3/document-ai/{sessionId}/documents/{documentUuid}/`` Args: - session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. - node_id: Workflow graph node ID of the feature to update (for example `feature_ocr_1`). Use the literal value `default` for non-graph (single-step) workflows where the feature has no node ID. - new_status: Target status for this feature. Must differ from the current value. - comment: Optional free-text note recorded on the session's review trail for this feature change. - feature_type: Which kind of step to target. Needed on non-graph workflows (`nodeId` = `default`), where every step shares no node; optional otherwise. An unknown value returns `400`. - defer_until_flow_finishes: While the person is still in the flow, store the override as `pending_until_flow_finishes` and apply it when the flow finishes, instead of at once. Omitted or `false`, the override applies at once. On a session whose flow already ended it applies at once either way. + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. + document_uuid: UUID of the Document AI document (`document_ai_documents[].items[].uuid` in `GET /v3/session/{sessionId}/decision/`). It must belong to the session in the path. + extracted_data: Field keys (the keys you configured for the document) and their corrected values. Must be a JSON object; merged key by key into the stored data. Leave it out rather than sending `null`, which returns `400`. + status: New review status of the document. 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( - "SessionsUpdateFeatureStatusResponse", + "SessionsUpdateDocumentAiDataResponse", await self._client.request( "patch", - "/v3/session/{sessionId}/features/{nodeId}/update-status/", - cast_to=SessionsUpdateFeatureStatusResponse, - path_params={"sessionId": session_id, "nodeId": node_id}, - auth="api_key", - body={ - "new_status": new_status, - "comment": comment, - "feature_type": feature_type, - "defer_until_flow_finishes": defer_until_flow_finishes, - }, + "/v3/document-ai/{sessionId}/documents/{documentUuid}/", + cast_to=SessionsUpdateDocumentAiDataResponse, + path_params={"sessionId": session_id, "documentUuid": document_uuid}, + auth="api_key", + body={"extracted_data": extracted_data, "status": status}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3237,53 +4372,38 @@ async def update_feature_status( ), ) - async def update_aml_hit_status( + async def regenerate_kyb_party( self, session_id: str, + party_uuid: str, *, - hit_id: str, - review_status: Literal["Unreviewed", "Confirmed Match", "False Positive", "Inconclusive"] - | str, - node_id: str | NotGiven = NOT_GIVEN, - node_id_query: 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, - ) -> SessionsUpdateAmlHitStatusResponse: - """Update an AML hit review status. - - Set the review status of a **single AML hit** (a potential sanction / PEP / watchlist / adverse-media match) returned by AML screening, without changing the overall session decision. Identify the hit by its `hit_id` (the `id` of an entry in the AML check's `hits` array - see the session decision). - - `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. Reviewer decisions are preserved across ongoing-monitoring updates, so a hit you mark `False Positive` stays that way when the provider re-screens. - - A successful call fires a `data.updated` webhook and appends an activity entry (with actor attribution) to the session's review trail. For graph workflows with multiple AML checks, pass `node_id` to target a specific check. + ) -> KYBKeyPeopleParty: + """Regenerate a Key People party's KYC session. - Authenticate with your API key (`x-api-key`) or a user authorization header - either must carry the `write:sessions` privilege. + Give a Key People party of a Business Verification (KYB) session a new individual KYC session after its previous one was deleted or expired before the person started it, so the Key People check can finish again; send no request body. It works when the party's KYC session was deleted (`kyc_session_deleted: true`) or expired before the person started it (`Expired`, never started). A session still in progress or one that ended in any other status (`Approved`, `Declined`, `In Review`, `Abandoned`, ...) returns `409` unless it was deleted. A party that never had one or a company party always returns `409`. Didit creates a new hosted KYC session with the workflow the party was verified with (its latest published version) or, when that is no longer known, the workflow your Key People settings assign to the party's role, so its link lasts that KYC workflow's session expiration time; it emails the link to the party when an email is on file, clears `is_skipped`, and recomputes the Key People check and the business session status. It then sends a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) for the business session with trigger `console_key_people_regenerate`; to exempt the party instead, use `PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/`. A scoped API key needs `decisions: write`, and without `sessions: write` it receives `kyc_session_url` as `null`. Deleted sessions qualify even if the person had already started or finished verification. Imported sessions do not qualify through expiry; they must have been deleted. - ``PATCH /v3/session/{sessionId}/update-aml-hit-status/`` + ``POST /v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/`` Args: - session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. - hit_id: The `id` of the hit in the AML check's `hits` array. - review_status: The new review status for the hit. - node_id: Optional graph node ID. Use it (here or as a query parameter) when the session has multiple AML checks. - node_id_query: Workflow graph node ID. Required only when the session has multiple AML checks (one per node); omit it for single-AML sessions. + session_id: UUID of the parent Business Verification (KYB) session. + party_uuid: UUID of the Key People party (`key_people_checks[].submitted.parties[].uuid` on the business session decision). Must belong to the session referenced by `sessionId`. 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( - "SessionsUpdateAmlHitStatusResponse", + "KYBKeyPeopleParty", await self._client.request( - "patch", - "/v3/session/{sessionId}/update-aml-hit-status/", - cast_to=SessionsUpdateAmlHitStatusResponse, - path_params={"sessionId": session_id}, + "post", + "/v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/", + cast_to=KYBKeyPeopleParty, + path_params={"sessionId": session_id, "partyUuid": party_uuid}, auth="api_key", - query={"node_id": node_id_query}, - body={"hit_id": hit_id, "review_status": review_status, "node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3291,48 +4411,44 @@ async def update_aml_hit_status( ), ) - async def bulk_update_aml_hit_status( + def list_events( self, session_id: str, *, - hit_updates: Sequence[SessionsBulkUpdateAmlHitStatusParamsHitUpdates], - node_id: str | NotGiven = NOT_GIVEN, - node_id_query: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | NotGiven = NOT_GIVEN, + ordering: 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, - ) -> SessionsBulkUpdateAmlHitStatusResponse: - """Bulk update AML hit review statuses. - - Update the review status of **multiple AML hits** in one call. Provide `hit_updates`, a list of `{ hit_id, review_status }` pairs. `review_status` is one of `Unreviewed`, `Confirmed Match`, `False Positive`, or `Inconclusive`. - - The update is all-or-nothing: if any `hit_id` is not found in the AML check, the request returns `404` and no hit is changed. A successful call fires a single `data.updated` webhook and records one activity entry covering all changes. For graph workflows with multiple AML checks, pass `node_id` to target a specific check. + ) -> AsyncPaginator[SessionEvent]: + """List session events. - Authenticate with your API key (`x-api-key`) or a user authorization header - either must carry the `write:sessions` privilege. + Read the event timeline of one verification session, newest first by `sent_at`: the screens the user saw, buttons and uploads, failed attempts, status and feature-step changes, and the workflow routing trace. Works for User Verification (KYC) and Business Verification (KYB) session IDs. Events are stored asynchronously, so a new event can take a few seconds to appear. Results are paginated with `limit` and `offset`; follow `next` until it is `null`. A scoped API key needs `sessions: read` and `decisions: read`, and without `media: read` it receives `file_url` as `null`. The routing events are described in [Retrieve session](https://docs.didit.me/sessions-api/retrieve-session). - ``PATCH /v3/session/{sessionId}/bulk-update-aml-hit-status/`` + ``GET /v3/session/{sessionId}/events/`` Args: - session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. - hit_updates: Non-empty list of hit updates. - node_id: Optional graph node ID. Use it (here or as a query parameter) when the session has multiple AML checks. - node_id_query: Workflow graph node ID. Required only when the session has multiple AML checks (one per node); omit it for single-AML sessions. + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. + limit: Maximum number of events per page. Defaults to 50. A value below 1 or a non-numeric value falls back to 50; a value above 1,000,000 returns `400`. + offset: Number of results to skip before the first returned one. Defaults to 0; a negative or non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and `previous` URLs. + ordering: Optional sort override. The default order is `-sent_at`. Pass a result field name (for example `sent_at`, `created_at`, `event_type`, `feature_step` or `step`) to sort ascending, prefix it with `-` to sort descending, and separate several fields with commas. Unknown fields are ignored. 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( - "SessionsBulkUpdateAmlHitStatusResponse", - await self._client.request( - "patch", - "/v3/session/{sessionId}/bulk-update-aml-hit-status/", - cast_to=SessionsBulkUpdateAmlHitStatusResponse, + "AsyncPaginator[SessionEvent]", + self._client.request_page( + "get", + "/v3/session/{sessionId}/events/", + cast_to=SessionsListEventsResponse, + item_type=SessionEvent, path_params={"sessionId": session_id}, auth="api_key", - query={"node_id": node_id_query}, - body={"hit_updates": hit_updates, "node_id": node_id}, + query={"limit": limit, "offset": offset, "ordering": ordering}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3340,87 +4456,53 @@ async def bulk_update_aml_hit_status( ), ) - async def update_poa_data( + def list_aml_screening_history( self, session_id: str, *, - issuing_state: str | None | NotGiven = NOT_GIVEN, - document_type: Literal[ - "UTILITY_BILL", - "BANK_STATEMENT", - "GOVERNMENT_ISSUED_DOCUMENT", - "OTHER_POA_DOCUMENT", - "UNKNOWN", - ] - | str - | NotGiven = NOT_GIVEN, - document_language: str | None | NotGiven = NOT_GIVEN, - issuer: str | None | NotGiven = NOT_GIVEN, - issue_date: str | _dt.date | None | NotGiven = NOT_GIVEN, - poa_address: str | None | NotGiven = NOT_GIVEN, - name_on_document: str | None | NotGiven = NOT_GIVEN, - extra_fields: Mapping[str, object] | None | NotGiven = NOT_GIVEN, - poa_parsed_address: SessionsUpdatePoaDataParamsPoaParsedAddress - | None - | NotGiven = NOT_GIVEN, node_id: str | NotGiven = NOT_GIVEN, + month: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | NotGiven = NOT_GIVEN, + ordering: 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, - ) -> SessionsUpdatePoaDataResponse: - """Update Proof of Address data extracted from the POA document on a verification session. - - Correct the fields extracted from the user's Proof of Address document - utility bill, bank statement, or other address evidence - after the verification has finished: issuer, dates, the printed name, the address itself, and banking details. Every field in the body is optional: only the keys you send are written, everything else is left untouched (`PATCH` semantics). - - The session must belong to your application and be in `Approved`, `Declined`, `In Review`, or `Kyc Expired` status. Sessions in any other state (e.g. still `In Progress`) return `404` with `"No Session matches the given query."` - distinct from the `"Not found."` returned for an unknown or deleted `sessionId`. The session must also carry a POA record: sessions whose workflow never ran a Proof of Address step return `404` (`"The session does not have a POA."`). For graph workflows with multiple POA steps, target a specific step with `node_id` (query parameter or body field); when omitted, the most recent POA record is patched. - - `extra_fields` is merged key-by-key: nine known keys (`bank_iban`, `additional_names`, …) write through to dedicated POA columns, any other key is kept as a custom extra, and `null` / `""` deletes a key. `poa_parsed_address` accepts only the seven documented keys and recomputes `formatted_address` / `poa_formatted_address` after every edit. If the free-text `poa_address` changes, the server may also re-geocode it and refresh the structured address (skipped for sandbox sessions). - - Unlike the KYC variant of this endpoint, the `data.updated` [webhook](/integration/webhooks) (trigger `manual_review`) fires only when at least one stored value **actually changed** - re-sending identical values is a silent no-op. When values change, a `POA_DATA_UPDATED` activity entry recording the changed fields with previous and new values is appended to the session's `reviews`, visible in [Get Decision](#get-/v3/session/-sessionId-/decision/) and the console activity timeline. The session's status and decision are **not** re-evaluated - use [Update Status](#patch-/v3/session/-sessionId-/update-status/) to change the outcome. - - Accepts an API key or a console user token; either way the credential needs the `write:sessions` permission. Authentication and permission failures both return `403` - this API never responds `401`. Note that the session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing credentials. This endpoint has a dedicated rate limit of 10 requests per minute per API key (invalid requests count too); the shared write budget of 300 requests per minute also applies. + ) -> AsyncPaginator[AMLScreeningRun]: + """List AML screening history. - An empty JSON body `{}` is a no-op: it returns `200` echoing the current POA record without firing the webhook (`has_changes` stays false). + List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`, including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves, so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed (the first screening is part of the session decision) and runs from before this history existed are not reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and capped at 100 above that, so follow `next` until it is `null`. Pass `month` to read one calendar month at a time. A scoped API key needs `decisions: read`; see [Continuous AML monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening). - ``PATCH /v3/session/{sessionId}/update-poa-data/`` + ``GET /v3/session/{sessionId}/aml-screening-history/`` Args: - session_id: UUID of the User Verification (KYC) session whose attached POA record you are correcting. - issuing_state: Country that issued the POA document, ISO 3166-1 alpha-3. Case-insensitive (normalized to uppercase); invalid codes return `400`. - document_type: POA document category. Values are uppercase - lowercase variants like `utility_bill` return `400`. - document_language: Language of the document, typically an ISO 639-1 code (e.g. `es`). Free text - not validated as a language code. - issuer: Organization that issued the document (utility company, bank, government agency). - issue_date: Issue date of the POA document in `YYYY-MM-DD`. Any other format returns `400`. - poa_address: Free-text address as printed on the document. When this value changes (non-sandbox sessions only) and the structured address is still missing or incomplete, the server re-geocodes it in the background of the same request and may overwrite `poa_parsed_address` / `poa_formatted_address` with the geocoder result. The re-geocode also requires `issuing_state` to be present on the POA record. - name_on_document: Recipient name as printed on the document. - extra_fields: Document-specific extras, merged key-by-key. Nine keys map to dedicated POA columns: `bank_account_number`, `bank_iban`, `bank_sort_code`, `bank_routing_number`, `bank_swift_bic`, `bank_branch_name`, `bank_branch_address`, `document_phone_number`, and `additional_names` (must be a list of strings or `null`, otherwise `400`). Any other key is stored as a custom extra field. Per-key semantics: a value sets the key; `null` or `""` deletes it. Must be a JSON object, otherwise `400`. - poa_parsed_address: Structured address. Only these nested keys are accepted: `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` - any other key returns `400`. Per-key semantics: a value sets the key, `null` removes it. `formatted_address` (and the top-level `poa_formatted_address`) is recomputed server-side by joining `street_1`, `street_2`, `city`, `region`, `postal_code`, and `country` - you cannot set it directly. - node_id: Workflow graph node whose POA record to patch, for graph workflows with multiple Proof of Address steps (also accepted as a `node_id` body field). When omitted, the most recent POA record on the session is patched. If no POA exists for the given node, the call returns `404` (`"The session does not have a POA for node ''."`). + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. + node_id: Workflow graph node ID of the AML check. Needed only when the session ran more than one AML step; without it the most recent AML check is used. An unknown node returns `404`. + month: A UTC calendar month as `YYYY-MM`. Only screenings completed in that month are returned; without it every month is returned. A malformed month returns `400`. + limit: Maximum number of screening runs per page. Defaults to 50. A value below 1 or a non-numeric value falls back to 50; a value above 1,000,000 returns `400`. + offset: Number of results to skip before the first returned one. Defaults to 0; a negative or non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and `previous` URLs. + ordering: Optional sort override. The default order is `-completed_at`. Pass a result field name (for example `completed_at`, `started_at`, `outcome` or `score`) to sort ascending, prefix it with `-` to sort descending, and separate several fields with commas. Unknown fields are ignored. 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( - "SessionsUpdatePoaDataResponse", - await self._client.request( - "patch", - "/v3/session/{sessionId}/update-poa-data/", - cast_to=SessionsUpdatePoaDataResponse, + "AsyncPaginator[AMLScreeningRun]", + self._client.request_page( + "get", + "/v3/session/{sessionId}/aml-screening-history/", + cast_to=SessionsListAmlScreeningHistoryResponse, + item_type=AMLScreeningRun, path_params={"sessionId": session_id}, auth="api_key", - query={"node_id": node_id}, - body={ - "issuing_state": issuing_state, - "document_type": document_type, - "document_language": document_language, - "issuer": issuer, - "issue_date": issue_date, - "poa_address": poa_address, - "name_on_document": name_on_document, - "extra_fields": extra_fields, - "poa_parsed_address": poa_parsed_address, + query={ + "node_id": node_id, + "month": month, + "limit": limit, + "offset": offset, + "ordering": ordering, }, extra_headers=extra_headers, extra_query=extra_query, @@ -3429,138 +4511,42 @@ async def update_poa_data( ), ) - async def update_kyb_company_data( + async def export_aml_screening_history( self, session_id: str, - company_uuid: str, *, - company_name: str | NotGiven = NOT_GIVEN, - registration_number: str | NotGiven = NOT_GIVEN, - country_code: str | NotGiven = NOT_GIVEN, - region: str | None | NotGiven = NOT_GIVEN, - incorporation_date: str | _dt.date | NotGiven = NOT_GIVEN, - registration_date: str | _dt.date | None | NotGiven = NOT_GIVEN, - dissolution_date: str | _dt.date | None | NotGiven = NOT_GIVEN, - tax_number: str | NotGiven = NOT_GIVEN, - legal_address: str | NotGiven = NOT_GIVEN, - company_type: str | NotGiven = NOT_GIVEN, - registry_status: Literal[ - "active", - "dissolved", - "deregistered", - "see full details", - "authorised", - "appointed representative", - "unauthorised", - "inactive", - "no longer authorised", - "closed", - "struck off", - ] - | str - | None - | NotGiven = NOT_GIVEN, - verification_status: Literal["verified", "failed", "unknown"] - | str - | None - | NotGiven = NOT_GIVEN, - alternative_names: str | NotGiven = NOT_GIVEN, - nature_of_business: str | NotGiven = NOT_GIVEN, - registered_capital: str | NotGiven = NOT_GIVEN, - registered_capital_amount: float | None | NotGiven = NOT_GIVEN, - registered_capital_currency: str | None | NotGiven = NOT_GIVEN, - website: str | NotGiven = NOT_GIVEN, - email: str | NotGiven = NOT_GIVEN, - phone: str | NotGiven = NOT_GIVEN, - legal_entity_identifier: str | NotGiven = NOT_GIVEN, - location_of_registration: str | NotGiven = NOT_GIVEN, - vat_number: str | NotGiven = NOT_GIVEN, - control_scheme: str | NotGiven = NOT_GIVEN, + node_id: str | NotGiven = NOT_GIVEN, + month: 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, - ) -> SessionsUpdateKybCompanyDataResponse: - """Update registry-extracted company data on a Business Verification (KYB) session. - - Correct the registry-extracted company data on a Business Verification (KYB) session - company name, registration number, addresses, status, contact details - identified by `companyUuid`. Typical callers are a compliance analyst fixing a registry misread, or your back office syncing corrected company data. Every field in the body is optional (`PATCH` semantics); an empty JSON body (`{}`) is a no-op that simply echoes the current company record. - - Edits are written in two places at once: fields with a canonical company column (name, registration number, country, incorporation date, tax number, type, statuses, capital fields (`registered_capital`, `registered_capital_amount`, `registered_capital_currency`), alternative names, nature of business, website, email, phone, LEI, location, and `legal_address` → `registered_address`) update that column, and **every** submitted key is also merged into the `registry_data` snapshot (dates as ISO strings) so the "extracted from registry" view reflects the correction. Fields without a column - `region`, `registration_date`, `dissolution_date`, `control_scheme` - land in `registry_data` only. `user_provided_data` (what the end user confirmed in the hosted flow) is never touched, and `last_console_edit_at` is stamped on every non-empty PATCH. - - Unlike the KYC/POA update endpoints, there is **no session-status gate**: the company can be edited at any point in the business session's lifecycle. The company must belong to the session in the path (`404` with `"KYB company does not belong to the given session."` otherwise) and to your application. Every non-empty PATCH fires the `data.updated` [webhook](/integration/webhooks) on the business session (trigger `console_registry_edit`) - even when the submitted values equal the stored ones. The session's status and decision are **not** re-evaluated, and no review/audit entry is recorded. - - Accepts an API key or a console user token; either way the credential needs the `write:businesses` permission. Authentication and permission failures both return `403` - this API never responds `401`. Note that the session lookup runs before credential checks, so an unknown `sessionId` returns `404` even with missing credentials. The shared write budget of 300 requests per minute per API key applies. - - For User Verification sessions, the KYC counterpart is `PATCH /v3/session/{sessionId}/update-data/`; to change the session decision itself use `PATCH /v3/session/{sessionId}/update-status/`. + ) -> bytes: + """Export AML screening history as CSV. - ``PATCH /v3/session/{sessionId}/kyb/{companyUuid}/update-data/`` + Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated, and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Pass `month` to export one calendar month. Errors are returned as JSON, not CSV. A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media: read` gets `403`. - Args: - session_id: UUID of the parent Business Verification (KYB) session. - company_uuid: UUID of the company record to update (`registry_checks[].company.uuid` on the business session decision). Must belong to the session referenced by `sessionId`. - company_name: Legal name of the company. Written to the canonical column and the registry snapshot. - registration_number: Official registration number with the company registry. - country_code: Country of incorporation, ISO 3166-1 alpha-2. Case-insensitive (`us` is stored as `US`). Alpha-3 codes fail the 2-character limit with `400`. - region: Subdivision / region tag where the registry has one (e.g. US state). Stored in the registry snapshot only - it has no canonical column. - incorporation_date: Incorporation date in `YYYY-MM-DD`. Optional like every other field - the `PATCH` is partial. Any other date format returns `400`. - registration_date: Registration date where the registry distinguishes it from incorporation. Stored in the registry snapshot only. - dissolution_date: Dissolution date for companies that are no longer active. Stored in the registry snapshot only. - tax_number: Tax identification number. - legal_address: Legal / registered address. Aliased server-side to the canonical `registered_address` column - the response returns it under `registered_address`, while the registry snapshot keeps the `legal_address` key you sent. - company_type: Legal entity type (e.g. `Limited Liability Company`, `PLC`, `GmbH`). - registry_status: Registry-reported company status. Lowercase, some values contain spaces (e.g. `struck off`, `no longer authorised`). Any other value returns `400`. - verification_status: Outcome of the registry verification. Any other value returns `400`. - alternative_names: Trade names, former legal names, DBA names (free text). - nature_of_business: Short description of the company's activity. - registered_capital: Human-readable registered capital (e.g. `USD 50000`). Use `registered_capital_amount` + `registered_capital_currency` for structured values, or this field for free-form text. - registered_capital_amount: Numeric registered-capital amount (up to 20 digits, 2 decimal places). Sets the `registered_capital_amount` column and is mirrored into `registry_data` as a decimal string; the response echoes it as a decimal string (e.g. `"1500000.50"`). - registered_capital_currency: ISO 4217 currency code for `registered_capital_amount`. Case-insensitive (`usd` is stored as `USD`); values that are not exactly 3 letters return `400` with the ISO 4217 message. Sets the canonical `registered_capital_currency` column and is mirrored into `registry_data`. - website: Company website. Bare domains are accepted and normalized with an `https://` prefix (`docsprobe.example.com` is stored as `https://docsprobe.example.com`); values that still fail URL validation return `400`. - email: Contact email on file with the registry. - phone: Contact phone. Must match `+`, digits, spaces, dashes, dots, or parentheses, with 7-15 digits total - otherwise `400`. - legal_entity_identifier: LEI, where the company has one. - location_of_registration: City / subdivision of the registry of record. - vat_number: EU VAT number. Merged into the `registry_data` snapshot only - editing it here does not re-run VAT and tax ID validation, so `vat_validation_status` and the other `vat_*` result fields are unchanged. - control_scheme: Control / governance scheme when the registry exposes it. Stored in the registry snapshot only. + ``GET /v3/session/{sessionId}/aml-screening-history/export/`` + + Args: + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. + node_id: Workflow graph node ID of the AML check. Needed only when the session ran more than one AML step; without it the most recent AML check is used. An unknown node returns `404`. + month: A UTC calendar month as `YYYY-MM`. Only screenings completed in that month are returned; without it every month is returned. A malformed month returns `400`. 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( - "SessionsUpdateKybCompanyDataResponse", + "bytes", await self._client.request( - "patch", - "/v3/session/{sessionId}/kyb/{companyUuid}/update-data/", - cast_to=SessionsUpdateKybCompanyDataResponse, - path_params={"sessionId": session_id, "companyUuid": company_uuid}, + "get", + "/v3/session/{sessionId}/aml-screening-history/export/", + cast_to=bytes, + path_params={"sessionId": session_id}, auth="api_key", - body={ - "company_name": company_name, - "registration_number": registration_number, - "country_code": country_code, - "region": region, - "incorporation_date": incorporation_date, - "registration_date": registration_date, - "dissolution_date": dissolution_date, - "tax_number": tax_number, - "legal_address": legal_address, - "company_type": company_type, - "registry_status": registry_status, - "verification_status": verification_status, - "alternative_names": alternative_names, - "nature_of_business": nature_of_business, - "registered_capital": registered_capital, - "registered_capital_amount": registered_capital_amount, - "registered_capital_currency": registered_capital_currency, - "website": website, - "email": email, - "phone": phone, - "legal_entity_identifier": legal_entity_identifier, - "location_of_registration": location_of_registration, - "vat_number": vat_number, - "control_scheme": control_scheme, - }, + query={"node_id": node_id, "month": month}, + accept="text/csv, application/json", extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3568,49 +4554,45 @@ async def update_kyb_company_data( ), ) - async def update_kyb_party( + async def add_images( self, session_id: str, - party_uuid: str, *, - is_skipped: bool, + file: FileTypes, + model_type: Literal["kyc", "poa"] | str, + file_password: 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, - ) -> SessionsUpdateKybPartyResponse: - """Skip (or re-require) a Key People party on a Business Verification (KYB) session. - - Exempt a Key People party from verification, or put it back in scope. This is the operator escape hatch for a party that can never finish its own check - most often because the individual KYC session handed to a UBO or director was deleted, which freezes that child's status and leaves the KYB parked in `Awaiting User` with nothing left that could move it. - - Setting `is_skipped: true` drops the party out of the Key People aggregation and immediately recomputes the `KYBKeyPeopleCheck` and the parent session status, so the business session can settle and then be approved or declined. Sending `is_skipped: false` puts the party back in scope and the check goes back to waiting on it. - - Unlike the applicant-facing skip in the hosted Key People screen, this endpoint is **not** gated by the role's `allow_skip` setting - that flag limits what the applicant may decide, not what your analyst may override. `requires_verification` is deliberately left untouched, so an overridden party reads as `requires_verification: true` **and** `is_skipped: true` and the record still shows what the rules asked for. - - The party must belong to the session in the path (`404` with `"Party does not belong to the given session."` otherwise) and to your application. A PATCH that actually changes the flag fires the `data.updated` [webhook](/integration/webhooks) on the business session with trigger `console_key_people_skip`; a PATCH that sets the flag to its current value is a no-op that echoes the party back. + ) -> SessionsAddImagesResponse: + """Add an image to a session. - Accepts an API key or a console user token; either way the credential needs the `write:businesses` permission. + Attach one extra image or PDF to the ID verification (`model_type=kyc`) or Proof of Address (`model_type=poa`) result of a finished User Verification (KYC) session, for example evidence collected outside the flow. The session must be `Approved`, `Declined`, `In Review` or `Kyc Expired` and carry the result named by `model_type`; Business Verification (KYB) sessions are not supported. Each call appends one file (to the most recent result when the step ran more than once), keeps the existing files and records a `FILE_ADDED` entry in the session activity log; the upload sends no webhook and does not change the session status. The file is compressed on upload and is returned in `extra_files` of the session decision. This endpoint is limited to 10 requests per minute per API key. A scoped API key needs `sessions: write`, and without `media: read` it receives the `extra_files` links as `null`. - ``PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/`` + ``PATCH /v3/session/{sessionId}/add-images/`` Args: - session_id: UUID of the parent Business Verification (KYB) session. - party_uuid: UUID of the Key People party to update (`key_people_checks[].submitted.parties[].uuid` on the business session decision). Must belong to the session referenced by `sessionId`. - is_skipped: `true` exempts the party from verification so the Key People check can settle without it; `false` puts it back in scope. + session_id: UUID of the User Verification (KYC) session to add the file to (the `session_id` returned by `POST /v3/session/`). A Business Verification (KYB) session ID returns `404`. + file: The image or PDF. Allowed extensions: `jpg`, `jpeg`, `png`, `webp`, `tiff`, `pdf`. At most 15 MB as uploaded; the file is then compressed and rejected with `400` if it is still larger than 2 MB (2,097,152 bytes). Empty files are rejected. + model_type: `kyc` adds the file to the ID verification result, `poa` to the Proof of Address result. + file_password: Password of an encrypted PDF. Without it, or with a wrong one, an encrypted PDF returns `400`. 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( - "SessionsUpdateKybPartyResponse", + "SessionsAddImagesResponse", await self._client.request( "patch", - "/v3/session/{sessionId}/kyb/parties/{partyUuid}/", - cast_to=SessionsUpdateKybPartyResponse, - path_params={"sessionId": session_id, "partyUuid": party_uuid}, + "/v3/session/{sessionId}/add-images/", + cast_to=SessionsAddImagesResponse, + path_params={"sessionId": session_id}, auth="api_key", - body={"is_skipped": is_skipped}, + body={"file": file, "model_type": model_type, "file_password": file_password}, + multipart=True, + file_fields=("file",), extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3618,37 +4600,45 @@ async def update_kyb_party( ), ) - async def list_networks( + async def update_aml_status( self, session_id: str, *, + status: Literal["Not Finished", "Approved", "Declined", "In Review", "Resub Requested"] + | str, + node_id: str | NotGiven = NOT_GIVEN, + node_id_query: 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, - ) -> EntityNetworkMembershipList: - """List networks for a session. + ) -> SessionsUpdateAmlStatusResponse: + """Update an AML check status. - List the networks the session's vendor user belongs to. Resolves through the session's vendor_data-linked user. + Set the status of a session's AML screening check as a whole (the `status` of an `aml_screenings[]` entry in the session decision), for example `Approved` after your team cleared every hit. Works for KYC and KYB session IDs; pass `node_id` (query parameter or body field) when the session ran more than one AML step, otherwise the most recent AML check is updated. When the status actually changes, an `AML_STATUS_UPDATED` activity entry is recorded and a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) is sent; sending the current status returns `200` and changes nothing. The session status is not recomputed: use `PATCH /v3/session/{sessionId}/update-status/` for the session decision and `PATCH /v3/session/{sessionId}/update-aml-hit-status/` for single hits. A scoped API key needs `decisions: write`. - ``GET /v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/`` + ``PATCH /v3/session/{sessionId}/update-aml-status/`` Args: - session_id: Session UUID. + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. + status: New status of the AML check. + node_id: Workflow graph node ID of the AML check, as an alternative to the query parameter. + node_id_query: Workflow graph node ID of the AML check to update. Needed only when the session ran more than one AML step. Takes precedence over `node_id` in the body. 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( - "EntityNetworkMembershipList", + "SessionsUpdateAmlStatusResponse", await self._client.request( - "get", - "/v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/", - cast_to=EntityNetworkMembershipList, - path_params={"session_id": session_id}, - scope="application", + "patch", + "/v3/session/{sessionId}/update-aml-status/", + cast_to=SessionsUpdateAmlStatusResponse, + path_params={"sessionId": session_id}, auth="api_key", + query={"node_id": node_id_query}, + body={"status": status, "node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3656,53 +4646,63 @@ async def list_networks( ), ) - async def preview_resubmission( + async def simulate( self, session_id: str, *, - nodes_to_resubmit: Sequence[SessionsPreviewResubmissionParamsNodesToResubmit] + new_status: Literal["Approved", "Declined", "In Review", "Expired", "Abandoned"] + | str | NotGiven = NOT_GIVEN, - email_address: str | NotGiven = NOT_GIVEN, - email_language: str | NotGiven = NOT_GIVEN, + comment: str | NotGiven = NOT_GIVEN, + scenario: str | NotGiven = NOT_GIVEN, + risk: str | NotGiven = NOT_GIVEN, + node_id: str | NotGiven = NOT_GIVEN, + send_webhooks: bool | 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, - ) -> SessionsPreviewResubmissionResponse: - """Preview a resubmission email. + ) -> SandboxSimulateResponse: + """Simulate a sandbox session's status. - Render the email that would accompany a KYC or KYB resubmission without changing the session, resetting checks, extending its expiry, running checks or sending mail. Requires the `write:sessions` privilege (a scoped API key needs write access to decisions) and a session in `Approved`, `Declined`, `In Review`, `Kyc Expired` or `Abandoned` status. The server validates the selected workflow steps and renders its fixed translated template with the applicable verified white-label sender and branding. The request cannot set a subject, message body or action URL. + Force a terminal status on a sandbox session after the fact, from your backend, without running the flow. Sandbox applications only: a live session returns `404`. Works for User Verification (KYC) and Business Verification (KYB) sessions. - `email_address` is optional. Without it, the email goes to the person's own address: the one they verified in an email verification step of the flow, else the one given in `contact_details` when the session was created. An address you pass wins (`recipient_source: request`). When no address is known and you pass none, `recipient` and `preview_token` are empty strings and no email can be sent. + Set `new_status`, or let `scenario` or `risk` supply it. `risk` (or the first risk the scenario's magic values carry) adds that warning to the session. The change is recorded in the session's activity. - The response includes the recipient and where it comes from, the sender, subject, HTML, language, resolved steps, whether confirming sends the email (`will_be_sent`, `not_sent_reason`) and a signed `preview_token`. `requires_user_action` is `false` when every selected step runs without the person: the resubmission then finishes on its own and no email goes out (`not_sent_reason: no_user_action`). + `send_webhooks` (default `true`) sends exactly the webhooks a real status change sends. With `false` the status still changes and the console still updates live, but no webhook is logged or sent, the missed-webhook recovery never re-sends that decision, and the next status change sends webhooks as usual. The response echoes the value applied. - This preview does not reserve session state or authorize delivery. After reviewing it, call [Update Session Status](/sessions-api/update-status) with `new_status: Resubmitted`, the same `nodes_to_resubmit` and `email_language` you previewed, `send_email: true`, `email_address` set to `recipient` and `email_preview_token` set to `preview_token`. The receipt expires after 15 minutes. When a receipt is supplied, changed inputs, message content, sender or session state return `409` before any mutation or send. Existing integrations may omit the receipt. Regenerate the preview after a conflict. Treat the response as sensitive verification content; responses use `Cache-Control: no-store`. Render HTML in a sandboxed frame, never directly in your application DOM. + Requires the `write:sessions` privilege; a scoped API key needs write access to sessions. An unknown `session_id` returns `404` and another application's session returns `403`, both before the body is read; a live session returns `404` only after the body is validated. To simulate from the hosted flow with the session's own token, use `POST /v3/session/{sessionId}/sandbox/simulate/`. See [Sandbox & Test Data](/integration/sandbox-testing) for the scenario catalog. - ``POST /v3/session/{sessionId}/resubmission-preview/`` + ``POST /v3/session/{sessionId}/simulate/`` Args: - session_id: UUID of the verification session to update. Accepts both user (KYC) and business (KYB) session IDs - the service resolves the ID across both session types. - nodes_to_resubmit: Steps to preview, using the same validation, selection and workflow ordering as a resubmission. Omit to auto-select recorded attempts needing resubmission. - email_address: Optional. Send the email to this address instead of the person's own. Without it, the recipient is the address the person verified in the flow, else the one given in `contact_details`. No email is sent by this call. - email_language: Language for the notification email. Accepts any string at schema level; unsupported codes silently fall back to English (`en`). + session_id: UUID of the sandbox verification session. Accepts both user (KYC) and business (KYB) session IDs. + new_status: The status to set. When you leave it out, it defaults to the default status of the risk case (`risk`, or the first risk the scenario's magic values carry), else to the scenario's default status. + comment: Note added to the activity entry the status change records. + scenario: A scenario slug from the catalog (`GET /v1/sandbox/scenarios/`). It supplies the default status and, without `risk`, the warning its magic values carry. An unknown slug returns `400`. + risk: A risk case from the catalog. Its warning is added to the session, with a log type that follows `new_status`. An unknown value returns `400`. + node_id: Workflow node the risk warning is attached to. Defaults to the session's current node. + send_webhooks: `true` sends exactly the webhooks a real status change sends to the sandbox application's destinations: `status.updated`, plus the `user.status.updated` / `user.data.updated` (or `business.status.updated` / `business.data.updated`) events the change causes, for destinations subscribed to them. `false` changes the status without logging or sending any webhook: the missed-webhook recovery never re-sends that decision, the console still updates live, and the next status change of the session sends webhooks as usual. 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( - "SessionsPreviewResubmissionResponse", + "SandboxSimulateResponse", await self._client.request( "post", - "/v3/session/{sessionId}/resubmission-preview/", - cast_to=SessionsPreviewResubmissionResponse, + "/v3/session/{sessionId}/simulate/", + cast_to=SandboxSimulateResponse, path_params={"sessionId": session_id}, auth="api_key", body={ - "nodes_to_resubmit": nodes_to_resubmit, - "email_address": email_address, - "email_language": email_language, + "new_status": new_status, + "comment": comment, + "scenario": scenario, + "risk": risk, + "node_id": node_id, + "send_webhooks": send_webhooks, }, extra_headers=extra_headers, extra_query=extra_query, @@ -3711,45 +4711,40 @@ async def preview_resubmission( ), ) - async def update_document_ai_data( + async def list_feature_overrides( self, session_id: str, - document_uuid: str, *, - extracted_data: Mapping[str, object] | NotGiven = NOT_GIVEN, - status: Literal["Approved", "Declined", "In Review", "Not Finished"] - | 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, - ) -> SessionsUpdateDocumentAiDataResponse: - """Update a Document AI document. + ) -> SessionsListFeatureOverridesResponse: + """List a session's check overrides. - Correct the fields Document AI extracted from one uploaded document, set its review status, or both, on a KYC or KYB session. `extracted_data` must be a JSON object and is merged key by key: a key you send replaces the stored value (a key sent as `null` is stored as `null`) and keys you leave out keep their values. The document status feeds the Document AI result of its workflow node in the session decision; the session status itself is not recomputed. Every successful call, including one that changes nothing, sends a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) with trigger `manual_review`. A scoped API key needs `decisions: write`; see [Document AI](https://docs.didit.me/core-technology/document-ai/overview). + Every override of an individual feature (step) status on a User Verification (KYC) or Business Verification (KYB) session, newest first and not paginated: applied ones, ones waiting for the person to finish the flow (`pending_until_flow_finishes`) and cancelled ones, each with who asked, their reason, and whether it applied while the person was still in the flow (`forced`). - ``PATCH /v3/document-ai/{sessionId}/documents/{documentUuid}/`` + `person_in_flow` tells you whether a new override with `defer_until_flow_finishes: true` would wait. `flow_finished_at` is when the person last finished the flow; it is `null` while they are still in it (a resubmission included) and when the session closed before they finished. + + Requires the `read:sessions` privilege; a scoped API key needs read access to decisions. + + ``GET /v3/session/{sessionId}/features/overrides/`` Args: - session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. - document_uuid: UUID of the Document AI document (`document_ai_documents[].items[].uuid` in `GET /v3/session/{sessionId}/decision/`). It must belong to the session in the path. - extracted_data: Field keys (the keys you configured for the document) and their corrected values. Must be a JSON object; merged key by key into the stored data. Leave it out rather than sending `null`, which returns `400`. - status: New review status of the document. + session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs. 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( - "SessionsUpdateDocumentAiDataResponse", + "SessionsListFeatureOverridesResponse", await self._client.request( - "patch", - "/v3/document-ai/{sessionId}/documents/{documentUuid}/", - cast_to=SessionsUpdateDocumentAiDataResponse, - path_params={"sessionId": session_id, "documentUuid": document_uuid}, + "get", + "/v3/session/{sessionId}/features/overrides/", + cast_to=SessionsListFeatureOverridesResponse, + path_params={"sessionId": session_id}, auth="api_key", - body={"extracted_data": extracted_data, "status": status}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3757,38 +4752,90 @@ async def update_document_ai_data( ), ) - async def regenerate_kyb_party( + async def cancel_feature_override( self, session_id: str, - party_uuid: str, + override_id: str, *, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> KYBKeyPeopleParty: - """Regenerate a Key People party's KYC session. + ) -> FeatureStatusOverride: + """Cancel a check override that waits for the flow to finish. + + Cancel an override of a feature (step) status that is still `pending_until_flow_finishes`, so it never applies. The check keeps its status, the cancellation is recorded in the session's activity as `FEATURE_OVERRIDE_CANCELLED`, and no webhook is sent. The response is the override with `state: cancelled` and `cancel_reason: cancelled_by_reviewer`. + + An override that already applied or was cancelled returns `409` with the code `feature_override_not_pending`. Find override IDs with `GET /v3/session/{sessionId}/features/overrides/` or in the `override` returned by the feature status update. + + Requires the `write:sessions` privilege; a scoped API key needs write access to decisions. + + ``POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`` + + Args: + session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs. + override_id: The `id` of the override to cancel. + 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( + "FeatureStatusOverride", + await self._client.request( + "post", + "/v3/session/{sessionId}/features/overrides/{overrideId}/cancel/", + cast_to=FeatureStatusOverride, + path_params={"sessionId": session_id, "overrideId": override_id}, + auth="api_key", + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def preview_decision_email( + self, + session_id: str, + *, + new_status: Literal["Approved", "Declined"] | str, + email_language: 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, + ) -> SessionsPreviewDecisionEmailResponse: + """Preview a session's decision email. + + Render the email the person receives when you set a session to `Approved` or `Declined` with `send_email: true`, without changing the session or sending anything. The response shows the subject and HTML exactly as they are sent, the recipient, the sender, the language, and whether confirming the change sends the email at all (`will_be_sent`, `not_sent_reason`). - Give a Key People party of a Business Verification (KYB) session a new individual KYC session after its previous one was deleted or expired before the person started it, so the Key People check can finish again; send no request body. It works when the party's KYC session was deleted (`kyc_session_deleted: true`) or expired before the person started it (`Expired`, never started). A session still in progress or one that ended in any other status (`Approved`, `Declined`, `In Review`, `Abandoned`, ...) returns `409` unless it was deleted. A party that never had one or a company party always returns `409`. Didit creates a new hosted KYC session with the workflow the party was verified with (its latest published version) or, when that is no longer known, the workflow your Key People settings assign to the party's role, so its link lasts that KYC workflow's session expiration time; it emails the link to the party when an email is on file, clears `is_skipped`, and recomputes the Key People check and the business session status. It then sends a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) for the business session with trigger `console_key_people_regenerate`; to exempt the party instead, use `PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/`. A scoped API key needs `decisions: write`, and without `sessions: write` it receives `kyc_session_url` as `null`. Deleted sessions qualify even if the person had already started or finished verification. Imported sessions do not qualify through expiry; they must have been deleted. + The recipient is the person's own address: the one they verified in an email verification step of the flow, else the one given in `contact_details` when the session was created. The sender is your application's verified sender domain when white label applies (`sender_kind: customer`), else Didit's sender (`sender_kind: didit`). - ``POST /v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/`` + To send exactly what you previewed, call [Update Session Status](/sessions-api/update-status) with the same `new_status`, `send_email: true`, `email_address` set to `recipient`, `email_language` set to `language` and `email_preview_token` set to `preview_token`. The receipt expires after 15 minutes. When the recipient, language, session status, sender or email changed since the preview, the update returns `409` before anything changes; preview again and confirm with the new receipt. + + Works for User Verification (KYC) and Business Verification (KYB) sessions in `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned` or `Resubmitted` status. The status check runs before body validation. Requires the `write:sessions` privilege; a scoped API key needs write access to decisions. Responses use `Cache-Control: no-store`: treat them as sensitive verification content. + + ``POST /v3/session/{sessionId}/decision-email-preview/`` Args: - session_id: UUID of the parent Business Verification (KYB) session. - party_uuid: UUID of the Key People party (`key_people_checks[].submitted.parties[].uuid` on the business session decision). Must belong to the session referenced by `sessionId`. + session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs. + new_status: The decision whose email you want to preview. + email_language: Language of the email, the same default as Update Session Status. A language that is not offered falls back to English; `language` in the response says which one is used. 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( - "KYBKeyPeopleParty", + "SessionsPreviewDecisionEmailResponse", await self._client.request( "post", - "/v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/", - cast_to=KYBKeyPeopleParty, - path_params={"sessionId": session_id, "partyUuid": party_uuid}, + "/v3/session/{sessionId}/decision-email-preview/", + cast_to=SessionsPreviewDecisionEmailResponse, + path_params={"sessionId": session_id}, auth="api_key", + body={"new_status": new_status, "email_language": email_language}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3796,44 +4843,62 @@ async def regenerate_kyb_party( ), ) - def list_events( + async def upload_kyb_documents( self, session_id: str, *, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - ordering: str | NotGiven = NOT_GIVEN, + documents: Sequence[FileTypes], + document_passwords: Sequence[str] | NotGiven = NOT_GIVEN, + document_group: Literal[ + "LEGAL_PRESENCE", + "COMPANY_DETAILS", + "OWNERSHIP_STRUCTURE", + "REPRESENTATIVES_AUTHORIZATION", + ] + | str + | NotGiven = NOT_GIVEN, + locale: str | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> AsyncPaginator[SessionEvent]: - """List session events. + ) -> SessionsUploadKybDocumentsResponse: + """Upload KYB documents to a session. - Read the event timeline of one verification session, newest first by `sent_at`: the screens the user saw, buttons and uploads, failed attempts, status and feature-step changes, and the workflow routing trace. Works for User Verification (KYC) and Business Verification (KYB) session IDs. Events are stored asynchronously, so a new event can take a few seconds to appear. Results are paginated with `limit` and `offset`; follow `next` until it is `null`. A scoped API key needs `sessions: read` and `decisions: read`, and without `media: read` it receives `file_url` as `null`. The routing events are described in [Retrieve session](https://docs.didit.me/sessions-api/retrieve-session). + Upload one or more corporate documents (articles of incorporation, shareholder register, certificate of incorporation, ...) to the KYB Documents step of a Business Verification session, from your own server instead of the hosted page. Didit runs the hosted pipeline: compression, OCR, tampering and cross-document checks, document grouping, and advances the session when the required document groups are satisfied. The step costs one flat fee however many files you send. The session must be open and on the KYB Documents step, and the company chosen at the registry step must exist. Read the people the documents name with `GET /v3/session/{sessionId}/kyb/extracted-parties/`. Requires `write:businesses`. - ``GET /v3/session/{sessionId}/events/`` + ``POST /v3/session/{sessionId}/kyb/documents/`` Args: - session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. - limit: Maximum number of events per page. Defaults to 50. A value below 1 or a non-numeric value falls back to 50; a value above 1,000,000 returns `400`. - offset: Number of results to skip before the first returned one. Defaults to 0; a negative or non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and `previous` URLs. - ordering: Optional sort override. The default order is `-sent_at`. Pass a result field name (for example `sent_at`, `created_at`, `event_type`, `feature_step` or `step`) to sort ascending, prefix it with `-` to sort descending, and separate several fields with commas. Unknown fields are ignored. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + documents: Files to upload: JPG, JPEG, PNG, TIFF, WEBP, PDF or ZIP archives of them. PDFs up to 50 MB, photos up to 6 MB before compression. + document_passwords: One entry per file in `documents`, in the same order: the password of a protected PDF, empty for any other file. + document_group: Required document group this upload answers. + locale: Locale used to translate the response of the next step. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "AsyncPaginator[SessionEvent]", - self._client.request_page( - "get", - "/v3/session/{sessionId}/events/", - cast_to=SessionsListEventsResponse, - item_type=SessionEvent, + "SessionsUploadKybDocumentsResponse", + await self._client.request( + "post", + "/v3/session/{sessionId}/kyb/documents/", + cast_to=SessionsUploadKybDocumentsResponse, path_params={"sessionId": session_id}, auth="api_key", - query={"limit": limit, "offset": offset, "ordering": ordering}, + query={"node_id": node_id}, + body={ + "documents": documents, + "document_passwords": document_passwords, + "document_group": document_group, + "locale": locale, + }, + multipart=True, + file_fields=("documents",), extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3841,46 +4906,39 @@ def list_events( ), ) - def list_aml_screening_history( + async def list_kyb_extracted_parties( self, session_id: str, *, node_id: str | NotGiven = NOT_GIVEN, - limit: int | NotGiven = NOT_GIVEN, - offset: int | NotGiven = NOT_GIVEN, - ordering: 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, - ) -> AsyncPaginator[AMLScreeningRun]: - """List AML screening history. + ) -> SessionsListKybExtractedPartiesResponse: + """List the parties named by the uploaded documents. - List every completed ongoing-monitoring re-screen of a session's AML check, newest first by `completed_at`, including the runs where nothing changed: alerts, activity entries and webhooks fire only when a result moves, so this history is the evidence that a clean subject was still being screened. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Only ongoing-monitoring re-screens are listed (the first screening is part of the session decision) and runs from before this history existed are not reconstructed, so a session without ongoing monitoring returns an empty list. `count` is exact up to 100 and capped at 100 above that, so follow `next` until it is `null`. A scoped API key needs `decisions: read`; see [Continuous AML monitoring](https://docs.didit.me/core-technology/aml-screening/continuous-monitoring-aml-screening). + Return the shareholders and directors that the documents uploaded to this KYB session name, merged per person and attributed to the documents that named them. Show them to your applicant to confirm, then declare them with the party draft endpoints. A range stays a range: `ownership_percent.text` keeps the verbatim figure and `min` / `max` the numbers read from it. Nobody is labelled a UBO here; that is decided when the parties are submitted, from the role settings and ownership thresholds of the workflow. The same list is in the session decision as `document_verifications[].extracted_parties`. Requires `read:businesses` or `read:sessions`. - ``GET /v3/session/{sessionId}/aml-screening-history/`` + ``GET /v3/session/{sessionId}/kyb/extracted-parties/`` Args: - session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. - node_id: Workflow graph node ID of the AML check. Needed only when the session ran more than one AML step; without it the most recent AML check is used. An unknown node returns `404`. - limit: Maximum number of screening runs per page. Defaults to 50. A value below 1 or a non-numeric value falls back to 50; a value above 1,000,000 returns `400`. - offset: Number of results to skip before the first returned one. Defaults to 0; a negative or non-numeric value falls back to 0, a value above 1,000,000 returns `400`. Prefer following the `next` and `previous` URLs. - ordering: Optional sort override. The default order is `-completed_at`. Pass a result field name (for example `completed_at`, `started_at`, `outcome` or `score`) to sort ascending, prefix it with `-` to sort descending, and separate several fields with commas. Unknown fields are ignored. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "AsyncPaginator[AMLScreeningRun]", - self._client.request_page( + "SessionsListKybExtractedPartiesResponse", + await self._client.request( "get", - "/v3/session/{sessionId}/aml-screening-history/", - cast_to=SessionsListAmlScreeningHistoryResponse, - item_type=AMLScreeningRun, + "/v3/session/{sessionId}/kyb/extracted-parties/", + cast_to=SessionsListKybExtractedPartiesResponse, path_params={"sessionId": session_id}, auth="api_key", - query={"node_id": node_id, "limit": limit, "offset": offset, "ordering": ordering}, + query={"node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3888,7 +4946,7 @@ def list_aml_screening_history( ), ) - async def export_aml_screening_history( + async def list_kyb_party_drafts( self, session_id: str, *, @@ -3897,31 +4955,30 @@ async def export_aml_screening_history( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> bytes: - """Export AML screening history as CSV. + ) -> SessionsListKybPartyDraftsResponse: + """List the KYB party drafts. - Download the same ongoing-monitoring history as `GET /v3/session/{sessionId}/aml-screening-history/` as a CSV file, one line per completed re-screen, newest first, ready to hand to an auditor. The file is streamed whole (no pagination) and starts with a header line; an empty cell means unknown, dataset dates are never estimated, and a value that would start a spreadsheet formula is prefixed with an apostrophe. Works for KYC and KYB session IDs; pass `node_id` when the session ran more than one AML step. Errors are returned as JSON, not CSV. A scoped API key needs `decisions: read` and `media: read`: the response is a file, so a key without `media: read` gets `403`. + List the parties you are preparing for this KYB session, oldest first. A draft is not a declared party: it does not appear in the decision or the console and creates no verification session until you submit it with `POST /v3/session/{sessionId}/kyb/parties/submit/`. Requires `write:businesses`. - ``GET /v3/session/{sessionId}/aml-screening-history/export/`` + ``GET /v3/session/{sessionId}/kyb/parties/drafts/`` Args: - session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. - node_id: Workflow graph node ID of the AML check. Needed only when the session ran more than one AML step; without it the most recent AML check is used. An unknown node returns `404`. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "bytes", + "SessionsListKybPartyDraftsResponse", await self._client.request( "get", - "/v3/session/{sessionId}/aml-screening-history/export/", - cast_to=bytes, + "/v3/session/{sessionId}/kyb/parties/drafts/", + cast_to=SessionsListKybPartyDraftsResponse, path_params={"sessionId": session_id}, auth="api_key", query={"node_id": node_id}, - accept="text/csv, application/json", extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3929,45 +4986,131 @@ async def export_aml_screening_history( ), ) - async def add_images( + async def create_kyb_party_draft( self, session_id: str, *, - file: FileTypes, - model_type: Literal["kyc", "poa"] | str, - file_password: str | NotGiven = NOT_GIVEN, + entity_type: Literal["person", "company"] | str, + nationality: str, + full_name: str | NotGiven = NOT_GIVEN, + first_name: str | NotGiven = NOT_GIVEN, + last_name: str | NotGiven = NOT_GIVEN, + role: Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + | NotGiven = NOT_GIVEN, + roles: Sequence[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | NotGiven = NOT_GIVEN, + position: str | NotGiven = NOT_GIVEN, + date_of_birth: str | _dt.date | None | NotGiven = NOT_GIVEN, + company_name: str | NotGiven = NOT_GIVEN, + registration_number: str | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, + ownership_percent: float | None | NotGiven = NOT_GIVEN, + phone_number: str | NotGiven = NOT_GIVEN, + custom_fields: Mapping[str, object] | NotGiven = NOT_GIVEN, + skip_verification: bool | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionsAddImagesResponse: - """Add an image to a session. + ) -> SessionsCreateKybPartyDraftResponse: + """Create a KYB party draft. - Attach one extra image or PDF to the ID verification (`model_type=kyc`) or Proof of Address (`model_type=poa`) result of a finished User Verification (KYC) session, for example evidence collected outside the flow. The session must be `Approved`, `Declined`, `In Review` or `Kyc Expired` and carry the result named by `model_type`; Business Verification (KYB) sessions are not supported. Each call appends one file (to the most recent result when the step ran more than once), keeps the existing files and records a `FILE_ADDED` entry in the session activity log; the upload sends no webhook and does not change the session status. The file is compressed on upload and is returned in `extra_files` of the session decision. This endpoint is limited to 10 requests per minute per API key. A scoped API key needs `sessions: write`, and without `media: read` it receives the `extra_files` links as `null`. + Add a party (a person or a company) to the list you are preparing for this KYB session. The same fields and rules as the hosted Key People screen apply: a person needs `full_name` or `first_name` and `last_name`, at least one role and a nationality; a company needs `company_name` and the country of incorporation in `nationality`. Nothing is declared or billed until `POST /v3/session/{sessionId}/kyb/parties/submit/`. Requires `write:businesses`. - ``PATCH /v3/session/{sessionId}/add-images/`` + ``POST /v3/session/{sessionId}/kyb/parties/drafts/`` Args: - session_id: UUID of the User Verification (KYC) session to add the file to (the `session_id` returned by `POST /v3/session/`). A Business Verification (KYB) session ID returns `404`. - file: The image or PDF. Allowed extensions: `jpg`, `jpeg`, `png`, `webp`, `tiff`, `pdf`. At most 15 MB as uploaded; the file is then compressed and rejected with `400` if it is still larger than 2 MB (2,097,152 bytes). Empty files are rejected. - model_type: `kyc` adds the file to the ID verification result, `poa` to the Proof of Address result. - file_password: Password of an encrypted PDF. Without it, or with a wrong one, an encrypted PDF returns `400`. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + entity_type: Whether the party is an individual or a company. + nationality: Nationality of a person, or country of incorporation of a company. Required for every party. + full_name: Full name of a person. Send it, or `first_name` and `last_name`. + first_name + last_name + role: Role the party holds. Interchangeable with `roles`; when both are sent they are merged. + roles: Every role the party holds. A person needs at least one role (here or in `role`). + position: Job title of a person. + date_of_birth + company_name: Name of a company party. Required when `entity_type` is `company`. + registration_number: Registration number of a company party. + email: Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow. + ownership_percent: Share of the company the party owns. + phone_number + custom_fields: Workflow-defined extra fields. + skip_verification: Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsAddImagesResponse", + "SessionsCreateKybPartyDraftResponse", await self._client.request( - "patch", - "/v3/session/{sessionId}/add-images/", - cast_to=SessionsAddImagesResponse, + "post", + "/v3/session/{sessionId}/kyb/parties/drafts/", + cast_to=SessionsCreateKybPartyDraftResponse, path_params={"sessionId": session_id}, auth="api_key", - body={"file": file, "model_type": model_type, "file_password": file_password}, - multipart=True, - file_fields=("file",), + query={"node_id": node_id}, + body={ + "entity_type": entity_type, + "nationality": nationality, + "full_name": full_name, + "first_name": first_name, + "last_name": last_name, + "role": role, + "roles": roles, + "position": position, + "date_of_birth": date_of_birth, + "company_name": company_name, + "registration_number": registration_number, + "email": email, + "ownership_percent": ownership_percent, + "phone_number": phone_number, + "custom_fields": custom_fields, + "skip_verification": skip_verification, + }, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -3975,45 +5118,41 @@ async def add_images( ), ) - async def update_aml_status( + async def delete_kyb_party_draft( self, session_id: str, + draft_id: str, *, - status: Literal["Not Finished", "Approved", "Declined", "In Review", "Resub Requested"] - | str, node_id: str | NotGiven = NOT_GIVEN, - node_id_query: 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, - ) -> SessionsUpdateAmlStatusResponse: - """Update an AML check status. + ) -> None: + """Delete a KYB party draft. - Set the status of a session's AML screening check as a whole (the `status` of an `aml_screenings[]` entry in the session decision), for example `Approved` after your team cleared every hit. Works for KYC and KYB session IDs; pass `node_id` (query parameter or body field) when the session ran more than one AML step, otherwise the most recent AML check is updated. When the status actually changes, an `AML_STATUS_UPDATED` activity entry is recorded and a `data.updated` [webhook](https://docs.didit.me/integration/webhooks) is sent; sending the current status returns `200` and changes nothing. The session status is not recomputed: use `PATCH /v3/session/{sessionId}/update-status/` for the session decision and `PATCH /v3/session/{sessionId}/update-aml-hit-status/` for single hits. A scoped API key needs `decisions: write`. + Drop one party draft. Declared parties are not affected. Requires `write:businesses`. - ``PATCH /v3/session/{sessionId}/update-aml-status/`` + ``DELETE /v3/session/{sessionId}/kyb/parties/drafts/{draftId}/`` Args: - session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs: the server resolves the ID across both session types. Must be a well-formed UUID; a malformed value does not match the route and returns an HTML `404`. - status: New status of the AML check. - node_id: Workflow graph node ID of the AML check, as an alternative to the query parameter. - node_id_query: Workflow graph node ID of the AML check to update. Needed only when the session ran more than one AML step. Takes precedence over `node_id` in the body. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + draft_id: UUID of the party draft (`draft_id` returned when it was created). + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsUpdateAmlStatusResponse", + "None", await self._client.request( - "patch", - "/v3/session/{sessionId}/update-aml-status/", - cast_to=SessionsUpdateAmlStatusResponse, - path_params={"sessionId": session_id}, + "delete", + "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/", + cast_to=None, + path_params={"sessionId": session_id, "draftId": draft_id}, auth="api_key", - query={"node_id": node_id_query}, - body={"status": status, "node_id": node_id}, + query={"node_id": node_id}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -4021,63 +5160,132 @@ async def update_aml_status( ), ) - async def simulate( + async def update_kyb_party_draft( self, session_id: str, + draft_id: str, *, - new_status: Literal["Approved", "Declined", "In Review", "Expired", "Abandoned"] + entity_type: Literal["person", "company"] | str | NotGiven = NOT_GIVEN, + full_name: str | NotGiven = NOT_GIVEN, + first_name: str | NotGiven = NOT_GIVEN, + last_name: str | NotGiven = NOT_GIVEN, + role: Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] | str | NotGiven = NOT_GIVEN, - comment: str | NotGiven = NOT_GIVEN, - scenario: str | NotGiven = NOT_GIVEN, - risk: str | NotGiven = NOT_GIVEN, + roles: Sequence[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | NotGiven = NOT_GIVEN, + position: str | NotGiven = NOT_GIVEN, + date_of_birth: str | _dt.date | None | NotGiven = NOT_GIVEN, + company_name: str | NotGiven = NOT_GIVEN, + registration_number: str | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, + ownership_percent: float | None | NotGiven = NOT_GIVEN, + nationality: str | NotGiven = NOT_GIVEN, + phone_number: str | NotGiven = NOT_GIVEN, + custom_fields: Mapping[str, object] | NotGiven = NOT_GIVEN, + skip_verification: bool | NotGiven = NOT_GIVEN, node_id: str | NotGiven = NOT_GIVEN, - send_webhooks: bool | 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, - ) -> SandboxSimulateResponse: - """Simulate a sandbox session's status. - - Force a terminal status on a sandbox session after the fact, from your backend, without running the flow. Sandbox applications only: a live session returns `404`. Works for User Verification (KYC) and Business Verification (KYB) sessions. - - Set `new_status`, or let `scenario` or `risk` supply it. `risk` (or the first risk the scenario's magic values carry) adds that warning to the session. The change is recorded in the session's activity. + ) -> SessionsUpdateKybPartyDraftResponse: + """Edit a KYB party draft. - `send_webhooks` (default `true`) sends exactly the webhooks a real status change sends. With `false` the status still changes and the console still updates live, but no webhook is logged or sent, the missed-webhook recovery never re-sends that decision, and the next status change sends webhooks as usual. The response echoes the value applied. - - Requires the `write:sessions` privilege; a scoped API key needs write access to sessions. An unknown `session_id` returns `404` and another application's session returns `403`, both before the body is read; a live session returns `404` only after the body is validated. To simulate from the hosted flow with the session's own token, use `POST /v3/session/{sessionId}/sandbox/simulate/`. See [Sandbox & Test Data](/integration/sandbox-testing) for the scenario catalog. + Change fields of one party draft. The edit is merged into the stored draft and the merged party is validated as a whole, so an edit that would leave the party incomplete is rejected. Changing `first_name` or `last_name` replaces the stored full name. Requires `write:businesses`. - ``POST /v3/session/{sessionId}/simulate/`` + ``PATCH /v3/session/{sessionId}/kyb/parties/drafts/{draftId}/`` Args: - session_id: UUID of the sandbox verification session. Accepts both user (KYC) and business (KYB) session IDs. - new_status: The status to set. When you leave it out, it defaults to the default status of the risk case (`risk`, or the first risk the scenario's magic values carry), else to the scenario's default status. - comment: Note added to the activity entry the status change records. - scenario: A scenario slug from the catalog (`GET /v1/sandbox/scenarios/`). It supplies the default status and, without `risk`, the warning its magic values carry. An unknown slug returns `400`. - risk: A risk case from the catalog. Its warning is added to the session, with a log type that follows `new_status`. An unknown value returns `400`. - node_id: Workflow node the risk warning is attached to. Defaults to the session's current node. - send_webhooks: `true` sends exactly the webhooks a real status change sends to the sandbox application's destinations: `status.updated`, plus the `user.status.updated` / `user.data.updated` (or `business.status.updated` / `business.data.updated`) events the change causes, for destinations subscribed to them. `false` changes the status without logging or sending any webhook: the missed-webhook recovery never re-sends that decision, the console still updates live, and the next status change of the session sends webhooks as usual. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + draft_id: UUID of the party draft (`draft_id` returned when it was created). + entity_type: Whether the party is an individual or a company. + full_name: Full name of a person. Send it, or `first_name` and `last_name`. + first_name + last_name + role: Role the party holds. Interchangeable with `roles`; when both are sent they are merged. + roles: Every role the party holds. A person needs at least one role (here or in `role`). + position: Job title of a person. + date_of_birth + company_name: Name of a company party. Required when `entity_type` is `company`. + registration_number: Registration number of a company party. + email: Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow. + ownership_percent: Share of the company the party owns. + nationality: Nationality of a person, or country of incorporation of a company. Required for every party. + phone_number + custom_fields: Workflow-defined extra fields. + skip_verification: Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SandboxSimulateResponse", + "SessionsUpdateKybPartyDraftResponse", await self._client.request( - "post", - "/v3/session/{sessionId}/simulate/", - cast_to=SandboxSimulateResponse, - path_params={"sessionId": session_id}, + "patch", + "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/", + cast_to=SessionsUpdateKybPartyDraftResponse, + path_params={"sessionId": session_id, "draftId": draft_id}, auth="api_key", + query={"node_id": node_id}, body={ - "new_status": new_status, - "comment": comment, - "scenario": scenario, - "risk": risk, - "node_id": node_id, - "send_webhooks": send_webhooks, + "entity_type": entity_type, + "full_name": full_name, + "first_name": first_name, + "last_name": last_name, + "role": role, + "roles": roles, + "position": position, + "date_of_birth": date_of_birth, + "company_name": company_name, + "registration_number": registration_number, + "email": email, + "ownership_percent": ownership_percent, + "nationality": nationality, + "phone_number": phone_number, + "custom_fields": custom_fields, + "skip_verification": skip_verification, }, extra_headers=extra_headers, extra_query=extra_query, @@ -4086,40 +5294,42 @@ async def simulate( ), ) - async def list_feature_overrides( + async def submit_kyb_parties( self, session_id: str, *, + locale: str | NotGiven = NOT_GIVEN, + node_id: 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, - ) -> SessionsListFeatureOverridesResponse: - """List a session's check overrides. - - Every override of an individual feature (step) status on a User Verification (KYC) or Business Verification (KYB) session, newest first and not paginated: applied ones, ones waiting for the person to finish the flow (`pending_until_flow_finishes`) and cancelled ones, each with who asked, their reason, and whether it applied while the person was still in the flow (`forced`). - - `person_in_flow` tells you whether a new override with `defer_until_flow_finishes: true` would wait. `flow_finished_at` is when the person last finished the flow; it is `null` while they are still in it (a resubmission included) and when the session closed before they finished. + ) -> SessionsSubmitKybPartiesResponse: + """Submit the KYB party drafts. - Requires the `read:sessions` privilege; a scoped API key needs read access to decisions. + Declare the stored drafts as the company's key people. This is the hosted Key People step under your API key: Didit decides from the role settings and ownership thresholds of the workflow which parties must be verified, creates one individual KYC session (or a KYB sub-session for a corporate owner) for each of them, sends the emails the workflow asks for, and advances the session. Each child session is billed like in the hosted flow. The drafts are consumed. Repeating the call after a successful submit changes nothing and answers `200` with `already_submitted: true` and the parties that already exist. The session must be on the Key People step. Send each person's `kyc_session_url` to them, or embed it. Requires `write:businesses`. - ``GET /v3/session/{sessionId}/features/overrides/`` + ``POST /v3/session/{sessionId}/kyb/parties/submit/`` Args: - session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs. + session_id: UUID of the Business Verification (KYB) session. It must belong to the application of the API key. + locale: Locale used to translate the response of the step the session advances to. + node_id: Workflow node of the KYB step. Only needed when the workflow has more than one KYB node; by default Didit uses the session's own node. 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( - "SessionsListFeatureOverridesResponse", + "SessionsSubmitKybPartiesResponse", await self._client.request( - "get", - "/v3/session/{sessionId}/features/overrides/", - cast_to=SessionsListFeatureOverridesResponse, + "post", + "/v3/session/{sessionId}/kyb/parties/submit/", + cast_to=SessionsSubmitKybPartiesResponse, path_params={"sessionId": session_id}, auth="api_key", + query={"node_id": node_id}, + body={"locale": locale}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -4127,41 +5337,37 @@ async def list_feature_overrides( ), ) - async def cancel_feature_override( + async def export_files( self, session_id: str, - override_id: str, *, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> FeatureStatusOverride: - """Cancel a check override that waits for the flow to finish. + ) -> SessionFilesExport: + """Export every file of a session. - Cancel an override of a feature (step) status that is still `pending_until_flow_finishes`, so it never applies. The check keeps its status, the cancellation is recorded in the session's activity as `FEATURE_OVERRIDE_CANCELLED`, and no webhook is sent. The response is the override with `state: cancelled` and `cancel_reason: cancelled_by_reviewer`. - - An override that already applied or was cancelled returns `409` with the code `feature_override_not_pending`. Find override IDs with `GET /v3/session/{sessionId}/features/overrides/` or in the `override` returned by the feature status update. + Start preparing one ZIP with every image, video and document of a User Verification (KYC) or Business Verification (KYB) session, in original quality: the files are stored in the ZIP as they were captured, never recompressed. Answers `202` with the export; read it with `GET /v3/session/{sessionId}/files-export/{exportId}/` until `status` is `READY`, then download `download_url`. While an export of the same session is still being prepared, that export is returned instead of a new one. - Requires the `write:sessions` privilege; a scoped API key needs write access to decisions. + The ZIP is deleted 24 hours after it is ready, and at once when the session is deleted. A deleted session cannot be exported. Every export and every download link handed out is written to the session's audit log. A scoped API key needs `media: read` and `decisions: read`; a console user needs the privilege to read sessions. - ``POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`` + ``POST /v3/session/{sessionId}/files-export/`` Args: - session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs. - override_id: The `id` of the override to cancel. + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs. A deleted session returns `404`. 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( - "FeatureStatusOverride", + "SessionFilesExport", await self._client.request( "post", - "/v3/session/{sessionId}/features/overrides/{overrideId}/cancel/", - cast_to=FeatureStatusOverride, - path_params={"sessionId": session_id, "overrideId": override_id}, + "/v3/session/{sessionId}/files-export/", + cast_to=SessionFilesExport, + path_params={"sessionId": session_id}, auth="api_key", extra_headers=extra_headers, extra_query=extra_query, @@ -4170,47 +5376,38 @@ async def cancel_feature_override( ), ) - async def preview_decision_email( + async def get_files_export( self, session_id: str, + export_id: str, *, - new_status: Literal["Approved", "Declined"] | str, - email_language: 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, - ) -> SessionsPreviewDecisionEmailResponse: - """Preview a session's decision email. - - Render the email the person receives when you set a session to `Approved` or `Declined` with `send_email: true`, without changing the session or sending anything. The response shows the subject and HTML exactly as they are sent, the recipient, the sender, the language, and whether confirming the change sends the email at all (`will_be_sent`, `not_sent_reason`). - - The recipient is the person's own address: the one they verified in an email verification step of the flow, else the one given in `contact_details` when the session was created. The sender is your application's verified sender domain when white label applies (`sender_kind: customer`), else Didit's sender (`sender_kind: didit`). - - To send exactly what you previewed, call [Update Session Status](/sessions-api/update-status) with the same `new_status`, `send_email: true`, `email_address` set to `recipient`, `email_language` set to `language` and `email_preview_token` set to `preview_token`. The receipt expires after 15 minutes. When the recipient, language, session status, sender or email changed since the preview, the update returns `409` before anything changes; preview again and confirm with the new receipt. + ) -> SessionFilesExport: + """Get a session files export. - Works for User Verification (KYC) and Business Verification (KYB) sessions in `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned` or `Resubmitted` status. The status check runs before body validation. Requires the `write:sessions` privilege; a scoped API key needs write access to decisions. Responses use `Cache-Control: no-store`: treat them as sensitive verification content. + Progress of an export started with `POST /v3/session/{sessionId}/files-export/`. Once `status` is `READY`, `download_url` is a signed URL of the ZIP that stays valid for a short time; read the export again for a new one until `expires_at`. Each read that hands out a download link is written to the session's audit log. An export of a deleted session returns `404`. - ``POST /v3/session/{sessionId}/decision-email-preview/`` + ``GET /v3/session/{sessionId}/files-export/{exportId}/`` Args: - session_id: UUID of the verification session. Accepts both user (KYC) and business (KYB) session IDs. - new_status: The decision whose email you want to preview. - email_language: Language of the email, the same default as Update Session Status. A language that is not offered falls back to English; `language` in the response says which one is used. + session_id: UUID of the verification session (the `session_id` returned by `POST /v3/session/`). Accepts both User Verification (KYC) and Business Verification (KYB) session IDs. A deleted session returns `404`. + export_id: The `export_id` returned by `POST /v3/session/{sessionId}/files-export/`. 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( - "SessionsPreviewDecisionEmailResponse", + "SessionFilesExport", await self._client.request( - "post", - "/v3/session/{sessionId}/decision-email-preview/", - cast_to=SessionsPreviewDecisionEmailResponse, - path_params={"sessionId": session_id}, + "get", + "/v3/session/{sessionId}/files-export/{exportId}/", + cast_to=SessionFilesExport, + path_params={"sessionId": session_id, "exportId": export_id}, auth="api_key", - body={"new_status": new_status, "email_language": email_language}, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -4258,6 +5455,17 @@ def __init__(self, resource: Sessions) -> None: self.list_feature_overrides = to_raw_response_wrapper(resource.list_feature_overrides) self.cancel_feature_override = to_raw_response_wrapper(resource.cancel_feature_override) self.preview_decision_email = to_raw_response_wrapper(resource.preview_decision_email) + self.upload_kyb_documents = to_raw_response_wrapper(resource.upload_kyb_documents) + self.list_kyb_extracted_parties = to_raw_response_wrapper( + resource.list_kyb_extracted_parties + ) + self.list_kyb_party_drafts = to_raw_response_wrapper(resource.list_kyb_party_drafts) + self.create_kyb_party_draft = to_raw_response_wrapper(resource.create_kyb_party_draft) + self.delete_kyb_party_draft = to_raw_response_wrapper(resource.delete_kyb_party_draft) + self.update_kyb_party_draft = to_raw_response_wrapper(resource.update_kyb_party_draft) + self.submit_kyb_parties = to_raw_response_wrapper(resource.submit_kyb_parties) + self.export_files = to_raw_response_wrapper(resource.export_files) + self.get_files_export = to_raw_response_wrapper(resource.get_files_export) @cached_property def imports(self) -> SessionsImportsWithRawResponse: @@ -4329,6 +5537,17 @@ def __init__(self, resource: AsyncSessions) -> None: resource.cancel_feature_override ) self.preview_decision_email = async_to_raw_response_wrapper(resource.preview_decision_email) + self.upload_kyb_documents = async_to_raw_response_wrapper(resource.upload_kyb_documents) + self.list_kyb_extracted_parties = async_to_raw_response_wrapper( + resource.list_kyb_extracted_parties + ) + self.list_kyb_party_drafts = async_to_raw_response_wrapper(resource.list_kyb_party_drafts) + self.create_kyb_party_draft = async_to_raw_response_wrapper(resource.create_kyb_party_draft) + self.delete_kyb_party_draft = async_to_raw_response_wrapper(resource.delete_kyb_party_draft) + self.update_kyb_party_draft = async_to_raw_response_wrapper(resource.update_kyb_party_draft) + self.submit_kyb_parties = async_to_raw_response_wrapper(resource.submit_kyb_parties) + self.export_files = async_to_raw_response_wrapper(resource.export_files) + self.get_files_export = async_to_raw_response_wrapper(resource.get_files_export) @cached_property def imports(self) -> AsyncSessionsImportsWithRawResponse: @@ -4400,6 +5619,17 @@ def __init__(self, resource: Sessions) -> None: resource.cancel_feature_override ) self.preview_decision_email = to_streamed_response_wrapper(resource.preview_decision_email) + self.upload_kyb_documents = to_streamed_response_wrapper(resource.upload_kyb_documents) + self.list_kyb_extracted_parties = to_streamed_response_wrapper( + resource.list_kyb_extracted_parties + ) + self.list_kyb_party_drafts = to_streamed_response_wrapper(resource.list_kyb_party_drafts) + self.create_kyb_party_draft = to_streamed_response_wrapper(resource.create_kyb_party_draft) + self.delete_kyb_party_draft = to_streamed_response_wrapper(resource.delete_kyb_party_draft) + self.update_kyb_party_draft = to_streamed_response_wrapper(resource.update_kyb_party_draft) + self.submit_kyb_parties = to_streamed_response_wrapper(resource.submit_kyb_parties) + self.export_files = to_streamed_response_wrapper(resource.export_files) + self.get_files_export = to_streamed_response_wrapper(resource.get_files_export) @cached_property def imports(self) -> SessionsImportsWithStreamingResponse: @@ -4485,6 +5715,27 @@ def __init__(self, resource: AsyncSessions) -> None: self.preview_decision_email = async_to_streamed_response_wrapper( resource.preview_decision_email ) + self.upload_kyb_documents = async_to_streamed_response_wrapper( + resource.upload_kyb_documents + ) + self.list_kyb_extracted_parties = async_to_streamed_response_wrapper( + resource.list_kyb_extracted_parties + ) + self.list_kyb_party_drafts = async_to_streamed_response_wrapper( + resource.list_kyb_party_drafts + ) + self.create_kyb_party_draft = async_to_streamed_response_wrapper( + resource.create_kyb_party_draft + ) + self.delete_kyb_party_draft = async_to_streamed_response_wrapper( + resource.delete_kyb_party_draft + ) + self.update_kyb_party_draft = async_to_streamed_response_wrapper( + resource.update_kyb_party_draft + ) + self.submit_kyb_parties = async_to_streamed_response_wrapper(resource.submit_kyb_parties) + self.export_files = async_to_streamed_response_wrapper(resource.export_files) + self.get_files_export = async_to_streamed_response_wrapper(resource.get_files_export) @cached_property def imports(self) -> AsyncSessionsImportsWithStreamingResponse: diff --git a/src/didit/resources/sessions/signatures.py b/src/didit/resources/sessions/signatures.py index 4865e3d..4e7c12a 100644 --- a/src/didit/resources/sessions/signatures.py +++ b/src/didit/resources/sessions/signatures.py @@ -57,15 +57,15 @@ def download_document( ) -> bytes: """Download a signed document. - Download the signed PDF of one document of an Electronic Signature step. Use the `signed_file` path of `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field values stamped, the evidence page (unless `signature_evidence_page` is off) and the PAdES signature with its timestamp. Didit checks the file against `sha256_signed` before returning it. + Download the signed PDF of one document of an E-signature step. Use the `signed_file` path of `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field values stamped and the evidence page (unless `signature_evidence_page` is off). An Advanced (AES) PDF also carries the PAdES signature with its timestamp; a Simple PDF has no digital signature, seal or timestamp. Didit checks the file against `sha256_signed` before returning it. - Works for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API key works. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents). + Works for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API key works. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents). ``GET /v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/`` Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. document_id: `id` of the document in `signatures[].documents[]`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -101,7 +101,7 @@ def download_evidence( ) -> bytes: """Download the signature evidence. - Download a signer's evidence PDF: the level and format, the signer and their verified identity session, the code confirmation, the IP address, each document with its original SHA-256 and field values, the certificate, the timestamp and the SHA-256 of every signed file. Use the `evidence_file` path of the signer's item in `signatures[]`. + Download a signer's evidence PDF: the level and format, the signer, the IP address, each document with its original SHA-256 and field values and the SHA-256 of every signed file, plus, for an Advanced (AES) signature, the verified identity session, the code confirmation, the certificate and the timestamp. Use the `evidence_file` path of the signer's item in `signatures[]`. Always pass `signature_id` when a Business Verification step has several signers: without it, the route picks one of the step's signers. Needs `read:sessions`; your API key works. @@ -109,7 +109,7 @@ def download_evidence( Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. signature_id: `id` of the signer's item in `signatures[]`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -152,7 +152,7 @@ def download_field_image( Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. field_id: The field on this signer's copy, as in the field's `image_url`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -188,7 +188,7 @@ def validate( ) -> SessionsSignaturesValidateResponse: """Validate signatures again. - Re-check the signed documents of an Electronic Signature step. Didit re-reads every signed PDF, checks its SHA-256 and validates the PAdES signature, the certificate, the revocation data and the timestamp, then saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if any of them hasn't signed. + Re-check the signed documents of an E-signature step. Didit re-reads every signed PDF, checks its SHA-256 and, for an Advanced (AES) signature, validates the PAdES signature, the certificate, the revocation data and the timestamp (a Simple signature has no digital signature, so only the file integrity is checked), then saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if any of them hasn't signed. Needs `write:sessions`; your API key works. In the console it's the **Validate again** button. @@ -196,7 +196,7 @@ def validate( Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. signature_id: `id` of one signer's item in `signatures[]`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -249,15 +249,15 @@ async def download_document( ) -> bytes: """Download a signed document. - Download the signed PDF of one document of an Electronic Signature step. Use the `signed_file` path of `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field values stamped, the evidence page (unless `signature_evidence_page` is off) and the PAdES signature with its timestamp. Didit checks the file against `sha256_signed` before returning it. + Download the signed PDF of one document of an E-signature step. Use the `signed_file` path of `signatures[].documents[]` in the decision. The PDF holds the document the signer was shown with their field values stamped and the evidence page (unless `signature_evidence_page` is off). An Advanced (AES) PDF also carries the PAdES signature with its timestamp; a Simple PDF has no digital signature, seal or timestamp. Didit checks the file against `sha256_signed` before returning it. - Works for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API key works. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents). + Works for User Verification (KYC) and Business Verification (KYB) sessions. Needs `read:sessions`; your API key works. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature#download-the-signed-documents). ``GET /v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/`` Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. document_id: `id` of the document in `signatures[].documents[]`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -293,7 +293,7 @@ async def download_evidence( ) -> bytes: """Download the signature evidence. - Download a signer's evidence PDF: the level and format, the signer and their verified identity session, the code confirmation, the IP address, each document with its original SHA-256 and field values, the certificate, the timestamp and the SHA-256 of every signed file. Use the `evidence_file` path of the signer's item in `signatures[]`. + Download a signer's evidence PDF: the level and format, the signer, the IP address, each document with its original SHA-256 and field values and the SHA-256 of every signed file, plus, for an Advanced (AES) signature, the verified identity session, the code confirmation, the certificate and the timestamp. Use the `evidence_file` path of the signer's item in `signatures[]`. Always pass `signature_id` when a Business Verification step has several signers: without it, the route picks one of the step's signers. Needs `read:sessions`; your API key works. @@ -301,7 +301,7 @@ async def download_evidence( Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. signature_id: `id` of the signer's item in `signatures[]`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -344,7 +344,7 @@ async def download_field_image( Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. field_id: The field on this signer's copy, as in the field's `image_url`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -380,7 +380,7 @@ async def validate( ) -> SessionsSignaturesValidateResponse: """Validate signatures again. - Re-check the signed documents of an Electronic Signature step. Didit re-reads every signed PDF, checks its SHA-256 and validates the PAdES signature, the certificate, the revocation data and the timestamp, then saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if any of them hasn't signed. + Re-check the signed documents of an E-signature step. Didit re-reads every signed PDF, checks its SHA-256 and, for an Advanced (AES) signature, validates the PAdES signature, the certificate, the revocation data and the timestamp (a Simple signature has no digital signature, so only the file integrity is checked), then saves the result in each signer's `validation` and returns the updated items. Nothing is signed again. Send `signature_id` to check one signer; without it, every signer of the step is checked, and the call fails if any of them hasn't signed. Needs `write:sessions`; your API key works. In the console it's the **Validate again** button. @@ -388,7 +388,7 @@ async def validate( Args: session_id: The User Verification (KYC) or Business Verification (KYB) session. - node_id: The Electronic Signature step: `node_id` of the item in `signatures[]`. + node_id: The E-signature step: `node_id` of the item in `signatures[]`. signature_id: `id` of one signer's item in `signatures[]`. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. diff --git a/src/didit/resources/transactions/__init__.py b/src/didit/resources/transactions/__init__.py index 5ddcdc2..2d5a60a 100644 --- a/src/didit/resources/transactions/__init__.py +++ b/src/didit/resources/transactions/__init__.py @@ -117,6 +117,7 @@ def list( limit: int | NotGiven = NOT_GIVEN, offset: int | NotGiven = NOT_GIVEN, travel_rule_status: str | NotGiven = NOT_GIVEN, + assignee: str | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -132,6 +133,7 @@ def list( limit: Page size. Defaults to 50 when omitted. There is no enforced maximum, but keep pages small for latency. offset: Zero-based offset of the first record to return. Prefer following the `next` URL from the previous page. travel_rule_status: Return only transactions whose Travel Rule transfer is in this exact status (for example `ON_HOLD` or `AWAITING_COUNTERPARTY`). `count` follows this filter; `total_transactions` still counts every transaction in the application. + assignee: Comma-separated; a transaction matches when it meets any value. `unassigned` is what nobody holds yet, `rules` is what the rules decided on their own without a reviewer, and a member email matches the reviewer assigned to it. `me` is the signed-in Console reviewer, so an API key sending `me` gets `400`. 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. @@ -145,7 +147,12 @@ def list( cast_to=TransactionsListResponse, item_type=TransactionsListResponseResults, auth="api_key", - query={"limit": limit, "offset": offset, "travel_rule_status": travel_rule_status}, + query={ + "limit": limit, + "offset": offset, + "travel_rule_status": travel_rule_status, + "assignee": assignee, + }, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -568,6 +575,7 @@ def list( limit: int | NotGiven = NOT_GIVEN, offset: int | NotGiven = NOT_GIVEN, travel_rule_status: str | NotGiven = NOT_GIVEN, + assignee: str | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -583,6 +591,7 @@ def list( limit: Page size. Defaults to 50 when omitted. There is no enforced maximum, but keep pages small for latency. offset: Zero-based offset of the first record to return. Prefer following the `next` URL from the previous page. travel_rule_status: Return only transactions whose Travel Rule transfer is in this exact status (for example `ON_HOLD` or `AWAITING_COUNTERPARTY`). `count` follows this filter; `total_transactions` still counts every transaction in the application. + assignee: Comma-separated; a transaction matches when it meets any value. `unassigned` is what nobody holds yet, `rules` is what the rules decided on their own without a reviewer, and a member email matches the reviewer assigned to it. `me` is the signed-in Console reviewer, so an API key sending `me` gets `400`. 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. @@ -596,7 +605,12 @@ def list( cast_to=TransactionsListResponse, item_type=TransactionsListResponseResults, auth="api_key", - query={"limit": limit, "offset": offset, "travel_rule_status": travel_rule_status}, + query={ + "limit": limit, + "offset": offset, + "travel_rule_status": travel_rule_status, + "assignee": assignee, + }, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, diff --git a/src/didit/resources/travel_rule/__init__.py b/src/didit/resources/travel_rule/__init__.py index 755ba31..c87b830 100644 --- a/src/didit/resources/travel_rule/__init__.py +++ b/src/didit/resources/travel_rule/__init__.py @@ -74,6 +74,14 @@ TravelRuleTransfersWithRawResponse, TravelRuleTransfersWithStreamingResponse, ) + from didit.resources.travel_rule.unmatched_deposits import ( + AsyncTravelRuleUnmatchedDeposits, + AsyncTravelRuleUnmatchedDepositsWithRawResponse, + AsyncTravelRuleUnmatchedDepositsWithStreamingResponse, + TravelRuleUnmatchedDeposits, + TravelRuleUnmatchedDepositsWithRawResponse, + TravelRuleUnmatchedDepositsWithStreamingResponse, + ) from didit.resources.travel_rule.wallet_addresses import ( AsyncTravelRuleWalletAddresses, AsyncTravelRuleWalletAddressesWithRawResponse, @@ -114,7 +122,7 @@ class TravelRule(SyncAPIResource): Methods: ``clear_vasp_decision``, ``create_widget_session``, ``list_vasp_questionnaires``, ``list_vasps``, ``register_inbound``, ``retrieve_settings``, ``retrieve_vasp``, ``retrieve_vasp_decision``, ``retrieve_vasp_screening``, ``screen_vasp``, ``send_compliance_email_confirmation``, ``send_vasp_questionnaire``, ``update_settings``, ``update_vasp_decision``. - Nested resources: ``counterparty_contacts``, ``networks``, ``transfers``, ``wallet_addresses``, ``wallet_proofs``, ``workspace``. + Nested resources: ``counterparty_contacts``, ``networks``, ``transfers``, ``unmatched_deposits``, ``wallet_addresses``, ``wallet_proofs``, ``workspace``. """ @cached_property @@ -135,6 +143,12 @@ def transfers(self) -> TravelRuleTransfers: return TravelRuleTransfers(self._client) + @cached_property + def unmatched_deposits(self) -> TravelRuleUnmatchedDeposits: + from didit.resources.travel_rule.unmatched_deposits import TravelRuleUnmatchedDeposits + + return TravelRuleUnmatchedDeposits(self._client) + @cached_property def wallet_addresses(self) -> TravelRuleWalletAddresses: from didit.resources.travel_rule.wallet_addresses import TravelRuleWalletAddresses @@ -850,7 +864,7 @@ class AsyncTravelRule(AsyncAPIResource): Methods: ``clear_vasp_decision``, ``create_widget_session``, ``list_vasp_questionnaires``, ``list_vasps``, ``register_inbound``, ``retrieve_settings``, ``retrieve_vasp``, ``retrieve_vasp_decision``, ``retrieve_vasp_screening``, ``screen_vasp``, ``send_compliance_email_confirmation``, ``send_vasp_questionnaire``, ``update_settings``, ``update_vasp_decision``. - Nested resources: ``counterparty_contacts``, ``networks``, ``transfers``, ``wallet_addresses``, ``wallet_proofs``, ``workspace``. + Nested resources: ``counterparty_contacts``, ``networks``, ``transfers``, ``unmatched_deposits``, ``wallet_addresses``, ``wallet_proofs``, ``workspace``. """ @cached_property @@ -873,6 +887,12 @@ def transfers(self) -> AsyncTravelRuleTransfers: return AsyncTravelRuleTransfers(self._client) + @cached_property + def unmatched_deposits(self) -> AsyncTravelRuleUnmatchedDeposits: + from didit.resources.travel_rule.unmatched_deposits import AsyncTravelRuleUnmatchedDeposits + + return AsyncTravelRuleUnmatchedDeposits(self._client) + @cached_property def wallet_addresses(self) -> AsyncTravelRuleWalletAddresses: from didit.resources.travel_rule.wallet_addresses import AsyncTravelRuleWalletAddresses @@ -1623,6 +1643,14 @@ def transfers(self) -> TravelRuleTransfersWithRawResponse: return TravelRuleTransfersWithRawResponse(self._resource.transfers) + @cached_property + def unmatched_deposits(self) -> TravelRuleUnmatchedDepositsWithRawResponse: + from didit.resources.travel_rule.unmatched_deposits import ( + TravelRuleUnmatchedDepositsWithRawResponse, + ) + + return TravelRuleUnmatchedDepositsWithRawResponse(self._resource.unmatched_deposits) + @cached_property def wallet_addresses(self) -> TravelRuleWalletAddressesWithRawResponse: from didit.resources.travel_rule.wallet_addresses import ( @@ -1692,6 +1720,14 @@ def transfers(self) -> AsyncTravelRuleTransfersWithRawResponse: return AsyncTravelRuleTransfersWithRawResponse(self._resource.transfers) + @cached_property + def unmatched_deposits(self) -> AsyncTravelRuleUnmatchedDepositsWithRawResponse: + from didit.resources.travel_rule.unmatched_deposits import ( + AsyncTravelRuleUnmatchedDepositsWithRawResponse, + ) + + return AsyncTravelRuleUnmatchedDepositsWithRawResponse(self._resource.unmatched_deposits) + @cached_property def wallet_addresses(self) -> AsyncTravelRuleWalletAddressesWithRawResponse: from didit.resources.travel_rule.wallet_addresses import ( @@ -1765,6 +1801,14 @@ def transfers(self) -> TravelRuleTransfersWithStreamingResponse: return TravelRuleTransfersWithStreamingResponse(self._resource.transfers) + @cached_property + def unmatched_deposits(self) -> TravelRuleUnmatchedDepositsWithStreamingResponse: + from didit.resources.travel_rule.unmatched_deposits import ( + TravelRuleUnmatchedDepositsWithStreamingResponse, + ) + + return TravelRuleUnmatchedDepositsWithStreamingResponse(self._resource.unmatched_deposits) + @cached_property def wallet_addresses(self) -> TravelRuleWalletAddressesWithStreamingResponse: from didit.resources.travel_rule.wallet_addresses import ( @@ -1848,6 +1892,16 @@ def transfers(self) -> AsyncTravelRuleTransfersWithStreamingResponse: return AsyncTravelRuleTransfersWithStreamingResponse(self._resource.transfers) + @cached_property + def unmatched_deposits(self) -> AsyncTravelRuleUnmatchedDepositsWithStreamingResponse: + from didit.resources.travel_rule.unmatched_deposits import ( + AsyncTravelRuleUnmatchedDepositsWithStreamingResponse, + ) + + return AsyncTravelRuleUnmatchedDepositsWithStreamingResponse( + self._resource.unmatched_deposits + ) + @cached_property def wallet_addresses(self) -> AsyncTravelRuleWalletAddressesWithStreamingResponse: from didit.resources.travel_rule.wallet_addresses import ( diff --git a/src/didit/resources/travel_rule/unmatched_deposits.py b/src/didit/resources/travel_rule/unmatched_deposits.py new file mode 100644 index 0000000..56fbe54 --- /dev/null +++ b/src/didit/resources/travel_rule/unmatched_deposits.py @@ -0,0 +1,310 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +"""The ``travel_rule.unmatched_deposits`` resource.""" + +from __future__ import annotations + +import datetime as _dt +from functools import cached_property +from typing import cast + +import httpx + +from didit._pagination import AsyncPaginator, SyncPage +from didit._resource import AsyncAPIResource, SyncAPIResource +from didit._response import ( + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, + to_raw_response_wrapper, + to_streamed_response_wrapper, +) +from didit._types import NOT_GIVEN, Body, Headers, NotGiven, Query +from didit.types.components.travel_rule_manual_match_response import TravelRuleManualMatchResponse +from didit.types.components.travel_rule_transfer_row import TravelRuleTransferRow +from didit.types.travel_rule.unmatched_deposits.list_response import ( + TravelRuleUnmatchedDepositsListResponse, +) + +__all__ = [ + "TravelRuleUnmatchedDeposits", + "AsyncTravelRuleUnmatchedDeposits", + "TravelRuleUnmatchedDepositsWithRawResponse", + "AsyncTravelRuleUnmatchedDepositsWithRawResponse", + "TravelRuleUnmatchedDepositsWithStreamingResponse", + "AsyncTravelRuleUnmatchedDepositsWithStreamingResponse", +] + + +class TravelRuleUnmatchedDeposits(SyncAPIResource): + """The ``travel_rule.unmatched_deposits`` resource of the Didit API. + + Methods: ``list``, ``match``. + """ + + @cached_property + def with_raw_response(self) -> TravelRuleUnmatchedDepositsWithRawResponse: + """Every method of this resource, returning the raw HTTP response.""" + return TravelRuleUnmatchedDepositsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> TravelRuleUnmatchedDepositsWithStreamingResponse: + """Every method of this resource, returning the HTTP response before reading its body.""" + return TravelRuleUnmatchedDepositsWithStreamingResponse(self) + + def list( + self, + *, + direction: str | NotGiven = NOT_GIVEN, + status: str | NotGiven = NOT_GIVEN, + rail: str | NotGiven = NOT_GIVEN, + kind: str | NotGiven = NOT_GIVEN, + currency: str | NotGiven = NOT_GIVEN, + start_date: str | _dt.date | NotGiven = NOT_GIVEN, + end_date: str | _dt.date | NotGiven = NOT_GIVEN, + counterparty: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | 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, + ) -> SyncPage[TravelRuleTransferRow]: + """List unmatched Travel Rule deposits. + + Inbound deposits that are still waiting for the originating VASP's Travel Rule data: their transfer is `AWAITING_COUNTERPARTY`, `NOT_ENOUGH_COUNTERPARTY_DATA` or `COUNTERPARTY_VASP_NOT_FOUND`, no received message is paired with them, and nobody matched them by hand. The rows and the filters are the same as in `GET /v3/travel-rule/transfers/`, newest first, paginated with `limit` (default 50) and `offset`. Pair a deposit with the message the originating VASP sent with `POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`. + + ``GET /v3/travel-rule/unmatched/`` + + Args: + direction: INBOUND, OUTBOUND, or both comma-separated. Case-sensitive. + status: One or more transfer statuses, comma-separated. + rail: One or more of INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP, comma-separated. + kind: withdrawal, deposit or message, comma-separated. + currency: The transaction's currency, case-insensitive. + start_date: Transfers created on or after this day (UTC), YYYY-MM-DD. + end_date: Transfers created on or before this day (UTC), YYYY-MM-DD. + counterparty: The `id` of a directory entry or Didit network member from GET /v3/travel-rule/vasps/: your transfers with that counterparty. A value that is not a valid id answers 400. + limit: Page size, default 50. + offset: Rows to skip. + 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( + "SyncPage[TravelRuleTransferRow]", + self._client.request_page( + "get", + "/v3/travel-rule/unmatched/", + cast_to=TravelRuleUnmatchedDepositsListResponse, + item_type=TravelRuleTransferRow, + auth="api_key", + query={ + "direction": direction, + "status": status, + "rail": rail, + "kind": kind, + "currency": currency, + "start_date": start_date, + "end_date": end_date, + "counterparty": counterparty, + "limit": limit, + "offset": offset, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + def match( + self, + transaction_uuid: str, + *, + transaction_id: str, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> TravelRuleManualMatchResponse: + """Match a Travel Rule deposit to a received message. + + Pair an inbound deposit that is still waiting for originator data with the Travel Rule message the originating VASP sent for it. The deposit takes the message's originator data, counterparty VASP and rail, and both transfers record the match on their timelines. `transaction_uuid` is the deposit's `transaction_id` from `GET /v3/travel-rule/unmatched/`. `transaction_id` in the body is the received message's `transaction_id`, from a row of `GET /v3/travel-rule/transfers/?kind=message`; the transfer's own `id` is not found. The message must be for the same asset as the deposit. A deposit or message deleted from the Console answers `404`; one that has already moved on (matched, or no longer waiting) answers `409`. + + ``POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`` + + Args: + transaction_uuid: The `transaction_id` of the unmatched deposit. + transaction_id: The `transaction_id` of the received Travel Rule message (a row with `kind: message`). + 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( + "TravelRuleManualMatchResponse", + self._client.request( + "post", + "/v3/travel-rule/unmatched/{transaction_uuid}/match/", + cast_to=TravelRuleManualMatchResponse, + path_params={"transaction_uuid": transaction_uuid}, + auth="api_key", + body={"transaction_id": transaction_id}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + +class AsyncTravelRuleUnmatchedDeposits(AsyncAPIResource): + """The ``travel_rule.unmatched_deposits`` resource of the Didit API. + + Methods: ``list``, ``match``. + """ + + @cached_property + def with_raw_response(self) -> AsyncTravelRuleUnmatchedDepositsWithRawResponse: + """Every method of this resource, returning the raw HTTP response.""" + return AsyncTravelRuleUnmatchedDepositsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncTravelRuleUnmatchedDepositsWithStreamingResponse: + """Every method of this resource, returning the HTTP response before reading its body.""" + return AsyncTravelRuleUnmatchedDepositsWithStreamingResponse(self) + + def list( + self, + *, + direction: str | NotGiven = NOT_GIVEN, + status: str | NotGiven = NOT_GIVEN, + rail: str | NotGiven = NOT_GIVEN, + kind: str | NotGiven = NOT_GIVEN, + currency: str | NotGiven = NOT_GIVEN, + start_date: str | _dt.date | NotGiven = NOT_GIVEN, + end_date: str | _dt.date | NotGiven = NOT_GIVEN, + counterparty: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + offset: int | 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, + ) -> AsyncPaginator[TravelRuleTransferRow]: + """List unmatched Travel Rule deposits. + + Inbound deposits that are still waiting for the originating VASP's Travel Rule data: their transfer is `AWAITING_COUNTERPARTY`, `NOT_ENOUGH_COUNTERPARTY_DATA` or `COUNTERPARTY_VASP_NOT_FOUND`, no received message is paired with them, and nobody matched them by hand. The rows and the filters are the same as in `GET /v3/travel-rule/transfers/`, newest first, paginated with `limit` (default 50) and `offset`. Pair a deposit with the message the originating VASP sent with `POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`. + + ``GET /v3/travel-rule/unmatched/`` + + Args: + direction: INBOUND, OUTBOUND, or both comma-separated. Case-sensitive. + status: One or more transfer statuses, comma-separated. + rail: One or more of INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP, comma-separated. + kind: withdrawal, deposit or message, comma-separated. + currency: The transaction's currency, case-insensitive. + start_date: Transfers created on or after this day (UTC), YYYY-MM-DD. + end_date: Transfers created on or before this day (UTC), YYYY-MM-DD. + counterparty: The `id` of a directory entry or Didit network member from GET /v3/travel-rule/vasps/: your transfers with that counterparty. A value that is not a valid id answers 400. + limit: Page size, default 50. + offset: Rows to skip. + 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( + "AsyncPaginator[TravelRuleTransferRow]", + self._client.request_page( + "get", + "/v3/travel-rule/unmatched/", + cast_to=TravelRuleUnmatchedDepositsListResponse, + item_type=TravelRuleTransferRow, + auth="api_key", + query={ + "direction": direction, + "status": status, + "rail": rail, + "kind": kind, + "currency": currency, + "start_date": start_date, + "end_date": end_date, + "counterparty": counterparty, + "limit": limit, + "offset": offset, + }, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + async def match( + self, + transaction_uuid: str, + *, + transaction_id: str, + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> TravelRuleManualMatchResponse: + """Match a Travel Rule deposit to a received message. + + Pair an inbound deposit that is still waiting for originator data with the Travel Rule message the originating VASP sent for it. The deposit takes the message's originator data, counterparty VASP and rail, and both transfers record the match on their timelines. `transaction_uuid` is the deposit's `transaction_id` from `GET /v3/travel-rule/unmatched/`. `transaction_id` in the body is the received message's `transaction_id`, from a row of `GET /v3/travel-rule/transfers/?kind=message`; the transfer's own `id` is not found. The message must be for the same asset as the deposit. A deposit or message deleted from the Console answers `404`; one that has already moved on (matched, or no longer waiting) answers `409`. + + ``POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`` + + Args: + transaction_uuid: The `transaction_id` of the unmatched deposit. + transaction_id: The `transaction_id` of the received Travel Rule message (a row with `kind: message`). + 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( + "TravelRuleManualMatchResponse", + await self._client.request( + "post", + "/v3/travel-rule/unmatched/{transaction_uuid}/match/", + cast_to=TravelRuleManualMatchResponse, + path_params={"transaction_uuid": transaction_uuid}, + auth="api_key", + body={"transaction_id": transaction_id}, + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + ), + ) + + +class TravelRuleUnmatchedDepositsWithRawResponse: + def __init__(self, resource: TravelRuleUnmatchedDeposits) -> None: + self._resource = resource + self.list = to_raw_response_wrapper(resource.list) + self.match = to_raw_response_wrapper(resource.match) + + +class AsyncTravelRuleUnmatchedDepositsWithRawResponse: + def __init__(self, resource: AsyncTravelRuleUnmatchedDeposits) -> None: + self._resource = resource + self.list = async_to_raw_response_wrapper(resource.list) + self.match = async_to_raw_response_wrapper(resource.match) + + +class TravelRuleUnmatchedDepositsWithStreamingResponse: + def __init__(self, resource: TravelRuleUnmatchedDeposits) -> None: + self._resource = resource + self.list = to_streamed_response_wrapper(resource.list) + self.match = to_streamed_response_wrapper(resource.match) + + +class AsyncTravelRuleUnmatchedDepositsWithStreamingResponse: + def __init__(self, resource: AsyncTravelRuleUnmatchedDeposits) -> None: + self._resource = resource + self.list = async_to_streamed_response_wrapper(resource.list) + self.match = async_to_streamed_response_wrapper(resource.match) diff --git a/src/didit/resources/users.py b/src/didit/resources/users.py index 17fa7c2..0a80d3d 100644 --- a/src/didit/resources/users.py +++ b/src/didit/resources/users.py @@ -259,6 +259,8 @@ def batch_delete( vendor_data_list: Sequence[str] | NotGiven = NOT_GIVEN, didit_internal_id_list: Sequence[str] | NotGiven = NOT_GIVEN, delete_all: bool | NotGiven = NOT_GIVEN, + retain_face_embeddings: bool | NotGiven = NOT_GIVEN, + face_retention_days: int | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -268,7 +270,7 @@ def batch_delete( **Permanently delete** users: the user records are removed permanently. For everyday blocking prefer [Update User Status](#patch-/v3/users/-vendor_data-/update-status/) with `BLOCKED`. Select users with `vendor_data_list`, with `didit_internal_id_list`, or with both at once; or pass `delete_all: true`. This endpoint never narrows `delete_all` with filters. The Console's People filters are refused with a `400` (see the `400` response), so a narrowed intent does not turn into a full wipe. Two exceptions: `filter_has_approved_sessions` and `filter_has_declined_sessions` are not refused and not applied, so with `delete_all: true` they still delete every user; do not send them. - **Biometric templates:** every image-free biometric template retained for these users after session deletion (see `/v3/biometric-templates/`) is purged before the user is deleted, so the person stops matching in duplicate detection and Face Search. If a template cannot be purged because a biometric store is unavailable, the call returns `503`, no user in the request is deleted, and repeating the request finishes the job. + **Biometric templates:** unless you set `retain_face_embeddings` to `true`, every image-free biometric template retained for these users after session deletion (see `/v3/biometric-templates/`) is purged before the user is deleted, so the person stops matching in duplicate detection and Face Search. With `retain_face_embeddings: true` and `face_retention_days`, you choose to keep one image-free biometric template per person for that many days, and nothing else about the person is kept. If a template cannot be purged because a biometric store is unavailable, the call returns `503`, no user in the request is deleted, and repeating the request finishes the job. **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request. @@ -278,6 +280,8 @@ def batch_delete( vendor_data_list: Your own identifiers to delete, matched exactly as sent. didit_internal_id_list: Didit internal user IDs to delete - the `didit_internal_id` returned by the create and get endpoints. delete_all: If `true`, deletes every user in the application. + retain_face_embeddings: Your explicit choice to keep one image-free biometric template of each deleted person for duplicate detection, for `face_retention_days`. Everything else about the person is deleted. Omit it, or send `false`, to delete the templates with the users. When `true`, `face_retention_days` is required. + face_retention_days: Number of days the image-free biometric template is kept when `retain_face_embeddings` is `true`. Required with it, and rejected without it with a `400` on `face_retention_days`. 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. @@ -294,6 +298,8 @@ def batch_delete( "vendor_data_list": vendor_data_list, "didit_internal_id_list": didit_internal_id_list, "delete_all": delete_all, + "retain_face_embeddings": retain_face_embeddings, + "face_retention_days": face_retention_days, }, extra_headers=extra_headers, extra_query=extra_query, @@ -890,6 +896,8 @@ async def batch_delete( vendor_data_list: Sequence[str] | NotGiven = NOT_GIVEN, didit_internal_id_list: Sequence[str] | NotGiven = NOT_GIVEN, delete_all: bool | NotGiven = NOT_GIVEN, + retain_face_embeddings: bool | NotGiven = NOT_GIVEN, + face_retention_days: int | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -899,7 +907,7 @@ async def batch_delete( **Permanently delete** users: the user records are removed permanently. For everyday blocking prefer [Update User Status](#patch-/v3/users/-vendor_data-/update-status/) with `BLOCKED`. Select users with `vendor_data_list`, with `didit_internal_id_list`, or with both at once; or pass `delete_all: true`. This endpoint never narrows `delete_all` with filters. The Console's People filters are refused with a `400` (see the `400` response), so a narrowed intent does not turn into a full wipe. Two exceptions: `filter_has_approved_sessions` and `filter_has_declined_sessions` are not refused and not applied, so with `delete_all: true` they still delete every user; do not send them. - **Biometric templates:** every image-free biometric template retained for these users after session deletion (see `/v3/biometric-templates/`) is purged before the user is deleted, so the person stops matching in duplicate detection and Face Search. If a template cannot be purged because a biometric store is unavailable, the call returns `503`, no user in the request is deleted, and repeating the request finishes the job. + **Biometric templates:** unless you set `retain_face_embeddings` to `true`, every image-free biometric template retained for these users after session deletion (see `/v3/biometric-templates/`) is purged before the user is deleted, so the person stops matching in duplicate detection and Face Search. With `retain_face_embeddings: true` and `face_retention_days`, you choose to keep one image-free biometric template per person for that many days, and nothing else about the person is kept. If a template cannot be purged because a biometric store is unavailable, the call returns `503`, no user in the request is deleted, and repeating the request finishes the job. **Filed regulatory reports:** if the selected data is in a finalized regulatory report, the whole request is refused with `409` and nothing is deleted. The body uses `code: in_filed_report` and names each report with `uuid`, `report_number`, `report_type` and `case_uuid`. Delete the reports, then repeat the request. @@ -909,6 +917,8 @@ async def batch_delete( vendor_data_list: Your own identifiers to delete, matched exactly as sent. didit_internal_id_list: Didit internal user IDs to delete - the `didit_internal_id` returned by the create and get endpoints. delete_all: If `true`, deletes every user in the application. + retain_face_embeddings: Your explicit choice to keep one image-free biometric template of each deleted person for duplicate detection, for `face_retention_days`. Everything else about the person is deleted. Omit it, or send `false`, to delete the templates with the users. When `true`, `face_retention_days` is required. + face_retention_days: Number of days the image-free biometric template is kept when `retain_face_embeddings` is `true`. Required with it, and rejected without it with a `400` on `face_retention_days`. 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. @@ -925,6 +935,8 @@ async def batch_delete( "vendor_data_list": vendor_data_list, "didit_internal_id_list": didit_internal_id_list, "delete_all": delete_all, + "retain_face_embeddings": retain_face_embeddings, + "face_retention_days": face_retention_days, }, extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/didit/resources/wallet_screening.py b/src/didit/resources/wallet_screening.py index 8be9ccb..03cf897 100644 --- a/src/didit/resources/wallet_screening.py +++ b/src/didit/resources/wallet_screening.py @@ -71,11 +71,16 @@ def screen( "BASE", "OP", "ARB", + "AVAX", + "ADA", + "XLM", + "HBAR", "CELO", "MODE", "PLUME", ] - | str, + | str + | NotGiven = NOT_GIVEN, direction: Literal["inbound", "outbound", "deposit", "withdrawal"] | str | NotGiven = NOT_GIVEN, @@ -92,7 +97,7 @@ def screen( Args: wallet_address: The crypto address or network identifier to screen. Must match the selected network (e.g. a `0x`-prefixed 40-hex-char address for EVM chains). Alias: `address`. - blockchain: Network identifier. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), and ARB (Arbitrum One). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`. + blockchain: Optional network identifier. When omitted, the network is read from the address format: `bc1`, `1` and `3` addresses are Bitcoin (BTC), `T` addresses are Tron (TRX) and base58 public keys are Solana (SOL). A `0x` address is valid on every EVM network, so omitting `blockchain` for it answers 422 with the candidate networks in `candidate_chains`. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar) and HBAR (Hedera). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`. direction: Optional. Whether the address is being screened as an inbound (deposit) or outbound (withdrawal) counterparty. Accepts `inbound`, `outbound`, `deposit`, or `withdrawal`. Defaults to a neutral pre-transfer screen when omitted. This is passed to the provider as context only; it does not change the returned `risk_score`, `severity`, or the `source_of_funds`/`destination_of_funds` breakdowns, which are always both returned regardless of `direction`. Changing or omitting `direction` therefore does not require re-screening an address. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. @@ -277,11 +282,16 @@ async def screen( "BASE", "OP", "ARB", + "AVAX", + "ADA", + "XLM", + "HBAR", "CELO", "MODE", "PLUME", ] - | str, + | str + | NotGiven = NOT_GIVEN, direction: Literal["inbound", "outbound", "deposit", "withdrawal"] | str | NotGiven = NOT_GIVEN, @@ -298,7 +308,7 @@ async def screen( Args: wallet_address: The crypto address or network identifier to screen. Must match the selected network (e.g. a `0x`-prefixed 40-hex-char address for EVM chains). Alias: `address`. - blockchain: Network identifier. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), and ARB (Arbitrum One). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`. + blockchain: Optional network identifier. When omitted, the network is read from the address format: `bc1`, `1` and `3` addresses are Bitcoin (BTC), `T` addresses are Tron (TRX) and base58 public keys are Solana (SOL). A `0x` address is valid on every EVM network, so omitting `blockchain` for it answers 422 with the candidate networks in `candidate_chains`. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar) and HBAR (Hedera). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`. direction: Optional. Whether the address is being screened as an inbound (deposit) or outbound (withdrawal) counterparty. Accepts `inbound`, `outbound`, `deposit`, or `withdrawal`. Defaults to a neutral pre-transfer screen when omitted. This is passed to the provider as context only; it does not change the returned `risk_score`, `severity`, or the `source_of_funds`/`destination_of_funds` breakdowns, which are always both returned regardless of `direction`. Changing or omitting `direction` therefore does not require re-screening an address. extra_headers: Headers to add to (or, with ``None``, remove from) this request. extra_query: Query parameters to add to this request. diff --git a/src/didit/resources/webhooks/__init__.py b/src/didit/resources/webhooks/__init__.py index bbd0744..293f9ea 100644 --- a/src/didit/resources/webhooks/__init__.py +++ b/src/didit/resources/webhooks/__init__.py @@ -111,6 +111,7 @@ def update_config( face_retention_days: int | None | NotGiven = NOT_GIVEN, biometric_consent_mode: Literal["auto", "always", "never"] | str | NotGiven = NOT_GIVEN, allowed_return_hosts: Sequence[str] | NotGiven = NOT_GIVEN, + allowed_domains: Sequence[str] | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -132,6 +133,7 @@ def update_config( face_retention_days: Retention period, in days, of biometric templates under `retain_until_user_deleted`. biometric_consent_mode: When the hosted flow and the native SDKs ask the person for explicit biometric consent before a face capture. `auto` (default) asks only where a trigger applies: a declared state, the person's IP, or the identity document's issuer is in Illinois, Texas or Colorado, or the person looks to be in the US without a known state. `always` asks every person whose workflow captures a face. `never` never shows the step, and you collect consent yourself before the selfie. Each change is recorded in the audit log. See [Biometric consent](https://docs.didit.me/getting-started/biometric-consent). allowed_return_hosts: Replaces the whole list of Digital ID wallet return hosts. Bare hostnames only, such as `shop.example.com`: no scheme, port, path or wildcard. Values are lowercased and duplicates are dropped. Send `[]` to clear the list. + allowed_domains: Replaces the whole list of allowed origins. Origins (for example `https://app.example.com`; `http` only for `localhost`) the hosted verification flow may be embedded in and may send the user back to with a session callback. Server-to-server calls are not affected. An empty list means no restriction. Didit stores each origin in lower case without a default port. An invalid entry fails with `400` on `allowed_domains`. Send `[]` to remove the restriction. 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. @@ -154,6 +156,7 @@ def update_config( "face_retention_days": face_retention_days, "biometric_consent_mode": biometric_consent_mode, "allowed_return_hosts": allowed_return_hosts, + "allowed_domains": allowed_domains, }, extra_headers=extra_headers, extra_query=extra_query, @@ -235,6 +238,7 @@ async def update_config( face_retention_days: int | None | NotGiven = NOT_GIVEN, biometric_consent_mode: Literal["auto", "always", "never"] | str | NotGiven = NOT_GIVEN, allowed_return_hosts: Sequence[str] | NotGiven = NOT_GIVEN, + allowed_domains: Sequence[str] | NotGiven = NOT_GIVEN, extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, @@ -256,6 +260,7 @@ async def update_config( face_retention_days: Retention period, in days, of biometric templates under `retain_until_user_deleted`. biometric_consent_mode: When the hosted flow and the native SDKs ask the person for explicit biometric consent before a face capture. `auto` (default) asks only where a trigger applies: a declared state, the person's IP, or the identity document's issuer is in Illinois, Texas or Colorado, or the person looks to be in the US without a known state. `always` asks every person whose workflow captures a face. `never` never shows the step, and you collect consent yourself before the selfie. Each change is recorded in the audit log. See [Biometric consent](https://docs.didit.me/getting-started/biometric-consent). allowed_return_hosts: Replaces the whole list of Digital ID wallet return hosts. Bare hostnames only, such as `shop.example.com`: no scheme, port, path or wildcard. Values are lowercased and duplicates are dropped. Send `[]` to clear the list. + allowed_domains: Replaces the whole list of allowed origins. Origins (for example `https://app.example.com`; `http` only for `localhost`) the hosted verification flow may be embedded in and may send the user back to with a session callback. Server-to-server calls are not affected. An empty list means no restriction. Didit stores each origin in lower case without a default port. An invalid entry fails with `400` on `allowed_domains`. Send `[]` to remove the restriction. 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. @@ -278,6 +283,7 @@ async def update_config( "face_retention_days": face_retention_days, "biometric_consent_mode": biometric_consent_mode, "allowed_return_hosts": allowed_return_hosts, + "allowed_domains": allowed_domains, }, extra_headers=extra_headers, extra_query=extra_query, diff --git a/src/didit/types/__init__.py b/src/didit/types/__init__.py index 7752125..fa8a2dc 100644 --- a/src/didit/types/__init__.py +++ b/src/didit/types/__init__.py @@ -458,6 +458,12 @@ from didit.types.components.application_analytics_summary import ( ApplicationAnalyticsSummary as ApplicationAnalyticsSummary, ) + from didit.types.components.application_analytics_today import ( + ApplicationAnalyticsToday as ApplicationAnalyticsToday, + ) + from didit.types.components.application_analytics_today import ( + ApplicationAnalyticsTodayOutcomes as ApplicationAnalyticsTodayOutcomes, + ) from didit.types.components.application_analytics_verification_time_point import ( ApplicationAnalyticsVerificationTimePoint as ApplicationAnalyticsVerificationTimePoint, ) @@ -559,6 +565,7 @@ from didit.types.components.bank_verification_result import ( BankVerificationResultRoute as BankVerificationResultRoute, ) + from didit.types.components.biometric_retention import BiometricRetention as BiometricRetention from didit.types.components.blocklisted_item import BlocklistedItem as BlocklistedItem from didit.types.components.branding_customization import ( BrandingCustomization as BrandingCustomization, @@ -851,6 +858,9 @@ from didit.types.components.digital_id_wallet_api_ftn_wallet_verification_start_country_enum import ( DigitalIdWalletApiFtnWalletVerificationStartCountryEnum as DigitalIdWalletApiFtnWalletVerificationStartCountryEnum, ) + from didit.types.components.digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum import ( + DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum as DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum, + ) from didit.types.components.digital_id_wallet_api_govbr_wallet_verification_start_country_enum import ( DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum as DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum, ) @@ -890,6 +900,9 @@ from didit.types.components.digital_id_wallet_api_wallet_catalog_response import ( DigitalIdWalletApiWalletCatalogResponse as DigitalIdWalletApiWalletCatalogResponse, ) + from didit.types.components.digital_id_wallet_api_wallet_digital_credentials_request import ( + DigitalIdWalletApiWalletDigitalCredentialsRequest as DigitalIdWalletApiWalletDigitalCredentialsRequest, + ) from didit.types.components.digital_id_wallet_api_wallet_identity import ( DigitalIdWalletApiWalletIdentity as DigitalIdWalletApiWalletIdentity, ) @@ -912,6 +925,9 @@ DocumentAIDetectedCode as DocumentAIDetectedCode, ) from didit.types.components.email_intelligence import EmailIntelligence as EmailIntelligence + from didit.types.components.email_intelligence import ( + EmailIntelligenceReasonCodes as EmailIntelligenceReasonCodes, + ) from didit.types.components.email_match_item import EmailMatchItem as EmailMatchItem from didit.types.components.email_risk_response import EmailRiskResponse as EmailRiskResponse from didit.types.components.email_risk_response import ( @@ -1002,6 +1018,29 @@ from didit.types.components.fraud_result_enum import FraudResultEnum as FraudResultEnum from didit.types.components.fraud_status_enum import FraudStatusEnum as FraudStatusEnum from didit.types.components.fraud_type_enum import FraudTypeEnum as FraudTypeEnum + from didit.types.components.geolocation_attempt import GeolocationAttempt as GeolocationAttempt + from didit.types.components.geolocation_attempt import ( + GeolocationAttemptAnonymizers as GeolocationAttemptAnonymizers, + ) + from didit.types.components.geolocation_attempt import ( + GeolocationAttemptConsent as GeolocationAttemptConsent, + ) + from didit.types.components.geolocation_attempt import ( + GeolocationAttemptGeofence as GeolocationAttemptGeofence, + ) + from didit.types.components.geolocation_check import GeolocationCheck as GeolocationCheck + from didit.types.components.geolocation_check import ( + GeolocationCheckAnonymizers as GeolocationCheckAnonymizers, + ) + from didit.types.components.geolocation_check import ( + GeolocationCheckConsent as GeolocationCheckConsent, + ) + from didit.types.components.geolocation_check import ( + GeolocationCheckGeofence as GeolocationCheckGeofence, + ) + from didit.types.components.geolocation_check import ( + GeolocationCheckWarnings as GeolocationCheckWarnings, + ) from didit.types.components.import_job_summary import ImportJobSummary as ImportJobSummary from didit.types.components.import_job_summary import ( ImportJobSummaryFaceTemplates as ImportJobSummaryFaceTemplates, @@ -1053,10 +1092,23 @@ from didit.types.components.kyb_key_people_party import ( KYBKeyPeoplePartyVerificationWorkflowFeatures as KYBKeyPeoplePartyVerificationWorkflowFeatures, ) + from didit.types.components.kyb_ownership_structure import ( + KYBOwnershipStructure as KYBOwnershipStructure, + ) + from didit.types.components.kyb_ownership_structure_owner import ( + KYBOwnershipStructureOwner as KYBOwnershipStructureOwner, + ) from didit.types.components.kyb_registry_address import KYBRegistryAddress as KYBRegistryAddress + from didit.types.components.kyb_registry_data import KYBRegistryData as KYBRegistryData + from didit.types.components.kyb_registry_group_company import ( + KYBRegistryGroupCompany as KYBRegistryGroupCompany, + ) from didit.types.components.kyb_registry_industry import ( KYBRegistryIndustry as KYBRegistryIndustry, ) + from didit.types.components.kyb_registry_lite_enrichment import ( + KYBRegistryLiteEnrichment as KYBRegistryLiteEnrichment, + ) from didit.types.components.kyb_registry_ownership import ( KYBRegistryOwnership as KYBRegistryOwnership, ) @@ -1072,9 +1124,19 @@ from didit.types.components.kyb_registry_search_results import ( KYBRegistrySearchResultsPagination as KYBRegistrySearchResultsPagination, ) + from didit.types.components.kyb_registry_section_error import ( + KYBRegistrySectionError as KYBRegistrySectionError, + ) from didit.types.components.kyb_registry_shareholding import ( KYBRegistryShareholding as KYBRegistryShareholding, ) + from didit.types.components.kyb_registry_source import KYBRegistrySource as KYBRegistrySource + from didit.types.components.kyb_registry_ubo_resolution import ( + KYBRegistryUboResolution as KYBRegistryUboResolution, + ) + from didit.types.components.kyb_registry_ubo_resolution import ( + KYBRegistryUboResolutionUnresolved as KYBRegistryUboResolutionUnresolved, + ) from didit.types.components.login_response import LoginResponse as LoginResponse from didit.types.components.monitoring_event import MonitoringEvent as MonitoringEvent from didit.types.components.monitoring_event_create_request import ( @@ -1247,6 +1309,9 @@ PaginatedOrganizationList as PaginatedOrganizationList, ) from didit.types.components.phone_intelligence import PhoneIntelligence as PhoneIntelligence + from didit.types.components.phone_intelligence import ( + PhoneIntelligenceReasonCodes as PhoneIntelligenceReasonCodes, + ) from didit.types.components.phone_match_item import PhoneMatchItem as PhoneMatchItem from didit.types.components.phone_risk_response import PhoneRiskResponse as PhoneRiskResponse from didit.types.components.phone_risk_response import ( @@ -1333,12 +1398,18 @@ SandboxSimulateResponse as SandboxSimulateResponse, ) from didit.types.components.session_decision import SessionDecision as SessionDecision + from didit.types.components.session_decision import ( + SessionDecisionAssignee as SessionDecisionAssignee, + ) from didit.types.components.session_decision import ( SessionDecisionBiometricConsent as SessionDecisionBiometricConsent, ) from didit.types.components.session_decision import ( SessionDecisionContactDetails as SessionDecisionContactDetails, ) + from didit.types.components.session_decision import ( + SessionDecisionDatabaseValidationNotPerformedReason as SessionDecisionDatabaseValidationNotPerformedReason, + ) from didit.types.components.session_decision import ( SessionDecisionDatabaseValidations as SessionDecisionDatabaseValidations, ) @@ -1357,6 +1428,15 @@ from didit.types.components.session_decision import ( SessionDecisionDatabaseValidationsWarnings as SessionDecisionDatabaseValidationsWarnings, ) + from didit.types.components.session_decision import ( + SessionDecisionDecisionTrace as SessionDecisionDecisionTrace, + ) + from didit.types.components.session_decision import ( + SessionDecisionDecisionTraceActor as SessionDecisionDecisionTraceActor, + ) + from didit.types.components.session_decision import ( + SessionDecisionDecisionTraceStatusWarnings as SessionDecisionDecisionTraceStatusWarnings, + ) from didit.types.components.session_decision import ( SessionDecisionDocumentAiDocuments as SessionDecisionDocumentAiDocuments, ) @@ -1408,6 +1488,18 @@ from didit.types.components.session_decision import ( SessionDecisionFaceMatches as SessionDecisionFaceMatches, ) + from didit.types.components.session_decision import ( + SessionDecisionFaceMatchesFaceCoverage as SessionDecisionFaceMatchesFaceCoverage, + ) + from didit.types.components.session_decision import ( + SessionDecisionFaceMatchesFaceCoverageEyes as SessionDecisionFaceMatchesFaceCoverageEyes, + ) + from didit.types.components.session_decision import ( + SessionDecisionFaceMatchesFaceCoverageFace as SessionDecisionFaceMatchesFaceCoverageFace, + ) + from didit.types.components.session_decision import ( + SessionDecisionFaceMatchesFaceCoverageMouth as SessionDecisionFaceMatchesFaceCoverageMouth, + ) from didit.types.components.session_decision import ( SessionDecisionFaceMatchesWarnings as SessionDecisionFaceMatchesWarnings, ) @@ -1570,6 +1662,24 @@ from didit.types.components.session_decision import ( SessionDecisionKeyPeopleChecksUboKycSummary as SessionDecisionKeyPeopleChecksUboKycSummary, ) + from didit.types.components.session_decision import ( + SessionDecisionLinkedRecords as SessionDecisionLinkedRecords, + ) + from didit.types.components.session_decision import ( + SessionDecisionLinkedRecordsEarlierVerifications as SessionDecisionLinkedRecordsEarlierVerifications, + ) + from didit.types.components.session_decision import ( + SessionDecisionLinkedRecordsNetworks as SessionDecisionLinkedRecordsNetworks, + ) + from didit.types.components.session_decision import ( + SessionDecisionLinkedRecordsNetworksItems as SessionDecisionLinkedRecordsNetworksItems, + ) + from didit.types.components.session_decision import ( + SessionDecisionLinkedRecordsSameFace as SessionDecisionLinkedRecordsSameFace, + ) + from didit.types.components.session_decision import ( + SessionDecisionLinkedRecordsSameFaceBestMatch as SessionDecisionLinkedRecordsSameFaceBestMatch, + ) from didit.types.components.session_decision import ( SessionDecisionLivenessChecks as SessionDecisionLivenessChecks, ) @@ -1675,6 +1785,9 @@ from didit.types.components.session_decision import ( SessionDecisionRegistryChecksCompanyOfficers as SessionDecisionRegistryChecksCompanyOfficers, ) + from didit.types.components.session_decision import ( + SessionDecisionRegistryChecksCompanyRegistryMonitoring as SessionDecisionRegistryChecksCompanyRegistryMonitoring, + ) from didit.types.components.session_decision import ( SessionDecisionResubmissions as SessionDecisionResubmissions, ) @@ -1687,11 +1800,15 @@ from didit.types.components.session_decision import ( SessionDecisionReviews as SessionDecisionReviews, ) + from didit.types.components.session_decision import ( + SessionDecisionStatusOverride as SessionDecisionStatusOverride, + ) from didit.types.components.session_deletion_job import SessionDeletionJob as SessionDeletionJob from didit.types.components.session_deletion_job import ( SessionDeletionJobOutcomes as SessionDeletionJobOutcomes, ) from didit.types.components.session_event import SessionEvent as SessionEvent + from didit.types.components.session_files_export import SessionFilesExport as SessionFilesExport from didit.types.components.session_import_error import SessionImportError as SessionImportError from didit.types.components.session_import_job import SessionImportJob as SessionImportJob from didit.types.components.session_sign_document import ( @@ -1967,6 +2084,9 @@ from didit.types.components.travel_rule_inbound_response import ( TravelRuleInboundResponse as TravelRuleInboundResponse, ) + from didit.types.components.travel_rule_manual_match_response import ( + TravelRuleManualMatchResponse as TravelRuleManualMatchResponse, + ) from didit.types.components.travel_rule_matching_rules import ( TravelRuleMatchingRules as TravelRuleMatchingRules, ) @@ -2125,6 +2245,9 @@ from didit.types.components.user_session_list_item import ( UserSessionListItemAdditionalDetailsPoa as UserSessionListItemAdditionalDetailsPoa, ) + from didit.types.components.user_session_list_item import ( + UserSessionListItemAssignee as UserSessionListItemAssignee, + ) from didit.types.components.user_session_list_item import ( UserSessionListItemEmailAddress as UserSessionListItemEmailAddress, ) @@ -2134,6 +2257,9 @@ from didit.types.components.user_session_list_item import ( UserSessionListItemPhoneNumber as UserSessionListItemPhoneNumber, ) + from didit.types.components.user_session_list_item import ( + UserSessionListItemTopWarnings as UserSessionListItemTopWarnings, + ) from didit.types.components.vasp_directory_entry import VaspDirectoryEntry as VaspDirectoryEntry from didit.types.components.vasp_directory_entry import ( VaspDirectoryEntryAliases as VaspDirectoryEntryAliases, @@ -2217,6 +2343,9 @@ WebhookSubscribedEventsParam as WebhookSubscribedEventsParam, ) from didit.types.components.workflow_detail import WorkflowDetail as WorkflowDetail + from didit.types.components.workflow_detail import ( + WorkflowDetailSignatureAvailability as WorkflowDetailSignatureAvailability, + ) from didit.types.components.workflow_list_item import WorkflowListItem as WorkflowListItem from didit.types.components.workflow_list_item import ( WorkflowListItemCreatedBy as WorkflowListItemCreatedBy, @@ -2387,6 +2516,9 @@ from didit.types.id_wallets.start_ftn_params import ( IdWalletsStartFtnParams as IdWalletsStartFtnParams, ) + from didit.types.id_wallets.start_google_wallet_params import ( + IdWalletsStartGoogleWalletParams as IdWalletsStartGoogleWalletParams, + ) from didit.types.id_wallets.start_govbr_params import ( IdWalletsStartGovbrParams as IdWalletsStartGovbrParams, ) @@ -2426,6 +2558,9 @@ from didit.types.id_wallets.start_vipps_params import ( IdWalletsStartVippsParams as IdWalletsStartVippsParams, ) + from didit.types.id_wallets.submit_verification_response_params import ( + IdWalletsSubmitVerificationResponseParams as IdWalletsSubmitVerificationResponseParams, + ) from didit.types.investigator.accept_run_params import ( InvestigatorAcceptRunParams as InvestigatorAcceptRunParams, ) @@ -2481,6 +2616,9 @@ from didit.types.kyb.list_shareholders_response import ( KybListShareholdersResponse202KybRegistryOfficers as KybListShareholdersResponse202KybRegistryOfficers, ) + from didit.types.kyb.list_shareholders_response import ( + KybListShareholdersResponse202KybRegistryRegistryMonitoring as KybListShareholdersResponse202KybRegistryRegistryMonitoring, + ) from didit.types.kyb.list_shareholders_response import ( KybListShareholdersResponseKybRegistry as KybListShareholdersResponseKybRegistry, ) @@ -2490,6 +2628,9 @@ from didit.types.kyb.list_shareholders_response import ( KybListShareholdersResponseKybRegistryOfficers as KybListShareholdersResponseKybRegistryOfficers, ) + from didit.types.kyb.list_shareholders_response import ( + KybListShareholdersResponseKybRegistryRegistryMonitoring as KybListShareholdersResponseKybRegistryRegistryMonitoring, + ) from didit.types.kyb.list_ubos_params import KybListUbosParams as KybListUbosParams from didit.types.kyb.list_ubos_response import KybListUbosResponse as KybListUbosResponse from didit.types.kyb.list_ubos_response import KybListUbosResponse202 as KybListUbosResponse202 @@ -2502,6 +2643,9 @@ from didit.types.kyb.list_ubos_response import ( KybListUbosResponse202KybRegistryOfficers as KybListUbosResponse202KybRegistryOfficers, ) + from didit.types.kyb.list_ubos_response import ( + KybListUbosResponse202KybRegistryRegistryMonitoring as KybListUbosResponse202KybRegistryRegistryMonitoring, + ) from didit.types.kyb.list_ubos_response import ( KybListUbosResponseKybRegistry as KybListUbosResponseKybRegistry, ) @@ -2511,6 +2655,9 @@ from didit.types.kyb.list_ubos_response import ( KybListUbosResponseKybRegistryOfficers as KybListUbosResponseKybRegistryOfficers, ) + from didit.types.kyb.list_ubos_response import ( + KybListUbosResponseKybRegistryRegistryMonitoring as KybListUbosResponseKybRegistryRegistryMonitoring, + ) from didit.types.kyb.search_params import KybSearchParams as KybSearchParams from didit.types.kyb.search_response import KybSearchResponse as KybSearchResponse from didit.types.kyb.select_params import KybSelectParams as KybSelectParams @@ -2524,6 +2671,9 @@ from didit.types.kyb.select_response import ( KybSelectResponseKybRegistryOfficers as KybSelectResponseKybRegistryOfficers, ) + from didit.types.kyb.select_response import ( + KybSelectResponseKybRegistryRegistryMonitoring as KybSelectResponseKybRegistryRegistryMonitoring, + ) from didit.types.lists.create_params import ListsCreateParams as ListsCreateParams from didit.types.lists.entries.create_params import ( ListsEntriesCreateParams as ListsEntriesCreateParams, @@ -2716,6 +2866,15 @@ from didit.types.sessions.bulk_update_aml_hit_status_response import ( SessionsBulkUpdateAmlHitStatusResponse as SessionsBulkUpdateAmlHitStatusResponse, ) + from didit.types.sessions.create_kyb_party_draft_params import ( + SessionsCreateKybPartyDraftParams as SessionsCreateKybPartyDraftParams, + ) + from didit.types.sessions.create_kyb_party_draft_response import ( + SessionsCreateKybPartyDraftResponse as SessionsCreateKybPartyDraftResponse, + ) + from didit.types.sessions.create_kyb_party_draft_response import ( + SessionsCreateKybPartyDraftResponseParty as SessionsCreateKybPartyDraftResponseParty, + ) from didit.types.sessions.create_params import SessionsCreateParams as SessionsCreateParams from didit.types.sessions.create_params import ( SessionsCreateParamsBiometricConsent as SessionsCreateParamsBiometricConsent, @@ -2784,6 +2943,30 @@ from didit.types.sessions.list_feature_overrides_response import ( SessionsListFeatureOverridesResponse as SessionsListFeatureOverridesResponse, ) + from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponse as SessionsListKybExtractedPartiesResponse, + ) + from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponseParties as SessionsListKybExtractedPartiesResponseParties, + ) + from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponsePartiesDocuments as SessionsListKybExtractedPartiesResponsePartiesDocuments, + ) + from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponsePartiesRoles as SessionsListKybExtractedPartiesResponsePartiesRoles, + ) + from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent as SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent, + ) + from didit.types.sessions.list_kyb_party_drafts_response import ( + SessionsListKybPartyDraftsResponse as SessionsListKybPartyDraftsResponse, + ) + from didit.types.sessions.list_kyb_party_drafts_response import ( + SessionsListKybPartyDraftsResponseParties as SessionsListKybPartyDraftsResponseParties, + ) + from didit.types.sessions.list_kyb_party_drafts_response import ( + SessionsListKybPartyDraftsResponsePartiesParty as SessionsListKybPartyDraftsResponsePartiesParty, + ) from didit.types.sessions.list_response import SessionsListResponse as SessionsListResponse from didit.types.sessions.preview_decision_email_params import ( SessionsPreviewDecisionEmailParams as SessionsPreviewDecisionEmailParams, @@ -2823,6 +3006,12 @@ from didit.types.sessions.simulate_params import ( SessionsSimulateParams as SessionsSimulateParams, ) + from didit.types.sessions.submit_kyb_parties_params import ( + SessionsSubmitKybPartiesParams as SessionsSubmitKybPartiesParams, + ) + from didit.types.sessions.submit_kyb_parties_response import ( + SessionsSubmitKybPartiesResponse as SessionsSubmitKybPartiesResponse, + ) from didit.types.sessions.update_aml_hit_status_params import ( SessionsUpdateAmlHitStatusParams as SessionsUpdateAmlHitStatusParams, ) @@ -2865,6 +3054,15 @@ from didit.types.sessions.update_kyb_company_data_response import ( SessionsUpdateKybCompanyDataResponse as SessionsUpdateKybCompanyDataResponse, ) + from didit.types.sessions.update_kyb_party_draft_params import ( + SessionsUpdateKybPartyDraftParams as SessionsUpdateKybPartyDraftParams, + ) + from didit.types.sessions.update_kyb_party_draft_response import ( + SessionsUpdateKybPartyDraftResponse as SessionsUpdateKybPartyDraftResponse, + ) + from didit.types.sessions.update_kyb_party_draft_response import ( + SessionsUpdateKybPartyDraftResponseParty as SessionsUpdateKybPartyDraftResponseParty, + ) from didit.types.sessions.update_kyb_party_params import ( SessionsUpdateKybPartyParams as SessionsUpdateKybPartyParams, ) @@ -2892,6 +3090,12 @@ from didit.types.sessions.update_status_response import ( SessionsUpdateStatusResponse as SessionsUpdateStatusResponse, ) + from didit.types.sessions.upload_kyb_documents_params import ( + SessionsUploadKybDocumentsParams as SessionsUploadKybDocumentsParams, + ) + from didit.types.sessions.upload_kyb_documents_response import ( + SessionsUploadKybDocumentsResponse as SessionsUploadKybDocumentsResponse, + ) from didit.types.transactions.batch_delete_params import ( TransactionsBatchDeleteParamsAllTransactions as TransactionsBatchDeleteParamsAllTransactions, ) @@ -3036,6 +3240,12 @@ from didit.types.travel_rule.transfers.list_response import ( TravelRuleTransfersListResponse as TravelRuleTransfersListResponse, ) + from didit.types.travel_rule.unmatched_deposits.list_response import ( + TravelRuleUnmatchedDepositsListResponse as TravelRuleUnmatchedDepositsListResponse, + ) + from didit.types.travel_rule.unmatched_deposits.match_params import ( + TravelRuleUnmatchedDepositsMatchParams as TravelRuleUnmatchedDepositsMatchParams, + ) from didit.types.travel_rule.update_settings_params import ( TravelRuleUpdateSettingsParams as TravelRuleUpdateSettingsParams, ) @@ -3257,6 +3467,8 @@ "ApplicationAnalyticsResubmissionPoint": "components.application_analytics_resubmission_point", "ApplicationAnalyticsResubmissionStats": "components.application_analytics_resubmission_stats", "ApplicationAnalyticsSummary": "components.application_analytics_summary", + "ApplicationAnalyticsToday": "components.application_analytics_today", + "ApplicationAnalyticsTodayOutcomes": "components.application_analytics_today", "ApplicationAnalyticsVerificationTimePoint": "components.application_analytics_verification_time_point", "ApplicationAnalyticsVerificationTimeStats": "components.application_analytics_verification_time_stats", "ApplicationAnalyticsVerificationTimeStatsPerFeatureValue": "components.application_analytics_verification_time_stats", @@ -3297,6 +3509,7 @@ "BillingRetrieveBalanceResponse": "billing.retrieve_balance_response", "BillingTopUpParams": "billing.top_up_params", "BillingTopUpResponse": "billing.top_up_response", + "BiometricRetention": "components.biometric_retention", "BiometricTemplatesBatchDeleteParams": "biometric_templates.batch_delete_params", "BiometricTemplatesBatchDeleteResponse": "biometric_templates.batch_delete_response", "BiometricTemplatesBatchDeleteResponseResults": "biometric_templates.batch_delete_response", @@ -3493,6 +3706,7 @@ "DigitalIdWalletApiEudiWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_eudi_wallet_verification_start_country_enum", "DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_franceconnect_wallet_verification_start_country_enum", "DigitalIdWalletApiFtnWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_ftn_wallet_verification_start_country_enum", + "DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum", "DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_govbr_wallet_verification_start_country_enum", "DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_idcard_ee_wallet_verification_start_country_enum", "DigitalIdWalletApiIdinWalletVerificationStartCountryEnum": "components.digital_id_wallet_api_idin_wallet_verification_start_country_enum", @@ -3506,6 +3720,7 @@ "DigitalIdWalletApiWallet": "components.digital_id_wallet_api_wallet", "DigitalIdWalletApiWalletCatalogEntry": "components.digital_id_wallet_api_wallet_catalog_entry", "DigitalIdWalletApiWalletCatalogResponse": "components.digital_id_wallet_api_wallet_catalog_response", + "DigitalIdWalletApiWalletDigitalCredentialsRequest": "components.digital_id_wallet_api_wallet_digital_credentials_request", "DigitalIdWalletApiWalletIdentity": "components.digital_id_wallet_api_wallet_identity", "DigitalIdWalletApiWalletNextAction": "components.digital_id_wallet_api_wallet_next_action", "DigitalIdWalletApiWalletNextActionTypeEnum": "components.digital_id_wallet_api_wallet_next_action_type_enum", @@ -3521,6 +3736,7 @@ "EmailAssessRiskParams": "email.assess_risk_params", "EmailCheckCodeParams": "email.check_code_params", "EmailIntelligence": "components.email_intelligence", + "EmailIntelligenceReasonCodes": "components.email_intelligence", "EmailMatchItem": "components.email_match_item", "EmailRiskResponse": "components.email_risk_response", "EmailRiskResponseEmail": "components.email_risk_response", @@ -3580,6 +3796,15 @@ "FraudResultEnum": "components.fraud_result_enum", "FraudStatusEnum": "components.fraud_status_enum", "FraudTypeEnum": "components.fraud_type_enum", + "GeolocationAttempt": "components.geolocation_attempt", + "GeolocationAttemptAnonymizers": "components.geolocation_attempt", + "GeolocationAttemptConsent": "components.geolocation_attempt", + "GeolocationAttemptGeofence": "components.geolocation_attempt", + "GeolocationCheck": "components.geolocation_check", + "GeolocationCheckAnonymizers": "components.geolocation_check", + "GeolocationCheckConsent": "components.geolocation_check", + "GeolocationCheckGeofence": "components.geolocation_check", + "GeolocationCheckWarnings": "components.geolocation_check", "IPRiskResponse": "components.ip_risk_response", "IPRiskResponseIp": "components.ip_risk_response", "IdVerificationVerifyParams": "id_verification.verify_params", @@ -3604,6 +3829,7 @@ "IdWalletsStartFranceconnectParams": "id_wallets.start_franceconnect_params", "IdWalletsStartFrejaidParams": "id_wallets.start_frejaid_params", "IdWalletsStartFtnParams": "id_wallets.start_ftn_params", + "IdWalletsStartGoogleWalletParams": "id_wallets.start_google_wallet_params", "IdWalletsStartGovbrParams": "id_wallets.start_govbr_params", "IdWalletsStartGovukWalletParams": "id_wallets.start_govuk_wallet_params", "IdWalletsStartIdcardEeParams": "id_wallets.start_idcard_ee_params", @@ -3617,6 +3843,7 @@ "IdWalletsStartSmartIdParams": "id_wallets.start_smart_id_params", "IdWalletsStartUaePassParams": "id_wallets.start_uae_pass_params", "IdWalletsStartVippsParams": "id_wallets.start_vipps_params", + "IdWalletsSubmitVerificationResponseParams": "id_wallets.submit_verification_response_params", "ImportJobSummary": "components.import_job_summary", "ImportJobSummaryFaceTemplates": "components.import_job_summary", "ImportJobSummaryProgress": "components.import_job_summary", @@ -3649,32 +3876,45 @@ "KYBKeyPeopleParty": "components.kyb_key_people_party", "KYBKeyPeoplePartyRoles": "components.kyb_key_people_party", "KYBKeyPeoplePartyVerificationWorkflowFeatures": "components.kyb_key_people_party", + "KYBOwnershipStructure": "components.kyb_ownership_structure", + "KYBOwnershipStructureOwner": "components.kyb_ownership_structure_owner", "KYBRegistryAddress": "components.kyb_registry_address", + "KYBRegistryData": "components.kyb_registry_data", + "KYBRegistryGroupCompany": "components.kyb_registry_group_company", "KYBRegistryIndustry": "components.kyb_registry_industry", + "KYBRegistryLiteEnrichment": "components.kyb_registry_lite_enrichment", "KYBRegistryOwnership": "components.kyb_registry_ownership", "KYBRegistryOwnershipUnresolved": "components.kyb_registry_ownership", "KYBRegistrySearchResults": "components.kyb_registry_search_results", "KYBRegistrySearchResultsCompanies": "components.kyb_registry_search_results", "KYBRegistrySearchResultsPagination": "components.kyb_registry_search_results", + "KYBRegistrySectionError": "components.kyb_registry_section_error", "KYBRegistryShareholding": "components.kyb_registry_shareholding", + "KYBRegistrySource": "components.kyb_registry_source", + "KYBRegistryUboResolution": "components.kyb_registry_ubo_resolution", + "KYBRegistryUboResolutionUnresolved": "components.kyb_registry_ubo_resolution", "KybListShareholdersParams": "kyb.list_shareholders_params", "KybListShareholdersResponse": "kyb.list_shareholders_response", "KybListShareholdersResponse202": "kyb.list_shareholders_response", "KybListShareholdersResponse202KybRegistry": "kyb.list_shareholders_response", "KybListShareholdersResponse202KybRegistryBeneficialOwners": "kyb.list_shareholders_response", "KybListShareholdersResponse202KybRegistryOfficers": "kyb.list_shareholders_response", + "KybListShareholdersResponse202KybRegistryRegistryMonitoring": "kyb.list_shareholders_response", "KybListShareholdersResponseKybRegistry": "kyb.list_shareholders_response", "KybListShareholdersResponseKybRegistryBeneficialOwners": "kyb.list_shareholders_response", "KybListShareholdersResponseKybRegistryOfficers": "kyb.list_shareholders_response", + "KybListShareholdersResponseKybRegistryRegistryMonitoring": "kyb.list_shareholders_response", "KybListUbosParams": "kyb.list_ubos_params", "KybListUbosResponse": "kyb.list_ubos_response", "KybListUbosResponse202": "kyb.list_ubos_response", "KybListUbosResponse202KybRegistry": "kyb.list_ubos_response", "KybListUbosResponse202KybRegistryBeneficialOwners": "kyb.list_ubos_response", "KybListUbosResponse202KybRegistryOfficers": "kyb.list_ubos_response", + "KybListUbosResponse202KybRegistryRegistryMonitoring": "kyb.list_ubos_response", "KybListUbosResponseKybRegistry": "kyb.list_ubos_response", "KybListUbosResponseKybRegistryBeneficialOwners": "kyb.list_ubos_response", "KybListUbosResponseKybRegistryOfficers": "kyb.list_ubos_response", + "KybListUbosResponseKybRegistryRegistryMonitoring": "kyb.list_ubos_response", "KybSearchParams": "kyb.search_params", "KybSearchResponse": "kyb.search_response", "KybSelectParams": "kyb.select_params", @@ -3682,6 +3922,7 @@ "KybSelectResponseKybRegistry": "kyb.select_response", "KybSelectResponseKybRegistryBeneficialOwners": "kyb.select_response", "KybSelectResponseKybRegistryOfficers": "kyb.select_response", + "KybSelectResponseKybRegistryRegistryMonitoring": "kyb.select_response", "ListsCreateParams": "lists.create_params", "ListsEntriesCreateParams": "lists.entries.create_params", "ListsEntriesCreateParamsMetadata": "lists.entries.create_params", @@ -3792,6 +4033,7 @@ "PhoneAssessRiskParams": "phone.assess_risk_params", "PhoneCheckCodeParams": "phone.check_code_params", "PhoneIntelligence": "components.phone_intelligence", + "PhoneIntelligenceReasonCodes": "components.phone_intelligence", "PhoneMatchItem": "components.phone_match_item", "PhoneRiskResponse": "components.phone_risk_response", "PhoneRiskResponsePhone": "components.phone_risk_response", @@ -3850,14 +4092,19 @@ "RoutingPublicationRoutingCondition": "components.routing_publication_routing_condition", "SandboxSimulateResponse": "components.sandbox_simulate_response", "SessionDecision": "components.session_decision", + "SessionDecisionAssignee": "components.session_decision", "SessionDecisionBiometricConsent": "components.session_decision", "SessionDecisionContactDetails": "components.session_decision", + "SessionDecisionDatabaseValidationNotPerformedReason": "components.session_decision", "SessionDecisionDatabaseValidations": "components.session_decision", "SessionDecisionDatabaseValidationsErrors": "components.session_decision", "SessionDecisionDatabaseValidationsScreenedData": "components.session_decision", "SessionDecisionDatabaseValidationsValidations": "components.session_decision", "SessionDecisionDatabaseValidationsValidationsValidation": "components.session_decision", "SessionDecisionDatabaseValidationsWarnings": "components.session_decision", + "SessionDecisionDecisionTrace": "components.session_decision", + "SessionDecisionDecisionTraceActor": "components.session_decision", + "SessionDecisionDecisionTraceStatusWarnings": "components.session_decision", "SessionDecisionDocumentAiDocuments": "components.session_decision", "SessionDecisionDocumentAiDocumentsItems": "components.session_decision", "SessionDecisionDocumentAiDocumentsItemsFields": "components.session_decision", @@ -3875,6 +4122,10 @@ "SessionDecisionEmailVerificationsWarnings": "components.session_decision", "SessionDecisionExpectedDetails": "components.session_decision", "SessionDecisionFaceMatches": "components.session_decision", + "SessionDecisionFaceMatchesFaceCoverage": "components.session_decision", + "SessionDecisionFaceMatchesFaceCoverageEyes": "components.session_decision", + "SessionDecisionFaceMatchesFaceCoverageFace": "components.session_decision", + "SessionDecisionFaceMatchesFaceCoverageMouth": "components.session_decision", "SessionDecisionFaceMatchesWarnings": "components.session_decision", "SessionDecisionIdVerifications": "components.session_decision", "SessionDecisionIdVerificationsBackImageQualityScore": "components.session_decision", @@ -3929,6 +4180,12 @@ "SessionDecisionKeyPeopleChecksSubmittedPartiesRoles": "components.session_decision", "SessionDecisionKeyPeopleChecksSubmittedPartiesVerificationWorkflowFeatures": "components.session_decision", "SessionDecisionKeyPeopleChecksUboKycSummary": "components.session_decision", + "SessionDecisionLinkedRecords": "components.session_decision", + "SessionDecisionLinkedRecordsEarlierVerifications": "components.session_decision", + "SessionDecisionLinkedRecordsNetworks": "components.session_decision", + "SessionDecisionLinkedRecordsNetworksItems": "components.session_decision", + "SessionDecisionLinkedRecordsSameFace": "components.session_decision", + "SessionDecisionLinkedRecordsSameFaceBestMatch": "components.session_decision", "SessionDecisionLivenessChecks": "components.session_decision", "SessionDecisionLivenessChecksMatches": "components.session_decision", "SessionDecisionLivenessChecksMatchesUserDetails": "components.session_decision", @@ -3964,13 +4221,16 @@ "SessionDecisionRegistryChecksCompany": "components.session_decision", "SessionDecisionRegistryChecksCompanyBeneficialOwners": "components.session_decision", "SessionDecisionRegistryChecksCompanyOfficers": "components.session_decision", + "SessionDecisionRegistryChecksCompanyRegistryMonitoring": "components.session_decision", "SessionDecisionResubmissions": "components.session_decision", "SessionDecisionResubmissionsNodes": "components.session_decision", "SessionDecisionResubmissionsRequestedBy": "components.session_decision", "SessionDecisionReviews": "components.session_decision", + "SessionDecisionStatusOverride": "components.session_decision", "SessionDeletionJob": "components.session_deletion_job", "SessionDeletionJobOutcomes": "components.session_deletion_job", "SessionEvent": "components.session_event", + "SessionFilesExport": "components.session_files_export", "SessionImportError": "components.session_import_error", "SessionImportJob": "components.session_import_job", "SessionSignDocument": "components.session_sign_document", @@ -3983,6 +4243,9 @@ "SessionsBulkUpdateAmlHitStatusParams": "sessions.bulk_update_aml_hit_status_params", "SessionsBulkUpdateAmlHitStatusParamsHitUpdates": "sessions.bulk_update_aml_hit_status_params", "SessionsBulkUpdateAmlHitStatusResponse": "sessions.bulk_update_aml_hit_status_response", + "SessionsCreateKybPartyDraftParams": "sessions.create_kyb_party_draft_params", + "SessionsCreateKybPartyDraftResponse": "sessions.create_kyb_party_draft_response", + "SessionsCreateKybPartyDraftResponseParty": "sessions.create_kyb_party_draft_response", "SessionsCreateParams": "sessions.create_params", "SessionsCreateParamsBiometricConsent": "sessions.create_params", "SessionsCreateParamsContactDetails": "sessions.create_params", @@ -4007,6 +4270,14 @@ "SessionsListAmlScreeningHistoryResponse": "sessions.list_aml_screening_history_response", "SessionsListEventsResponse": "sessions.list_events_response", "SessionsListFeatureOverridesResponse": "sessions.list_feature_overrides_response", + "SessionsListKybExtractedPartiesResponse": "sessions.list_kyb_extracted_parties_response", + "SessionsListKybExtractedPartiesResponseParties": "sessions.list_kyb_extracted_parties_response", + "SessionsListKybExtractedPartiesResponsePartiesDocuments": "sessions.list_kyb_extracted_parties_response", + "SessionsListKybExtractedPartiesResponsePartiesRoles": "sessions.list_kyb_extracted_parties_response", + "SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent": "sessions.list_kyb_extracted_parties_response", + "SessionsListKybPartyDraftsResponse": "sessions.list_kyb_party_drafts_response", + "SessionsListKybPartyDraftsResponseParties": "sessions.list_kyb_party_drafts_response", + "SessionsListKybPartyDraftsResponsePartiesParty": "sessions.list_kyb_party_drafts_response", "SessionsListResponse": "sessions.list_response", "SessionsPreviewDecisionEmailParams": "sessions.preview_decision_email_params", "SessionsPreviewDecisionEmailResponse": "sessions.preview_decision_email_response", @@ -4022,6 +4293,8 @@ "SessionsSignaturesValidateParams": "sessions.signatures.validate_params", "SessionsSignaturesValidateResponse": "sessions.signatures.validate_response", "SessionsSimulateParams": "sessions.simulate_params", + "SessionsSubmitKybPartiesParams": "sessions.submit_kyb_parties_params", + "SessionsSubmitKybPartiesResponse": "sessions.submit_kyb_parties_response", "SessionsUpdateAmlHitStatusParams": "sessions.update_aml_hit_status_params", "SessionsUpdateAmlHitStatusResponse": "sessions.update_aml_hit_status_response", "SessionsUpdateAmlStatusParams": "sessions.update_aml_status_params", @@ -4036,6 +4309,9 @@ "SessionsUpdateFeatureStatusResponse": "sessions.update_feature_status_response", "SessionsUpdateKybCompanyDataParams": "sessions.update_kyb_company_data_params", "SessionsUpdateKybCompanyDataResponse": "sessions.update_kyb_company_data_response", + "SessionsUpdateKybPartyDraftParams": "sessions.update_kyb_party_draft_params", + "SessionsUpdateKybPartyDraftResponse": "sessions.update_kyb_party_draft_response", + "SessionsUpdateKybPartyDraftResponseParty": "sessions.update_kyb_party_draft_response", "SessionsUpdateKybPartyParams": "sessions.update_kyb_party_params", "SessionsUpdateKybPartyResponse": "sessions.update_kyb_party_response", "SessionsUpdatePoaDataParams": "sessions.update_poa_data_params", @@ -4045,6 +4321,8 @@ "SessionsUpdateStatusParams": "sessions.update_status_params", "SessionsUpdateStatusParamsNodesToResubmit": "sessions.update_status_params", "SessionsUpdateStatusResponse": "sessions.update_status_response", + "SessionsUploadKybDocumentsParams": "sessions.upload_kyb_documents_params", + "SessionsUploadKybDocumentsResponse": "sessions.upload_kyb_documents_response", "SignatureField": "components.signature_field", "SignatureFieldAnchor": "components.signature_field_anchor", "SignatureFieldResult": "components.signature_field_result", @@ -4178,6 +4456,7 @@ "TravelRuleDiscoveryStep": "components.travel_rule_discovery_step", "TravelRuleInboundResponse": "components.travel_rule_inbound_response", "TravelRuleListVaspsResponse": "travel_rule.list_vasps_response", + "TravelRuleManualMatchResponse": "components.travel_rule_manual_match_response", "TravelRuleMatchingRules": "components.travel_rule_matching_rules", "TravelRuleMatchingRulesCompany": "components.travel_rule_matching_rules", "TravelRuleMatchingRulesCompanyParam": "components.travel_rule_matching_rules", @@ -4216,6 +4495,8 @@ "TravelRuleTransferDetailTimeline": "components.travel_rule_transfer_detail", "TravelRuleTransferRow": "components.travel_rule_transfer_row", "TravelRuleTransfersListResponse": "travel_rule.transfers.list_response", + "TravelRuleUnmatchedDepositsListResponse": "travel_rule.unmatched_deposits.list_response", + "TravelRuleUnmatchedDepositsMatchParams": "travel_rule.unmatched_deposits.match_params", "TravelRuleUpdateSettingsParams": "travel_rule.update_settings_params", "TravelRuleUpdateVaspDecisionParams": "travel_rule.update_vasp_decision_params", "TravelRuleUtxo": "components.travel_rule_utxo", @@ -4253,9 +4534,11 @@ "UserSessionListItemAdditionalDetailsLiveness": "components.user_session_list_item", "UserSessionListItemAdditionalDetailsPhoneVerification": "components.user_session_list_item", "UserSessionListItemAdditionalDetailsPoa": "components.user_session_list_item", + "UserSessionListItemAssignee": "components.user_session_list_item", "UserSessionListItemEmailAddress": "components.user_session_list_item", "UserSessionListItemFeatures": "components.user_session_list_item", "UserSessionListItemPhoneNumber": "components.user_session_list_item", + "UserSessionListItemTopWarnings": "components.user_session_list_item", "UsersBatchDeleteParams": "users.batch_delete_params", "UsersBatchDeleteResponse": "users.batch_delete_response", "UsersCreateParams": "users.create_params", @@ -4324,6 +4607,7 @@ "WebhooksDestinationsUpdateResponseSummary": "webhooks.destinations.update_response", "WebhooksUpdateConfigParams": "webhooks.update_config_params", "WorkflowDetail": "components.workflow_detail", + "WorkflowDetailSignatureAvailability": "components.workflow_detail", "WorkflowListItem": "components.workflow_list_item", "WorkflowListItemCreatedBy": "components.workflow_list_item", "WorkflowsCreateParams": "workflows.create_params", @@ -4416,6 +4700,8 @@ "ApplicationAnalyticsResubmissionPoint", "ApplicationAnalyticsResubmissionStats", "ApplicationAnalyticsSummary", + "ApplicationAnalyticsToday", + "ApplicationAnalyticsTodayOutcomes", "ApplicationAnalyticsVerificationTimePoint", "ApplicationAnalyticsVerificationTimeStats", "ApplicationAnalyticsVerificationTimeStatsPerFeatureValue", @@ -4456,6 +4742,7 @@ "BillingRetrieveBalanceResponse", "BillingTopUpParams", "BillingTopUpResponse", + "BiometricRetention", "BiometricTemplatesBatchDeleteParams", "BiometricTemplatesBatchDeleteResponse", "BiometricTemplatesBatchDeleteResponseResults", @@ -4652,6 +4939,7 @@ "DigitalIdWalletApiEudiWalletVerificationStartCountryEnum", "DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum", "DigitalIdWalletApiFtnWalletVerificationStartCountryEnum", + "DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum", "DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum", "DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum", "DigitalIdWalletApiIdinWalletVerificationStartCountryEnum", @@ -4665,6 +4953,7 @@ "DigitalIdWalletApiWallet", "DigitalIdWalletApiWalletCatalogEntry", "DigitalIdWalletApiWalletCatalogResponse", + "DigitalIdWalletApiWalletDigitalCredentialsRequest", "DigitalIdWalletApiWalletIdentity", "DigitalIdWalletApiWalletNextAction", "DigitalIdWalletApiWalletNextActionTypeEnum", @@ -4680,6 +4969,7 @@ "EmailAssessRiskParams", "EmailCheckCodeParams", "EmailIntelligence", + "EmailIntelligenceReasonCodes", "EmailMatchItem", "EmailRiskResponse", "EmailRiskResponseEmail", @@ -4739,6 +5029,15 @@ "FraudResultEnum", "FraudStatusEnum", "FraudTypeEnum", + "GeolocationAttempt", + "GeolocationAttemptAnonymizers", + "GeolocationAttemptConsent", + "GeolocationAttemptGeofence", + "GeolocationCheck", + "GeolocationCheckAnonymizers", + "GeolocationCheckConsent", + "GeolocationCheckGeofence", + "GeolocationCheckWarnings", "IPRiskResponse", "IPRiskResponseIp", "IdVerificationVerifyParams", @@ -4763,6 +5062,7 @@ "IdWalletsStartFranceconnectParams", "IdWalletsStartFrejaidParams", "IdWalletsStartFtnParams", + "IdWalletsStartGoogleWalletParams", "IdWalletsStartGovbrParams", "IdWalletsStartGovukWalletParams", "IdWalletsStartIdcardEeParams", @@ -4776,6 +5076,7 @@ "IdWalletsStartSmartIdParams", "IdWalletsStartUaePassParams", "IdWalletsStartVippsParams", + "IdWalletsSubmitVerificationResponseParams", "ImportJobSummary", "ImportJobSummaryFaceTemplates", "ImportJobSummaryProgress", @@ -4808,32 +5109,45 @@ "KYBKeyPeopleParty", "KYBKeyPeoplePartyRoles", "KYBKeyPeoplePartyVerificationWorkflowFeatures", + "KYBOwnershipStructure", + "KYBOwnershipStructureOwner", "KYBRegistryAddress", + "KYBRegistryData", + "KYBRegistryGroupCompany", "KYBRegistryIndustry", + "KYBRegistryLiteEnrichment", "KYBRegistryOwnership", "KYBRegistryOwnershipUnresolved", "KYBRegistrySearchResults", "KYBRegistrySearchResultsCompanies", "KYBRegistrySearchResultsPagination", + "KYBRegistrySectionError", "KYBRegistryShareholding", + "KYBRegistrySource", + "KYBRegistryUboResolution", + "KYBRegistryUboResolutionUnresolved", "KybListShareholdersParams", "KybListShareholdersResponse", "KybListShareholdersResponse202", "KybListShareholdersResponse202KybRegistry", "KybListShareholdersResponse202KybRegistryBeneficialOwners", "KybListShareholdersResponse202KybRegistryOfficers", + "KybListShareholdersResponse202KybRegistryRegistryMonitoring", "KybListShareholdersResponseKybRegistry", "KybListShareholdersResponseKybRegistryBeneficialOwners", "KybListShareholdersResponseKybRegistryOfficers", + "KybListShareholdersResponseKybRegistryRegistryMonitoring", "KybListUbosParams", "KybListUbosResponse", "KybListUbosResponse202", "KybListUbosResponse202KybRegistry", "KybListUbosResponse202KybRegistryBeneficialOwners", "KybListUbosResponse202KybRegistryOfficers", + "KybListUbosResponse202KybRegistryRegistryMonitoring", "KybListUbosResponseKybRegistry", "KybListUbosResponseKybRegistryBeneficialOwners", "KybListUbosResponseKybRegistryOfficers", + "KybListUbosResponseKybRegistryRegistryMonitoring", "KybSearchParams", "KybSearchResponse", "KybSelectParams", @@ -4841,6 +5155,7 @@ "KybSelectResponseKybRegistry", "KybSelectResponseKybRegistryBeneficialOwners", "KybSelectResponseKybRegistryOfficers", + "KybSelectResponseKybRegistryRegistryMonitoring", "ListsCreateParams", "ListsEntriesCreateParams", "ListsEntriesCreateParamsMetadata", @@ -4951,6 +5266,7 @@ "PhoneAssessRiskParams", "PhoneCheckCodeParams", "PhoneIntelligence", + "PhoneIntelligenceReasonCodes", "PhoneMatchItem", "PhoneRiskResponse", "PhoneRiskResponsePhone", @@ -5009,14 +5325,19 @@ "RoutingPublicationRoutingCondition", "SandboxSimulateResponse", "SessionDecision", + "SessionDecisionAssignee", "SessionDecisionBiometricConsent", "SessionDecisionContactDetails", + "SessionDecisionDatabaseValidationNotPerformedReason", "SessionDecisionDatabaseValidations", "SessionDecisionDatabaseValidationsErrors", "SessionDecisionDatabaseValidationsScreenedData", "SessionDecisionDatabaseValidationsValidations", "SessionDecisionDatabaseValidationsValidationsValidation", "SessionDecisionDatabaseValidationsWarnings", + "SessionDecisionDecisionTrace", + "SessionDecisionDecisionTraceActor", + "SessionDecisionDecisionTraceStatusWarnings", "SessionDecisionDocumentAiDocuments", "SessionDecisionDocumentAiDocumentsItems", "SessionDecisionDocumentAiDocumentsItemsFields", @@ -5034,6 +5355,10 @@ "SessionDecisionEmailVerificationsWarnings", "SessionDecisionExpectedDetails", "SessionDecisionFaceMatches", + "SessionDecisionFaceMatchesFaceCoverage", + "SessionDecisionFaceMatchesFaceCoverageEyes", + "SessionDecisionFaceMatchesFaceCoverageFace", + "SessionDecisionFaceMatchesFaceCoverageMouth", "SessionDecisionFaceMatchesWarnings", "SessionDecisionIdVerifications", "SessionDecisionIdVerificationsBackImageQualityScore", @@ -5088,6 +5413,12 @@ "SessionDecisionKeyPeopleChecksSubmittedPartiesRoles", "SessionDecisionKeyPeopleChecksSubmittedPartiesVerificationWorkflowFeatures", "SessionDecisionKeyPeopleChecksUboKycSummary", + "SessionDecisionLinkedRecords", + "SessionDecisionLinkedRecordsEarlierVerifications", + "SessionDecisionLinkedRecordsNetworks", + "SessionDecisionLinkedRecordsNetworksItems", + "SessionDecisionLinkedRecordsSameFace", + "SessionDecisionLinkedRecordsSameFaceBestMatch", "SessionDecisionLivenessChecks", "SessionDecisionLivenessChecksMatches", "SessionDecisionLivenessChecksMatchesUserDetails", @@ -5123,13 +5454,16 @@ "SessionDecisionRegistryChecksCompany", "SessionDecisionRegistryChecksCompanyBeneficialOwners", "SessionDecisionRegistryChecksCompanyOfficers", + "SessionDecisionRegistryChecksCompanyRegistryMonitoring", "SessionDecisionResubmissions", "SessionDecisionResubmissionsNodes", "SessionDecisionResubmissionsRequestedBy", "SessionDecisionReviews", + "SessionDecisionStatusOverride", "SessionDeletionJob", "SessionDeletionJobOutcomes", "SessionEvent", + "SessionFilesExport", "SessionImportError", "SessionImportJob", "SessionSignDocument", @@ -5142,6 +5476,9 @@ "SessionsBulkUpdateAmlHitStatusParams", "SessionsBulkUpdateAmlHitStatusParamsHitUpdates", "SessionsBulkUpdateAmlHitStatusResponse", + "SessionsCreateKybPartyDraftParams", + "SessionsCreateKybPartyDraftResponse", + "SessionsCreateKybPartyDraftResponseParty", "SessionsCreateParams", "SessionsCreateParamsBiometricConsent", "SessionsCreateParamsContactDetails", @@ -5166,6 +5503,14 @@ "SessionsListAmlScreeningHistoryResponse", "SessionsListEventsResponse", "SessionsListFeatureOverridesResponse", + "SessionsListKybExtractedPartiesResponse", + "SessionsListKybExtractedPartiesResponseParties", + "SessionsListKybExtractedPartiesResponsePartiesDocuments", + "SessionsListKybExtractedPartiesResponsePartiesRoles", + "SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent", + "SessionsListKybPartyDraftsResponse", + "SessionsListKybPartyDraftsResponseParties", + "SessionsListKybPartyDraftsResponsePartiesParty", "SessionsListResponse", "SessionsPreviewDecisionEmailParams", "SessionsPreviewDecisionEmailResponse", @@ -5181,6 +5526,8 @@ "SessionsSignaturesValidateParams", "SessionsSignaturesValidateResponse", "SessionsSimulateParams", + "SessionsSubmitKybPartiesParams", + "SessionsSubmitKybPartiesResponse", "SessionsUpdateAmlHitStatusParams", "SessionsUpdateAmlHitStatusResponse", "SessionsUpdateAmlStatusParams", @@ -5195,6 +5542,9 @@ "SessionsUpdateFeatureStatusResponse", "SessionsUpdateKybCompanyDataParams", "SessionsUpdateKybCompanyDataResponse", + "SessionsUpdateKybPartyDraftParams", + "SessionsUpdateKybPartyDraftResponse", + "SessionsUpdateKybPartyDraftResponseParty", "SessionsUpdateKybPartyParams", "SessionsUpdateKybPartyResponse", "SessionsUpdatePoaDataParams", @@ -5204,6 +5554,8 @@ "SessionsUpdateStatusParams", "SessionsUpdateStatusParamsNodesToResubmit", "SessionsUpdateStatusResponse", + "SessionsUploadKybDocumentsParams", + "SessionsUploadKybDocumentsResponse", "SignatureField", "SignatureFieldAnchor", "SignatureFieldResult", @@ -5337,6 +5689,7 @@ "TravelRuleDiscoveryStep", "TravelRuleInboundResponse", "TravelRuleListVaspsResponse", + "TravelRuleManualMatchResponse", "TravelRuleMatchingRules", "TravelRuleMatchingRulesCompany", "TravelRuleMatchingRulesCompanyParam", @@ -5375,6 +5728,8 @@ "TravelRuleTransferDetailTimeline", "TravelRuleTransferRow", "TravelRuleTransfersListResponse", + "TravelRuleUnmatchedDepositsListResponse", + "TravelRuleUnmatchedDepositsMatchParams", "TravelRuleUpdateSettingsParams", "TravelRuleUpdateVaspDecisionParams", "TravelRuleUtxo", @@ -5412,9 +5767,11 @@ "UserSessionListItemAdditionalDetailsLiveness", "UserSessionListItemAdditionalDetailsPhoneVerification", "UserSessionListItemAdditionalDetailsPoa", + "UserSessionListItemAssignee", "UserSessionListItemEmailAddress", "UserSessionListItemFeatures", "UserSessionListItemPhoneNumber", + "UserSessionListItemTopWarnings", "UsersBatchDeleteParams", "UsersBatchDeleteResponse", "UsersCreateParams", @@ -5483,6 +5840,7 @@ "WebhooksDestinationsUpdateResponseSummary", "WebhooksUpdateConfigParams", "WorkflowDetail", + "WorkflowDetailSignatureAvailability", "WorkflowListItem", "WorkflowListItemCreatedBy", "WorkflowsCreateParams", diff --git a/src/didit/types/aml/screen_response.py b/src/didit/types/aml/screen_response.py index 4b14229..ee3d12d 100644 --- a/src/didit/types/aml/screen_response.py +++ b/src/didit/types/aml/screen_response.py @@ -132,7 +132,7 @@ class AmlScreenResponseAmlHits(BaseModel): """One screening hit. `match_score` (0–100) measures identity confidence - hits below `aml_match_score_threshold` are tagged `review_status: "False Positive"` and excluded from the risk assessment; hits at or above it are `"Unreviewed"` possible matches. `risk_score` (0–100) measures how risky the matched entity is and drives the top-level `aml.score`.""" id: str | None = None - """Stable identifier of the matched entity in the screening datasets.""" + """Didit's stable identifier for the hit: `hit_` followed by 24 hexadecimal characters. The same matched entity keeps the same `id` when the subject is screened again. Pass it as `hit_id` to the AML hit review endpoints.""" url: str | None = None """Source URL for the matched entity, when available.""" @@ -154,8 +154,28 @@ class AmlScreenResponseAmlHits(BaseModel): caption: str | None = None """Display name of the matched entity.""" - datasets: list[str] | None = None - """Datasets the entity appears in (e.g. `PEP`, `PEP Level 1`, sanctions list names).""" + datasets: ( + list[ + Literal[ + "PEP", + "PEP Level 1", + "PEP Level 2", + "PEP Level 3", + "PEP Level 4", + "Sanctions", + "Adverse Media", + "Warnings and Regulatory Enforcement", + "Fitness and Probity", + "SIP", + "SIE", + "Insolvency", + "Other Lists", + ] + | str + ] + | None + ) = None + """Risk categories the entity is listed under: `PEP` (with its level, `PEP Level 1` to `PEP Level 4`), `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`, `SIP`, `SIE` or `Insolvency`. `Other Lists` when the entity's source states none of these categories.""" features: dict[str, object] | None = None diff --git a/src/didit/types/bank/account_check_params.py b/src/didit/types/bank/account_check_params.py index c14f22e..baef58e 100644 --- a/src/didit/types/bank/account_check_params.py +++ b/src/didit/types/bank/account_check_params.py @@ -60,3 +60,6 @@ class BankAccountCheckParams(TypedDict, total=False): vendor_data: str | None """Your own reference for this check, returned unchanged.""" + + consent: bool + """Set to `true` when the account holder has explicitly consented to this check. Required in the countries whose account check needs that consent: without it the check is refused with a `400` whose `field` is `consent` and whose `reason` is `required`, and nothing is billed. Elsewhere it is optional, and Didit records it with the check's charge when you send it.""" diff --git a/src/didit/types/components/aml_screening.py b/src/didit/types/components/aml_screening.py index 8a17d76..d4b384b 100644 --- a/src/didit/types/components/aml_screening.py +++ b/src/didit/types/components/aml_screening.py @@ -355,7 +355,7 @@ class AMLScreeningHitsWarningMatches(BaseModel): class AMLScreeningHits(BaseModel): id: str | None = None - """Unique identifier of the match""" + """Didit's stable identifier for the hit: `hit_` followed by 24 hexadecimal characters. The same matched entity keeps the same `id` when the subject is screened again. Pass it as `hit_id` to the AML hit review endpoints.""" url: str | None = None """Source URL for the match""" @@ -387,12 +387,13 @@ class AMLScreeningHits(BaseModel): "SIP", "SIE", "Insolvency", + "Other Lists", ] | str ] | None ) = None - """List of dataset categories where the match was found. Indicates whether the entity appeared in PEP lists (with level), sanctions databases, adverse media, warnings/regulatory enforcement, or other compliance datasets.""" + """List of dataset categories where the match was found. Indicates whether the entity appeared in PEP lists (with level), sanctions databases, adverse media, warnings/regulatory enforcement, or other compliance datasets. `Other Lists` when the entity's source states none of these categories.""" features: dict[str, object] | None = None """Additional features of the match""" @@ -469,6 +470,8 @@ class AMLScreeningWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None diff --git a/src/didit/types/components/aml_screening_run.py b/src/didit/types/components/aml_screening_run.py index f0c2396..d19f854 100644 --- a/src/didit/types/components/aml_screening_run.py +++ b/src/didit/types/components/aml_screening_run.py @@ -16,6 +16,9 @@ class AMLScreeningRun(BaseModel): uuid: str """Identifier of this screening run.""" + run_id: str + """The monitoring run this screening belongs to. Every verification screened in the same run shares it.""" + completed_at: _dt.datetime """When this subject's re-screen finished. Results are ordered by it, newest first.""" @@ -42,5 +45,11 @@ class AMLScreeningRun(BaseModel): total_hits: int | None """Number of hits this run left the check in.""" + new_hits: int | None + """Number of hits this run found that the check did not have before it. `0` when nothing new was found; `null` when the run failed or was recorded before this count existed.""" + + entities_screened: int + """Number of entities this run screened for the verification: `1` when the subject was screened, `0` when the run failed.""" + dataset_freshness: AMLDatasetFreshness | None """Dataset freshness behind this run, or `null` when no dates were available.""" diff --git a/src/didit/types/components/application_analytics_today.py b/src/didit/types/components/application_analytics_today.py new file mode 100644 index 0000000..d871537 --- /dev/null +++ b/src/didit/types/components/application_analytics_today.py @@ -0,0 +1,49 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt + +from didit._models import BaseModel + +__all__ = ["ApplicationAnalyticsToday", "ApplicationAnalyticsTodayOutcomes"] + + +class ApplicationAnalyticsTodayOutcomes(BaseModel): + """Of today's verifications, how many are approved, waiting in review and declined now. The rest are not finished yet.""" + + approved: int + + in_review: int + + declined: int + + +class ApplicationAnalyticsToday(BaseModel): + """Today's verifications by local hour against the same weekday last week.""" + + time_zone: str + """The IANA time zone the day and its hours are in.""" + + date: _dt.date + """Today in that time zone.""" + + current_hour: int + """The local hour it is now.""" + + previous_date: _dt.date + """The comparison day: the same weekday one week before.""" + + hours: list[int] + """Verifications created today, per local hour from 00:00. The hours still to come are 0.""" + + previous_hours: list[int] + """Verifications created on the comparison day, per local hour from 00:00.""" + + total: int + """Verifications created today so far.""" + + previous_total_so_far: int + """Verifications created on the comparison day up to the same local time.""" + + outcomes: ApplicationAnalyticsTodayOutcomes + """Of today's verifications, how many are approved, waiting in review and declined now. The rest are not finished yet.""" diff --git a/src/didit/types/components/biometric_retention.py b/src/didit/types/components/biometric_retention.py new file mode 100644 index 0000000..aa2fad3 --- /dev/null +++ b/src/didit/types/components/biometric_retention.py @@ -0,0 +1,18 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt + +from didit._models import BaseModel + +__all__ = ["BiometricRetention"] + + +class BiometricRetention(BaseModel): + """When the live biometric data of this session is deleted.""" + + jurisdictions: list[str] + """Codes of the US states whose biometric rules set a deletion limit for this person (`US` when the state is unknown). Empty when none applies.""" + + deletes_at: _dt.datetime | None + """The date the live biometric data (face images and templates) of this session is deleted, from your application's retention setting and, where one applies, the legal limit for the person's jurisdiction. `null` when no date applies yet.""" diff --git a/src/didit/types/components/digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum.py b/src/didit/types/components/digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum.py new file mode 100644 index 0000000..f1d65e6 --- /dev/null +++ b/src/didit/types/components/digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum.py @@ -0,0 +1,19 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Literal + +from typing_extensions import TypeAlias + +__all__ = ["DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum"] + + +DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum: TypeAlias = ( + Literal["USA", "GBR", "BRA", "SGP", "TWN"] | str +) +"""* `USA` - USA +* `GBR` - GBR +* `BRA` - BRA +* `SGP` - SGP +* `TWN` - TWN +""" diff --git a/src/didit/types/components/digital_id_wallet_api_interaction_enum.py b/src/didit/types/components/digital_id_wallet_api_interaction_enum.py index b8ee1fc..8edd810 100644 --- a/src/didit/types/components/digital_id_wallet_api_interaction_enum.py +++ b/src/didit/types/components/digital_id_wallet_api_interaction_enum.py @@ -8,7 +8,10 @@ __all__ = ["DigitalIdWalletApiInteractionEnum"] -DigitalIdWalletApiInteractionEnum: TypeAlias = Literal["redirect", "in_app"] | str +DigitalIdWalletApiInteractionEnum: TypeAlias = ( + Literal["redirect", "in_app", "digital_credentials"] | str +) """* `redirect` - redirect * `in_app` - in_app +* `digital_credentials` - digital_credentials """ diff --git a/src/didit/types/components/digital_id_wallet_api_wallet_catalog_entry.py b/src/didit/types/components/digital_id_wallet_api_wallet_catalog_entry.py index d09c165..ad670c7 100644 --- a/src/didit/types/components/digital_id_wallet_api_wallet_catalog_entry.py +++ b/src/didit/types/components/digital_id_wallet_api_wallet_catalog_entry.py @@ -26,6 +26,7 @@ class DigitalIdWalletApiWalletCatalogEntry(BaseModel): interaction: DigitalIdWalletApiInteractionEnum """* `redirect` - redirect * `in_app` - in_app + * `digital_credentials` - digital_credentials """ required_fields: list[str] diff --git a/src/didit/types/components/digital_id_wallet_api_wallet_digital_credentials_request.py b/src/didit/types/components/digital_id_wallet_api_wallet_digital_credentials_request.py new file mode 100644 index 0000000..2fdaeda --- /dev/null +++ b/src/didit/types/components/digital_id_wallet_api_wallet_digital_credentials_request.py @@ -0,0 +1,14 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel + +__all__ = ["DigitalIdWalletApiWalletDigitalCredentialsRequest"] + + +class DigitalIdWalletApiWalletDigitalCredentialsRequest(BaseModel): + protocol: str + """openid4vp-v1-signed.""" + + request: dict[str, object] + """Pass as is: navigator.credentials.get({digital: request}) in the browser, or JSON.stringify(request) as GetDigitalCredentialOption's requestJson on Android. Signed by Didit for your application.""" diff --git a/src/didit/types/components/digital_id_wallet_api_wallet_next_action.py b/src/didit/types/components/digital_id_wallet_api_wallet_next_action.py index 0821f9f..e14b9ff 100644 --- a/src/didit/types/components/digital_id_wallet_api_wallet_next_action.py +++ b/src/didit/types/components/digital_id_wallet_api_wallet_next_action.py @@ -2,6 +2,9 @@ from __future__ import annotations from didit._models import BaseModel +from didit.types.components.digital_id_wallet_api_wallet_digital_credentials_request import ( + DigitalIdWalletApiWalletDigitalCredentialsRequest, +) from didit.types.components.digital_id_wallet_api_wallet_next_action_type_enum import ( DigitalIdWalletApiWalletNextActionTypeEnum, ) @@ -11,15 +14,19 @@ class DigitalIdWalletApiWalletNextAction(BaseModel): type: DigitalIdWalletApiWalletNextActionTypeEnum - """redirect: send the user's browser to url. confirm_in_app: show verification_code to the user, who checks it matches the code in their wallet app and confirms there; then poll. + """redirect: send the user's browser to url. confirm_in_app: show verification_code to the user, who checks it matches the code in their wallet app and confirms there; then poll. request_digital_credential: in a user gesture on the origin you started with, ask the wallet with digital_credentials.request, then send what it returns to POST .../verifications/{request_id}/response/. * `redirect` - redirect * `confirm_in_app` - confirm_in_app + * `request_digital_credential` - request_digital_credential """ url: str | None = None """redirect only: where the user signs in with the wallet.""" + digital_credentials: DigitalIdWalletApiWalletDigitalCredentialsRequest | None = None + """request_digital_credential only: the request to hand to the wallet.""" + verification_code: str | None = None """confirm_in_app only: the 4-digit comparison code the wallet app shows too.""" diff --git a/src/didit/types/components/digital_id_wallet_api_wallet_next_action_type_enum.py b/src/didit/types/components/digital_id_wallet_api_wallet_next_action_type_enum.py index dae7b0a..f7f915c 100644 --- a/src/didit/types/components/digital_id_wallet_api_wallet_next_action_type_enum.py +++ b/src/didit/types/components/digital_id_wallet_api_wallet_next_action_type_enum.py @@ -8,7 +8,10 @@ __all__ = ["DigitalIdWalletApiWalletNextActionTypeEnum"] -DigitalIdWalletApiWalletNextActionTypeEnum: TypeAlias = Literal["redirect", "confirm_in_app"] | str +DigitalIdWalletApiWalletNextActionTypeEnum: TypeAlias = ( + Literal["redirect", "confirm_in_app", "request_digital_credential"] | str +) """* `redirect` - redirect * `confirm_in_app` - confirm_in_app +* `request_digital_credential` - request_digital_credential """ diff --git a/src/didit/types/components/email_intelligence.py b/src/didit/types/components/email_intelligence.py index 268b3ea..3bd5e20 100644 --- a/src/didit/types/components/email_intelligence.py +++ b/src/didit/types/components/email_intelligence.py @@ -1,9 +1,28 @@ # Code generated by codegen from openapi/*.json. DO NOT EDIT. from __future__ import annotations +from typing import Literal + from didit._models import BaseModel -__all__ = ["EmailIntelligence"] +__all__ = ["EmailIntelligence", "EmailIntelligenceReasonCodes"] + + +class EmailIntelligenceReasonCodes(BaseModel): + code: str | None = None + """Stable Didit identifier of the signal, for example `IR-5AC67A32`. Opaque: group and filter on it, do not parse it.""" + + value: object = None + """For a risk flag (for example `voip`, `leaked`, `disposable`, `spam_trap`), its value: a boolean, a level or a date. Null for a scored reason code.""" + + direction: Literal["risk", "trust"] | str | None = None + """Whether the signal raised the risk or added trust.""" + + message: str | None = None + """Human-readable explanation of the signal, in English.""" + + impact_level: str | None = None + """How strongly the signal moved the score, for example `low`, `medium` or `high`.""" class EmailIntelligence(BaseModel): @@ -39,5 +58,5 @@ class EmailIntelligence(BaseModel): no_of_breaches: float | None = None """Number of known breaches containing the address.""" - reason_codes: list[str] | None = None - """Machine-readable codes explaining the score. Values can grow over time, so do not reject unknown codes.""" + reason_codes: list[EmailIntelligenceReasonCodes] | None = None + """Signals that explain the score, each with a stable Didit code, a direction, a message and an impact level. New codes can appear over time, so do not reject unknown codes.""" diff --git a/src/didit/types/components/email_verification_check_response.py b/src/didit/types/components/email_verification_check_response.py index 1b9f6e1..3455310 100644 --- a/src/didit/types/components/email_verification_check_response.py +++ b/src/didit/types/components/email_verification_check_response.py @@ -5,6 +5,7 @@ from typing import Literal from didit._models import BaseModel +from didit.types.components.email_intelligence import EmailIntelligence from didit.types.components.email_social_footprint import EmailSocialFootprint __all__ = [ @@ -147,6 +148,9 @@ class EmailVerificationCheckResponseEmail(BaseModel): email_social: EmailSocialFootprint | None = None """Social footprint of the email address: the online platforms it is registered on. Present only when `enable_social` was set and the check completed. Every count may be null when no data was returned for it. `profiles_registered: 0` means the platforms were checked and the email address was found on none of them - a valid, billable answer and a common synthetic-identity signal.""" + email_intelligence: EmailIntelligence | None = None + """Email intelligence signals. Present only when `enable_enrichment` was `true` on the check.""" + class EmailVerificationCheckResponse(BaseModel): request_id: str | None = None diff --git a/src/didit/types/components/geolocation_attempt.py b/src/didit/types/components/geolocation_attempt.py new file mode 100644 index 0000000..3794f2a --- /dev/null +++ b/src/didit/types/components/geolocation_attempt.py @@ -0,0 +1,199 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal + +from didit._models import BaseModel + +__all__ = [ + "GeolocationAttempt", + "GeolocationAttemptAnonymizers", + "GeolocationAttemptConsent", + "GeolocationAttemptGeofence", +] + + +class GeolocationAttemptAnonymizers(BaseModel): + """What the connection and device look like, each `true`, `false` or `null` when the source cannot tell.""" + + vpn: bool | None = None + + proxy: bool | None = None + + tor: bool | None = None + + spoofing: bool | None = None + + emulator: bool | None = None + + +class GeolocationAttemptConsent(BaseModel): + """The consent the person gave before the system prompt, recorded with the wording version and language they saw.""" + + accepted_at: _dt.datetime | None = None + + version: str | None = None + + locale: str | None = None + + +class GeolocationAttemptGeofence(BaseModel): + """Result of the country and area rules of the step.""" + + enabled: bool | None = None + """Whether the step applies any country or area rule.""" + + result: Literal["inside", "outside", "undetermined"] | str | None = None + """Where the position sits relative to the rules. `undetermined` means the accuracy circle straddles the border or the position resolved to no country; it is not evidence of being outside.""" + + +class GeolocationAttempt(BaseModel): + """One attempt of a Location verification step: the same keys as `geolocation_checks[]` except `warnings`, plus when Didit received it.""" + + node_id: str | None = None + """Workflow node that produced this result, so a workflow with two Location verification steps stays readable.""" + + status: ( + Literal["Not Finished", "Approved", "Declined", "In Review", "Resub Requested"] | str | None + ) = None + """Feature-level status of this Location verification step, resolved from its warnings. Independent of the session `status`.""" + + outcome: ( + Literal[ + "verified", + "low_accuracy", + "accuracy_undetermined", + "stale", + "approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "mock_detected", + "outside_geofence", + "in_blocked_area", + "anonymizer_detected", + "skipped", + "replay_rejected", + "unsupported_client", + ] + | str + | None + ) = None + """What happened on this attempt.""" + + permission: ( + Literal[ + "granted_precise", + "granted_approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "dismissed", + "not_requested", + ] + | str + | None + ) = None + """What the operating system or browser granted. `not_requested` means the step uses the connection's IP location only, so the person is never asked for a permission.""" + + latitude: float | None = None + """WGS84 latitude of the fix. `null` when there is no fix.""" + + longitude: float | None = None + """WGS84 longitude of the fix. `null` when there is no fix.""" + + accuracy_m: float | None = None + """Radius of uncertainty in metres, at the confidence level in `accuracy_confidence`.""" + + accuracy_confidence: Literal["p95", "p68", "unspecified"] | str | None = None + """Confidence level the platform attaches to `accuracy_m`: `p95` (browsers), `p68` (Android) or `unspecified` (iOS).""" + + measured_at: _dt.datetime | None = None + """When the device took the fix, by its own clock.""" + + age_seconds: int | None = None + """Seconds between the device taking the fix and Didit receiving it.""" + + source: ( + Literal["gps", "fused", "network", "wifi", "cell", "browser", "unknown", "ip"] | str | None + ) = None + """Where the fix came from, when the platform says. `ip` means the position is the connection's IP location.""" + + platform: Literal["web", "ios", "android", "react_native", "flutter"] | str | None = None + """The client that produced the fix.""" + + sdk_version: str | None = None + """Version of the SDK that produced the fix.""" + + is_mock: bool | None = None + """`true` when the device says the fix came from a mock location provider or simulation software. `null` when the platform does not report it (browsers cannot tell); `null` is not `false`.""" + + produced_by_accessory: bool | None = None + """iOS only: `true` when the fix came from an external accessory. `null` elsewhere.""" + + integrity: ( + Literal["attested", "not_attested", "failed", "unsupported", "not_determined"] | str | None + ) = None + """Whether device attestation backs the fix. `unsupported` is what browsers report, because the web has no attestation mechanism; it is not a failure.""" + + country_code: str | None = None + """ISO 3166-1 alpha-2 country the fix is in.""" + + region_code: str | None = None + """ISO 3166-2 subdivision the fix is in.""" + + city: str | None = None + """Nearest populated place, a label for reviewers.""" + + geofence: GeolocationAttemptGeofence | None = None + """Result of the country and area rules of the step.""" + + inside_geofence: bool | None = None + """`true` when `geofence.result` is `inside`, `false` when `outside`, `null` otherwise.""" + + geofence_basis: Literal["device", "ip"] | str | None = None + """Which position the area result was judged from: the `device` fix, or the connection's `ip` location.""" + + inside_areas: list[str] | None = None + """Ids of the configured allowed areas the position is inside.""" + + blocked_areas: list[str] | None = None + """Ids of the configured blocked areas the position is in.""" + + position_source: Literal["device_and_ip", "device_only", "ip_only"] | str | None = None + """Where the step takes the position from, as configured: the device checked against the IP location, the device only, or the IP location only.""" + + anonymizers: GeolocationAttemptAnonymizers | None = None + """What the connection and device look like, each `true`, `false` or `null` when the source cannot tell.""" + + ip_distance_km: float | None = None + """Distance to the session's IP location after both uncertainty radii are subtracted; `0` when they overlap.""" + + ip_distance_uncertainty_km: float | None = None + """Combined radius that was subtracted: the IP location's radius plus this fix's accuracy.""" + + ip_consistent: bool | None = None + """Whether `ip_distance_km` is within the distance configured on the step. `null` when either side is unknown.""" + + document_distance_km: float | None = None + """Distance to the geocoded address on the ID document or proof of address. `null` when no address is on file.""" + + travel_excused: bool | None = None + """Whether the step's travel tolerance excused the distance from the address. `null` when tolerance is off.""" + + consecutive_mismatches: int | None = None + """On the final attempt: this check plus the same person's earlier mismatches in a row.""" + + attempts: int | None = None + """Number of this attempt within the node, starting at 1.""" + + consent: GeolocationAttemptConsent | None = None + """The consent the person gave before the system prompt, recorded with the wording version and language they saw.""" + + received_at: _dt.datetime | None = None + """When Didit received the attempt.""" + + created_at: _dt.datetime | None = None diff --git a/src/didit/types/components/geolocation_check.py b/src/didit/types/components/geolocation_check.py new file mode 100644 index 0000000..0d6d832 --- /dev/null +++ b/src/didit/types/components/geolocation_check.py @@ -0,0 +1,238 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal + +from didit._models import BaseModel + +__all__ = [ + "GeolocationCheck", + "GeolocationCheckAnonymizers", + "GeolocationCheckConsent", + "GeolocationCheckGeofence", + "GeolocationCheckWarnings", +] + + +class GeolocationCheckAnonymizers(BaseModel): + """What the connection and device look like, each `true`, `false` or `null` when the source cannot tell.""" + + vpn: bool | None = None + + proxy: bool | None = None + + tor: bool | None = None + + spoofing: bool | None = None + + emulator: bool | None = None + + +class GeolocationCheckConsent(BaseModel): + """The consent the person gave before the system prompt, recorded with the wording version and language they saw.""" + + accepted_at: _dt.datetime | None = None + + version: str | None = None + + locale: str | None = None + + +class GeolocationCheckGeofence(BaseModel): + """Result of the country and area rules of the step.""" + + enabled: bool | None = None + """Whether the step applies any country or area rule.""" + + result: Literal["inside", "outside", "undetermined"] | str | None = None + """Where the position sits relative to the rules. `undetermined` means the accuracy circle straddles the border or the position resolved to no country; it is not evidence of being outside.""" + + +class GeolocationCheckWarnings(BaseModel): + feature: ( + Literal[ + "ID_VERIFICATION", + "NFC", + "LIVENESS", + "FACEMATCH", + "PROOF_OF_ADDRESS", + "PHONE", + "EMAIL", + "AML", + "LOCATION", + "DATABASE_VALIDATION", + "QUESTIONNAIRE", + "DOCUMENT_AI", + "KYB_REGISTRY", + "KYB_DOCUMENTS", + "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", + ] + | str + | None + ) = None + """The feature that generated this warning. The value identifies the feature block the warning belongs to. Each module's warnings array typically uses the value matching its module (e.g. `PHONE` inside `phone_verifications[].warnings`), but the enum above is authoritative across all feature warnings on the decision payload.""" + + risk: str | None = None + + additional_data: dict[str, object] | None = None + + log_type: str | None = None + + short_description: str | None = None + + long_description: str | None = None + + node_id: str | None = None + """The workflow graph node ID that generated this warning""" + + +class GeolocationCheck(BaseModel): + """One Location verification result, the accepted attempt of one workflow node. Measurement, uncertainty and authenticity are separate keys, so a precise unattested fix reads differently from an imprecise attested one.""" + + node_id: str | None = None + """Workflow node that produced this result, so a workflow with two Location verification steps stays readable.""" + + status: ( + Literal["Not Finished", "Approved", "Declined", "In Review", "Resub Requested"] | str | None + ) = None + """Feature-level status of this Location verification step, resolved from its warnings. Independent of the session `status`.""" + + outcome: ( + Literal[ + "verified", + "low_accuracy", + "accuracy_undetermined", + "stale", + "approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "mock_detected", + "outside_geofence", + "in_blocked_area", + "anonymizer_detected", + "skipped", + "replay_rejected", + "unsupported_client", + ] + | str + | None + ) = None + """What happened on this attempt.""" + + permission: ( + Literal[ + "granted_precise", + "granted_approximate", + "denied", + "restricted", + "unavailable", + "timeout", + "dismissed", + "not_requested", + ] + | str + | None + ) = None + """What the operating system or browser granted. `not_requested` means the step uses the connection's IP location only, so the person is never asked for a permission.""" + + latitude: float | None = None + """WGS84 latitude of the fix. `null` when there is no fix.""" + + longitude: float | None = None + """WGS84 longitude of the fix. `null` when there is no fix.""" + + accuracy_m: float | None = None + """Radius of uncertainty in metres, at the confidence level in `accuracy_confidence`.""" + + accuracy_confidence: Literal["p95", "p68", "unspecified"] | str | None = None + """Confidence level the platform attaches to `accuracy_m`: `p95` (browsers), `p68` (Android) or `unspecified` (iOS).""" + + measured_at: _dt.datetime | None = None + """When the device took the fix, by its own clock.""" + + age_seconds: int | None = None + """Seconds between the device taking the fix and Didit receiving it.""" + + source: ( + Literal["gps", "fused", "network", "wifi", "cell", "browser", "unknown", "ip"] | str | None + ) = None + """Where the fix came from, when the platform says. `ip` means the position is the connection's IP location.""" + + platform: Literal["web", "ios", "android", "react_native", "flutter"] | str | None = None + """The client that produced the fix.""" + + sdk_version: str | None = None + """Version of the SDK that produced the fix.""" + + is_mock: bool | None = None + """`true` when the device says the fix came from a mock location provider or simulation software. `null` when the platform does not report it (browsers cannot tell); `null` is not `false`.""" + + produced_by_accessory: bool | None = None + """iOS only: `true` when the fix came from an external accessory. `null` elsewhere.""" + + integrity: ( + Literal["attested", "not_attested", "failed", "unsupported", "not_determined"] | str | None + ) = None + """Whether device attestation backs the fix. `unsupported` is what browsers report, because the web has no attestation mechanism; it is not a failure.""" + + country_code: str | None = None + """ISO 3166-1 alpha-2 country the fix is in.""" + + region_code: str | None = None + """ISO 3166-2 subdivision the fix is in.""" + + city: str | None = None + """Nearest populated place, a label for reviewers.""" + + geofence: GeolocationCheckGeofence | None = None + """Result of the country and area rules of the step.""" + + inside_geofence: bool | None = None + """`true` when `geofence.result` is `inside`, `false` when `outside`, `null` otherwise.""" + + geofence_basis: Literal["device", "ip"] | str | None = None + """Which position the area result was judged from: the `device` fix, or the connection's `ip` location.""" + + inside_areas: list[str] | None = None + """Ids of the configured allowed areas the position is inside.""" + + blocked_areas: list[str] | None = None + """Ids of the configured blocked areas the position is in.""" + + position_source: Literal["device_and_ip", "device_only", "ip_only"] | str | None = None + """Where the step takes the position from, as configured: the device checked against the IP location, the device only, or the IP location only.""" + + anonymizers: GeolocationCheckAnonymizers | None = None + """What the connection and device look like, each `true`, `false` or `null` when the source cannot tell.""" + + ip_distance_km: float | None = None + """Distance to the session's IP location after both uncertainty radii are subtracted; `0` when they overlap.""" + + ip_distance_uncertainty_km: float | None = None + """Combined radius that was subtracted: the IP location's radius plus this fix's accuracy.""" + + ip_consistent: bool | None = None + """Whether `ip_distance_km` is within the distance configured on the step. `null` when either side is unknown.""" + + document_distance_km: float | None = None + """Distance to the geocoded address on the ID document or proof of address. `null` when no address is on file.""" + + travel_excused: bool | None = None + """Whether the step's travel tolerance excused the distance from the address. `null` when tolerance is off.""" + + consecutive_mismatches: int | None = None + """On the final attempt: this check plus the same person's earlier mismatches in a row.""" + + attempts: int | None = None + """Number of this attempt within the node, starting at 1.""" + + consent: GeolocationCheckConsent | None = None + """The consent the person gave before the system prompt, recorded with the wording version and language they saw.""" + + warnings: list[GeolocationCheckWarnings] | None = None + """Warnings this Location verification step raised, with `feature` set to `GEOLOCATION`. Warning codes start with `LOCATION_`.""" diff --git a/src/didit/types/components/kyb_ownership_structure.py b/src/didit/types/components/kyb_ownership_structure.py new file mode 100644 index 0000000..ed25744 --- /dev/null +++ b/src/didit/types/components/kyb_ownership_structure.py @@ -0,0 +1,15 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel +from didit.types.components.kyb_ownership_structure_owner import KYBOwnershipStructureOwner + +__all__ = ["KYBOwnershipStructure"] + + +class KYBOwnershipStructure(BaseModel): + """The cap table the registry proved, as it stood when the ownership tier was delivered: direct `shareholders` and `beneficial_owners`. Null when the registry proved no ownership. It never carries the registry source's own rows; read `company.beneficial_owners` and `company.ownership` for the current record.""" + + shareholders: list[KYBOwnershipStructureOwner] + + beneficial_owners: list[KYBOwnershipStructureOwner] diff --git a/src/didit/types/components/kyb_ownership_structure_owner.py b/src/didit/types/components/kyb_ownership_structure_owner.py new file mode 100644 index 0000000..3d7dbcd --- /dev/null +++ b/src/didit/types/components/kyb_ownership_structure_owner.py @@ -0,0 +1,67 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Literal + +from didit._models import BaseModel +from didit.types.components.kyb_registry_shareholding import KYBRegistryShareholding + +__all__ = ["KYBOwnershipStructureOwner"] + + +class KYBOwnershipStructureOwner(BaseModel): + """One owner of the ownership snapshot: the same registry identity and stake as `company.beneficial_owners[]`, and its canonical `shareholding`.""" + + name: str | None + """Owner name as the registry states it.""" + + first_name: str | None + """Given name, for a natural person, when the registry states it.""" + + last_name: str | None + """Family name, for a natural person, when the registry states it.""" + + date_of_birth: str | None + """Date of birth (ISO 8601) when the registry publishes it.""" + + country_of_birth: str | None + """Country of birth when the registry publishes it.""" + + company_name: str | None + """Company name, for a corporate owner.""" + + registration_number: str | None + """Registration number, for a corporate owner.""" + + entity_type: Literal["person", "company"] | str | None + """Whether the owner is a natural person or a company.""" + + nationality: str | None + """Nationality when the registry states it.""" + + designation: str | None + """The owner's title or role as the registry prints it.""" + + roles: list[str] + """`shareholder` for a direct holder, `ubo` for a beneficial owner.""" + + ownership_min_shares: str | None + """Lower bound of the stake, in percent (equal to the upper bound for an exact stake).""" + + ownership_max_shares: str | None + """Upper bound of the stake, in percent.""" + + voting_min_shares: str | None + """Lower bound of the voting rights, in percent.""" + + voting_max_shares: str | None + """Upper bound of the voting rights, in percent.""" + + appointment_date: str | None + """Date the holding or appointment started (ISO 8601).""" + + is_active: bool | None + """False for a former owner.""" + + shareholding: KYBRegistryShareholding | None + """What an owner holds, in the same shape for every country and registry source. Null when the registry states no holding. A band (for example a UK PSC's 25-50%) is not a stake: `percentage` is null and the band stays in `ownership_min_shares` / `ownership_max_shares`.""" diff --git a/src/didit/types/components/kyb_registry_data.py b/src/didit/types/components/kyb_registry_data.py new file mode 100644 index 0000000..2519c7a --- /dev/null +++ b/src/didit/types/components/kyb_registry_data.py @@ -0,0 +1,132 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Literal + +from didit._models import BaseModel +from didit.types.components.kyb_registry_lite_enrichment import KYBRegistryLiteEnrichment +from didit.types.components.kyb_registry_section_error import KYBRegistrySectionError +from didit.types.components.kyb_registry_source import KYBRegistrySource +from didit.types.components.kyb_registry_ubo_resolution import KYBRegistryUboResolution + +__all__ = ["KYBRegistryData"] + + +class KYBRegistryData(BaseModel): + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" + + company_name: str | None = None + """Company name as corrected in the console.""" + + registration_number: str | None = None + """Registration number as the registry or a console correction states it.""" + + country_code: str | None = None + """Country of the registration as the registry or a console correction states it.""" + + region: str | None = None + """Region or state of the registration.""" + + incorporation_date: str | None = None + """Incorporation date (ISO 8601).""" + + registration_date: str | None = None + """Registration date (ISO 8601) when the registry states one apart from the incorporation date.""" + + dissolution_date: str | None = None + """Dissolution date (ISO 8601) when the registry states one.""" + + tax_number: str | None = None + """Tax identification number.""" + + vat_number: str | None = None + """VAT number.""" + + legal_address: str | None = None + """Legal address as corrected in the console.""" + + registered_address: str | None = None + """Registered address as the registry states it.""" + + company_type: str | None = None + """Legal form.""" + + registry_status: str | None = None + """Company status at the registry.""" + + verification_status: str | None = None + """Verification status.""" + + alternative_names: str | None = None + """Other names the company trades or traded under.""" + + nature_of_business: str | None = None + """Activity description.""" + + registered_capital: str | None = None + """Registered capital as printed.""" + + registered_capital_amount: str | None = None + """Registered capital amount, as a decimal string.""" + + registered_capital_currency: str | None = None + """Registered capital currency (ISO 4217).""" + + website: str | None = None + """Website.""" + + email: str | None = None + """Contact email.""" + + phone: str | None = None + """Contact phone.""" + + legal_entity_identifier: str | None = None + """Legal Entity Identifier (LEI).""" + + location_of_registration: str | None = None + """Place of registration.""" + + control_scheme: str | None = None + """Governance scheme when the registry exposes it.""" + + ownership_error: ( + Literal[ + "no_owners_on_record", + "no_natural_person_owner", + "ownership_section_unavailable", + "company_not_found", + "ambiguous_company_match", + "missing_registration_number", + "entity_type_not_covered", + "provider_unavailable", + "other", + ] + | str + | None + ) = None + """Why a requested ownership tier was not delivered, in the same codes as `ownership.unavailable_reason`. `no_owners_on_record` (the registry answered and names no owner) and `ownership_section_unavailable` (the registry did not return the ownership section) are different findings.""" + + section_errors: dict[str, KYBRegistrySectionError] | None = None + """Sections the registry did not return, keyed by section (`officers`, `shareholders`, `group_structure`). A section listed here was never delivered: an empty list next to it says nothing about the company.""" + + ubo_resolution: KYBRegistryUboResolution | None = None + """How the UBO tier walked the ownership chain above the company.""" + + lite_enrichment: KYBRegistryLiteEnrichment | None = None + """Blank Lite profile fields another of the country's registry sources filled. The source is not named.""" + + registry_metadata: dict[str, str | float | bool] | None = None + """The register's own fields for the company, keyed as the register names them, as plain values (legacy records). Only fields reviewed as registry facts are included.""" + + registry_sources: list[KYBRegistrySource] | None = None + """The official registers the record was read from (legacy records). Other sources are not named.""" + + previous_names: list[str] | None = None + """Names the company was registered under before (legacy records).""" + + parent_companies: list[str] | None = None + """Parent companies the registry names (legacy records).""" + + documents_available: int | None = None + """How many filings the registry offers for the company (legacy records).""" diff --git a/src/didit/types/components/kyb_registry_group_company.py b/src/didit/types/components/kyb_registry_group_company.py new file mode 100644 index 0000000..63c5624 --- /dev/null +++ b/src/didit/types/components/kyb_registry_group_company.py @@ -0,0 +1,19 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel + +__all__ = ["KYBRegistryGroupCompany"] + + +class KYBRegistryGroupCompany(BaseModel): + """A company of the corporate group, by its registry identity.""" + + name: str | None + """Company name.""" + + country_code: str | None + """Country of registration.""" + + registration_number: str | None + """Registration number.""" diff --git a/src/didit/types/components/kyb_registry_lite_enrichment.py b/src/didit/types/components/kyb_registry_lite_enrichment.py new file mode 100644 index 0000000..a504be5 --- /dev/null +++ b/src/didit/types/components/kyb_registry_lite_enrichment.py @@ -0,0 +1,16 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel + +__all__ = ["KYBRegistryLiteEnrichment"] + + +class KYBRegistryLiteEnrichment(BaseModel): + """Blank Lite profile fields another of the country's registry sources filled. The source is not named.""" + + fields: list[str] + """The company fields that were filled.""" + + people_added: int + """How many officers or owners were added.""" diff --git a/src/didit/types/components/kyb_registry_section_error.py b/src/didit/types/components/kyb_registry_section_error.py new file mode 100644 index 0000000..cd3f5d4 --- /dev/null +++ b/src/didit/types/components/kyb_registry_section_error.py @@ -0,0 +1,13 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel + +__all__ = ["KYBRegistrySectionError"] + + +class KYBRegistrySectionError(BaseModel): + """A section the registry did not return.""" + + status_code: int | None + """The status the registry answered for the section.""" diff --git a/src/didit/types/components/kyb_registry_source.py b/src/didit/types/components/kyb_registry_source.py new file mode 100644 index 0000000..2f0cd74 --- /dev/null +++ b/src/didit/types/components/kyb_registry_source.py @@ -0,0 +1,18 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Literal + +from didit._models import BaseModel + +__all__ = ["KYBRegistrySource"] + + +class KYBRegistrySource(BaseModel): + """An official register the record was read from. Only official government registers, regulators and the official identifier system are named; any other source is left out.""" + + name: str + """Register name, for example `UK Companies House`.""" + + source_type: Literal["official"] | str + """Always `official`.""" diff --git a/src/didit/types/components/kyb_registry_ubo_resolution.py b/src/didit/types/components/kyb_registry_ubo_resolution.py new file mode 100644 index 0000000..78eca3e --- /dev/null +++ b/src/didit/types/components/kyb_registry_ubo_resolution.py @@ -0,0 +1,28 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel +from didit.types.components.kyb_registry_group_company import KYBRegistryGroupCompany + +__all__ = ["KYBRegistryUboResolution", "KYBRegistryUboResolutionUnresolved"] + + +class KYBRegistryUboResolutionUnresolved(BaseModel): + reason: str + """Why, for example `no_group_structure_on_record`, `selected_company_not_in_group_structure` or `section_error`.""" + + section: str | None + """The section concerned, for example `group_structure`.""" + + +class KYBRegistryUboResolution(BaseModel): + """How the UBO tier walked the ownership chain above the company.""" + + parent_chain: list[KYBRegistryGroupCompany] + """Corporate parents from the ultimate parent down to the company.""" + + subsidiaries: list[KYBRegistryGroupCompany] + """Companies directly below the company in its corporate group.""" + + unresolved: list[KYBRegistryUboResolutionUnresolved] + """Parts of the chain the registry could not resolve (the same entries as `ownership.unresolved`).""" diff --git a/src/didit/types/components/phone_intelligence.py b/src/didit/types/components/phone_intelligence.py index e22ee0e..854126c 100644 --- a/src/didit/types/components/phone_intelligence.py +++ b/src/didit/types/components/phone_intelligence.py @@ -1,9 +1,28 @@ # Code generated by codegen from openapi/*.json. DO NOT EDIT. from __future__ import annotations +from typing import Literal + from didit._models import BaseModel -__all__ = ["PhoneIntelligence"] +__all__ = ["PhoneIntelligence", "PhoneIntelligenceReasonCodes"] + + +class PhoneIntelligenceReasonCodes(BaseModel): + code: str | None = None + """Stable Didit identifier of the signal, for example `IR-5AC67A32`. Opaque: group and filter on it, do not parse it.""" + + value: object = None + """For a risk flag (for example `voip`, `leaked`, `disposable`, `spam_trap`), its value: a boolean, a level or a date. Null for a scored reason code.""" + + direction: Literal["risk", "trust"] | str | None = None + """Whether the signal raised the risk or added trust.""" + + message: str | None = None + """Human-readable explanation of the signal, in English.""" + + impact_level: str | None = None + """How strongly the signal moved the score, for example `low`, `medium` or `high`.""" class PhoneIntelligence(BaseModel): @@ -33,5 +52,5 @@ class PhoneIntelligence(BaseModel): carrier_type: str | None = None """Line classification reported by the lookup (e.g., `mobile`).""" - reason_codes: list[str] | None = None - """Machine-readable codes explaining the score. Values can grow over time, so do not reject unknown codes.""" + reason_codes: list[PhoneIntelligenceReasonCodes] | None = None + """Signals that explain the score, each with a stable Didit code, a direction, a message and an impact level. New codes can appear over time, so do not reject unknown codes.""" diff --git a/src/didit/types/components/phone_verification_check_response.py b/src/didit/types/components/phone_verification_check_response.py index fbea1d2..d386c24 100644 --- a/src/didit/types/components/phone_verification_check_response.py +++ b/src/didit/types/components/phone_verification_check_response.py @@ -5,6 +5,7 @@ from typing import Literal from didit._models import BaseModel +from didit.types.components.phone_intelligence import PhoneIntelligence from didit.types.components.phone_social_footprint import PhoneSocialFootprint __all__ = [ @@ -143,6 +144,9 @@ class PhoneVerificationCheckResponsePhone(BaseModel): phone_social: PhoneSocialFootprint | None = None """Social footprint of the phone number: the online platforms it is registered on. Present only when `enable_social` was set and the check completed. Every count may be null when no data was returned for it. `profiles_registered: 0` means the platforms were checked and the phone number was found on none of them - a valid, billable answer and a common synthetic-identity signal.""" + phone_intelligence: PhoneIntelligence | None = None + """Phone intelligence signals. Present only when `enable_enrichment` was `true` on the check.""" + class PhoneVerificationCheckResponse(BaseModel): request_id: str | None = None diff --git a/src/didit/types/components/session_decision.py b/src/didit/types/components/session_decision.py index 2de967c..973d28a 100644 --- a/src/didit/types/components/session_decision.py +++ b/src/didit/types/components/session_decision.py @@ -8,24 +8,38 @@ from didit.types.components.address_validation_result import AddressValidationResult from didit.types.components.aml_screening import AMLScreening from didit.types.components.bank_verification_result import BankVerificationResult +from didit.types.components.biometric_retention import BiometricRetention from didit.types.components.document_ai_detected_code import DocumentAIDetectedCode +from didit.types.components.email_intelligence import EmailIntelligence +from didit.types.components.email_social_footprint import EmailSocialFootprint +from didit.types.components.geolocation_attempt import GeolocationAttempt +from didit.types.components.geolocation_check import GeolocationCheck from didit.types.components.investigator_block import InvestigatorBlock +from didit.types.components.kyb_ownership_structure import KYBOwnershipStructure from didit.types.components.kyb_registry_address import KYBRegistryAddress +from didit.types.components.kyb_registry_data import KYBRegistryData from didit.types.components.kyb_registry_industry import KYBRegistryIndustry from didit.types.components.kyb_registry_ownership import KYBRegistryOwnership from didit.types.components.kyb_registry_shareholding import KYBRegistryShareholding +from didit.types.components.phone_intelligence import PhoneIntelligence +from didit.types.components.phone_social_footprint import PhoneSocialFootprint from didit.types.components.signature_result import SignatureResult __all__ = [ "SessionDecision", + "SessionDecisionAssignee", "SessionDecisionBiometricConsent", "SessionDecisionContactDetails", + "SessionDecisionDatabaseValidationNotPerformedReason", "SessionDecisionDatabaseValidations", "SessionDecisionDatabaseValidationsErrors", "SessionDecisionDatabaseValidationsScreenedData", "SessionDecisionDatabaseValidationsValidations", "SessionDecisionDatabaseValidationsValidationsValidation", "SessionDecisionDatabaseValidationsWarnings", + "SessionDecisionDecisionTrace", + "SessionDecisionDecisionTraceActor", + "SessionDecisionDecisionTraceStatusWarnings", "SessionDecisionDocumentAiDocuments", "SessionDecisionDocumentAiDocumentsItems", "SessionDecisionDocumentAiDocumentsItemsFields", @@ -43,6 +57,10 @@ "SessionDecisionEmailVerificationsWarnings", "SessionDecisionExpectedDetails", "SessionDecisionFaceMatches", + "SessionDecisionFaceMatchesFaceCoverage", + "SessionDecisionFaceMatchesFaceCoverageEyes", + "SessionDecisionFaceMatchesFaceCoverageFace", + "SessionDecisionFaceMatchesFaceCoverageMouth", "SessionDecisionFaceMatchesWarnings", "SessionDecisionIdVerifications", "SessionDecisionIdVerificationsBackImageQualityScore", @@ -97,6 +115,12 @@ "SessionDecisionKeyPeopleChecksSubmittedPartiesRoles", "SessionDecisionKeyPeopleChecksSubmittedPartiesVerificationWorkflowFeatures", "SessionDecisionKeyPeopleChecksUboKycSummary", + "SessionDecisionLinkedRecords", + "SessionDecisionLinkedRecordsEarlierVerifications", + "SessionDecisionLinkedRecordsNetworks", + "SessionDecisionLinkedRecordsNetworksItems", + "SessionDecisionLinkedRecordsSameFace", + "SessionDecisionLinkedRecordsSameFaceBestMatch", "SessionDecisionLivenessChecks", "SessionDecisionLivenessChecksMatches", "SessionDecisionLivenessChecksMatchesUserDetails", @@ -132,13 +156,23 @@ "SessionDecisionRegistryChecksCompany", "SessionDecisionRegistryChecksCompanyBeneficialOwners", "SessionDecisionRegistryChecksCompanyOfficers", + "SessionDecisionRegistryChecksCompanyRegistryMonitoring", "SessionDecisionResubmissions", "SessionDecisionResubmissionsNodes", "SessionDecisionResubmissionsRequestedBy", "SessionDecisionReviews", + "SessionDecisionStatusOverride", ] +class SessionDecisionAssignee(BaseModel): + """The Console reviewer the session is assigned to, or `null` when nobody holds it.""" + + email: str | None = None + + assigned_at: _dt.datetime | None = None + + class SessionDecisionBiometricConsent(BaseModel): """Whether the session required explicit biometric consent before a face capture, why, and the evidence of the answer. User Verification (KYC) sessions only; the same object is in the `decision` of session webhooks. `null` when the session was never evaluated, for example a workflow without a face capture. Fields with no recorded value are `null`. A native SDK below 4.10.0, or one that does not report its version, cannot show the consent step: its face captures run as before, and a session that required consent then reports `status: "pending"` with `reason: "BIOMETRIC_CONSENT_UNSUPPORTED_SDK"`. See [Biometric consent](/getting-started/biometric-consent).""" @@ -253,6 +287,16 @@ class SessionDecisionContactDetails(BaseModel): """Phone number of the user in E.164 format if available (e.g., +14155552671). `null` when only an email was supplied at session creation. Note: This field returns the original phone number provided during session creation. If the number was invalid, it may not be in E.164 format.""" +class SessionDecisionDatabaseValidationNotPerformedReason(BaseModel): + """Why a configured database validation produced no result, as `{code, message}` plus context fields. Present only when `database_validations` is `null` for a workflow that has the step, so you can tell "the registry agreed" from "nothing ran". `null` otherwise.""" + + code: str | None = None + """Stable machine-readable reason.""" + + message: str | None = None + """Human-readable explanation.""" + + class SessionDecisionDatabaseValidationsErrors(BaseModel): """The upstream service's error object spread as-is - its keys vary by service (commonly a message/code and any provider-specific details) - plus `service_id` identifying the service that errored.""" @@ -336,6 +380,8 @@ class SessionDecisionDatabaseValidationsWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -387,6 +433,58 @@ class SessionDecisionDatabaseValidations(BaseModel): """Warnings related to the database validation.""" +class SessionDecisionDecisionTraceActor(BaseModel): + """The reviewer behind a manual decision.""" + + user: str | None = None + + actor_type: str | None = None + + +class SessionDecisionDecisionTraceStatusWarnings(BaseModel): + risk: str | None = None + + feature: str | None = None + + node_id: str | None = None + + log_type: str | None = None + + check_status: str | None = None + + source: str | None = None + """The payload list the warning came from, for example `id_verifications`.""" + + short_description: str | None = None + + +class SessionDecisionDecisionTrace(BaseModel): + """How the status was reached: who set it and which warnings did.""" + + status: str | None = None + """The session status.""" + + decided_by: Literal["manual", "automatic", "investigator"] | str | None = None + """Who set the status. `null` while the session is not decided.""" + + decided_at: _dt.datetime | None = None + + automatic_status: str | None = None + """What the platform's own checks conclude, which differs from `status` after a manual decision.""" + + terminal_node_id: str | None = None + """The workflow status node that ended the session, when one did.""" + + actor: SessionDecisionDecisionTraceActor | None = None + """The reviewer behind a manual decision.""" + + warning_counts: dict[str, int] | None = None + """Warnings per `log_type` (`error`, `warning`, `information`) and `total`.""" + + status_warnings: list[SessionDecisionDecisionTraceStatusWarnings] | None = None + """The warnings that set a `Declined` or `In Review` status.""" + + class SessionDecisionDocumentAiDocumentsItemsFields(BaseModel): key: str | None = None """Stable field key used as the key in `extracted_data`.""" @@ -740,6 +838,8 @@ class SessionDecisionEmailVerificationsWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -799,6 +899,12 @@ class SessionDecisionEmailVerifications(BaseModel): matches: list[SessionDecisionEmailVerificationsMatches] | None = None """Matches found for this email address. Each match has a `source`: `session` (another verification session in your application matched on the same email, returned with `session_id`/`session_number`/`vendor_data`/`verification_date`) or `list_entry` (the email is on an org-managed allow/block list - see `/management-api/lists/overview`). Cross-session matches use different `vendor_data` and are capped at 5.""" + email_intelligence: EmailIntelligence | None = None + """Email intelligence signals. Present only when the email intelligence add-on ran for this address.""" + + email_social: EmailSocialFootprint | None = None + """Social footprint of the address. Present only when the social footprint add-on ran for this address.""" + class SessionDecisionExpectedDetails(BaseModel): """Expected details supplied at session creation - used for cross-validation against extracted data (KYC) or to pre-fill the company registry search (KYB). Echoes back exactly the keys that were provided; `null` when none were supplied. KYC sessions carry the person fields; Business (KYB) sessions carry `company_name`, `registry_country` and `registration_number`.""" @@ -851,6 +957,43 @@ class SessionDecisionExpectedDetails(BaseModel): """Expected company registration number. Business (KYB) sessions only.""" +class SessionDecisionFaceMatchesFaceCoverageEyes(BaseModel): + covered: bool | None = None + + calibrated: bool | None = None + """`false` means the reading is shadow evidence only and no warning acts on it.""" + + visibility_score: float | None = None + + +class SessionDecisionFaceMatchesFaceCoverageFace(BaseModel): + covered: bool | None = None + + calibrated: bool | None = None + """`false` means the reading is shadow evidence only and no warning acts on it.""" + + visibility_score: float | None = None + + +class SessionDecisionFaceMatchesFaceCoverageMouth(BaseModel): + covered: bool | None = None + + calibrated: bool | None = None + """`false` means the reading is shadow evidence only and no warning acts on it.""" + + visibility_score: float | None = None + + +class SessionDecisionFaceMatchesFaceCoverage(BaseModel): + """Whether the eyes, mouth and face are covered in the captured image. Returned by `GET /v3/session/{sessionId}/decision/` only; it is not part of webhook payloads. `null` when no coverage reading exists.""" + + eyes: SessionDecisionFaceMatchesFaceCoverageEyes | None = None + + mouth: SessionDecisionFaceMatchesFaceCoverageMouth | None = None + + face: SessionDecisionFaceMatchesFaceCoverageFace | None = None + + class SessionDecisionFaceMatchesWarnings(BaseModel): feature: ( Literal[ @@ -869,6 +1012,8 @@ class SessionDecisionFaceMatchesWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -915,6 +1060,9 @@ class SessionDecisionFaceMatches(BaseModel): warnings: list[SessionDecisionFaceMatchesWarnings] | None = None """Face match verification warnings""" + face_coverage: SessionDecisionFaceMatchesFaceCoverage | None = None + """Whether the eyes, mouth and face are covered in the captured image. Returned by `GET /v3/session/{sessionId}/decision/` only; it is not part of webhook payloads. `null` when no coverage reading exists.""" + class SessionDecisionIdVerificationsBackImageQualityScore(BaseModel): """Quality metrics for the back document image. Same structure as front_image_quality_score.""" @@ -1444,6 +1592,8 @@ class SessionDecisionIdVerificationsWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -1620,6 +1770,15 @@ class SessionDecisionIdVerifications(BaseModel): address_validation: AddressValidationResult | None = None """Address Validation of the address printed on this document: whether it exists and its normalised form, as the document read it (a later correction of `address` does not run it again). Present when this ID verification step enabled the Address Validation add-on; `null` otherwise.""" + region: str | None = None + """Region or state of the document's issuing country where the document identifies one.""" + + extracted_data: dict[str, object] | None = None + """Snapshot of the data extracted from the document that the person was shown to review, kept next to the confirmed values so you can compare what was read with what the person confirmed. `null` when the person was not asked to review.""" + + barcodes: list[dict[str, object]] | None = None + """Data read from the document's barcodes. Empty when the document has none or none was read.""" + class SessionDecisionIpAnalysesIdDocumentLocation(BaseModel): """Coordinates, or `null` when unavailable.""" @@ -1788,6 +1947,8 @@ class SessionDecisionIpAnalysesWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -1888,6 +2049,28 @@ class SessionDecisionIpAnalyses(BaseModel): matches: list[SessionDecisionIpAnalysesMatches] | None = None """Cross-session matches found for this entry's IP address or device identity. Every match is another verification session in your application (`source` is always `session`) that shares the same value, always belonging to a different vendor user / `vendor_data` than the current session, capped at 5 per collector (`device_fingerprint` sums two independently capped collectors, so up to 10 entries are possible). Every item carries `match_source`, `confidence`, `match_mode`, `device_info` and `location_info`; the keys `recovery_similarity`, `tls_ja4_corroborated` and `recovery_gate_reason` are present only when `match_source` is `recovered_high`.""" + browser_version: str | None = None + + os_version: str | None = None + + user_agent: str | None = None + """The browser's user agent string.""" + + accept_language: str | None = None + """The `Accept-Language` header the browser sent.""" + + session_identifier: str | None = None + """Identifier of the browsing session the verification ran in.""" + + session_age_ms: int | None = None + """Age of that browsing session in milliseconds when the step ran.""" + + coords_accuracy: float | None = None + """Accuracy radius, in metres, of the coordinates the device reported.""" + + raw_device_data: dict[str, object] | None = None + """Raw device signals collected for the step.""" + class SessionDecisionKeyPeopleChecksRegistryBeneficialOwnersKycAmlCategories(BaseModel): """Per-category summary derived from the person's AML hits. `null` when there are no hits.""" @@ -2378,6 +2561,63 @@ class SessionDecisionKeyPeopleChecks(BaseModel): warnings: list[dict[str, object]] | None = None +class SessionDecisionLinkedRecordsEarlierVerifications(BaseModel): + count: int | None = None + + vendor_user_id: str | None = None + + +class SessionDecisionLinkedRecordsNetworksItems(BaseModel): + network_id: str | None = None + + display_number: int | None = None + + name: str | None = None + + status: str | None = None + + risk_score: float | None = None + + +class SessionDecisionLinkedRecordsNetworks(BaseModel): + count: int | None = None + + open: int | None = None + + dismissed: int | None = None + + items: list[SessionDecisionLinkedRecordsNetworksItems] | None = None + + +class SessionDecisionLinkedRecordsSameFaceBestMatch(BaseModel): + session_id: str | None = None + + session_number: int | None = None + + vendor_user_id: str | None = None + + similarity_percentage: float | None = None + + +class SessionDecisionLinkedRecordsSameFace(BaseModel): + """Other people whose face matched one of this session's face searches.""" + + count: int | None = None + + best_match: SessionDecisionLinkedRecordsSameFaceBestMatch | None = None + + +class SessionDecisionLinkedRecords(BaseModel): + """A summary of other records linked to the session. `null` when there is nothing to show, and for workflows that declare an age assurance standard.""" + + same_face: SessionDecisionLinkedRecordsSameFace | None = None + """Other people whose face matched one of this session's face searches.""" + + earlier_verifications: SessionDecisionLinkedRecordsEarlierVerifications | None = None + + networks: SessionDecisionLinkedRecordsNetworks | None = None + + class SessionDecisionLivenessChecksMatchesUserDetails(BaseModel): """Identity data from the matching session or imported User profile. Always `null` for `retained_template` and `list_entry` matches.""" @@ -2449,6 +2689,8 @@ class SessionDecisionLivenessChecksWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -2667,6 +2909,8 @@ class SessionDecisionNfcVerificationsWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -2812,6 +3056,8 @@ class SessionDecisionPhoneVerificationsWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -2882,6 +3128,12 @@ class SessionDecisionPhoneVerifications(BaseModel): matches: list[SessionDecisionPhoneVerificationsMatches] | None = None """Matches found for this phone number. Each match has a `source`: `session` (another verification session in your application matched on the same number, returned with `session_id`/`session_number`/`vendor_data`/`verification_date`) or `list_entry` (the number is on an org-managed allow/block list - see `/management-api/lists/overview`). Cross-session matches use different `vendor_data` and are capped at 5.""" + phone_intelligence: PhoneIntelligence | None = None + """Phone intelligence signals. Present only when the phone intelligence add-on ran for this number.""" + + phone_social: PhoneSocialFootprint | None = None + """Social footprint of the number. Present only when the social footprint add-on ran for this number.""" + class SessionDecisionPoaVerificationsDocumentMetadataOverlayManipulationManipulatedRegions( BaseModel @@ -3047,6 +3299,8 @@ class SessionDecisionPoaVerificationsWarnings(BaseModel): "KYB_REGISTRY", "KYB_DOCUMENTS", "KYB_KEY_PEOPLE", + "GEOLOCATION", + "SIGNATURE", ] | str | None @@ -3346,6 +3600,31 @@ class SessionDecisionRegistryChecksCompanyOfficers(BaseModel): """Registry-reported birth month. Null when only the year is known.""" +class SessionDecisionRegistryChecksCompanyRegistryMonitoring(BaseModel): + """The latest registry monitor for the company, or `null` when none exists.""" + + uuid: str | None = None + + status: str | None = None + + unavailable_reason: str | None = None + + enrolled_at: _dt.datetime | None = None + + cancelled_at: _dt.datetime | None = None + + last_bill_date: _dt.date | None = None + + next_bill_date: _dt.date | None = None + + last_event_at: _dt.datetime | None = None + + events_count: int | None = None + + watched_fields: object = None + """The company fields the monitor watches.""" + + class SessionDecisionRegistryChecksCompany(BaseModel): """Full registry payload for the company (registry record merged with any user-provided or console-edited data).""" @@ -3470,8 +3749,8 @@ class SessionDecisionRegistryChecksCompany(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """Data confirmed or edited by the end user.""" @@ -3494,6 +3773,9 @@ class SessionDecisionRegistryChecksCompany(BaseModel): registry_ownership_status: str | None = None """`not_requested`, `pending`, `delivered`, `not_held` or `unavailable`. Also in `ownership.status`.""" + registry_monitoring: SessionDecisionRegistryChecksCompanyRegistryMonitoring | None = None + """The latest registry monitor for the company, or `null` when none exists.""" + class SessionDecisionRegistryChecks(BaseModel): """One company registry check - the full company-registry payload enriched with ownership structure and warnings. Present only when `session_kind = business`.""" @@ -3508,8 +3790,8 @@ class SessionDecisionRegistryChecks(BaseModel): company: SessionDecisionRegistryChecksCompany | None = None """Full registry payload for the company (registry record merged with any user-provided or console-edited data).""" - ownership_structure: dict[str, object] | None = None - """Raw ownership snapshot kept for reviewers; its shape differs by registry source and is not a stable contract. Read `company.beneficial_owners` and `company.ownership` instead.""" + ownership_structure: KYBOwnershipStructure | None = None + """The cap table the registry proved, as it stood when the ownership tier was delivered: direct `shareholders` and `beneficial_owners`. Null when the registry proved no ownership. It never carries the registry source's own rows; read `company.beneficial_owners` and `company.ownership` for the current record.""" warnings: list[dict[str, object]] | None = None @@ -3564,6 +3846,15 @@ class SessionDecisionReviews(BaseModel): created_at: _dt.datetime | None = None +class SessionDecisionStatusOverride(BaseModel): + """Present when a reviewer set `status` by hand. `null` when the status is the automatic one. Use it to tell a manual approval from an automatic one.""" + + overridden_at: _dt.datetime | None = None + + automatic_status: str | None = None + """The status the platform's own checks conclude.""" + + class SessionDecision(BaseModel): session_id: str | None = None """The unique identifier of the session.""" @@ -3574,6 +3865,9 @@ class SessionDecision(BaseModel): shared_from_session: str | None = None """For a session cloned with `POST /v3/session/import-shared/`: the `session_id` of the original session in the source application. `null` for every other session. Omitted when `include=events` is passed.""" + shared_from_session_number: int | None = None + """`session_number` of the source session when this session was imported from another application of your organization. `null` otherwise.""" + session_number: int | None = None """The number of the session.""" @@ -3598,11 +3892,20 @@ class SessionDecision(BaseModel): ) = None """Overall lifecycle status of the session - the rolled-up workflow result. Terminal values are `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired`, and `Abandoned`; `Not Started`, `In Progress`, `Awaiting User`, and `Resubmitted` indicate the session is still moving through the workflow.""" + status_override: SessionDecisionStatusOverride | None = None + """Present when a reviewer set `status` by hand. `null` when the status is the automatic one. Use it to tell a manual approval from an automatic one.""" + + decision_trace: SessionDecisionDecisionTrace | None = None + """How the status was reached: who set it and which warnings did.""" + + linked_records: SessionDecisionLinkedRecords | None = None + """A summary of other records linked to the session. `null` when there is nothing to show, and for workflows that declare an age assurance standard.""" + workflow_id: str | None = None """Stable identifier of the workflow group that produced this session. Workflows are versioned - this value identifies the workflow itself, not the specific version.""" features: list[str] | None = None - """List of verification features configured for this session, as display names: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH` (Business Verification sessions use the KYB feature set: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). With `include=events` each entry becomes an object `{feature, node_id}` instead of a plain string, and the email feature is renamed: it appears as `EMAIL` in events mode instead of the `EMAIL_VERIFICATION` used here.""" + """List of verification features configured for this session, as display names: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH`, `GEOLOCATION` (Location verification) (Business Verification sessions use the KYB feature set: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). With `include=events` each entry becomes an object `{feature, node_id}` instead of a plain string, and the email feature is renamed: it appears as `EMAIL` in events mode instead of the `EMAIL_VERIFICATION` used here.""" vendor_data: str | None = None """The vendor data of the session.""" @@ -3662,10 +3965,10 @@ class SessionDecision(BaseModel): """**Array of questionnaire response reports** - always a JSON array, never a singular `questionnaire` object. `null` until at least one questionnaire step has produced data. Each item is the full report, including `node_id`, the questionnaire metadata, sections with form elements, and the user's answers.""" bank_verifications: list[BankVerificationResult] | None = None - """Bank Verification results, one item per Bank Verification step, for User and Business Verification. `null` until a step produces one. Each item's `method` says how the account was verified: `open_banking` (bank sign-in) or `account_lookup` (account check), or a `statement` or `microdeposits` fallback, and `none` when the person continued without a bank before any attempt was evaluated (`continued_without_bank`). See [Bank verification methods](/core-technology/bank-verification/verification-methods).""" + """Bank Verification results, one item per Bank Verification step, for User and Business Verification. `null` until a step produces one. Each item's `method` says how the account was verified: `open_banking` (bank sign-in) or `account_lookup` (account check), or a `statement` or `microdeposits` fallback, and `none` when the person continued without a bank before any attempt was evaluated (`continued_without_bank`). See [Bank verification methods](/core-technology/bank-verification/verification-methods). Bank Verification is not enabled in production yet, so this stays `null` on production sessions until it is.""" signatures: list[SignatureResult] | None = None - """Electronic Signature results, one item per signer and signature step, for User and Business Verification. Present only when the workflow has an Electronic Signature step; an empty array until a signer reaches it. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature).""" + """E-signature results, one item per signer and signature step, for User and Business Verification. Present only when the workflow has an E-signature step; an empty array until a signer reaches it. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature).""" aml_screenings: list[AMLScreening] | None = None """**Array of AML screening reports** - always a JSON array, never a singular `aml` object. `null` until at least one AML step has produced data. Each item is the full report, including `node_id`, feature-level `status`, `total_hits`, `entity_type`, `hits[]`, `score`, `screened_data`, `is_ongoing_monitoring_enabled`, and `warnings[]`.""" @@ -3673,6 +3976,12 @@ class SessionDecision(BaseModel): ip_analyses: list[SessionDecisionIpAnalyses] | None = None """**Array of Device & IP Analysis reports** - always a JSON array, never a singular `ip_analysis` object. `null` until at least one IP-analysis step has produced data. Each item is the full report, including `node_id`, feature-level `status`, IP and geolocation data, device fingerprint, and `warnings[]`. Entries with duplicate `(node_id, ip_address, device_fingerprint)` are deduplicated server-side.""" + geolocation_checks: list[GeolocationCheck] | None = None + """**Array of Location verification results**, one per Location verification step: that step's accepted attempt. `null` until a Location verification step has produced data. Earlier attempts of the same step are in `geolocation_attempts`.""" + + geolocation_attempts: list[GeolocationAttempt] | None = None + """Every attempt of every Location verification step of this session, oldest first. Attempts that a resubmission replaced are left out. A workflow that withholds `geolocation_checks` through its response attributes withholds this list too.""" + database_validations: list[SessionDecisionDatabaseValidations] | None = None """**Array of Database Validation reports** - always a JSON array, never a singular `database_validation` object. `null` until at least one DB validation step has produced data. Each item is the full report, including `node_id`, feature-level `status`, `screened_data`, the per-service `validations[]` (each with its registry `source_data`), and `warnings[]`. The `screened_data` and `source_data` fields vary by country: @@ -3713,8 +4022,22 @@ class SessionDecision(BaseModel): **VEN (Venezuela)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, gender, date_of_birth, document_type} """ + database_validation_not_performed_reason: ( + SessionDecisionDatabaseValidationNotPerformedReason | None + ) = None + """Why a configured database validation produced no result, as `{code, message}` plus context fields. Present only when `database_validations` is `null` for a workflow that has the step, so you can tell "the registry agreed" from "nothing ran". `null` otherwise.""" + reviews: list[SessionDecisionReviews] | None = None + assignee: SessionDecisionAssignee | None = None + """The Console reviewer the session is assigned to, or `null` when nobody holds it.""" + + waiting_since: _dt.datetime | None = None + """When the session started waiting for review. `null` unless the session is `In Review` and your application sets a review deadline.""" + + sla_due_at: _dt.datetime | None = None + """When the review is due. `null` unless the session is `In Review` and your application sets a review deadline.""" + created_at: _dt.datetime | None = None """Timestamp at which the session was created (ISO 8601, UTC).""" @@ -3733,6 +4056,9 @@ class SessionDecision(BaseModel): environment: Literal["live", "sandbox"] | str | None = None """Whether the session was created by a live application (`live`) or a sandbox application (`sandbox`). Sandbox sessions are free, fully simulated, and never bill credits.""" + sandbox_scenario: str | None = None + """The sandbox scenario the session was created with. `null` for live sessions and for sandbox sessions created without one.""" + resubmissions: list[SessionDecisionResubmissions] | None = None """Returned only with `include=resubmissions`, for user and business sessions. One entry per resubmission request, oldest first. Each entry carries the results the resubmitted steps returned before the request, so earlier submissions stay readable. Deleting the session deletes every submission.""" @@ -3741,3 +4067,15 @@ class SessionDecision(BaseModel): investigator: InvestigatorBlock | None = None """The item's latest Investigator review, or null when it never had one. Carried by the V3 session and business session decision (and so by `status.updated` webhooks).""" + + biometric_retention: BiometricRetention | None = None + """When the live biometric data of this session is deleted.""" + + fraud_check: dict[str, object] | None = None + """The result of a Fraud Check API call. `null` for every other session.""" + + full_session_video: str | None = None + """Expiring URL of the full-session recording. Returned only when your organization records full-session video.""" + + full_session_video_recorded_at: _dt.datetime | None = None + """When the full-session recording was made. Returned only when your organization records full-session video.""" diff --git a/src/didit/types/components/session_files_export.py b/src/didit/types/components/session_files_export.py new file mode 100644 index 0000000..e4c0a4a --- /dev/null +++ b/src/didit/types/components/session_files_export.py @@ -0,0 +1,43 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal + +from didit._models import BaseModel + +__all__ = ["SessionFilesExport"] + + +class SessionFilesExport(BaseModel): + """One ZIP with every file of a session, in original quality.""" + + export_id: str + """ID of the export. Pass it to `GET /v3/session/{sessionId}/files-export/{exportId}/`.""" + + session_id: str + """The session the files are from.""" + + status: Literal["PENDING", "PROCESSING", "READY", "FAILED", "EXPIRED"] | str + """`PENDING` and `PROCESSING` while the ZIP is prepared, `READY` once it can be downloaded, `FAILED` when it could not be prepared (request a new export), `EXPIRED` once the ZIP was deleted.""" + + file_count: int | None + """Files in the ZIP. Set only while `status` is `READY`.""" + + size_bytes: int | None + """Size of the ZIP in bytes. Set only while `status` is `READY`.""" + + download_url: str | None + """Signed URL of the ZIP, valid for a short time. Set only while `status` is `READY`; read the export again for a new one.""" + + expires_at: _dt.datetime | None + """When the ZIP is deleted, 24 hours after it was ready. Set only while `status` is `READY`.""" + + error: str | None + """Why the export failed, when `status` is `FAILED`.""" + + created_at: _dt.datetime + """When the export was requested.""" + + completed_at: _dt.datetime | None + """When the ZIP was ready or the export failed.""" diff --git a/src/didit/types/components/signature_result.py b/src/didit/types/components/signature_result.py index eb27dbc..542e096 100644 --- a/src/didit/types/components/signature_result.py +++ b/src/didit/types/components/signature_result.py @@ -41,7 +41,7 @@ class SignatureResultAdoptedSignature(BaseModel): class SignatureResultCertificate(BaseModel): - """The certificate the documents were signed with. `null` until signed.""" + """The certificate the documents were signed with. `null` until signed, and always `null` for a Simple signature.""" issuer: str | None = None @@ -57,6 +57,7 @@ class SignatureResultCertificate(BaseModel): class SignatureResultConfirmation(BaseModel): channel: Literal["email", "sms"] | str | None = None + """`null` for a Simple signature, which has no code.""" destination: str | None = None """The masked contact the code went to.""" @@ -139,6 +140,8 @@ class SignatureResultDocuments(BaseModel): class SignatureResultIdentityUsed(BaseModel): + """The verified identity the signature relies on. Empty for a Simple signature with no verified identity.""" + session_id: str | None = None kyc_id: str | None = None @@ -151,7 +154,7 @@ class SignatureResultIdentityUsed(BaseModel): class SignatureResultSigner(BaseModel): name: str | None = None - """Verified name.""" + """The signer's name. Verified (from the approved ID verification or the session) except at the Simple level without a verified session name, where it is the name the signer typed and is not verified.""" capacity: Literal["self", "company"] | str | None = None @@ -168,7 +171,7 @@ class SignatureResultSigner(BaseModel): class SignatureResultTimestamp(BaseModel): - """The trusted timestamp in the signature. `null` until signed.""" + """The RFC 3161 timestamp in the signature, issued by Didit. `null` until signed, and always `null` for a Simple signature.""" time: _dt.datetime | None = None @@ -179,7 +182,7 @@ class SignatureResultTimestamp(BaseModel): class SignatureResultValidationDocumentsCertificate(BaseModel): - """The certificate the documents were signed with. `null` until signed.""" + """The certificate the documents were signed with. `null` until signed, and always `null` for a Simple signature.""" issuer: str | None = None @@ -194,7 +197,7 @@ class SignatureResultValidationDocumentsCertificate(BaseModel): class SignatureResultValidationDocumentsTimestamp(BaseModel): - """The trusted timestamp in the signature. `null` until signed.""" + """The RFC 3161 timestamp in the signature, issued by Didit. `null` until signed, and always `null` for a Simple signature.""" time: _dt.datetime | None = None @@ -232,10 +235,10 @@ class SignatureResultValidationDocuments(BaseModel): """EU Trusted List check. For AES: `{"status": "not_applicable", "reason": "aes_not_qualified"}`.""" certificate: SignatureResultValidationDocumentsCertificate | None = None - """The certificate the documents were signed with. `null` until signed.""" + """The certificate the documents were signed with. `null` until signed, and always `null` for a Simple signature.""" timestamp: SignatureResultValidationDocumentsTimestamp | None = None - """The trusted timestamp in the signature. `null` until signed.""" + """The RFC 3161 timestamp in the signature, issued by Didit. `null` until signed, and always `null` for a Simple signature.""" class SignatureResultValidation(BaseModel): @@ -270,7 +273,7 @@ class SignatureResultWarnings(BaseModel): class SignatureResult(BaseModel): - """One signer's result for one Electronic Signature step. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature).""" + """One signer's result for one E-signature step. See the [E-signature report](/core-technology/electronic-signature/report-electronic-signature).""" id: str | None = None """Pass it as `signature_id` to download this signer's evidence or validate their signature.""" @@ -284,25 +287,27 @@ class SignatureResult(BaseModel): verdict: Literal["Not Finished", "Approved", "In Review", "Declined"] | str | None = None """The step's outcome. A warning sets it through its rule; custom status rules apply after.""" - level: Literal["aes", "qes"] | str | None = None - """`aes`. `qes` (Qualified Electronic Signature, QES) is coming soon.""" + level: Literal["simple", "aes", "qes"] | str | None = None + """`simple` (default) or `aes`. `qes` (Qualified Electronic Signature, QES) is an add-on that is not available yet.""" - format: Literal["pades"] | str | None = None + format: Literal["pdf", "pades"] | str | None = None + """`pdf` for a Simple signature, `pades` for Advanced (AES).""" profile: str | None = None - """`PAdES-B-LT` once signed.""" + """`PAdES-B-LT` once an Advanced (AES) signature is signed, otherwise null.""" signer: SignatureResultSigner | None = None identity_used: SignatureResultIdentityUsed | None = None + """The verified identity the signature relies on. Empty for a Simple signature with no verified identity.""" certificate: SignatureResultCertificate | None = None - """The certificate the documents were signed with. `null` until signed.""" + """The certificate the documents were signed with. `null` until signed, and always `null` for a Simple signature.""" confirmation: SignatureResultConfirmation | None = None timestamp: SignatureResultTimestamp | None = None - """The trusted timestamp in the signature. `null` until signed.""" + """The RFC 3161 timestamp in the signature, issued by Didit. `null` until signed, and always `null` for a Simple signature.""" documents: list[SignatureResultDocuments] | None = None @@ -316,7 +321,7 @@ class SignatureResult(BaseModel): """Path of the evidence PDF, once signed. See [Download the signature evidence](/sessions-api/electronic-signature/download-evidence).""" warnings: list[SignatureResultWarnings] | None = None - """Warnings raised for this signer. See [Electronic Signature warnings](/core-technology/electronic-signature/warnings-electronic-signature).""" + """Warnings raised for this signer. See [E-signature warnings](/core-technology/electronic-signature/warnings-electronic-signature).""" validation: SignatureResultValidation | None = None """The last cryptographic check of the signed documents. `null` until the documents are signed. If Didit can't confirm the outcome of signing, it's `{"valid": null, "reason": "signature_provider_outcome_unknown", "checked_at": ...}` and `status` stays `signing`: treat it as not signed.""" diff --git a/src/didit/types/components/simple_workflow_feature.py b/src/didit/types/components/simple_workflow_feature.py index 13ee806..f554df7 100644 --- a/src/didit/types/components/simple_workflow_feature.py +++ b/src/didit/types/components/simple_workflow_feature.py @@ -34,7 +34,7 @@ class SimpleWorkflowFeature(TypedDict, total=False): """Feature to run. Use the uppercase values shown here.""" config: Mapping[str, object] - """Feature-specific settings. For `QUESTIONNAIRE`, include `questionnaire_uuid` with the `questionnaire_id` returned by the questionnaire create endpoint. For `OCR`, `methods` selects which ID Verification methods each country may use (document capture, non-doc lookup against a government or other authoritative source, and digital identity wallets); omit it and every country is document capture only. For `SIGNATURE`, see [Electronic Signature settings](/management-api/workflows/feature-configs#electronic-signature): `signature_level` accepts `aes` only for now, and workflow documents and their fields are managed in the console, so through the API send documents and fields per session with `signature_documents_source: "session"`.""" + """Feature-specific settings. For `QUESTIONNAIRE`, include `questionnaire_uuid` with the `questionnaire_id` returned by the questionnaire create endpoint. For `SIGNATURE`, a workflow that goes live needs a document to sign: set `signature_documents_source` to `session` or `both` so each session can bring its own, or send `status: "draft"` and add the documents before you publish. `signature_level: "aes"` is refused with `aes_not_available` while `signature_availability.aes` is `false` on the workflow. For `OCR`, `methods` selects which ID Verification methods each country may use (document capture, non-doc lookup against a government or other authoritative source, and digital identity wallets); omit it and every country is document capture only. For `SIGNATURE`, see [E-signature settings](/management-api/workflows/feature-configs#e-signature): `signature_level` accepts `simple` (the default, no ID verification, email or phone needed) and `aes` for now, and workflow documents and their fields are managed in the console, so through the API send documents and fields per session with `signature_documents_source: "session"`.""" label: str """Optional internal label for this workflow node.""" diff --git a/src/didit/types/components/transaction_detail.py b/src/didit/types/components/transaction_detail.py index 2b04ecf..0be5e37 100644 --- a/src/didit/types/components/transaction_detail.py +++ b/src/didit/types/components/transaction_detail.py @@ -445,7 +445,7 @@ class TransactionDetail(BaseModel): """Activity log entries (creation, notes, manual reviews, status changes).""" alerts: list[TransactionDetailAlerts] | None = None - """Alerts raised by rules and providers.""" + """Always empty today. An open alert is a transaction with status `IN_REVIEW` or `AWAITING_USER`.""" rule_runs: list[TransactionDetailRuleRuns] | None = None """Per-rule execution results - which rule fired, with what score impact.""" diff --git a/src/didit/types/components/transaction_rule_condition.py b/src/didit/types/components/transaction_rule_condition.py index 708489b..cccfa8a 100644 --- a/src/didit/types/components/transaction_rule_condition.py +++ b/src/didit/types/components/transaction_rule_condition.py @@ -43,7 +43,7 @@ class TransactionRuleCondition(BaseModel): """Comparison operator. in/not_in test membership (value may be a list or a single scalar). contains/not_contains are case-insensitive substring checks against a string value. contains_any takes a list of strings and matches when any is a case-insensitive substring of the field value. regex matches the value pattern against the field. fuzzy_match compares against the value string with the required `score` threshold (0-100). gt/gte/lt/lte never match when either side is missing. exists/is_not_empty/is_not_null (aliases) and not_exists/is_empty/is_null (aliases) are presence checks that ignore `value`.""" value: object = None - """Comparison value. Its shape depends on the operator and value_type; omit for the presence-check operators.""" + """Comparison value. Its shape depends on the operator and value_type; omit it for the presence-check operators. Every other operator needs a value that is not `null` or an empty list, otherwise the rule is refused with `400`. `contains_any` needs a list of strings, and `contains`, `not_contains` and `regex` need a single string.""" value_type: Literal["list", "field", "relative_date"] | str | None = None """Optional value interpretation. `list`: value is a List UUID and the list's entries become the comparison value. `field`: value is another field path, compared field-to-field. `relative_date`: value is a relative-date object, e.g. {"direction": "past", "unit": "days", "amount": 30}.""" @@ -94,7 +94,7 @@ class TransactionRuleConditionParam(TypedDict, total=False): """Comparison operator. in/not_in test membership (value may be a list or a single scalar). contains/not_contains are case-insensitive substring checks against a string value. contains_any takes a list of strings and matches when any is a case-insensitive substring of the field value. regex matches the value pattern against the field. fuzzy_match compares against the value string with the required `score` threshold (0-100). gt/gte/lt/lte never match when either side is missing. exists/is_not_empty/is_not_null (aliases) and not_exists/is_empty/is_null (aliases) are presence checks that ignore `value`.""" value: object - """Comparison value. Its shape depends on the operator and value_type; omit for the presence-check operators.""" + """Comparison value. Its shape depends on the operator and value_type; omit it for the presence-check operators. Every other operator needs a value that is not `null` or an empty list, otherwise the rule is refused with `400`. `contains_any` needs a list of strings, and `contains`, `not_contains` and `regex` need a single string.""" value_type: Literal["list", "field", "relative_date"] | str """Optional value interpretation. `list`: value is a List UUID and the list's entries become the comparison value. `field`: value is another field path, compared field-to-field. `relative_date`: value is a relative-date object, e.g. {"direction": "past", "unit": "days", "amount": 30}.""" diff --git a/src/didit/types/components/travel_rule_manual_match_response.py b/src/didit/types/components/travel_rule_manual_match_response.py new file mode 100644 index 0000000..24cb847 --- /dev/null +++ b/src/didit/types/components/travel_rule_manual_match_response.py @@ -0,0 +1,15 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel +from didit.types.components.travel_rule_transfer_row import TravelRuleTransferRow + +__all__ = ["TravelRuleManualMatchResponse"] + + +class TravelRuleManualMatchResponse(BaseModel): + deposit: TravelRuleTransferRow + """One Travel Rule transfer as the transfers list shows it: VASP names, wallets and memos only, never the originator or beneficiary person data.""" + + message: TravelRuleTransferRow + """One Travel Rule transfer as the transfers list shows it: VASP names, wallets and memos only, never the originator or beneficiary person data.""" diff --git a/src/didit/types/components/user_session_list_item.py b/src/didit/types/components/user_session_list_item.py index 3b2bb26..b1971d8 100644 --- a/src/didit/types/components/user_session_list_item.py +++ b/src/didit/types/components/user_session_list_item.py @@ -17,9 +17,11 @@ "UserSessionListItemAdditionalDetailsLiveness", "UserSessionListItemAdditionalDetailsPhoneVerification", "UserSessionListItemAdditionalDetailsPoa", + "UserSessionListItemAssignee", "UserSessionListItemEmailAddress", "UserSessionListItemFeatures", "UserSessionListItemPhoneNumber", + "UserSessionListItemTopWarnings", ] @@ -143,6 +145,14 @@ class UserSessionListItemAdditionalDetails(BaseModel): """Present when email verification ran.""" +class UserSessionListItemAssignee(BaseModel): + """The Console reviewer the session is assigned to, or `null` when nobody holds it.""" + + email: str | None = None + + assigned_at: _dt.datetime | None = None + + class UserSessionListItemEmailAddress(BaseModel): """Email associated with the session: the verified email when email verification ran, otherwise the contact email provided at session creation. `null` when neither exists.""" @@ -167,6 +177,7 @@ class UserSessionListItemFeatures(BaseModel): "IP_ANALYSIS", "AGE_ESTIMATION", "DATABASE_VALIDATION", + "GEOLOCATION", ] | str ) @@ -186,6 +197,19 @@ class UserSessionListItemPhoneNumber(BaseModel): """`true` only when the phone-verification feature approved this number.""" +class UserSessionListItemTopWarnings(BaseModel): + risk: str | None = None + """Warning code, for example `FACE_MATCH_LOW_SIMILARITY`.""" + + feature: str | None = None + """The feature that raised it.""" + + log_type: str | None = None + """`error` or `warning`; `null` for a legacy entry.""" + + short_description: str | None = None + + class UserSessionListItem(BaseModel): """Summary row for a User Verification (KYC) session. Identity fields (`full_name`, `country`, `document_type`, `portrait_image`, contact fields) are populated progressively as the user completes verification steps, and are `null` until the relevant step finishes. Fields restricted by the workflow's response-attributes configuration are also returned as `null`.""" @@ -261,3 +285,18 @@ class UserSessionListItem(BaseModel): additional_details: UserSessionListItemAdditionalDetails | None """Compact per-feature extras. Only features that produced data appear as keys; `null` when no feature produced extras. Fields excluded by the workflow's response-attributes configuration are omitted.""" + + assignee: UserSessionListItemAssignee | None = None + """The Console reviewer the session is assigned to, or `null` when nobody holds it.""" + + waiting_since: _dt.datetime | None = None + """When the session started waiting for review. `null` unless the session is `In Review`.""" + + sla_due_at: _dt.datetime | None = None + """When the review is due, from the review deadline set for your application in the Console. `null` unless the session is `In Review` and a deadline is set.""" + + top_warnings: list[UserSessionListItemTopWarnings] | None = None + """Up to a few of the session's most important warnings, for a quick triage view. The full list is in the decision.""" + + warnings_count: int | None = None + """Number of warnings on the session.""" diff --git a/src/didit/types/components/webhook_config.py b/src/didit/types/components/webhook_config.py index 2937747..8cc7945 100644 --- a/src/didit/types/components/webhook_config.py +++ b/src/didit/types/components/webhook_config.py @@ -53,3 +53,6 @@ class WebhookConfig(BaseModel): endpoints: list[WebhookConfigDestination] """Every webhook destination of the application, oldest first, each with its signing secret. Read only here: manage destinations with the `/v3/webhook/destinations/` endpoints.""" + + allowed_domains: list[str] | None = None + """Origins (for example `https://app.example.com`; `http` only for `localhost`) the hosted verification flow may be embedded in and may send the user back to with a session callback. Server-to-server calls are not affected. An empty list means no restriction. Didit stores each origin in lower case without a default port. An invalid entry fails with `400` on `allowed_domains`.""" diff --git a/src/didit/types/components/webhook_event.py b/src/didit/types/components/webhook_event.py index b4438bf..63a6324 100644 --- a/src/didit/types/components/webhook_event.py +++ b/src/didit/types/components/webhook_event.py @@ -21,6 +21,7 @@ "transaction.status.updated", "travel_rule.status.updated", "workflow.compliance_changed", + "transaction_rule_suggestions.created", "auth.signup", "auth.login", "auth.login_failed", diff --git a/src/didit/types/components/workflow_detail.py b/src/didit/types/components/workflow_detail.py index a7d517e..3e77769 100644 --- a/src/didit/types/components/workflow_detail.py +++ b/src/didit/types/components/workflow_detail.py @@ -6,7 +6,20 @@ from didit._models import BaseModel -__all__ = ["WorkflowDetail"] +__all__ = ["WorkflowDetail", "WorkflowDetailSignatureAvailability"] + + +class WorkflowDetailSignatureAvailability(BaseModel): + """Which E-signature levels can sign right now. Check it before you set `signature_level`. Returned on `kyc`, `kyb` and graph workflows.""" + + simple: bool | None = None + """Simple is always available.""" + + aes: bool | None = None + """Whether Advanced (AES) can sign now. While it is `false`, saving a new step at `signature_level: "aes"` is refused with `aes_not_available`.""" + + qes: bool | None = None + """Whether Qualified (QES) can sign now. It is `false` until a qualified provider is connected.""" class WorkflowDetail(BaseModel): @@ -98,6 +111,9 @@ class WorkflowDetail(BaseModel): updated_at: _dt.datetime | None = None + signature_availability: WorkflowDetailSignatureAvailability | None = None + """Which E-signature levels can sign right now. Check it before you set `signature_level`. Returned on `kyc`, `kyb` and graph workflows.""" + is_bank_verification_enabled: bool | None = None """Whether a simple KYC or KYB workflow runs Bank verification. It runs after the contact steps (and Location verification) and before database validation, AML and IP analysis. Bank verification is not generally available yet: turning it on is refused wherever it is not enabled.""" diff --git a/src/didit/types/database_validation/validate_params.py b/src/didit/types/database_validation/validate_params.py index 096b931..4a3e52a 100644 --- a/src/didit/types/database_validation/validate_params.py +++ b/src/didit/types/database_validation/validate_params.py @@ -193,6 +193,54 @@ class DatabaseValidationValidateParams(TypedDict, total=False): bank_card_number: str """Bank card number (CHN bank-card verification).""" + company_registration_number: str + """Company registration number as issued by the companies register: the CNPJ in Brazil (e.g. `11222333000181`), the registration number in South Africa (e.g. `1936/007721/06`). Required by the company registry and company directors services (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`).""" + + company_name: str + """Registered company name, cross-checked against the register entry. Optional for `zaf_company_registry`.""" + + initials: str + """The person's initials as printed on the document. Required by `zaf_drivers_license`; accepted by `zaf_bank_account_holder`.""" + + licence_number: str + """Driving licence number as printed on the card, for `zaf_drivers_license`. When omitted, `document_number` is used.""" + + refugee_file_number: str + """Refugee file number issued by South Africa's Department of Home Affairs. Required by `zaf_refugee`.""" + + bank_name: str + """Name of the bank that holds the account. Required by `zaf_bank_account_holder`.""" + + bank_account_number: str + """Bank account number. Required by `zaf_bank_account_holder`; accepted by `zaf_fraud_prevention`.""" + + account_type: str + """Bank account type for `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare` or `notKnown`, case-insensitive. Any other value returns `400`. Omit it when you do not know the type: the account-type cross-check is then reported as not confirmed.""" + + phone_number: str + """Contact mobile number, for the services that cross-check contactability (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`).""" + + right_thumb: str + """Base64-encoded right thumb fingerprint for `zaf_dha_fingerprint_match`, with `left_thumb` or on its own.""" + + left_thumb: str + """Base64-encoded left thumb fingerprint for `zaf_dha_fingerprint_match`, with `right_thumb` or on its own.""" + + score_level: int + """Minimum biometric score level for `zaf_criminal_face_screening`. Defaults to `3`.""" + + max_matches: int + """Maximum number of candidate matches `zaf_criminal_face_screening` returns. Defaults to `1`.""" + + vehicle_register_number: str + """Vehicle register number. Required, with `vehicle_licence_plate` and `vin`, by `zaf_vehicle_ownership`.""" + + vehicle_licence_plate: str + """Vehicle licence plate number. Required, with `vehicle_register_number` and `vin`, by `zaf_vehicle_ownership`.""" + + vin: str + """Vehicle Identification Number (VIN or chassis number). Required, with `vehicle_register_number` and `vehicle_licence_plate`, by `zaf_vehicle_ownership`.""" + ssn: str """Social Security Number (USA).""" diff --git a/src/didit/types/email/check_code_params.py b/src/didit/types/email/check_code_params.py index 117b0a7..51b83b2 100644 --- a/src/didit/types/email/check_code_params.py +++ b/src/didit/types/email/check_code_params.py @@ -24,6 +24,18 @@ class EmailCheckCodeParams(TypedDict, total=False): disposable_email_action: Literal["NO_ACTION", "DECLINE"] | str """What to do when the domain belongs to a disposable/temporary-mail provider (`email.is_disposable`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `email.warnings`.""" + enable_enrichment: bool + """When `true`, also run email intelligence on the address: a risk score and its breach history. Billed as one `email_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it.""" + + email_intelligence_score_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the email intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + + recent_email_breach_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the address appears in a recent known data breach. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + + frequent_email_breach_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the address appears in many known data breaches. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + enable_social: bool """When true, also look up the social footprint of the address - the email, social, professional, e-commerce and entertainment platforms it is registered on. Billed as one `email_social` unit per request in addition to this endpoint's own price.""" diff --git a/src/didit/types/id_verification/verify_response.py b/src/didit/types/id_verification/verify_response.py index 128cf51..44da1d8 100644 --- a/src/didit/types/id_verification/verify_response.py +++ b/src/didit/types/id_verification/verify_response.py @@ -189,7 +189,7 @@ class IdVerificationVerifyResponseIdVerificationParsedAddress(BaseModel): class IdVerificationVerifyResponseIdVerificationWarnings(BaseModel): risk: str | None = None - """Machine-readable risk code. Always-decline risks: `DOCUMENT_EXPIRED`, `MINIMUM_AGE_NOT_MET`, `PORTRAIT_IMAGE_NOT_DETECTED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT` (400-only, never a warning), `DOCUMENT_NUMBER_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`. Governed by request options: `MRZ_NOT_DETECTED` / `MRZ_VALIDATION_FAILED` (`invalid_mrz_action`), `DATA_INCONSISTENT` / `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` / `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS` (`inconsistent_data_action`), `EXPIRATION_DATE_NOT_DETECTED` (`expiration_date_not_detected_action`). Other risks (e.g. `POSSIBLE_DUPLICATED_USER`) are informational. `DOCUMENT_LIVENESS_NOT_COMPUTED` is raised when `perform_document_liveness=true` but the forgery check returned no usable score; it sets `status` to `In Review`.""" + """Machine-readable risk code. Always-decline risks: `DOCUMENT_EXPIRED`, `MINIMUM_AGE_NOT_MET`, `PORTRAIT_IMAGE_NOT_DETECTED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT` (400-only, never a warning), `DOCUMENT_NUMBER_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`. Governed by request options: `MRZ_NOT_DETECTED` / `MRZ_VALIDATION_FAILED` (`invalid_mrz_action`), `DATA_INCONSISTENT` / `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` / `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS` (`inconsistent_data_action`), `EXPIRATION_DATE_NOT_DETECTED` (`expiration_date_not_detected_action`). Other risks (e.g. `POSSIBLE_DUPLICATED_USER`) are informational. `DOCUMENT_LIVENESS_NOT_COMPUTED` is raised when `perform_document_liveness=true` but the forgery check returned no usable score; it sets `status` to `In Review`. `COULD_NOT_DETECT_DOCUMENT_TYPE` is also returned when the front of the document does not match a known official document design with high confidence, for example an edited or computer-generated document, or a design that is not supported yet.""" feature: Literal["ID_VERIFICATION"] | str | None = None """Feature that raised the warning. Always `ID_VERIFICATION` on this endpoint.""" diff --git a/src/didit/types/id_wallets/start_google_wallet_params.py b/src/didit/types/id_wallets/start_google_wallet_params.py new file mode 100644 index 0000000..82fbe56 --- /dev/null +++ b/src/didit/types/id_wallets/start_google_wallet_params.py @@ -0,0 +1,38 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Mapping + +from typing_extensions import Required, TypedDict + +from didit.types.components.digital_id_wallet_api_google_wallet_wallet_verification_start_country_enum import ( + DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum, +) + +__all__ = ["IdWalletsStartGoogleWalletParams"] + + +class IdWalletsStartGoogleWalletParams(TypedDict, total=False): + """Start a Google Wallet verification (USA, GBR, BRA, SGP, TWN).""" + + vendor_data: str | None + """Your own reference for this verification (e.g. your user id). Returned in results and webhooks.""" + + metadata: Mapping[str, object] | None + """Optional JSON object stored with the verification and returned in results and webhooks.""" + + sandbox_scenario: str + """Sandbox applications only: the simulated outcome - 'wallet_cancelled', 'wallet_timeout' or 'wallet_provider_error'; any other scenario (or none) verifies. Rejected on live applications. The full catalog is available at GET /v1/sandbox/scenarios/.""" + + country: Required[DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum] + """ISO 3166-1 alpha-3 country of the Google Wallet identity. + + * `USA` - USA + * `GBR` - GBR + * `BRA` - BRA + * `SGP` - SGP + * `TWN` - TWN + """ + + origin: Required[str] + """Where your page or app will ask the wallet: the https origin of your page (its host must be in the application's allowed_return_hosts, or be its white-label domain), e.g. https://app.example.com, or android:apk-key-hash:. The wallet refuses the request anywhere else.""" diff --git a/src/didit/types/id_wallets/submit_verification_response_params.py b/src/didit/types/id_wallets/submit_verification_response_params.py new file mode 100644 index 0000000..491cad0 --- /dev/null +++ b/src/didit/types/id_wallets/submit_verification_response_params.py @@ -0,0 +1,15 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Mapping + +from typing_extensions import Required, TypedDict + +__all__ = ["IdWalletsSubmitVerificationResponseParams"] + + +class IdWalletsSubmitVerificationResponseParams(TypedDict, total=False): + """What the wallet answered your page or app, for a ``request_digital_credential`` verification.""" + + response: Required[Mapping[str, object]] + """Exactly what the wallet returned: {protocol, data} of the DigitalCredential from navigator.credentials.get, or the parsed credentialJson of Android's DigitalCredential. Encrypted to Didit; do not alter it.""" diff --git a/src/didit/types/kyb/list_shareholders_params.py b/src/didit/types/kyb/list_shareholders_params.py index 3b419bf..7aacb4e 100644 --- a/src/didit/types/kyb/list_shareholders_params.py +++ b/src/didit/types/kyb/list_shareholders_params.py @@ -10,7 +10,7 @@ class KybListShareholdersParams(TypedDict, total=False): kyb_response_id: Required[str] - """Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it.""" + """Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length.""" vendor_data: str """Your identifier for this company; echoed back and stored with the business session.""" diff --git a/src/didit/types/kyb/list_shareholders_response.py b/src/didit/types/kyb/list_shareholders_response.py index b1a57c8..c42199e 100644 --- a/src/didit/types/kyb/list_shareholders_response.py +++ b/src/didit/types/kyb/list_shareholders_response.py @@ -6,6 +6,7 @@ from didit._models import BaseModel from didit.types.components.kyb_registry_address import KYBRegistryAddress +from didit.types.components.kyb_registry_data import KYBRegistryData from didit.types.components.kyb_registry_industry import KYBRegistryIndustry from didit.types.components.kyb_registry_ownership import KYBRegistryOwnership from didit.types.components.kyb_registry_shareholding import KYBRegistryShareholding @@ -16,9 +17,11 @@ "KybListShareholdersResponse202KybRegistry", "KybListShareholdersResponse202KybRegistryBeneficialOwners", "KybListShareholdersResponse202KybRegistryOfficers", + "KybListShareholdersResponse202KybRegistryRegistryMonitoring", "KybListShareholdersResponseKybRegistry", "KybListShareholdersResponseKybRegistryBeneficialOwners", "KybListShareholdersResponseKybRegistryOfficers", + "KybListShareholdersResponseKybRegistryRegistryMonitoring", ] @@ -147,6 +150,31 @@ class KybListShareholdersResponseKybRegistryOfficers(BaseModel): """Registry-reported birth month. Null when only the year is known.""" +class KybListShareholdersResponseKybRegistryRegistryMonitoring(BaseModel): + """The latest registry monitor for the company, or `null` when none exists.""" + + uuid: str | None = None + + status: str | None = None + + unavailable_reason: str | None = None + + enrolled_at: _dt.datetime | None = None + + cancelled_at: _dt.datetime | None = None + + last_bill_date: _dt.date | None = None + + next_bill_date: _dt.date | None = None + + last_event_at: _dt.datetime | None = None + + events_count: int | None = None + + watched_fields: object = None + """The company fields the monitor watches.""" + + class KybListShareholdersResponseKybRegistry(BaseModel): """Full registry company profile.""" @@ -301,8 +329,8 @@ class KybListShareholdersResponseKybRegistry(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """Always `null` on this endpoint (used by the hosted KYB flow when end users edit registry data).""" @@ -330,6 +358,9 @@ class KybListShareholdersResponseKybRegistry(BaseModel): registry_tier: str | None = None """The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`.""" + registry_monitoring: KybListShareholdersResponseKybRegistryRegistryMonitoring | None = None + """The latest registry monitor for the company, or `null` when none exists.""" + class KybListShareholdersResponse(BaseModel): request_id: str | None = None @@ -478,6 +509,31 @@ class KybListShareholdersResponse202KybRegistryOfficers(BaseModel): """Registry-reported birth month. Null when only the year is known.""" +class KybListShareholdersResponse202KybRegistryRegistryMonitoring(BaseModel): + """The latest registry monitor for the company, or `null` when none exists.""" + + uuid: str | None = None + + status: str | None = None + + unavailable_reason: str | None = None + + enrolled_at: _dt.datetime | None = None + + cancelled_at: _dt.datetime | None = None + + last_bill_date: _dt.date | None = None + + next_bill_date: _dt.date | None = None + + last_event_at: _dt.datetime | None = None + + events_count: int | None = None + + watched_fields: object = None + """The company fields the monitor watches.""" + + class KybListShareholdersResponse202KybRegistry(BaseModel): """Full registry company profile.""" @@ -632,8 +688,8 @@ class KybListShareholdersResponse202KybRegistry(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """Always `null` on this endpoint (used by the hosted KYB flow when end users edit registry data).""" @@ -661,6 +717,9 @@ class KybListShareholdersResponse202KybRegistry(BaseModel): registry_tier: str | None = None """The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`.""" + registry_monitoring: KybListShareholdersResponse202KybRegistryRegistryMonitoring | None = None + """The latest registry monitor for the company, or `null` when none exists.""" + class KybListShareholdersResponse202(BaseModel): request_id: str | None = None diff --git a/src/didit/types/kyb/list_ubos_params.py b/src/didit/types/kyb/list_ubos_params.py index 0d2f885..20cbad5 100644 --- a/src/didit/types/kyb/list_ubos_params.py +++ b/src/didit/types/kyb/list_ubos_params.py @@ -10,7 +10,7 @@ class KybListUbosParams(TypedDict, total=False): kyb_response_id: Required[str] - """Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it.""" + """Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length.""" vendor_data: str """Your identifier for this company; echoed back and stored with the business session.""" diff --git a/src/didit/types/kyb/list_ubos_response.py b/src/didit/types/kyb/list_ubos_response.py index 71a9126..418808c 100644 --- a/src/didit/types/kyb/list_ubos_response.py +++ b/src/didit/types/kyb/list_ubos_response.py @@ -6,6 +6,7 @@ from didit._models import BaseModel from didit.types.components.kyb_registry_address import KYBRegistryAddress +from didit.types.components.kyb_registry_data import KYBRegistryData from didit.types.components.kyb_registry_industry import KYBRegistryIndustry from didit.types.components.kyb_registry_ownership import KYBRegistryOwnership from didit.types.components.kyb_registry_shareholding import KYBRegistryShareholding @@ -16,9 +17,11 @@ "KybListUbosResponse202KybRegistry", "KybListUbosResponse202KybRegistryBeneficialOwners", "KybListUbosResponse202KybRegistryOfficers", + "KybListUbosResponse202KybRegistryRegistryMonitoring", "KybListUbosResponseKybRegistry", "KybListUbosResponseKybRegistryBeneficialOwners", "KybListUbosResponseKybRegistryOfficers", + "KybListUbosResponseKybRegistryRegistryMonitoring", ] @@ -147,6 +150,31 @@ class KybListUbosResponseKybRegistryOfficers(BaseModel): """Registry-reported birth month. Null when only the year is known.""" +class KybListUbosResponseKybRegistryRegistryMonitoring(BaseModel): + """The latest registry monitor for the company, or `null` when none exists.""" + + uuid: str | None = None + + status: str | None = None + + unavailable_reason: str | None = None + + enrolled_at: _dt.datetime | None = None + + cancelled_at: _dt.datetime | None = None + + last_bill_date: _dt.date | None = None + + next_bill_date: _dt.date | None = None + + last_event_at: _dt.datetime | None = None + + events_count: int | None = None + + watched_fields: object = None + """The company fields the monitor watches.""" + + class KybListUbosResponseKybRegistry(BaseModel): """Full registry company profile.""" @@ -301,8 +329,8 @@ class KybListUbosResponseKybRegistry(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """Always `null` on this endpoint (used by the hosted KYB flow when end users edit registry data).""" @@ -330,6 +358,9 @@ class KybListUbosResponseKybRegistry(BaseModel): registry_tier: str | None = None """The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`.""" + registry_monitoring: KybListUbosResponseKybRegistryRegistryMonitoring | None = None + """The latest registry monitor for the company, or `null` when none exists.""" + class KybListUbosResponse(BaseModel): request_id: str | None = None @@ -478,6 +509,31 @@ class KybListUbosResponse202KybRegistryOfficers(BaseModel): """Registry-reported birth month. Null when only the year is known.""" +class KybListUbosResponse202KybRegistryRegistryMonitoring(BaseModel): + """The latest registry monitor for the company, or `null` when none exists.""" + + uuid: str | None = None + + status: str | None = None + + unavailable_reason: str | None = None + + enrolled_at: _dt.datetime | None = None + + cancelled_at: _dt.datetime | None = None + + last_bill_date: _dt.date | None = None + + next_bill_date: _dt.date | None = None + + last_event_at: _dt.datetime | None = None + + events_count: int | None = None + + watched_fields: object = None + """The company fields the monitor watches.""" + + class KybListUbosResponse202KybRegistry(BaseModel): """Full registry company profile.""" @@ -632,8 +688,8 @@ class KybListUbosResponse202KybRegistry(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """Always `null` on this endpoint (used by the hosted KYB flow when end users edit registry data).""" @@ -661,6 +717,9 @@ class KybListUbosResponse202KybRegistry(BaseModel): registry_tier: str | None = None """The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`.""" + registry_monitoring: KybListUbosResponse202KybRegistryRegistryMonitoring | None = None + """The latest registry monitor for the company, or `null` when none exists.""" + class KybListUbosResponse202(BaseModel): request_id: str | None = None diff --git a/src/didit/types/kyb/select_params.py b/src/didit/types/kyb/select_params.py index 0985dc3..8bd6662 100644 --- a/src/didit/types/kyb/select_params.py +++ b/src/didit/types/kyb/select_params.py @@ -10,7 +10,7 @@ class KybSelectParams(TypedDict, total=False): kyb_response_id: Required[str] - """Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral - use it shortly after the search that produced it.""" + """Candidate handle from `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Ephemeral: use it shortly after the search that produced it. Handles can be long, so store and send the value exactly as returned, without trimming or assuming a length.""" vendor_data: str """Your identifier for this company; echoed back and stored with the business session.""" diff --git a/src/didit/types/kyb/select_response.py b/src/didit/types/kyb/select_response.py index 7ab497b..b16a079 100644 --- a/src/didit/types/kyb/select_response.py +++ b/src/didit/types/kyb/select_response.py @@ -6,6 +6,7 @@ from didit._models import BaseModel from didit.types.components.kyb_registry_address import KYBRegistryAddress +from didit.types.components.kyb_registry_data import KYBRegistryData from didit.types.components.kyb_registry_industry import KYBRegistryIndustry from didit.types.components.kyb_registry_ownership import KYBRegistryOwnership from didit.types.components.kyb_registry_shareholding import KYBRegistryShareholding @@ -15,6 +16,7 @@ "KybSelectResponseKybRegistry", "KybSelectResponseKybRegistryBeneficialOwners", "KybSelectResponseKybRegistryOfficers", + "KybSelectResponseKybRegistryRegistryMonitoring", ] @@ -143,6 +145,31 @@ class KybSelectResponseKybRegistryOfficers(BaseModel): """Registry-reported birth month. Null when only the year is known.""" +class KybSelectResponseKybRegistryRegistryMonitoring(BaseModel): + """The latest registry monitor for the company, or `null` when none exists.""" + + uuid: str | None = None + + status: str | None = None + + unavailable_reason: str | None = None + + enrolled_at: _dt.datetime | None = None + + cancelled_at: _dt.datetime | None = None + + last_bill_date: _dt.date | None = None + + next_bill_date: _dt.date | None = None + + last_event_at: _dt.datetime | None = None + + events_count: int | None = None + + watched_fields: object = None + """The company fields the monitor watches.""" + + class KybSelectResponseKybRegistry(BaseModel): """Full registry company profile.""" @@ -297,8 +324,8 @@ class KybSelectResponseKybRegistry(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw record returned by the registry source, kept for reviewers. Its shape differs by country and source and is not a stable contract: read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) instead.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """Always `null` on this endpoint (used by the hosted KYB flow when end users edit registry data).""" @@ -326,6 +353,9 @@ class KybSelectResponseKybRegistry(BaseModel): registry_tier: str | None = None """The registry tier the workflow ordered: `basic`, `shareholders` or `ubo`. Also in `ownership.tier_requested`.""" + registry_monitoring: KybSelectResponseKybRegistryRegistryMonitoring | None = None + """The latest registry monitor for the company, or `null` when none exists.""" + class KybSelectResponse(BaseModel): request_id: str | None = None diff --git a/src/didit/types/phone/check_code_params.py b/src/didit/types/phone/check_code_params.py index 48a48ed..21a0221 100644 --- a/src/didit/types/phone/check_code_params.py +++ b/src/didit/types/phone/check_code_params.py @@ -24,6 +24,21 @@ class PhoneCheckCodeParams(TypedDict, total=False): voip_number_action: Literal["NO_ACTION", "DECLINE"] | str """What to do when the carrier lookup reports a virtual line type - `voip`, `isp`, or `vpn` (`phone.is_virtual`). `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the risk in `phone.warnings`.""" + enable_enrichment: bool + """When `true`, also run phone intelligence on the number: a risk score, the line type, whether it was recently ported and a trust index. Billed as one `phone_intelligence_api` unit per request ($0.05 at list price) in addition to this endpoint's own price. The request returns `403` when your balance cannot cover it.""" + + phone_intelligence_score_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the phone intelligence risk score is above the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + + phone_type_risk_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the number is a high-risk line type. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + + recent_port_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the number was ported to another carrier recently. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + + low_phone_trust_action: Literal["NO_ACTION", "DECLINE"] | str + """Action when the phone intelligence trust index is at or below the threshold. `DECLINE` flips the final `status` to `Declined`; `NO_ACTION` records the signal without declining. Only takes effect when `enable_enrichment` is `true`.""" + enable_social: bool """When true, also look up the social footprint of the number - the messaging, social, e-commerce and professional platforms it is registered on. Billed as one `phone_social` unit per request in addition to this endpoint's own price.""" diff --git a/src/didit/types/sessions/bulk_update_aml_hit_status_params.py b/src/didit/types/sessions/bulk_update_aml_hit_status_params.py index 84eb276..646762f 100644 --- a/src/didit/types/sessions/bulk_update_aml_hit_status_params.py +++ b/src/didit/types/sessions/bulk_update_aml_hit_status_params.py @@ -10,6 +10,7 @@ class SessionsBulkUpdateAmlHitStatusParamsHitUpdates(TypedDict, total=False): hit_id: Required[str] + """The `id` of the hit in the AML check's `hits` array (`hit_...`). A hit id returned in the earlier format is still accepted.""" review_status: Required[ Literal["Unreviewed", "Confirmed Match", "False Positive", "Inconclusive"] | str diff --git a/src/didit/types/sessions/bulk_update_aml_hit_status_response.py b/src/didit/types/sessions/bulk_update_aml_hit_status_response.py index 6ffd6e5..a7ea290 100644 --- a/src/didit/types/sessions/bulk_update_aml_hit_status_response.py +++ b/src/didit/types/sessions/bulk_update_aml_hit_status_response.py @@ -11,4 +11,4 @@ class SessionsBulkUpdateAmlHitStatusResponse(BaseModel): """`Updated {n} hit(s) successfully`, where `n` is the number of entries in `hit_updates`.""" updated_hits: list[str] - """The `hit_id` of every entry in `hit_updates`, in request order, including hits whose status did not change.""" + """The `id` of the hit each entry in `hit_updates` names, as the session decision returns it, in request order, including hits whose status did not change.""" diff --git a/src/didit/types/sessions/create_kyb_party_draft_params.py b/src/didit/types/sessions/create_kyb_party_draft_params.py new file mode 100644 index 0000000..55f700e --- /dev/null +++ b/src/didit/types/sessions/create_kyb_party_draft_params.py @@ -0,0 +1,97 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal, Mapping, Sequence + +from typing_extensions import Required, TypedDict + +__all__ = ["SessionsCreateKybPartyDraftParams"] + + +class SessionsCreateKybPartyDraftParams(TypedDict, total=False): + entity_type: Required[Literal["person", "company"] | str] + """Whether the party is an individual or a company.""" + + full_name: str + """Full name of a person. Send it, or `first_name` and `last_name`.""" + + first_name: str + + last_name: str + + role: ( + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ) + """Role the party holds. Interchangeable with `roles`; when both are sent they are merged.""" + + roles: Sequence[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + """Every role the party holds. A person needs at least one role (here or in `role`).""" + + position: str + """Job title of a person.""" + + date_of_birth: str | _dt.date | None + + company_name: str + """Name of a company party. Required when `entity_type` is `company`.""" + + registration_number: str + """Registration number of a company party.""" + + email: str + """Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow.""" + + ownership_percent: float | None + """Share of the company the party owns.""" + + nationality: Required[str] + """Nationality of a person, or country of incorporation of a company. Required for every party.""" + + phone_number: str + + custom_fields: Mapping[str, object] + """Workflow-defined extra fields.""" + + skip_verification: bool + """Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings.""" diff --git a/src/didit/types/sessions/create_kyb_party_draft_response.py b/src/didit/types/sessions/create_kyb_party_draft_response.py new file mode 100644 index 0000000..5fa10ee --- /dev/null +++ b/src/didit/types/sessions/create_kyb_party_draft_response.py @@ -0,0 +1,111 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal + +from didit._models import BaseModel + +__all__ = ["SessionsCreateKybPartyDraftResponse", "SessionsCreateKybPartyDraftResponseParty"] + + +class SessionsCreateKybPartyDraftResponseParty(BaseModel): + entity_type: Literal["person", "company"] | str + """Whether the party is an individual or a company.""" + + full_name: str | None = None + """Full name of a person. Send it, or `first_name` and `last_name`.""" + + first_name: str | None = None + + last_name: str | None = None + + role: ( + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + | None + ) = None + """Role the party holds. Interchangeable with `roles`; when both are sent they are merged.""" + + roles: ( + list[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | None + ) = None + """Every role the party holds. A person needs at least one role (here or in `role`).""" + + position: str | None = None + """Job title of a person.""" + + date_of_birth: _dt.date | None = None + + company_name: str | None = None + """Name of a company party. Required when `entity_type` is `company`.""" + + registration_number: str | None = None + """Registration number of a company party.""" + + email: str | None = None + """Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow.""" + + ownership_percent: float | None = None + """Share of the company the party owns.""" + + nationality: str + """Nationality of a person, or country of incorporation of a company. Required for every party.""" + + phone_number: str | None = None + + custom_fields: dict[str, object] | None = None + """Workflow-defined extra fields.""" + + skip_verification: bool | None = None + """Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings.""" + + +class SessionsCreateKybPartyDraftResponse(BaseModel): + draft_id: str + + created_at: _dt.datetime + + updated_at: _dt.datetime + + party: SessionsCreateKybPartyDraftResponseParty diff --git a/src/didit/types/sessions/create_params.py b/src/didit/types/sessions/create_params.py index 31c7350..92ac47d 100644 --- a/src/didit/types/sessions/create_params.py +++ b/src/didit/types/sessions/create_params.py @@ -151,7 +151,7 @@ class SessionsCreateParamsExpectedDetails(TypedDict, total=False): class SessionsCreateParamsSign(TypedDict, total=False): - """Electronic Signature input for this session. `documents` are the documents to sign, for a workflow whose Electronic Signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [Electronic signature documents](/sessions-api/create-session#electronic-signature-documents).""" + """E-signature input for this session. `documents` are the documents to sign, for a workflow whose E-signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [E-signature documents](/sessions-api/create-session#e-signature-documents).""" documents: Sequence[SessionSignDocument] @@ -166,6 +166,9 @@ class SessionsCreateParams(TypedDict, total=False): vendor_data: str """A unique identifier for the user being verified, such as a UUID, email, or internal user ID. This field is used for: (1) **User grouping** - sessions with the same vendor_data are linked to the same user profile in the Users tab. (2) **Cross-session duplicate detection** - when checking for duplicated faces, documents, phone numbers, emails, IP addresses, or device fingerprints, sessions with the same vendor_data are treated as the same user and excluded from matches. Without vendor_data, every session is treated as a unique user and all potential duplicates are surfaced. We strongly recommend always providing a vendor_data to reduce noise in duplicate detection.""" + multi_account_segment: str + """Optional duplicate-detection realm inside your organization. Duplicate face checks compare this session only with other sessions that carry the same segment, so separate account bases (personal and business accounts, or one per B2B sub-client) do not flag a person who legitimately holds one account in each. Omit it to use the single default realm, which is what every session uses today. Blocklist and allowlist matching ignore this field.""" + callback: str """URL to redirect the user to after verification completes. Didit automatically appends `verificationSessionId` and `status` (Approved, Declined, In Review) as query parameters. Custom URL schemes (e.g. `myapp://`) are supported for mobile callbacks. If omitted, the workflow's default `callback_url` is used. When the application has allowed domains (`allowed_domains` on `PATCH /v3/webhook/`), an `http` or `https` callback must be on one of those origins (same scheme, host and port), otherwise the request fails with 400 on `callback`: `callback must be on one of the application's allowed domains: https://app.example.com`. Custom URL schemes are always accepted.""" @@ -252,7 +255,7 @@ class SessionsCreateParams(TypedDict, total=False): """Sandbox-only scenario slug. Only accepted when the API key belongs to a sandbox-mode application; rejected on live applications. When set, the create flow expands the scenario's bundled magic values onto the session's input fields (contact_details, expected_details) so the mocked providers reproduce the scenario's outcome through the real workflow pipeline. See the scenario catalog at GET /v1/sandbox/scenarios/ or [Sandbox & Test Data](/integration/sandbox-testing). You can also arm (or re-arm) a scenario after create via POST /v3/session/{sessionId}/sandbox/arm/, as long as the session is still `Not Started`. For non-doc lookup, use `lookup_partial_match`, `lookup_no_match`, or `lookup_provider_error` to test the configured attempt budget and fallback. For identity wallets, use `wallet_cancelled`, `wallet_timeout`, or `wallet_provider_error`; `approve` simulates a verified wallet. All catalog wallets can be tested in sandbox, including schemes unavailable on live applications. Simulated attempts are not charged.""" sign: SessionsCreateParamsSign - """Electronic Signature input for this session. `documents` are the documents to sign, for a workflow whose Electronic Signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [Electronic signature documents](/sessions-api/create-session#electronic-signature-documents).""" + """E-signature input for this session. `documents` are the documents to sign, for a workflow whose E-signature step takes documents from the session (`signature_documents_source` `session` or `both`): up to 20 documents and 50 MB in total. `field_values` fills the fields whose `prefill` is `api.`, on workflow and session documents alike. Creating a session again for the same `workflow_id` and `vendor_data` returns the pending session; if that call sends `sign`, its documents, fields and values must be identical to the first ones, and anything different returns `400` with `{"sign": "signature_document_changed"}`. See [E-signature documents](/sessions-api/create-session#e-signature-documents).""" user_state: str """Where the person lives, when you know it: an ISO 3166-2 subdivision code (`US-IL`, `ES-M`) or a US state code or name (`IL`, `Illinois`). A state whose law requires explicit biometric consent (Illinois, Texas, Colorado) makes the verification flow ask for it before capturing a face, with trigger `declared_state`. An unrecognized value returns `400`. See [Biometric consent](/getting-started/biometric-consent).""" diff --git a/src/didit/types/sessions/list_kyb_extracted_parties_response.py b/src/didit/types/sessions/list_kyb_extracted_parties_response.py new file mode 100644 index 0000000..2e46d16 --- /dev/null +++ b/src/didit/types/sessions/list_kyb_extracted_parties_response.py @@ -0,0 +1,96 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Literal + +from didit._models import BaseModel + +__all__ = [ + "SessionsListKybExtractedPartiesResponse", + "SessionsListKybExtractedPartiesResponseParties", + "SessionsListKybExtractedPartiesResponsePartiesDocuments", + "SessionsListKybExtractedPartiesResponsePartiesRoles", + "SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent", +] + + +class SessionsListKybExtractedPartiesResponsePartiesDocuments(BaseModel): + document_uuid: str | None = None + + document_type: str | None = None + + document_subtype: str | None = None + + original_filename: str | None = None + + status: str | None = None + + +class SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent(BaseModel): + text: str | None = None + """The ownership figure exactly as the document states it, such as `25-50%`, `>50%` or `NO EXHIBE`.""" + + min: float | None = None + """Lower number read out of `text`; null when it states none.""" + + max: float | None = None + """Upper number read out of `text`; null when it states none.""" + + +class SessionsListKybExtractedPartiesResponsePartiesRoles(BaseModel): + role: ( + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + | None + ) = None + + ownership_percent: ( + SessionsListKybExtractedPartiesResponsePartiesRolesOwnershipPercent | None + ) = None + + +class SessionsListKybExtractedPartiesResponseParties(BaseModel): + name: str | None = None + + entity_type: Literal["person", "company"] | str | None = None + + first_name: str | None = None + + last_name: str | None = None + + appointment_date: str | None = None + + designation: str | None = None + + roles: list[SessionsListKybExtractedPartiesResponsePartiesRoles] | None = None + + documents: list[SessionsListKybExtractedPartiesResponsePartiesDocuments] | None = None + """The uploaded documents that named this party.""" + + +class SessionsListKybExtractedPartiesResponse(BaseModel): + parties: list[SessionsListKybExtractedPartiesResponseParties] + """The shareholders and directors the uploaded documents name, merged per person. Nobody is labelled a UBO here: that is decided when the parties are submitted.""" + + document_count: int + """Number of uploaded documents the list was read from.""" + + node_id: str | None = None diff --git a/src/didit/types/sessions/list_kyb_party_drafts_response.py b/src/didit/types/sessions/list_kyb_party_drafts_response.py new file mode 100644 index 0000000..6d0272c --- /dev/null +++ b/src/didit/types/sessions/list_kyb_party_drafts_response.py @@ -0,0 +1,121 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal + +from didit._models import BaseModel + +__all__ = [ + "SessionsListKybPartyDraftsResponse", + "SessionsListKybPartyDraftsResponseParties", + "SessionsListKybPartyDraftsResponsePartiesParty", +] + + +class SessionsListKybPartyDraftsResponsePartiesParty(BaseModel): + entity_type: Literal["person", "company"] | str + """Whether the party is an individual or a company.""" + + full_name: str | None = None + """Full name of a person. Send it, or `first_name` and `last_name`.""" + + first_name: str | None = None + + last_name: str | None = None + + role: ( + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + | None + ) = None + """Role the party holds. Interchangeable with `roles`; when both are sent they are merged.""" + + roles: ( + list[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | None + ) = None + """Every role the party holds. A person needs at least one role (here or in `role`).""" + + position: str | None = None + """Job title of a person.""" + + date_of_birth: _dt.date | None = None + + company_name: str | None = None + """Name of a company party. Required when `entity_type` is `company`.""" + + registration_number: str | None = None + """Registration number of a company party.""" + + email: str | None = None + """Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow.""" + + ownership_percent: float | None = None + """Share of the company the party owns.""" + + nationality: str + """Nationality of a person, or country of incorporation of a company. Required for every party.""" + + phone_number: str | None = None + + custom_fields: dict[str, object] | None = None + """Workflow-defined extra fields.""" + + skip_verification: bool | None = None + """Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings.""" + + +class SessionsListKybPartyDraftsResponseParties(BaseModel): + draft_id: str + + created_at: _dt.datetime + + updated_at: _dt.datetime + + party: SessionsListKybPartyDraftsResponsePartiesParty + + +class SessionsListKybPartyDraftsResponse(BaseModel): + parties: list[SessionsListKybPartyDraftsResponseParties] | None = None + + node_id: str | None = None diff --git a/src/didit/types/sessions/list_response.py b/src/didit/types/sessions/list_response.py index 7008405..0c4bb9d 100644 --- a/src/didit/types/sessions/list_response.py +++ b/src/didit/types/sessions/list_response.py @@ -10,7 +10,7 @@ class SessionsListResponse(BaseModel): count: int - """Number of sessions matching the filters. Exact for KYC rows; for KYB rows it is capped at 100 (use `next` to know whether more pages exist). For `session_kind=all` it is the sum of both kinds.""" + """Number of sessions matching the filters: exact up to 100 and capped at 100 beyond that, so do not use it as a total. Use `next` to know whether more pages exist. For `session_kind=all` it is the sum of both kinds, each capped at 100.""" next: str | None """Absolute URL of the next page, or `null` on the last page.""" diff --git a/src/didit/types/sessions/preview_decision_email_response.py b/src/didit/types/sessions/preview_decision_email_response.py index 1d6f2ef..4134168 100644 --- a/src/didit/types/sessions/preview_decision_email_response.py +++ b/src/didit/types/sessions/preview_decision_email_response.py @@ -33,6 +33,9 @@ class SessionsPreviewDecisionEmailResponse(BaseModel): html: str """The email's HTML exactly as it is sent, with its logo embedded as a data URL. Render it in a sandboxed frame, never directly in your application DOM.""" + text: str + """The email's words as plain text, as the person's Messages thread keeps them, for a compact preview (the HTML stays the email the person receives).""" + language: str """The language the email is written in. English (`en`) when the `email_language` you asked for is not offered.""" diff --git a/src/didit/types/sessions/preview_resubmission_params.py b/src/didit/types/sessions/preview_resubmission_params.py index 32dc685..9210dbc 100644 --- a/src/didit/types/sessions/preview_resubmission_params.py +++ b/src/didit/types/sessions/preview_resubmission_params.py @@ -38,6 +38,7 @@ class SessionsPreviewResubmissionParamsNodesToResubmit(TypedDict, total=False): "KYB_REGISTRY", "KYB_KEY_PEOPLE", "KYB", + "GEOLOCATION", ] | str ] diff --git a/src/didit/types/sessions/preview_resubmission_response.py b/src/didit/types/sessions/preview_resubmission_response.py index f485878..139cf33 100644 --- a/src/didit/types/sessions/preview_resubmission_response.py +++ b/src/didit/types/sessions/preview_resubmission_response.py @@ -41,6 +41,7 @@ class SessionsPreviewResubmissionResponseNodesToResubmit(BaseModel): "KYB_REGISTRY", "KYB_KEY_PEOPLE", "KYB", + "GEOLOCATION", ] | str ) @@ -72,6 +73,9 @@ class SessionsPreviewResubmissionResponse(BaseModel): html: str """The email's HTML exactly as it is sent, with its logo embedded as a data URL. Render it in a sandboxed frame, never directly in your application DOM.""" + text: str + """The email's words as plain text, as the person's Messages thread keeps them, for a compact preview (the HTML stays the email the person receives).""" + language: str """The language the email is written in. English (`en`) when the `email_language` you asked for is not offered.""" diff --git a/src/didit/types/sessions/submit_kyb_parties_params.py b/src/didit/types/sessions/submit_kyb_parties_params.py new file mode 100644 index 0000000..dd89ed9 --- /dev/null +++ b/src/didit/types/sessions/submit_kyb_parties_params.py @@ -0,0 +1,11 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["SessionsSubmitKybPartiesParams"] + + +class SessionsSubmitKybPartiesParams(TypedDict, total=False): + locale: str + """Locale used to translate the response of the step the session advances to.""" diff --git a/src/didit/types/sessions/submit_kyb_parties_response.py b/src/didit/types/sessions/submit_kyb_parties_response.py new file mode 100644 index 0000000..9b071c5 --- /dev/null +++ b/src/didit/types/sessions/submit_kyb_parties_response.py @@ -0,0 +1,27 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel +from didit.types.components.kyb_key_people_party import KYBKeyPeopleParty + +__all__ = ["SessionsSubmitKybPartiesResponse"] + + +class SessionsSubmitKybPartiesResponse(BaseModel): + valid: bool | None = None + + next_step: str | None = None + """Step the session is on.""" + + status: str | None = None + """Status of the business session.""" + + advanced: bool | None = None + """`true` when this call declared the parties and advanced the session.""" + + already_submitted: bool | None = None + """`true` when the parties had been declared by an earlier call.""" + + kyb_key_people_status: str | None = None + + parties: list[KYBKeyPeopleParty] | None = None diff --git a/src/didit/types/sessions/update_aml_hit_status_params.py b/src/didit/types/sessions/update_aml_hit_status_params.py index f523069..739ec31 100644 --- a/src/didit/types/sessions/update_aml_hit_status_params.py +++ b/src/didit/types/sessions/update_aml_hit_status_params.py @@ -10,7 +10,7 @@ class SessionsUpdateAmlHitStatusParams(TypedDict, total=False): hit_id: Required[str] - """The `id` of the hit in the AML check's `hits` array.""" + """The `id` of the hit in the AML check's `hits` array (`hit_...`). A hit id returned in the earlier format is still accepted.""" review_status: Required[ Literal["Unreviewed", "Confirmed Match", "False Positive", "Inconclusive"] | str diff --git a/src/didit/types/sessions/update_aml_hit_status_response.py b/src/didit/types/sessions/update_aml_hit_status_response.py index fe76f11..6e33997 100644 --- a/src/didit/types/sessions/update_aml_hit_status_response.py +++ b/src/didit/types/sessions/update_aml_hit_status_response.py @@ -13,7 +13,7 @@ class SessionsUpdateAmlHitStatusResponse(BaseModel): """Always `Hit status updated successfully`.""" hit_id: str - """The updated hit, with surrounding whitespace removed.""" + """The `id` of the updated hit, as the session decision returns it, also when the request named the hit by an id in the earlier format.""" review_status: Literal["Unreviewed", "Confirmed Match", "False Positive", "Inconclusive"] | str """The review status now stored on the hit.""" diff --git a/src/didit/types/sessions/update_kyb_company_data_response.py b/src/didit/types/sessions/update_kyb_company_data_response.py index 3f89e4b..29e907d 100644 --- a/src/didit/types/sessions/update_kyb_company_data_response.py +++ b/src/didit/types/sessions/update_kyb_company_data_response.py @@ -5,6 +5,7 @@ from typing import Literal from didit._models import BaseModel +from didit.types.components.kyb_registry_data import KYBRegistryData __all__ = ["SessionsUpdateKybCompanyDataResponse"] @@ -143,8 +144,8 @@ class SessionsUpdateKybCompanyDataResponse(BaseModel): accounts: dict[str, object] | None = None """Registry filing dates, when available. Annual returns and general meetings use last_annual_return_date and last_agm_date; they are distinct from financial accounts.""" - registry_data: dict[str, object] | None = None - """Raw registry payload snapshot. Every key you PATCH is merged into this map (dates serialized as ISO strings), so the "extracted from registry" view reflects operator corrections.""" + registry_data: KYBRegistryData | None = None + """Didit's normalized registry detail for the company: the ownership outcome (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), the corrections made with update-data, and registry facts that have no field of their own. It never carries the registry source's own record. Every key is optional and present only when the company has a value for it; new keys may be added. Read the canonical fields (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) for anything they cover.""" user_provided_data: dict[str, object] | None = None """What the end user typed during the hosted registry-confirmation step. Never modified by this endpoint.""" diff --git a/src/didit/types/sessions/update_kyb_party_draft_params.py b/src/didit/types/sessions/update_kyb_party_draft_params.py new file mode 100644 index 0000000..1ab641c --- /dev/null +++ b/src/didit/types/sessions/update_kyb_party_draft_params.py @@ -0,0 +1,99 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal, Mapping, Sequence + +from typing_extensions import TypedDict + +__all__ = ["SessionsUpdateKybPartyDraftParams"] + + +class SessionsUpdateKybPartyDraftParams(TypedDict, total=False): + """Any subset of the party fields. The edit is merged into the stored draft and the merged party is validated as a whole, so a draft that could be submitted before an edit can still be submitted after it.""" + + entity_type: Literal["person", "company"] | str + """Whether the party is an individual or a company.""" + + full_name: str + """Full name of a person. Send it, or `first_name` and `last_name`.""" + + first_name: str + + last_name: str + + role: ( + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ) + """Role the party holds. Interchangeable with `roles`; when both are sent they are merged.""" + + roles: Sequence[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + """Every role the party holds. A person needs at least one role (here or in `role`).""" + + position: str + """Job title of a person.""" + + date_of_birth: str | _dt.date | None + + company_name: str + """Name of a company party. Required when `entity_type` is `company`.""" + + registration_number: str + """Registration number of a company party.""" + + email: str + """Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow.""" + + ownership_percent: float | None + """Share of the company the party owns.""" + + nationality: str + """Nationality of a person, or country of incorporation of a company. Required for every party.""" + + phone_number: str + + custom_fields: Mapping[str, object] + """Workflow-defined extra fields.""" + + skip_verification: bool + """Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings.""" diff --git a/src/didit/types/sessions/update_kyb_party_draft_response.py b/src/didit/types/sessions/update_kyb_party_draft_response.py new file mode 100644 index 0000000..15a77b9 --- /dev/null +++ b/src/didit/types/sessions/update_kyb_party_draft_response.py @@ -0,0 +1,111 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +import datetime as _dt +from typing import Literal + +from didit._models import BaseModel + +__all__ = ["SessionsUpdateKybPartyDraftResponse", "SessionsUpdateKybPartyDraftResponseParty"] + + +class SessionsUpdateKybPartyDraftResponseParty(BaseModel): + entity_type: Literal["person", "company"] | str + """Whether the party is an individual or a company.""" + + full_name: str | None = None + """Full name of a person. Send it, or `first_name` and `last_name`.""" + + first_name: str | None = None + + last_name: str | None = None + + role: ( + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + | None + ) = None + """Role the party holds. Interchangeable with `roles`; when both are sent they are merged.""" + + roles: ( + list[ + Literal[ + "director", + "non_executive_director", + "secretary", + "chairman", + "ubo", + "shareholder", + "representative", + "founder", + "legal_advisor", + "authorized_signatory", + "trustee", + "beneficiary", + "settlor", + "protector", + "company_officer", + "investor", + "other", + ] + | str + ] + | None + ) = None + """Every role the party holds. A person needs at least one role (here or in `role`).""" + + position: str | None = None + """Job title of a person.""" + + date_of_birth: _dt.date | None = None + + company_name: str | None = None + """Name of a company party. Required when `entity_type` is `company`.""" + + registration_number: str | None = None + """Registration number of a company party.""" + + email: str | None = None + """Where the verification link is sent. Required when the party has to complete verification, which depends on the role settings and ownership thresholds of the workflow.""" + + ownership_percent: float | None = None + """Share of the company the party owns.""" + + nationality: str + """Nationality of a person, or country of incorporation of a company. Required for every party.""" + + phone_number: str | None = None + + custom_fields: dict[str, object] | None = None + """Workflow-defined extra fields.""" + + skip_verification: bool | None = None + """Ask to skip this party's verification. Honoured only when the party's role allows skipping in the workflow's Key People settings.""" + + +class SessionsUpdateKybPartyDraftResponse(BaseModel): + draft_id: str + + created_at: _dt.datetime + + updated_at: _dt.datetime + + party: SessionsUpdateKybPartyDraftResponseParty diff --git a/src/didit/types/sessions/update_status_params.py b/src/didit/types/sessions/update_status_params.py index ca9950d..c21ec8b 100644 --- a/src/didit/types/sessions/update_status_params.py +++ b/src/didit/types/sessions/update_status_params.py @@ -38,6 +38,7 @@ class SessionsUpdateStatusParamsNodesToResubmit(TypedDict, total=False): "KYB_REGISTRY", "KYB_KEY_PEOPLE", "KYB", + "GEOLOCATION", ] | str ] diff --git a/src/didit/types/sessions/upload_kyb_documents_params.py b/src/didit/types/sessions/upload_kyb_documents_params.py new file mode 100644 index 0000000..83c4db4 --- /dev/null +++ b/src/didit/types/sessions/upload_kyb_documents_params.py @@ -0,0 +1,32 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing import Literal, Sequence + +from typing_extensions import Required, TypedDict + +from didit._types import FileTypes + +__all__ = ["SessionsUploadKybDocumentsParams"] + + +class SessionsUploadKybDocumentsParams(TypedDict, total=False): + documents: Required[Sequence[FileTypes]] + """Files to upload: JPG, JPEG, PNG, TIFF, WEBP, PDF or ZIP archives of them. PDFs up to 50 MB, photos up to 6 MB before compression.""" + + document_passwords: Sequence[str] + """One entry per file in `documents`, in the same order: the password of a protected PDF, empty for any other file.""" + + document_group: ( + Literal[ + "LEGAL_PRESENCE", + "COMPANY_DETAILS", + "OWNERSHIP_STRUCTURE", + "REPRESENTATIVES_AUTHORIZATION", + ] + | str + ) + """Required document group this upload answers.""" + + locale: str + """Locale used to translate the response of the next step.""" diff --git a/src/didit/types/sessions/upload_kyb_documents_response.py b/src/didit/types/sessions/upload_kyb_documents_response.py new file mode 100644 index 0000000..5e9152d --- /dev/null +++ b/src/didit/types/sessions/upload_kyb_documents_response.py @@ -0,0 +1,19 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel + +__all__ = ["SessionsUploadKybDocumentsResponse"] + + +class SessionsUploadKybDocumentsResponse(BaseModel): + valid: bool | None = None + + next_step: str | None = None + """Step the session is on after the upload.""" + + kyb_status: str | None = None + """Status of the company check.""" + + document_answer: dict[str, object] | None = None + """Result per uploaded document and the uploads left.""" diff --git a/src/didit/types/transactions/create_params.py b/src/didit/types/transactions/create_params.py index 6c5a55f..41b33fc 100644 --- a/src/didit/types/transactions/create_params.py +++ b/src/didit/types/transactions/create_params.py @@ -273,7 +273,7 @@ class TransactionsCreateParamsTransactionDetailsCryptoParams(TypedDict, total=Fa """Crypto network selection, separate from currency (the asset symbol). Recording a custom token symbol does not guarantee transaction-hash coverage for its contract.""" crypto_chain: str - """Actual network used for screening. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism) and ARB (Arbitrum One). Always specify this for multi-network tokens. When it is missing for USDT, USDC or ETH sent with a 0x transaction hash, Didit looks the hash up on Ethereum, BNB Chain, Polygon, Base, Arbitrum and Optimism and screens it on the network where it is found; if no network has it, the transaction is not screened and custom_values.aml_screening_status is FAILED with the reason in custom_values.aml_screening_error. When it is missing for USDT or USDC screened by wallet (no transaction hash), a Tron address is screened on Tron, a Solana address on Solana, and a 0x address on the first of those six networks where it has sent a transaction or holds the token, or on Ethereum when it is active on none of them. Connected-provider coverage varies; LIGHTNING requires a supported connected provider.""" + """Actual network used for screening. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar) and HBAR (Hedera). Common network names are accepted too, for example POLYGON or POL for MATIC, BSC for BNB and TRON for TRX. Always specify this for multi-network tokens. When it is missing for USDT, USDC or ETH sent with a 0x transaction hash, Didit looks the hash up on Ethereum, BNB Chain, Polygon, Base, Arbitrum and Optimism and screens it on the network where it is found; if no network has it, the transaction is not screened and custom_values.aml_screening_status is FAILED with the reason in custom_values.aml_screening_error. When it is missing for USDT or USDC screened by wallet (no transaction hash), a Tron address is screened on Tron, a Solana address on Solana, and a 0x address on the first of those six networks where it has sent a transaction or holds the token, or on Ethereum when it is active on none of them. Connected-provider coverage varies; LIGHTNING requires a supported connected provider.""" class TransactionsCreateParamsTransactionDetails(TypedDict, total=False): @@ -283,7 +283,7 @@ class TransactionsCreateParamsTransactionDetails(TypedDict, total=False): """Direction of the transaction relative to the subject. Case-insensitive; `in`/`out` are accepted as aliases. Echoed back uppercase (`INBOUND`/`OUTBOUND`).""" amount: Required[float] - """Transaction amount (up to 18 decimal places). Send it as a decimal string (e.g. `"0.123456789012345678"`) when exact precision matters: a JSON number is parsed as a binary float first, so digits beyond about 15 significant digits are rounded before the amount is stored.""" + """Transaction amount (up to 18 decimal places). Send it as a decimal string (e.g. `"0.123456789012345678"`) when exact precision matters: a JSON number is parsed as a binary float first, so digits beyond about 15 significant digits are rounded before the amount is stored. Must be zero or greater: the direction carries the sign, and a negative amount returns `400`.""" currency: Required[str] """Currency code. Any ISO 4217 alphabetic code is accepted (e.g. `EUR`, `USD`, `NGN`), as is a crypto asset symbol (e.g. `BTC`). Prefer a currently-circulating code. Not every accepted code has an exchange rate: when none is available for the code (for example the ISO accounting unit `XSU`, or a crypto symbol Didit does not price), automatic conversion fails and `preferred_currency_amount` is returned null unless the request supplied a pre-converted `amount_in_default_currency`.""" @@ -292,7 +292,7 @@ class TransactionsCreateParamsTransactionDetails(TypedDict, total=False): """Whether the currency is `fiat` or `crypto`.""" amount_in_default_currency: float | None - """Pre-converted amount in the default currency. If omitted, automatic FX conversion is attempted.""" + """Pre-converted amount in the default currency. If omitted, automatic FX conversion is attempted. Must be zero or greater.""" default_currency: str """The default currency code for the converted amount. Any currently-circulating ISO 4217 code.""" diff --git a/src/didit/types/travel_rule/unmatched_deposits/__init__.py b/src/didit/types/travel_rule/unmatched_deposits/__init__.py new file mode 100644 index 0000000..73f4330 --- /dev/null +++ b/src/didit/types/travel_rule/unmatched_deposits/__init__.py @@ -0,0 +1 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. diff --git a/src/didit/types/travel_rule/unmatched_deposits/list_response.py b/src/didit/types/travel_rule/unmatched_deposits/list_response.py new file mode 100644 index 0000000..43a1acc --- /dev/null +++ b/src/didit/types/travel_rule/unmatched_deposits/list_response.py @@ -0,0 +1,17 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from didit._models import BaseModel +from didit.types.components.travel_rule_transfer_row import TravelRuleTransferRow + +__all__ = ["TravelRuleUnmatchedDepositsListResponse"] + + +class TravelRuleUnmatchedDepositsListResponse(BaseModel): + count: int | None = None + + next: str | None = None + + previous: str | None = None + + results: list[TravelRuleTransferRow] | None = None diff --git a/src/didit/types/travel_rule/unmatched_deposits/match_params.py b/src/didit/types/travel_rule/unmatched_deposits/match_params.py new file mode 100644 index 0000000..10b73cf --- /dev/null +++ b/src/didit/types/travel_rule/unmatched_deposits/match_params.py @@ -0,0 +1,11 @@ +# Code generated by codegen from openapi/*.json. DO NOT EDIT. +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["TravelRuleUnmatchedDepositsMatchParams"] + + +class TravelRuleUnmatchedDepositsMatchParams(TypedDict, total=False): + transaction_id: Required[str] + """The `transaction_id` of the received Travel Rule message (a row with `kind: message`).""" diff --git a/src/didit/types/users/batch_delete_params.py b/src/didit/types/users/batch_delete_params.py index e657d28..a963144 100644 --- a/src/didit/types/users/batch_delete_params.py +++ b/src/didit/types/users/batch_delete_params.py @@ -19,3 +19,9 @@ class UsersBatchDeleteParams(TypedDict, total=False): delete_all: bool """If `true`, deletes every user in the application.""" + + retain_face_embeddings: bool + """Your explicit choice to keep one image-free biometric template of each deleted person for duplicate detection, for `face_retention_days`. Everything else about the person is deleted. Omit it, or send `false`, to delete the templates with the users. When `true`, `face_retention_days` is required.""" + + face_retention_days: int + """Number of days the image-free biometric template is kept when `retain_face_embeddings` is `true`. Required with it, and rejected without it with a `400` on `face_retention_days`.""" diff --git a/src/didit/types/wallet_screening/screen_params.py b/src/didit/types/wallet_screening/screen_params.py index e2dc924..aaaf055 100644 --- a/src/didit/types/wallet_screening/screen_params.py +++ b/src/didit/types/wallet_screening/screen_params.py @@ -12,7 +12,7 @@ class WalletScreeningScreenParams(TypedDict, total=False): wallet_address: Required[str] """The crypto address or network identifier to screen. Must match the selected network (e.g. a `0x`-prefixed 40-hex-char address for EVM chains). Alias: `address`.""" - blockchain: Required[ + blockchain: ( Literal[ "BTC", "LIGHTNING", @@ -30,13 +30,17 @@ class WalletScreeningScreenParams(TypedDict, total=False): "BASE", "OP", "ARB", + "AVAX", + "ADA", + "XLM", + "HBAR", "CELO", "MODE", "PLUME", ] | str - ] - """Network identifier. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), and ARB (Arbitrum One). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`.""" + ) + """Optional network identifier. When omitted, the network is read from the address format: `bc1`, `1` and `3` addresses are Bitcoin (BTC), `T` addresses are Tron (TRX) and base58 public keys are Solana (SOL). A `0x` address is valid on every EVM network, so omitting `blockchain` for it answers 422 with the candidate networks in `candidate_chains`. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar) and HBAR (Hedera). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: `currency`.""" direction: Literal["inbound", "outbound", "deposit", "withdrawal"] | str """Optional. Whether the address is being screened as an inbound (deposit) or outbound (withdrawal) counterparty. Accepts `inbound`, `outbound`, `deposit`, or `withdrawal`. Defaults to a neutral pre-transfer screen when omitted. This is passed to the provider as context only; it does not change the returned `risk_score`, `severity`, or the `source_of_funds`/`destination_of_funds` breakdowns, which are always both returned regardless of `direction`. Changing or omitting `direction` therefore does not require re-screening an address.""" diff --git a/src/didit/types/webhooks/update_config_params.py b/src/didit/types/webhooks/update_config_params.py index 85d3917..3d4b94a 100644 --- a/src/didit/types/webhooks/update_config_params.py +++ b/src/didit/types/webhooks/update_config_params.py @@ -37,3 +37,6 @@ class WebhooksUpdateConfigParams(TypedDict, total=False): allowed_return_hosts: Sequence[str] """Replaces the whole list of Digital ID wallet return hosts. Bare hostnames only, such as `shop.example.com`: no scheme, port, path or wildcard. Values are lowercased and duplicates are dropped. Send `[]` to clear the list.""" + + allowed_domains: Sequence[str] + """Replaces the whole list of allowed origins. Origins (for example `https://app.example.com`; `http` only for `localhost`) the hosted verification flow may be embedded in and may send the user back to with a session callback. Server-to-server calls are not affected. An empty list means no restriction. Didit stores each origin in lower case without a default port. An invalid entry fails with `400` on `allowed_domains`. Send `[]` to remove the restriction.""" diff --git a/tests/generated/test_aml.py b/tests/generated/test_aml.py index c50da4c..ca71324 100644 --- a/tests/generated/test_aml.py +++ b/tests/generated/test_aml.py @@ -55,7 +55,14 @@ def test_aml_screen() -> None: path="/v3/aml/", api="verification", auth="api_key", - json_body={"full_name": "Antonio Ejemplo Modelo"}, + json_body={ + "full_name": "Antonio Ejemplo Modelo", + "entity_type": "person", + "date_of_birth": "1972-02-29", + "nationality": "ES", + "include_adverse_media": False, + "vendor_data": "user-1234", + }, status=200, response_json={ "request_id": "d27c5509-7a66-45a9-b05e-d69d9f4c336a", @@ -78,8 +85,22 @@ def test_aml_screen() -> None: "created_at": "2026-06-11T10:21:07.013938+00:00", }, ), - lambda c: c.aml.screen(full_name="Antonio Ejemplo Modelo"), - lambda c: c.aml.screen(full_name="Antonio Ejemplo Modelo"), + lambda c: c.aml.screen( + full_name="Antonio Ejemplo Modelo", + entity_type="person", + date_of_birth="1972-02-29", + nationality="ES", + include_adverse_media=False, + vendor_data="user-1234", + ), + lambda c: c.aml.screen( + full_name="Antonio Ejemplo Modelo", + entity_type="person", + date_of_birth="1972-02-29", + nationality="ES", + include_adverse_media=False, + vendor_data="user-1234", + ), lambda r: isinstance(r, AmlScreenResponse), lambda r: isinstance(r, AmlScreenResponse), ) diff --git a/tests/generated/test_analytics.py b/tests/generated/test_analytics.py index 7ad6d0e..0eeaa11 100644 --- a/tests/generated/test_analytics.py +++ b/tests/generated/test_analytics.py @@ -4,6 +4,7 @@ from __future__ import annotations 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, ) @@ -309,3 +310,82 @@ def test_analytics_retrieve() -> None: or (isinstance(r, ApplicationAnalyticsWidgetResponse)) ), ) + + +def test_analytics_retrieve_today() -> None: + """``GET /v3/organization/{organization_id}/application/{application_id}/analytics/today/``""" + check_operation( + Expect( + method="GET", + path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/analytics/today/", + api="verification", + auth="api_key", + query={"tz": ["Europe/Madrid"]}, + status=200, + response_json={ + "time_zone": "Europe/Madrid", + "date": "2026-10-30", + "current_hour": 14, + "previous_date": "2026-10-23", + "hours": [ + 3, + 1, + 0, + 0, + 1, + 2, + 4, + 9, + 14, + 18, + 21, + 19, + 22, + 24, + 27, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "previous_hours": [ + 2, + 1, + 1, + 0, + 1, + 3, + 5, + 8, + 12, + 16, + 19, + 18, + 20, + 22, + 24, + 26, + 23, + 19, + 15, + 12, + 9, + 7, + 5, + 3, + ], + "total": 165, + "previous_total_so_far": 151, + "outcomes": {"approved": 139, "in_review": 6, "declined": 18}, + }, + ), + lambda c: c.analytics.retrieve_today(tz="Europe/Madrid"), + lambda c: c.analytics.retrieve_today(tz="Europe/Madrid"), + lambda r: isinstance(r, ApplicationAnalyticsToday), + lambda r: isinstance(r, ApplicationAnalyticsToday), + ) diff --git a/tests/generated/test_businesses.py b/tests/generated/test_businesses.py index da86877..687f0bd 100644 --- a/tests/generated/test_businesses.py +++ b/tests/generated/test_businesses.py @@ -414,7 +414,10 @@ def test_businesses_set_ongoing_monitoring() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/vendor-businesses/toggle-ongoing-monitoring/", api="verification", auth="api_key", - json_body={"is_enabled": True}, + json_body={ + "is_enabled": True, + "didit_internal_id_list": ["b0000000-0000-4000-8000-0000000000b1"], + }, status=200, response_json={ "users_total": 1, @@ -428,8 +431,12 @@ def test_businesses_set_ongoing_monitoring() -> None: "balance_sufficient": True, }, ), - lambda c: c.businesses.set_ongoing_monitoring(is_enabled=True), - lambda c: c.businesses.set_ongoing_monitoring(is_enabled=True), + lambda c: c.businesses.set_ongoing_monitoring( + is_enabled=True, didit_internal_id_list=["b0000000-0000-4000-8000-0000000000b1"] + ), + lambda c: c.businesses.set_ongoing_monitoring( + is_enabled=True, didit_internal_id_list=["b0000000-0000-4000-8000-0000000000b1"] + ), lambda r: ( ( (isinstance(r, OngoingMonitoringToggleResultVariant1)) @@ -455,7 +462,7 @@ def test_businesses_set_session_ongoing_monitoring() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/businesses/toggle-ongoing-monitoring/", api="verification", auth="api_key", - json_body={"is_enabled": True}, + json_body={"is_enabled": True, "session_numbers": ["1001", "1002"]}, status=200, response_json={ "users_total": 1, @@ -469,8 +476,12 @@ def test_businesses_set_session_ongoing_monitoring() -> None: "balance_sufficient": True, }, ), - lambda c: c.businesses.set_session_ongoing_monitoring(is_enabled=True), - lambda c: c.businesses.set_session_ongoing_monitoring(is_enabled=True), + lambda c: c.businesses.set_session_ongoing_monitoring( + is_enabled=True, session_numbers=["1001", "1002"] + ), + lambda c: c.businesses.set_session_ongoing_monitoring( + is_enabled=True, session_numbers=["1001", "1002"] + ), lambda r: ( ( (isinstance(r, OngoingMonitoringToggleResultVariant1)) diff --git a/tests/generated/test_cases.py b/tests/generated/test_cases.py index f25203e..69c41a9 100644 --- a/tests/generated/test_cases.py +++ b/tests/generated/test_cases.py @@ -74,7 +74,11 @@ def test_cases_apply_entity_action() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/00000000-0000-4000-8000-000000000001/entity-actions/", api="verification", auth="api_key", - json_body={"action": "set_status"}, + json_body={ + "action": "add_tags", + "client_reference": "e1a00000-0000-4000-8000-000000000001", + "tags": ["source-of-funds-reviewed"], + }, status=200, response_json={ "receipt": { @@ -101,10 +105,16 @@ def test_cases_apply_entity_action() -> None: strict_type=CaseActionCaseEntityActionResult, ), lambda c: c.cases.apply_entity_action( - "00000000-0000-4000-8000-000000000001", action="set_status" + "00000000-0000-4000-8000-000000000001", + action="add_tags", + client_reference="e1a00000-0000-4000-8000-000000000001", + tags=["source-of-funds-reviewed"], ), lambda c: c.cases.apply_entity_action( - "00000000-0000-4000-8000-000000000001", action="set_status" + "00000000-0000-4000-8000-000000000001", + action="add_tags", + client_reference="e1a00000-0000-4000-8000-000000000001", + tags=["source-of-funds-reviewed"], ), lambda r: isinstance(r, CaseActionCaseEntityActionResult), lambda r: isinstance(r, CaseActionCaseEntityActionResult), @@ -279,7 +289,7 @@ def test_cases_assign() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/c1a5e000-0000-4000-8000-000000000001/assign/", api="verification", auth="api_key", - json_body={"assignee_user_id": "00000000-0000-4000-8000-000000000001"}, + json_body={"assignee_user_id": "9a000000-0000-4000-8000-0000000000aa"}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -427,11 +437,11 @@ def test_cases_assign() -> None: ), lambda c: c.cases.assign( "c1a5e000-0000-4000-8000-000000000001", - assignee_user_id="00000000-0000-4000-8000-000000000001", + assignee_user_id="9a000000-0000-4000-8000-0000000000aa", ), lambda c: c.cases.assign( "c1a5e000-0000-4000-8000-000000000001", - assignee_user_id="00000000-0000-4000-8000-000000000001", + assignee_user_id="9a000000-0000-4000-8000-0000000000aa", ), lambda r: isinstance(r, CaseDetail), lambda r: isinstance(r, CaseDetail), @@ -447,8 +457,8 @@ def test_cases_bulk_assign() -> None: api="verification", auth="api_key", json_body={ - "case_uuids": ["00000000-0000-4000-8000-000000000002"], - "assignee_user_id": "00000000-0000-4000-8000-000000000001", + "case_uuids": ["c1a5e000-0000-4000-8000-000000000001"], + "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa", }, status=200, response_json={ @@ -460,12 +470,12 @@ def test_cases_bulk_assign() -> None: strict_type=CaseBulkUpdateResult, ), lambda c: c.cases.bulk_assign( - case_uuids=["00000000-0000-4000-8000-000000000002"], - assignee_user_id="00000000-0000-4000-8000-000000000001", + case_uuids=["c1a5e000-0000-4000-8000-000000000001"], + assignee_user_id="9a000000-0000-4000-8000-0000000000aa", ), lambda c: c.cases.bulk_assign( - case_uuids=["00000000-0000-4000-8000-000000000002"], - assignee_user_id="00000000-0000-4000-8000-000000000001", + case_uuids=["c1a5e000-0000-4000-8000-000000000001"], + assignee_user_id="9a000000-0000-4000-8000-0000000000aa", ), lambda r: isinstance(r, CaseBulkUpdateResult), lambda r: isinstance(r, CaseBulkUpdateResult), @@ -480,7 +490,11 @@ def test_cases_bulk_update_status() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/bulk/status/", api="verification", auth="api_key", - json_body={"case_uuids": ["00000000-0000-4000-8000-000000000002"], "status": "OPEN"}, + json_body={ + "case_uuids": ["c1a5e000-0000-4000-8000-000000000001"], + "status": "RESOLVED", + "resolution": "FALSE_POSITIVE", + }, status=200, response_json={ "updated": 1, @@ -491,10 +505,14 @@ def test_cases_bulk_update_status() -> None: strict_type=CaseBulkUpdateResult, ), lambda c: c.cases.bulk_update_status( - case_uuids=["00000000-0000-4000-8000-000000000002"], status="OPEN" + case_uuids=["c1a5e000-0000-4000-8000-000000000001"], + status="RESOLVED", + resolution="FALSE_POSITIVE", ), lambda c: c.cases.bulk_update_status( - case_uuids=["00000000-0000-4000-8000-000000000002"], status="OPEN" + case_uuids=["c1a5e000-0000-4000-8000-000000000001"], + status="RESOLVED", + resolution="FALSE_POSITIVE", ), lambda r: isinstance(r, CaseBulkUpdateResult), lambda r: isinstance(r, CaseBulkUpdateResult), @@ -509,7 +527,13 @@ def test_cases_create() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/", api="verification", auth="api_key", - json_body={"title": "sample"}, + json_body={ + "title": "Manual - Jane Doe", + "blueprint": "b1de0000-0000-4000-8000-000000000002", + "priority": "HIGH", + "tags": ["review"], + "subject": {"type": "user", "uuid": "5b9a0000-0000-4000-8000-00000000f00d"}, + }, status=201, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -655,8 +679,20 @@ def test_cases_create() -> None: }, strict_type=CaseDetail, ), - lambda c: c.cases.create(title="sample"), - lambda c: c.cases.create(title="sample"), + lambda c: c.cases.create( + title="Manual - Jane Doe", + blueprint="b1de0000-0000-4000-8000-000000000002", + priority="HIGH", + tags=["review"], + subject={"type": "user", "uuid": "5b9a0000-0000-4000-8000-00000000f00d"}, + ), + lambda c: c.cases.create( + title="Manual - Jane Doe", + blueprint="b1de0000-0000-4000-8000-000000000002", + priority="HIGH", + tags=["review"], + subject={"type": "user", "uuid": "5b9a0000-0000-4000-8000-00000000f00d"}, + ), lambda r: isinstance(r, CaseDetail), lambda r: isinstance(r, CaseDetail), ) @@ -847,7 +883,7 @@ def test_cases_find_duplicates() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/duplicates/", api="verification", auth="api_key", - json_body={"subject": {"type": "user", "uuid": "00000000-0000-4000-8000-000000000003"}}, + json_body={"subject": {"type": "user", "uuid": "5b9a0000-0000-4000-8000-00000000f00d"}}, status=200, response_json={ "count": 1, @@ -866,10 +902,10 @@ def test_cases_find_duplicates() -> None: strict_type=CaseDuplicateCaseDuplicatePage, ), lambda c: c.cases.find_duplicates( - subject={"type": "user", "uuid": "00000000-0000-4000-8000-000000000003"} + subject={"type": "user", "uuid": "5b9a0000-0000-4000-8000-00000000f00d"} ), lambda c: c.cases.find_duplicates( - subject={"type": "user", "uuid": "00000000-0000-4000-8000-000000000003"} + subject={"type": "user", "uuid": "5b9a0000-0000-4000-8000-00000000f00d"} ), lambda r: isinstance(r, CaseDuplicateCaseDuplicatePage), lambda r: isinstance(r, CaseDuplicateCaseDuplicatePage), @@ -1343,7 +1379,7 @@ def test_cases_reject_resolution() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/c1a5e000-0000-4000-8000-000000000001/reject-approval/", api="verification", auth="api_key", - json_body={"notes": "sample"}, + json_body={"notes": "Needs a clearer rationale before this can be approved."}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -1489,8 +1525,14 @@ def test_cases_reject_resolution() -> None: }, strict_type=CaseDetail, ), - lambda c: c.cases.reject_resolution("c1a5e000-0000-4000-8000-000000000001", notes="sample"), - lambda c: c.cases.reject_resolution("c1a5e000-0000-4000-8000-000000000001", notes="sample"), + lambda c: c.cases.reject_resolution( + "c1a5e000-0000-4000-8000-000000000001", + notes="Needs a clearer rationale before this can be approved.", + ), + lambda c: c.cases.reject_resolution( + "c1a5e000-0000-4000-8000-000000000001", + notes="Needs a clearer rationale before this can be approved.", + ), lambda r: isinstance(r, CaseDetail), lambda r: isinstance(r, CaseDetail), ) @@ -2316,7 +2358,7 @@ def test_cases_transfer() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/c1a5e000-0000-4000-8000-000000000001/transfer/", api="verification", auth="api_key", - json_body={"target_blueprint": "00000000-0000-4000-8000-000000000001"}, + json_body={"target_blueprint": "b1de0000-0000-4000-8000-000000000002"}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -2464,11 +2506,11 @@ def test_cases_transfer() -> None: ), lambda c: c.cases.transfer( "c1a5e000-0000-4000-8000-000000000001", - target_blueprint="00000000-0000-4000-8000-000000000001", + target_blueprint="b1de0000-0000-4000-8000-000000000002", ), lambda c: c.cases.transfer( "c1a5e000-0000-4000-8000-000000000001", - target_blueprint="00000000-0000-4000-8000-000000000001", + target_blueprint="b1de0000-0000-4000-8000-000000000002", ), lambda r: isinstance(r, CaseDetail), lambda r: isinstance(r, CaseDetail), @@ -2648,7 +2690,16 @@ def test_cases_blueprints_create() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/blueprints/", api="verification", auth="api_key", - json_body={"name": "sample", "assignee_pool": ["00000000-0000-4000-8000-000000000002"]}, + json_body={ + "name": "AML investigation", + "assignee_pool": ["9a000000-0000-4000-8000-0000000000aa"], + "assignment_method": "AUTOMATIC", + "max_active_cases": 15, + "require_resolution_note": True, + "content_config": { + "aml_control": {"enabled": True, "financial": True, "identity": False} + }, + }, status=201, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -2696,10 +2747,20 @@ def test_cases_blueprints_create() -> None: strict_type=CaseBlueprintDetail, ), lambda c: c.cases.blueprints.create( - name="sample", assignee_pool=["00000000-0000-4000-8000-000000000002"] + name="AML investigation", + assignee_pool=["9a000000-0000-4000-8000-0000000000aa"], + assignment_method="AUTOMATIC", + max_active_cases=15, + require_resolution_note=True, + content_config={"aml_control": {"enabled": True, "financial": True, "identity": False}}, ), lambda c: c.cases.blueprints.create( - name="sample", assignee_pool=["00000000-0000-4000-8000-000000000002"] + name="AML investigation", + assignee_pool=["9a000000-0000-4000-8000-0000000000aa"], + assignment_method="AUTOMATIC", + max_active_cases=15, + require_resolution_note=True, + content_config={"aml_control": {"enabled": True, "financial": True, "identity": False}}, ), lambda r: isinstance(r, CaseBlueprintDetail), lambda r: isinstance(r, CaseBlueprintDetail), @@ -2760,13 +2821,13 @@ def test_cases_blueprints_install_presets() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/blueprints/presets/install/", api="verification", auth="api_key", - json_body={"preset_keys": ["sample"]}, + json_body={"preset_keys": ["aml_investigation", "kyc"]}, status=200, response_json={"created": ["sample"]}, strict_type=CaseBlueprintPresetInstallResult, ), - lambda c: c.cases.blueprints.install_presets(preset_keys=["sample"]), - lambda c: c.cases.blueprints.install_presets(preset_keys=["sample"]), + lambda c: c.cases.blueprints.install_presets(preset_keys=["aml_investigation", "kyc"]), + lambda c: c.cases.blueprints.install_presets(preset_keys=["aml_investigation", "kyc"]), lambda r: isinstance(r, CaseBlueprintPresetInstallResult), lambda r: isinstance(r, CaseBlueprintPresetInstallResult), ) @@ -3060,8 +3121,8 @@ def test_cases_blueprints_save_draft() -> None: auth="api_key", json_body={ "expected_version": 1, - "expected_revision": "00000000-0000-4000-8000-000000000001", - "changes": {}, + "expected_revision": "4e5f0000-0000-4000-8000-000000000003", + "changes": {"max_active_cases": 20}, }, status=200, response_json={ @@ -3076,14 +3137,14 @@ def test_cases_blueprints_save_draft() -> None: lambda c: c.cases.blueprints.save_draft( "00000000-0000-4000-8000-000000000001", expected_version=1, - expected_revision="00000000-0000-4000-8000-000000000001", - changes={}, + expected_revision="4e5f0000-0000-4000-8000-000000000003", + changes={"max_active_cases": 20}, ), lambda c: c.cases.blueprints.save_draft( "00000000-0000-4000-8000-000000000001", expected_version=1, - expected_revision="00000000-0000-4000-8000-000000000001", - changes={}, + expected_revision="4e5f0000-0000-4000-8000-000000000003", + changes={"max_active_cases": 20}, ), lambda r: isinstance(r, CasePublicationPolicyDraft), lambda r: isinstance(r, CasePublicationPolicyDraft), @@ -3098,7 +3159,7 @@ def test_cases_blueprints_update() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/blueprints/b1de0000-0000-4000-8000-000000000002/", api="verification", auth="api_key", - json_body={"name": "sample"}, + json_body={"transfer_enabled": True}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -3145,8 +3206,12 @@ def test_cases_blueprints_update() -> None: }, strict_type=CaseBlueprintDetail, ), - lambda c: c.cases.blueprints.update("b1de0000-0000-4000-8000-000000000002", name="sample"), - lambda c: c.cases.blueprints.update("b1de0000-0000-4000-8000-000000000002", name="sample"), + lambda c: c.cases.blueprints.update( + "b1de0000-0000-4000-8000-000000000002", transfer_enabled=True + ), + lambda c: c.cases.blueprints.update( + "b1de0000-0000-4000-8000-000000000002", transfer_enabled=True + ), lambda r: isinstance(r, CaseBlueprintDetail), lambda r: isinstance(r, CaseBlueprintDetail), ) @@ -3224,8 +3289,8 @@ def test_cases_links_create() -> None: api="verification", auth="api_key", json_body={ - "entity_type": "session", - "entity_uuid": "00000000-0000-4000-8000-000000000001", + "entity_type": "transaction", + "entity_uuid": "77000000-0000-4000-8000-000000000077", }, status=201, response_json={ @@ -3239,13 +3304,13 @@ def test_cases_links_create() -> None: ), lambda c: c.cases.links.create( "c1a5e000-0000-4000-8000-000000000001", - entity_type="session", - entity_uuid="00000000-0000-4000-8000-000000000001", + entity_type="transaction", + entity_uuid="77000000-0000-4000-8000-000000000077", ), lambda c: c.cases.links.create( "c1a5e000-0000-4000-8000-000000000001", - entity_type="session", - entity_uuid="00000000-0000-4000-8000-000000000001", + entity_type="transaction", + entity_uuid="77000000-0000-4000-8000-000000000077", ), lambda r: isinstance(r, CaseLink), lambda r: isinstance(r, CaseLink), @@ -3308,7 +3373,7 @@ def test_cases_notes_create() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/00000000-0000-4000-8000-000000000001/notes/", api="verification", auth="api_key", - json_body={"comment": "sample"}, + json_body={"comment": "Proof of address matches the ID document."}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -3331,8 +3396,14 @@ def test_cases_notes_create() -> None: }, strict_type=CaseCollaborationCaseNote, ), - lambda c: c.cases.notes.create("00000000-0000-4000-8000-000000000001", comment="sample"), - lambda c: c.cases.notes.create("00000000-0000-4000-8000-000000000001", comment="sample"), + lambda c: c.cases.notes.create( + "00000000-0000-4000-8000-000000000001", + comment="Proof of address matches the ID document.", + ), + lambda c: c.cases.notes.create( + "00000000-0000-4000-8000-000000000001", + comment="Proof of address matches the ID document.", + ), lambda r: isinstance(r, CaseCollaborationCaseNote), lambda r: isinstance(r, CaseCollaborationCaseNote), ) @@ -3525,7 +3596,7 @@ def test_cases_regulatory_reports_create() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/", api="verification", auth="api_key", - json_body={"report_type": "SAR"}, + json_body={"template": "7ec00000-0000-4000-8000-000000000006"}, status=201, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -3572,10 +3643,10 @@ def test_cases_regulatory_reports_create() -> None: strict_type=RegulatoryReportDetail, ), lambda c: c.cases.regulatory_reports.create( - "c1a5e000-0000-4000-8000-000000000001", report_type="SAR" + "c1a5e000-0000-4000-8000-000000000001", template="7ec00000-0000-4000-8000-000000000006" ), lambda c: c.cases.regulatory_reports.create( - "c1a5e000-0000-4000-8000-000000000001", report_type="SAR" + "c1a5e000-0000-4000-8000-000000000001", template="7ec00000-0000-4000-8000-000000000006" ), lambda r: isinstance(r, RegulatoryReportDetail), lambda r: isinstance(r, RegulatoryReportDetail), @@ -3942,9 +4013,9 @@ def test_cases_routing_rules_create() -> None: api="verification", auth="api_key", json_body={ - "name": "sample", - "conditions": [{"field": "source", "operator": "equals", "value": "sample"}], - "blueprint": "00000000-0000-4000-8000-000000000001", + "name": "AML screening alerts", + "conditions": [{"field": "source", "operator": "equals", "value": "AML_SCREENING"}], + "blueprint": "b1de0000-0000-4000-8000-000000000002", }, status=201, response_json={ @@ -3966,14 +4037,14 @@ def test_cases_routing_rules_create() -> None: strict_type=CaseRoutingRule, ), lambda c: c.cases.routing_rules.create( - name="sample", - conditions=[{"field": "source", "operator": "equals", "value": "sample"}], - blueprint="00000000-0000-4000-8000-000000000001", + name="AML screening alerts", + conditions=[{"field": "source", "operator": "equals", "value": "AML_SCREENING"}], + blueprint="b1de0000-0000-4000-8000-000000000002", ), lambda c: c.cases.routing_rules.create( - name="sample", - conditions=[{"field": "source", "operator": "equals", "value": "sample"}], - blueprint="00000000-0000-4000-8000-000000000001", + name="AML screening alerts", + conditions=[{"field": "source", "operator": "equals", "value": "AML_SCREENING"}], + blueprint="b1de0000-0000-4000-8000-000000000002", ), lambda r: isinstance(r, CaseRoutingRule), lambda r: isinstance(r, CaseRoutingRule), @@ -4257,8 +4328,8 @@ def test_cases_routing_rules_save_draft() -> None: auth="api_key", json_body={ "expected_version": 1, - "expected_revision": "00000000-0000-4000-8000-000000000001", - "changes": {}, + "expected_revision": "4e5f0000-0000-4000-8000-000000000003", + "changes": {"priority": 10}, }, status=200, response_json={ @@ -4273,14 +4344,14 @@ def test_cases_routing_rules_save_draft() -> None: lambda c: c.cases.routing_rules.save_draft( "00000000-0000-4000-8000-000000000001", expected_version=1, - expected_revision="00000000-0000-4000-8000-000000000001", - changes={}, + expected_revision="4e5f0000-0000-4000-8000-000000000003", + changes={"priority": 10}, ), lambda c: c.cases.routing_rules.save_draft( "00000000-0000-4000-8000-000000000001", expected_version=1, - expected_revision="00000000-0000-4000-8000-000000000001", - changes={}, + expected_revision="4e5f0000-0000-4000-8000-000000000003", + changes={"priority": 10}, ), lambda r: isinstance(r, RoutingPublicationPolicyDraft), lambda r: isinstance(r, RoutingPublicationPolicyDraft), @@ -4335,8 +4406,8 @@ def test_cases_teams_create() -> None: api="verification", auth="api_key", json_body={ - "name": "sample", - "members": [{"user_id": "00000000-0000-4000-8000-000000000004"}], + "name": "AML analysts", + "members": [{"user_id": "9a000000-0000-4000-8000-0000000000aa", "capacity": 10}], }, status=201, response_json={ @@ -4360,10 +4431,12 @@ def test_cases_teams_create() -> None: strict_type=CaseReviewTeam, ), lambda c: c.cases.teams.create( - name="sample", members=[{"user_id": "00000000-0000-4000-8000-000000000004"}] + name="AML analysts", + members=[{"user_id": "9a000000-0000-4000-8000-0000000000aa", "capacity": 10}], ), lambda c: c.cases.teams.create( - name="sample", members=[{"user_id": "00000000-0000-4000-8000-000000000004"}] + name="AML analysts", + members=[{"user_id": "9a000000-0000-4000-8000-0000000000aa", "capacity": 10}], ), lambda r: isinstance(r, CaseReviewTeam), lambda r: isinstance(r, CaseReviewTeam), diff --git a/tests/generated/test_database_validation.py b/tests/generated/test_database_validation.py index 3ab5a3e..bd509ca 100644 --- a/tests/generated/test_database_validation.py +++ b/tests/generated/test_database_validation.py @@ -15,7 +15,15 @@ def test_database_validation_validate() -> None: path="/v3/database-validation/", api="verification", auth="api_key", - json_body={"issuing_state": "BRA"}, + json_body={ + "issuing_state": "BRA", + "services": ["bra_cpf"], + "identification_number": "12345678900", + "first_name": "John", + "last_name": "Doe", + "date_of_birth": "1980-01-01", + "vendor_data": "user-1234", + }, status=200, response_json={ "request_id": "7f9a1c0e-1f2b-4f6e-9d3a-2b1c0e7f9a1c", @@ -59,8 +67,24 @@ def test_database_validation_validate() -> None: "created_at": "2026-06-11T10:30:00.000000+00:00", }, ), - lambda c: c.database_validation.validate(issuing_state="BRA"), - lambda c: c.database_validation.validate(issuing_state="BRA"), + lambda c: c.database_validation.validate( + issuing_state="BRA", + services=["bra_cpf"], + identification_number="12345678900", + first_name="John", + last_name="Doe", + date_of_birth="1980-01-01", + vendor_data="user-1234", + ), + lambda c: c.database_validation.validate( + issuing_state="BRA", + services=["bra_cpf"], + identification_number="12345678900", + first_name="John", + last_name="Doe", + date_of_birth="1980-01-01", + vendor_data="user-1234", + ), lambda r: isinstance(r, DatabaseValidationValidateResponse), lambda r: isinstance(r, DatabaseValidationValidateResponse), ) diff --git a/tests/generated/test_fraud_checks.py b/tests/generated/test_fraud_checks.py index fdf687a..08dee28 100644 --- a/tests/generated/test_fraud_checks.py +++ b/tests/generated/test_fraud_checks.py @@ -16,7 +16,14 @@ def test_fraud_checks_create() -> None: path="/v3/fraud/checks/", api="verification", auth="api_key", - json_body={"subject": {"identifiers": [{"type": "email", "value": "sample"}]}}, + json_body={ + "subject": { + "identifiers": [{"type": "email", "value": "applicant@example.com"}], + "attributes": {"first_name": "Alex", "last_name": "Example"}, + }, + "client_reference": "review-attempt-001", + "checks": {"include": ["networks_same_org", "networks_cross_org", "email_risk"]}, + }, status=200, response_json={ "check_id": "00000000-0000-4000-8000-000000000003", @@ -80,10 +87,20 @@ def test_fraud_checks_create() -> None: strict_type=FraudCheckResponse, ), lambda c: c.fraud_checks.create( - subject={"identifiers": [{"type": "email", "value": "sample"}]} + subject={ + "identifiers": [{"type": "email", "value": "applicant@example.com"}], + "attributes": {"first_name": "Alex", "last_name": "Example"}, + }, + client_reference="review-attempt-001", + checks={"include": ["networks_same_org", "networks_cross_org", "email_risk"]}, ), lambda c: c.fraud_checks.create( - subject={"identifiers": [{"type": "email", "value": "sample"}]} + subject={ + "identifiers": [{"type": "email", "value": "applicant@example.com"}], + "attributes": {"first_name": "Alex", "last_name": "Example"}, + }, + client_reference="review-attempt-001", + checks={"include": ["networks_same_org", "networks_cross_org", "email_risk"]}, ), lambda r: isinstance(r, FraudCheckResponse), lambda r: isinstance(r, FraudCheckResponse), @@ -98,7 +115,14 @@ def test_fraud_checks_plan() -> None: path="/v3/fraud/checks/plan/", api="verification", auth="api_key", - json_body={"subject": {"identifiers": [{"type": "email", "value": "sample"}]}}, + json_body={ + "subject": { + "identifiers": [{"type": "email", "value": "applicant@example.com"}], + "attributes": {"first_name": "Alex", "last_name": "Example"}, + }, + "client_reference": "review-attempt-001", + "checks": {"include": ["networks_same_org", "networks_cross_org", "email_risk"]}, + }, status=200, response_json={ "profile_id": "sample", @@ -121,10 +145,20 @@ def test_fraud_checks_plan() -> None: strict_type=FraudCheckPlan, ), lambda c: c.fraud_checks.plan( - subject={"identifiers": [{"type": "email", "value": "sample"}]} + subject={ + "identifiers": [{"type": "email", "value": "applicant@example.com"}], + "attributes": {"first_name": "Alex", "last_name": "Example"}, + }, + client_reference="review-attempt-001", + checks={"include": ["networks_same_org", "networks_cross_org", "email_risk"]}, ), lambda c: c.fraud_checks.plan( - subject={"identifiers": [{"type": "email", "value": "sample"}]} + subject={ + "identifiers": [{"type": "email", "value": "applicant@example.com"}], + "attributes": {"first_name": "Alex", "last_name": "Example"}, + }, + client_reference="review-attempt-001", + checks={"include": ["networks_same_org", "networks_cross_org", "email_risk"]}, ), lambda r: isinstance(r, FraudCheckPlan), lambda r: isinstance(r, FraudCheckPlan), diff --git a/tests/generated/test_id_wallets.py b/tests/generated/test_id_wallets.py index 6885fb1..35d305c 100644 --- a/tests/generated/test_id_wallets.py +++ b/tests/generated/test_id_wallets.py @@ -940,6 +940,79 @@ def test_id_wallets_start_ftn() -> None: ) +def test_id_wallets_start_google_wallet() -> None: + """``POST /v3/id-verification/wallets/google-wallet/``""" + check_operation( + Expect( + method="POST", + path="/v3/id-verification/wallets/google-wallet/", + api="verification", + auth="api_key", + json_body={ + "country": "USA", + "origin": "https://app.example.com", + "vendor_data": "your-customer-reference", + "metadata": {"reference": "example"}, + }, + status=201, + response_json={ + "request_id": "00000000-0000-4000-8000-000000000001", + "wallet_verification": { + "wallet": { + "id": "google_wallet", + "name": "Google Wallet", + "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)", + }, + "country": "USA", + "status": "Not Finished", + "outcome": "pending", + "error": None, + "interaction": "digital_credentials", + "simulated": False, + "expires_at": "2026-01-01T10:10:00Z", + "next_action": { + "type": "request_digital_credential", + "digital_credentials": { + "protocol": "openid4vp-v1-signed", + "request": { + "requests": [ + { + "protocol": "openid4vp-v1-signed", + "data": {"request": ""}, + } + ] + }, + }, + }, + "identity": None, + "attributes": None, + "level_of_assurance": None, + "verified_at": None, + "signature_valid": None, + "credential_type": "sample-secret", + }, + "vendor_data": "your-customer-reference", + "metadata": {"reference": "example"}, + "created_at": "2026-01-01T10:00:00Z", + }, + ), + lambda c: c.id_wallets.start_google_wallet( + country="USA", + origin="https://app.example.com", + vendor_data="your-customer-reference", + metadata={"reference": "example"}, + ), + lambda c: c.id_wallets.start_google_wallet( + country="USA", + origin="https://app.example.com", + vendor_data="your-customer-reference", + metadata={"reference": "example"}, + ), + lambda r: isinstance(r, DigitalIdWalletApiWalletVerificationResponse), + lambda r: isinstance(r, DigitalIdWalletApiWalletVerificationResponse), + ) + + def test_id_wallets_start_govbr() -> None: """``POST /v3/id-verification/wallets/govbr/``""" check_operation( @@ -1758,3 +1831,75 @@ def test_id_wallets_start_vipps() -> None: lambda r: isinstance(r, DigitalIdWalletApiWalletVerificationResponse), lambda r: isinstance(r, DigitalIdWalletApiWalletVerificationResponse), ) + + +def test_id_wallets_submit_verification_response() -> None: + """``POST /v3/id-verification/wallets/verifications/{request_id}/response/``""" + check_operation( + Expect( + method="POST", + path="/v3/id-verification/wallets/verifications/00000000-0000-4000-8000-000000000001/response/", + api="verification", + auth="api_key", + json_body={ + "response": { + "protocol": "openid4vp-v1-signed", + "data": {"response": ""}, + } + }, + status=200, + response_json={ + "request_id": "00000000-0000-4000-8000-000000000001", + "wallet_verification": { + "wallet": { + "id": "google_wallet", + "name": "Google Wallet", + "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)", + }, + "country": "USA", + "status": "Approved", + "outcome": "verified", + "error": None, + "interaction": "digital_credentials", + "simulated": False, + "expires_at": "2026-01-01T10:10:00Z", + "next_action": None, + "identity": { + "full_name": "Alex Example", + "first_name": "Alex", + "last_name": "Example", + "date_of_birth": "1990-01-31", + "nationality": "USA", + "issuing_state": "USA", + }, + "attributes": { + "document_number": "X0000000", + "document_expiry_date": "2030-01-31", + }, + "level_of_assurance": "substantial", + "verified_at": "2026-01-01T10:01:00Z", + "signature_valid": True, + "credential_type": "sample-secret", + }, + "vendor_data": "your-customer-reference", + "metadata": {"reference": "example"}, + "created_at": "2026-01-01T10:00:00Z", + }, + ), + lambda c: c.id_wallets.submit_verification_response( + "00000000-0000-4000-8000-000000000001", + response={ + "protocol": "openid4vp-v1-signed", + "data": {"response": ""}, + }, + ), + lambda c: c.id_wallets.submit_verification_response( + "00000000-0000-4000-8000-000000000001", + response={ + "protocol": "openid4vp-v1-signed", + "data": {"response": ""}, + }, + ), + lambda r: isinstance(r, DigitalIdWalletApiWalletVerificationResponse), + lambda r: isinstance(r, DigitalIdWalletApiWalletVerificationResponse), + ) diff --git a/tests/generated/test_investigator.py b/tests/generated/test_investigator.py index ae60cb4..692324d 100644 --- a/tests/generated/test_investigator.py +++ b/tests/generated/test_investigator.py @@ -33,7 +33,7 @@ def test_investigator_accept_run() -> None: path="/v3/investigator/runs/00000000-0000-4000-8000-000000000001/accept/", api="verification", auth="api_key", - json_body={"narrative": "sample"}, + json_body={"send_email": False}, status=200, response_json={ "outcome": "accepted", @@ -69,10 +69,10 @@ def test_investigator_accept_run() -> None: strict_type=InvestigatorDecision, ), lambda c: c.investigator.accept_run( - "00000000-0000-4000-8000-000000000001", narrative="sample" + "00000000-0000-4000-8000-000000000001", send_email=False ), lambda c: c.investigator.accept_run( - "00000000-0000-4000-8000-000000000001", narrative="sample" + "00000000-0000-4000-8000-000000000001", send_email=False ), lambda r: isinstance(r, InvestigatorDecision), lambda r: isinstance(r, InvestigatorDecision), @@ -319,7 +319,11 @@ def test_investigator_override_run() -> None: path="/v3/investigator/runs/00000000-0000-4000-8000-000000000001/override/", api="verification", auth="api_key", - json_body={"action": "approve", "category": "missing_context", "reason": "samplexxxx"}, + json_body={ + "action": "decline", + "category": "evidence_misread", + "reason": "The proof of address is older than three months.", + }, status=200, response_json={ "outcome": "accepted", @@ -356,15 +360,15 @@ def test_investigator_override_run() -> None: ), lambda c: c.investigator.override_run( "00000000-0000-4000-8000-000000000001", - action="approve", - category="missing_context", - reason="samplexxxx", + action="decline", + category="evidence_misread", + reason="The proof of address is older than three months.", ), lambda c: c.investigator.override_run( "00000000-0000-4000-8000-000000000001", - action="approve", - category="missing_context", - reason="samplexxxx", + action="decline", + category="evidence_misread", + reason="The proof of address is older than three months.", ), lambda r: isinstance(r, InvestigatorDecision), lambda r: isinstance(r, InvestigatorDecision), @@ -636,7 +640,7 @@ def test_investigator_update_settings() -> None: path="/v3/investigator/settings/", api="verification", auth="api_key", - json_body={"stage": "none"}, + json_body={"stage": "shadow", "monthly_spend_limit": "500.00"}, status=200, response_json={ "stage": "none", @@ -655,8 +659,8 @@ def test_investigator_update_settings() -> None: }, strict_type=InvestigatorSettings, ), - lambda c: c.investigator.update_settings(stage="none"), - lambda c: c.investigator.update_settings(stage="none"), + lambda c: c.investigator.update_settings(stage="shadow", monthly_spend_limit="500.00"), + lambda c: c.investigator.update_settings(stage="shadow", monthly_spend_limit="500.00"), lambda r: isinstance(r, InvestigatorSettings), lambda r: isinstance(r, InvestigatorSettings), ) diff --git a/tests/generated/test_kyb.py b/tests/generated/test_kyb.py index 0c0596f..2f8756c 100644 --- a/tests/generated/test_kyb.py +++ b/tests/generated/test_kyb.py @@ -21,7 +21,10 @@ def test_kyb_list_shareholders() -> None: path="/v3/kyb/shareholders/", api="verification", auth="api_key", - json_body={"kyb_response_id": "69aeeb95febb0f1704042259"}, + json_body={ + "kyb_response_id": "69aeeb95febb0f1704042259", + "vendor_data": "company-1234", + }, status=200, response_json={ "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e", @@ -94,24 +97,7 @@ def test_kyb_list_shareholders() -> None: "next_account": "26 February 2026", "due_by_date": "26 August 2026", }, - "registry_data": { - "name": "Tesco PLC", - "registration_number": "00445790", - "status": "active", - "type": "Public Limited Company", - "incorporation_date": "1947-11-27", - "tax_number": "GB412 8925 93", - "country_code": "GB", - "fetch_status": "resolved", - "industries_detail": [ - { - "code": "47110", - "name": "Retail Sale In Non-specialised Stores With Food, Beverages Or Tobacco Predominating", - "description": None, - "meta_detail": [], - } - ], - }, + "registry_data": {}, "user_provided_data": None, "confirmed_by_user_at": None, "last_console_edit_at": None, @@ -122,8 +108,12 @@ def test_kyb_list_shareholders() -> None: "created_at": "2026-06-11T10:45:00.000000+00:00", }, ), - lambda c: c.kyb.list_shareholders(kyb_response_id="69aeeb95febb0f1704042259"), - lambda c: c.kyb.list_shareholders(kyb_response_id="69aeeb95febb0f1704042259"), + lambda c: c.kyb.list_shareholders( + kyb_response_id="69aeeb95febb0f1704042259", vendor_data="company-1234" + ), + lambda c: c.kyb.list_shareholders( + kyb_response_id="69aeeb95febb0f1704042259", vendor_data="company-1234" + ), lambda r: ( (isinstance(r, KybListShareholdersResponse)) or (isinstance(r, KybListShareholdersResponse202)) @@ -143,7 +133,10 @@ def test_kyb_list_ubos() -> None: path="/v3/kyb/ubo/", api="verification", auth="api_key", - json_body={"kyb_response_id": "69aeeb95febb0f1704042259"}, + json_body={ + "kyb_response_id": "69aeeb95febb0f1704042259", + "vendor_data": "company-1234", + }, status=200, response_json={ "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e", @@ -217,22 +210,7 @@ def test_kyb_list_ubos() -> None: "due_by_date": "26 August 2026", }, "registry_data": { - "name": "Tesco PLC", - "registration_number": "00445790", - "status": "active", - "type": "Public Limited Company", - "incorporation_date": "1947-11-27", - "tax_number": "GB412 8925 93", - "country_code": "GB", - "fetch_status": "resolved", - "industries_detail": [ - { - "code": "47110", - "name": "Retail Sale In Non-specialised Stores With Food, Beverages Or Tobacco Predominating", - "description": None, - "meta_detail": [], - } - ], + "ubo_resolution": {"parent_chain": [], "subsidiaries": [], "unresolved": []} }, "user_provided_data": None, "confirmed_by_user_at": None, @@ -244,8 +222,12 @@ def test_kyb_list_ubos() -> None: "created_at": "2026-06-11T10:45:00.000000+00:00", }, ), - lambda c: c.kyb.list_ubos(kyb_response_id="69aeeb95febb0f1704042259"), - lambda c: c.kyb.list_ubos(kyb_response_id="69aeeb95febb0f1704042259"), + lambda c: c.kyb.list_ubos( + kyb_response_id="69aeeb95febb0f1704042259", vendor_data="company-1234" + ), + lambda c: c.kyb.list_ubos( + kyb_response_id="69aeeb95febb0f1704042259", vendor_data="company-1234" + ), lambda r: (isinstance(r, KybListUbosResponse)) or (isinstance(r, KybListUbosResponse202)), lambda r: (isinstance(r, KybListUbosResponse)) or (isinstance(r, KybListUbosResponse202)), ) @@ -259,7 +241,12 @@ def test_kyb_search() -> None: path="/v3/kyb/search/", api="verification", auth="api_key", - json_body={"country_code": "GB"}, + json_body={ + "country_code": "GB", + "name": "Tesco", + "search_type": "contains", + "vendor_data": "company-1234", + }, status=200, response_json={ "request_id": "0c7e9a40-3a13-4f7e-8a44-9d2e2f1c5b6a", @@ -293,8 +280,12 @@ def test_kyb_search() -> None: "created_at": "2026-06-11T10:40:00.000000+00:00", }, ), - lambda c: c.kyb.search(country_code="GB"), - lambda c: c.kyb.search(country_code="GB"), + lambda c: c.kyb.search( + country_code="GB", name="Tesco", search_type="contains", vendor_data="company-1234" + ), + lambda c: c.kyb.search( + country_code="GB", name="Tesco", search_type="contains", vendor_data="company-1234" + ), lambda r: isinstance(r, KybSearchResponse), lambda r: isinstance(r, KybSearchResponse), ) @@ -308,7 +299,10 @@ def test_kyb_select() -> None: path="/v3/kyb/select/", api="verification", auth="api_key", - json_body={"kyb_response_id": "69aeeb95febb0f1704042259"}, + json_body={ + "kyb_response_id": "69aeeb95febb0f1704042259", + "vendor_data": "company-1234", + }, status=200, response_json={ "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e", @@ -381,24 +375,7 @@ def test_kyb_select() -> None: "next_account": "26 February 2026", "due_by_date": "26 August 2026", }, - "registry_data": { - "name": "Tesco PLC", - "registration_number": "00445790", - "status": "active", - "type": "Public Limited Company", - "incorporation_date": "1947-11-27", - "tax_number": "GB412 8925 93", - "country_code": "GB", - "fetch_status": "resolved", - "industries_detail": [ - { - "code": "47110", - "name": "Retail Sale In Non-specialised Stores With Food, Beverages Or Tobacco Predominating", - "description": None, - "meta_detail": [], - } - ], - }, + "registry_data": {}, "user_provided_data": None, "confirmed_by_user_at": None, "last_console_edit_at": None, @@ -409,8 +386,12 @@ def test_kyb_select() -> None: "created_at": "2026-06-11T10:45:00.000000+00:00", }, ), - lambda c: c.kyb.select(kyb_response_id="69aeeb95febb0f1704042259"), - lambda c: c.kyb.select(kyb_response_id="69aeeb95febb0f1704042259"), + lambda c: c.kyb.select( + kyb_response_id="69aeeb95febb0f1704042259", vendor_data="company-1234" + ), + lambda c: c.kyb.select( + kyb_response_id="69aeeb95febb0f1704042259", vendor_data="company-1234" + ), lambda r: isinstance(r, KybSelectResponse), lambda r: isinstance(r, KybSelectResponse), ) diff --git a/tests/generated/test_regulatory_reports.py b/tests/generated/test_regulatory_reports.py index 76d25a2..2312728 100644 --- a/tests/generated/test_regulatory_reports.py +++ b/tests/generated/test_regulatory_reports.py @@ -21,8 +21,8 @@ def test_regulatory_reports_create() -> None: api="verification", auth="api_key", json_body={ - "case": "00000000-0000-4000-8000-000000000001", - "template": "00000000-0000-4000-8000-000000000001", + "case": "c1a5e000-0000-4000-8000-000000000001", + "template": "7ec00000-0000-4000-8000-000000000006", }, status=201, response_json={ @@ -70,12 +70,12 @@ def test_regulatory_reports_create() -> None: strict_type=RegulatoryReportDetail, ), lambda c: c.regulatory_reports.create( - case="00000000-0000-4000-8000-000000000001", - template="00000000-0000-4000-8000-000000000001", + case="c1a5e000-0000-4000-8000-000000000001", + template="7ec00000-0000-4000-8000-000000000006", ), lambda c: c.regulatory_reports.create( - case="00000000-0000-4000-8000-000000000001", - template="00000000-0000-4000-8000-000000000001", + case="c1a5e000-0000-4000-8000-000000000001", + template="7ec00000-0000-4000-8000-000000000006", ), lambda r: isinstance(r, RegulatoryReportDetail), lambda r: isinstance(r, RegulatoryReportDetail), @@ -347,7 +347,7 @@ def test_regulatory_reports_update() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/regulatory-reports/5ec00000-0000-4000-8000-000000000007/", api="verification", auth="api_key", - json_body={"jurisdiction": "sa"}, + json_body={"rentity_id": "FIU-US-00123", "currency_code_local": "USD"}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -394,10 +394,14 @@ def test_regulatory_reports_update() -> None: strict_type=RegulatoryReportDetail, ), lambda c: c.regulatory_reports.update( - "5ec00000-0000-4000-8000-000000000007", jurisdiction="sa" + "5ec00000-0000-4000-8000-000000000007", + rentity_id="FIU-US-00123", + currency_code_local="USD", ), lambda c: c.regulatory_reports.update( - "5ec00000-0000-4000-8000-000000000007", jurisdiction="sa" + "5ec00000-0000-4000-8000-000000000007", + rentity_id="FIU-US-00123", + currency_code_local="USD", ), lambda r: isinstance(r, RegulatoryReportDetail), lambda r: isinstance(r, RegulatoryReportDetail), diff --git a/tests/generated/test_report_templates.py b/tests/generated/test_report_templates.py index 11bf549..1ac9c47 100644 --- a/tests/generated/test_report_templates.py +++ b/tests/generated/test_report_templates.py @@ -16,7 +16,16 @@ def test_report_templates_create() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/report-templates/", api="verification", auth="api_key", - json_body={"name": "sample", "jurisdiction": "sa", "report_type": "SAR"}, + json_body={ + "name": "US SAR default", + "jurisdiction": "US", + "report_type": "SAR", + "field_config": { + "rentity_id": "FIU-US-00123", + "submission_code": "E", + "currency_code_local": "USD", + }, + }, status=201, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -30,8 +39,26 @@ def test_report_templates_create() -> None: }, strict_type=ReportTemplateDetail, ), - lambda c: c.report_templates.create(name="sample", jurisdiction="sa", report_type="SAR"), - lambda c: c.report_templates.create(name="sample", jurisdiction="sa", report_type="SAR"), + lambda c: c.report_templates.create( + name="US SAR default", + jurisdiction="US", + report_type="SAR", + field_config={ + "rentity_id": "FIU-US-00123", + "submission_code": "E", + "currency_code_local": "USD", + }, + ), + lambda c: c.report_templates.create( + name="US SAR default", + jurisdiction="US", + report_type="SAR", + field_config={ + "rentity_id": "FIU-US-00123", + "submission_code": "E", + "currency_code_local": "USD", + }, + ), lambda r: isinstance(r, ReportTemplateDetail), lambda r: isinstance(r, ReportTemplateDetail), ) @@ -131,7 +158,7 @@ def test_report_templates_update() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/report-templates/7ec00000-0000-4000-8000-000000000006/", api="verification", auth="api_key", - json_body={"name": "sample"}, + json_body={"field_config": {"rentity_id": "FIU-US-00124"}}, status=200, response_json={ "uuid": "00000000-0000-4000-8000-000000000003", @@ -145,8 +172,12 @@ def test_report_templates_update() -> None: }, strict_type=ReportTemplateDetail, ), - lambda c: c.report_templates.update("7ec00000-0000-4000-8000-000000000006", name="sample"), - lambda c: c.report_templates.update("7ec00000-0000-4000-8000-000000000006", name="sample"), + lambda c: c.report_templates.update( + "7ec00000-0000-4000-8000-000000000006", field_config={"rentity_id": "FIU-US-00124"} + ), + lambda c: c.report_templates.update( + "7ec00000-0000-4000-8000-000000000006", field_config={"rentity_id": "FIU-US-00124"} + ), lambda r: isinstance(r, ReportTemplateDetail), lambda r: isinstance(r, ReportTemplateDetail), ) diff --git a/tests/generated/test_sessions.py b/tests/generated/test_sessions.py index 02a15d8..f2f2429 100644 --- a/tests/generated/test_sessions.py +++ b/tests/generated/test_sessions.py @@ -14,6 +14,7 @@ from didit.types.components.session_decision import SessionDecision from didit.types.components.session_deletion_job import SessionDeletionJob from didit.types.components.session_event import SessionEvent +from didit.types.components.session_files_export import SessionFilesExport from didit.types.components.session_import_error import SessionImportError from didit.types.components.session_import_job import SessionImportJob from didit.types.components.session_webhook_delivery import SessionWebhookDelivery @@ -23,6 +24,7 @@ from didit.types.sessions.bulk_update_aml_hit_status_response import ( SessionsBulkUpdateAmlHitStatusResponse, ) +from didit.types.sessions.create_kyb_party_draft_response import SessionsCreateKybPartyDraftResponse from didit.types.sessions.create_response import SessionsCreateResponse from didit.types.sessions.delete_response import SessionsDeleteResponse from didit.types.sessions.imports.check_provider_response import ( @@ -38,6 +40,10 @@ from didit.types.sessions.list_feature_overrides_response import ( SessionsListFeatureOverridesResponse, ) +from didit.types.sessions.list_kyb_extracted_parties_response import ( + SessionsListKybExtractedPartiesResponse, +) +from didit.types.sessions.list_kyb_party_drafts_response import SessionsListKybPartyDraftsResponse from didit.types.sessions.preview_decision_email_response import ( SessionsPreviewDecisionEmailResponse, ) @@ -45,6 +51,7 @@ from didit.types.sessions.reviews.create_response import SessionsReviewsCreateResponse from didit.types.sessions.share_response import SessionsShareResponse from didit.types.sessions.signatures.validate_response import SessionsSignaturesValidateResponse +from didit.types.sessions.submit_kyb_parties_response import SessionsSubmitKybPartiesResponse from didit.types.sessions.update_aml_hit_status_response import SessionsUpdateAmlHitStatusResponse from didit.types.sessions.update_aml_status_response import SessionsUpdateAmlStatusResponse from didit.types.sessions.update_data_response import SessionsUpdateDataResponse @@ -55,9 +62,11 @@ from didit.types.sessions.update_kyb_company_data_response import ( SessionsUpdateKybCompanyDataResponse, ) +from didit.types.sessions.update_kyb_party_draft_response import SessionsUpdateKybPartyDraftResponse from didit.types.sessions.update_kyb_party_response import SessionsUpdateKybPartyResponse from didit.types.sessions.update_poa_data_response import SessionsUpdatePoaDataResponse from didit.types.sessions.update_status_response import SessionsUpdateStatusResponse +from didit.types.sessions.upload_kyb_documents_response import SessionsUploadKybDocumentsResponse from tests.harness import BINARY_BODY, Expect, check_operation @@ -156,21 +165,32 @@ def test_sessions_bulk_update_aml_hit_status() -> None: api="verification", auth="api_key", query={"node_id": ["feature_aml_1"]}, - json_body={"hit_updates": [{"hit_id": "abc123", "review_status": "Unreviewed"}]}, + json_body={ + "hit_updates": [ + {"hit_id": "hit_7c1e9a40b2d35f86e0a4c912", "review_status": "Confirmed Match"}, + {"hit_id": "hit_3b8f20d6a91c4e75f0b2d6a8", "review_status": "False Positive"}, + ] + }, status=200, response_json={ "message": "Updated 2 hit(s) successfully", - "updated_hits": ["abc123", "def456"], + "updated_hits": ["hit_7c1e9a40b2d35f86e0a4c912", "hit_3b8f20d6a91c4e75f0b2d6a8"], }, ), lambda c: c.sessions.bulk_update_aml_hit_status( "11111111-2222-3333-4444-555555555555", - hit_updates=[{"hit_id": "abc123", "review_status": "Unreviewed"}], + hit_updates=[ + {"hit_id": "hit_7c1e9a40b2d35f86e0a4c912", "review_status": "Confirmed Match"}, + {"hit_id": "hit_3b8f20d6a91c4e75f0b2d6a8", "review_status": "False Positive"}, + ], node_id_query="feature_aml_1", ), lambda c: c.sessions.bulk_update_aml_hit_status( "11111111-2222-3333-4444-555555555555", - hit_updates=[{"hit_id": "abc123", "review_status": "Unreviewed"}], + hit_updates=[ + {"hit_id": "hit_7c1e9a40b2d35f86e0a4c912", "review_status": "Confirmed Match"}, + {"hit_id": "hit_3b8f20d6a91c4e75f0b2d6a8", "review_status": "False Positive"}, + ], node_id_query="feature_aml_1", ), lambda r: isinstance(r, SessionsBulkUpdateAmlHitStatusResponse), @@ -312,6 +332,71 @@ def test_sessions_create() -> None: ) +def test_sessions_create_kyb_party_draft() -> None: + """``POST /v3/session/{sessionId}/kyb/parties/drafts/``""" + check_operation( + Expect( + method="POST", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/drafts/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + json_body={ + "entity_type": "person", + "nationality": "MEX", + "first_name": "Ana", + "last_name": "Lopez", + "roles": ["ubo", "director"], + "date_of_birth": "1984-06-12", + "email": "ana.lopez@example.com", + "ownership_percent": 60, + }, + status=201, + response_json={ + "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + "created_at": "2026-10-31T10:00:00Z", + "updated_at": "2026-10-31T10:00:00Z", + "party": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": ["ubo", "director"], + "ownership_percent": 60, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12", + }, + }, + ), + lambda c: c.sessions.create_kyb_party_draft( + "33333333-4444-5555-6666-777777777777", + entity_type="person", + nationality="MEX", + first_name="Ana", + last_name="Lopez", + roles=["ubo", "director"], + date_of_birth="1984-06-12", + email="ana.lopez@example.com", + ownership_percent=60, + node_id="sample", + ), + lambda c: c.sessions.create_kyb_party_draft( + "33333333-4444-5555-6666-777777777777", + entity_type="person", + nationality="MEX", + first_name="Ana", + last_name="Lopez", + roles=["ubo", "director"], + date_of_birth="1984-06-12", + email="ana.lopez@example.com", + ownership_percent=60, + node_id="sample", + ), + lambda r: isinstance(r, SessionsCreateKybPartyDraftResponse), + lambda r: isinstance(r, SessionsCreateKybPartyDraftResponse), + ) + + def test_sessions_delete() -> None: """``DELETE /v3/session/{sessionId}/delete/``""" check_operation( @@ -352,6 +437,32 @@ def test_sessions_delete() -> None: ) +def test_sessions_delete_kyb_party_draft() -> None: + """``DELETE /v3/session/{sessionId}/kyb/parties/drafts/{draftId}/``""" + check_operation( + Expect( + method="DELETE", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/drafts/5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + status=204, + ), + lambda c: c.sessions.delete_kyb_party_draft( + "33333333-4444-5555-6666-777777777777", + "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + node_id="sample", + ), + lambda c: c.sessions.delete_kyb_party_draft( + "33333333-4444-5555-6666-777777777777", + "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + node_id="sample", + ), + lambda r: r is None, + lambda r: r is None, + ) + + def test_sessions_export_aml_screening_history() -> None: """``GET /v3/session/{sessionId}/aml-screening-history/export/``""" check_operation( @@ -360,22 +471,51 @@ def test_sessions_export_aml_screening_history() -> None: path="/v3/session/11111111-2222-3333-4444-555555555555/aml-screening-history/export/", api="verification", auth="api_key", - query={"node_id": ["feature_aml_1"]}, + query={"node_id": ["feature_aml_1"], "month": ["2026-09"]}, status=200, response_bytes=BINARY_BODY, response_content_type="text/csv", ), lambda c: c.sessions.export_aml_screening_history( - "11111111-2222-3333-4444-555555555555", node_id="feature_aml_1" + "11111111-2222-3333-4444-555555555555", node_id="feature_aml_1", month="2026-09" ), lambda c: c.sessions.export_aml_screening_history( - "11111111-2222-3333-4444-555555555555", node_id="feature_aml_1" + "11111111-2222-3333-4444-555555555555", node_id="feature_aml_1", month="2026-09" ), lambda r: r == BINARY_BODY, lambda r: r == BINARY_BODY, ) +def test_sessions_export_files() -> None: + """``POST /v3/session/{sessionId}/files-export/``""" + check_operation( + Expect( + method="POST", + path="/v3/session/11111111-2222-3333-4444-555555555555/files-export/", + api="verification", + auth="api_key", + status=202, + response_json={ + "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", + "session_id": "11111111-2222-3333-4444-555555555555", + "status": "PENDING", + "file_count": None, + "size_bytes": None, + "download_url": None, + "expires_at": None, + "error": None, + "created_at": "2026-10-29T12:00:03Z", + "completed_at": None, + }, + ), + lambda c: c.sessions.export_files("11111111-2222-3333-4444-555555555555"), + lambda c: c.sessions.export_files("11111111-2222-3333-4444-555555555555"), + lambda r: isinstance(r, SessionFilesExport), + lambda r: isinstance(r, SessionFilesExport), + ) + + def test_sessions_generate_pdf() -> None: """``GET /v3/session/{sessionId}/generate-pdf/``""" check_operation( @@ -395,6 +535,39 @@ def test_sessions_generate_pdf() -> None: ) +def test_sessions_get_files_export() -> None: + """``GET /v3/session/{sessionId}/files-export/{exportId}/``""" + check_operation( + Expect( + method="GET", + path="/v3/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/", + api="verification", + auth="api_key", + status=200, + response_json={ + "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", + "session_id": "11111111-2222-3333-4444-555555555555", + "status": "READY", + "file_count": 9, + "size_bytes": 18734120, + "download_url": "https://storage.example.com/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/session-42-files.zip?X-Amz-Signature=...", + "expires_at": "2026-10-30T12:00:41Z", + "error": None, + "created_at": "2026-10-29T12:00:03Z", + "completed_at": "2026-10-29T12:00:41Z", + }, + ), + lambda c: c.sessions.get_files_export( + "11111111-2222-3333-4444-555555555555", "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + ), + lambda c: c.sessions.get_files_export( + "11111111-2222-3333-4444-555555555555", "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + ), + lambda r: isinstance(r, SessionFilesExport), + lambda r: isinstance(r, SessionFilesExport), + ) + + def test_sessions_import_shared() -> None: """``POST /v3/session/import-shared/``""" check_operation( @@ -458,6 +631,9 @@ def test_sessions_list() -> None: "workflow_id": ["9f9b1234-aaaa-bbbb-cccc-1234567890ab"], "date_from": ["2026-06-01"], "date_to": ["2026-06-30"], + "tags": ["sample"], + "decided_from": ["2026-01-01T00:00:00Z"], + "decided_to": ["2026-01-01T00:00:00Z"], "country": ["ESP,USA"], "document_type": ["P,ID"], "document_name": ["Spain - Id Card (2021)"], @@ -547,6 +723,9 @@ def test_sessions_list() -> None: workflow_id="9f9b1234-aaaa-bbbb-cccc-1234567890ab", date_from="2026-06-01", date_to="2026-06-30", + tags="sample", + decided_from="2026-01-01T00:00:00Z", + decided_to="2026-01-01T00:00:00Z", country="ESP,USA", document_type="P,ID", document_name="Spain - Id Card (2021)", @@ -571,6 +750,9 @@ def test_sessions_list() -> None: workflow_id="9f9b1234-aaaa-bbbb-cccc-1234567890ab", date_from="2026-06-01", date_to="2026-06-30", + tags="sample", + decided_from="2026-01-01T00:00:00Z", + decided_to="2026-01-01T00:00:00Z", country="ESP,USA", document_type="P,ID", document_name="Spain - Id Card (2021)", @@ -612,6 +794,7 @@ def test_sessions_list_aml_screening_history() -> None: auth="api_key", query={ "node_id": ["feature_aml_1"], + "month": ["2026-09"], "limit": ["50"], "offset": ["0"], "ordering": ["completed_at"], @@ -624,6 +807,7 @@ def test_sessions_list_aml_screening_history() -> None: "results": [ { "uuid": "dddddddd-1111-2222-3333-444444444444", + "run_id": "aaaaaaaa-1111-2222-3333-444444444444", "completed_at": "2026-09-14T04:12:33.481207Z", "started_at": "2026-09-14T04:00:01.002311Z", "outcome": "NO_CHANGE", @@ -632,6 +816,8 @@ def test_sessions_list_aml_screening_history() -> None: "status": "Approved", "score": 0.0, "total_hits": 0, + "new_hits": 0, + "entities_screened": 1, "dataset_freshness": { "captured_at": "2026-09-14T03:58:02.114820+00:00", "provider": "aml_data_source", @@ -660,6 +846,7 @@ def test_sessions_list_aml_screening_history() -> None: }, { "uuid": "eeeeeeee-1111-2222-3333-444444444444", + "run_id": "bbbbbbbb-1111-2222-3333-444444444444", "completed_at": "2026-09-13T04:11:58.020914Z", "started_at": "2026-09-13T04:00:00.871022Z", "outcome": "FAILED", @@ -668,6 +855,8 @@ def test_sessions_list_aml_screening_history() -> None: "status": "Approved", "score": 0.0, "total_hits": 0, + "new_hits": None, + "entities_screened": 0, "dataset_freshness": None, }, ], @@ -676,6 +865,7 @@ def test_sessions_list_aml_screening_history() -> None: lambda c: c.sessions.list_aml_screening_history( "11111111-2222-3333-4444-555555555555", node_id="feature_aml_1", + month="2026-09", limit=50, offset=0, ordering="completed_at", @@ -683,6 +873,7 @@ def test_sessions_list_aml_screening_history() -> None: lambda c: c.sessions.list_aml_screening_history( "11111111-2222-3333-4444-555555555555", node_id="feature_aml_1", + month="2026-09", limit=50, offset=0, ordering="completed_at", @@ -833,6 +1024,99 @@ def test_sessions_list_feature_overrides() -> None: ) +def test_sessions_list_kyb_extracted_parties() -> None: + """``GET /v3/session/{sessionId}/kyb/extracted-parties/``""" + check_operation( + Expect( + method="GET", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/extracted-parties/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + status=200, + response_json={ + "parties": [ + { + "name": "Ana Lopez", + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "appointment_date": None, + "designation": "Administrador unico", + "roles": [ + { + "role": "shareholder", + "ownership_percent": {"text": "60%", "min": 60, "max": 60}, + } + ], + "documents": [ + { + "document_uuid": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41", + "document_type": "OWNERSHIP_STRUCTURE", + "document_subtype": "ARTICLES_OF_INCORPORATION", + "original_filename": "acta_constitutiva.pdf", + "status": "Approved", + } + ], + } + ], + "document_count": 1, + "node_id": "node_kyb_documents", + }, + ), + lambda c: c.sessions.list_kyb_extracted_parties( + "33333333-4444-5555-6666-777777777777", node_id="sample" + ), + lambda c: c.sessions.list_kyb_extracted_parties( + "33333333-4444-5555-6666-777777777777", node_id="sample" + ), + lambda r: isinstance(r, SessionsListKybExtractedPartiesResponse), + lambda r: isinstance(r, SessionsListKybExtractedPartiesResponse), + ) + + +def test_sessions_list_kyb_party_drafts() -> None: + """``GET /v3/session/{sessionId}/kyb/parties/drafts/``""" + check_operation( + Expect( + method="GET", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/drafts/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + status=200, + response_json={ + "parties": [ + { + "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + "created_at": "2026-10-31T10:00:00Z", + "updated_at": "2026-10-31T10:00:00Z", + "party": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": ["ubo", "director"], + "ownership_percent": 60, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12", + }, + } + ], + "node_id": "node_kyb_key_people", + }, + ), + lambda c: c.sessions.list_kyb_party_drafts( + "33333333-4444-5555-6666-777777777777", node_id="sample" + ), + lambda c: c.sessions.list_kyb_party_drafts( + "33333333-4444-5555-6666-777777777777", node_id="sample" + ), + lambda r: isinstance(r, SessionsListKybPartyDraftsResponse), + lambda r: isinstance(r, SessionsListKybPartyDraftsResponse), + ) + + def test_sessions_list_networks() -> None: """``GET /v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/``""" check_operation( @@ -2009,7 +2293,7 @@ def test_sessions_retrieve_decision() -> None: "entity_type": "person", "hits": [ { - "id": "cPtTGRKkyddAcAC4xgsLCm", + "id": "hit_7c1e9a40b2d35f86e0a4c912", "url": "https://news.example.org/articles/sample", "match": False, "score": 0.73, @@ -2664,6 +2948,38 @@ def test_sessions_simulate() -> None: ) +def test_sessions_submit_kyb_parties() -> None: + """``POST /v3/session/{sessionId}/kyb/parties/submit/``""" + check_operation( + Expect( + method="POST", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/submit/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + json_body={"locale": "es"}, + status=200, + response_json={ + "valid": True, + "next_step": "FINISHED", + "status": "In Progress", + "advanced": True, + "already_submitted": False, + "kyb_key_people_status": "In Progress", + "parties": [], + }, + ), + lambda c: c.sessions.submit_kyb_parties( + "33333333-4444-5555-6666-777777777777", locale="es", node_id="sample" + ), + lambda c: c.sessions.submit_kyb_parties( + "33333333-4444-5555-6666-777777777777", locale="es", node_id="sample" + ), + lambda r: isinstance(r, SessionsSubmitKybPartiesResponse), + lambda r: isinstance(r, SessionsSubmitKybPartiesResponse), + ) + + def test_sessions_update_aml_hit_status() -> None: """``PATCH /v3/session/{sessionId}/update-aml-hit-status/``""" check_operation( @@ -2673,24 +2989,24 @@ def test_sessions_update_aml_hit_status() -> None: api="verification", auth="api_key", query={"node_id": ["feature_aml_1"]}, - json_body={"hit_id": "abc123", "review_status": "Unreviewed"}, + json_body={"hit_id": "hit_7c1e9a40b2d35f86e0a4c912", "review_status": "False Positive"}, status=200, response_json={ "message": "Hit status updated successfully", - "hit_id": "abc123", + "hit_id": "hit_7c1e9a40b2d35f86e0a4c912", "review_status": "False Positive", }, ), lambda c: c.sessions.update_aml_hit_status( "11111111-2222-3333-4444-555555555555", - hit_id="abc123", - review_status="Unreviewed", + hit_id="hit_7c1e9a40b2d35f86e0a4c912", + review_status="False Positive", node_id_query="feature_aml_1", ), lambda c: c.sessions.update_aml_hit_status( "11111111-2222-3333-4444-555555555555", - hit_id="abc123", - review_status="Unreviewed", + hit_id="hit_7c1e9a40b2d35f86e0a4c912", + review_status="False Positive", node_id_query="feature_aml_1", ), lambda r: isinstance(r, SessionsUpdateAmlHitStatusResponse), @@ -3067,6 +3383,50 @@ def test_sessions_update_kyb_party() -> None: ) +def test_sessions_update_kyb_party_draft() -> None: + """``PATCH /v3/session/{sessionId}/kyb/parties/drafts/{draftId}/``""" + check_operation( + Expect( + method="PATCH", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/drafts/5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + json_body={"ownership_percent": 55}, + status=200, + response_json={ + "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + "created_at": "2026-10-31T10:00:00Z", + "updated_at": "2026-10-31T10:00:00Z", + "party": { + "entity_type": "person", + "first_name": "Ana", + "last_name": "Lopez", + "roles": ["ubo", "director"], + "ownership_percent": 55, + "nationality": "MEX", + "email": "ana.lopez@example.com", + "date_of_birth": "1984-06-12", + }, + }, + ), + lambda c: c.sessions.update_kyb_party_draft( + "33333333-4444-5555-6666-777777777777", + "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + ownership_percent=55, + node_id="sample", + ), + lambda c: c.sessions.update_kyb_party_draft( + "33333333-4444-5555-6666-777777777777", + "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d", + ownership_percent=55, + node_id="sample", + ), + lambda r: isinstance(r, SessionsUpdateKybPartyDraftResponse), + lambda r: isinstance(r, SessionsUpdateKybPartyDraftResponse), + ) + + def test_sessions_update_poa_data() -> None: """``PATCH /v3/session/{sessionId}/update-poa-data/``""" check_operation( @@ -3196,6 +3556,35 @@ def test_sessions_update_status() -> None: ) +def test_sessions_upload_kyb_documents() -> None: + """``POST /v3/session/{sessionId}/kyb/documents/``""" + check_operation( + Expect( + method="POST", + path="/v3/session/33333333-4444-5555-6666-777777777777/kyb/documents/", + api="verification", + auth="api_key", + query={"node_id": ["sample"]}, + multipart_fields=[], + multipart_files=["documents"], + status=200, + response_json={ + "valid": True, + "next_step": "KYB_KEY_PEOPLE", + "kyb_status": "In Progress", + }, + ), + lambda c: c.sessions.upload_kyb_documents( + "33333333-4444-5555-6666-777777777777", documents=b"file-content", node_id="sample" + ), + lambda c: c.sessions.upload_kyb_documents( + "33333333-4444-5555-6666-777777777777", documents=b"file-content", node_id="sample" + ), + lambda r: isinstance(r, SessionsUploadKybDocumentsResponse), + lambda r: isinstance(r, SessionsUploadKybDocumentsResponse), + ) + + def test_sessions_imports_cancel() -> None: """``POST /v3/session/imports/{importId}/cancel/``""" check_operation( @@ -3261,16 +3650,21 @@ def test_sessions_imports_check_provider() -> None: path="/v3/session/imports/providers/check/", api="verification", auth="api_key", - json_body={"provider": "sumsub", "credentials": {"key": "sample"}}, + json_body={ + "provider": "sumsub", + "credentials": {"app_token": "sample-token", "secret_key": "sample-secret"}, + }, status=200, response_json={"ok": True, "provider": "sample", "credential_hint": "sample-secret"}, strict_type=SessionsImportsCheckProviderResponse, ), lambda c: c.sessions.imports.check_provider( - provider="sumsub", credentials={"key": "sample"} + provider="sumsub", + credentials={"app_token": "sample-token", "secret_key": "sample-secret"}, ), lambda c: c.sessions.imports.check_provider( - provider="sumsub", credentials={"key": "sample"} + provider="sumsub", + credentials={"app_token": "sample-token", "secret_key": "sample-secret"}, ), lambda r: isinstance(r, SessionsImportsCheckProviderResponse), lambda r: isinstance(r, SessionsImportsCheckProviderResponse), @@ -3770,10 +4164,12 @@ def test_sessions_imports_retry() -> None: strict_type=SessionImportJob, ), lambda c: c.sessions.imports.retry( - "00000000-0000-4000-8000-000000000001", credentials={"key": "sample"} + "00000000-0000-4000-8000-000000000001", + credentials={"app_token": "sample-token", "secret_key": "sample-secret"}, ), lambda c: c.sessions.imports.retry( - "00000000-0000-4000-8000-000000000001", credentials={"key": "sample"} + "00000000-0000-4000-8000-000000000001", + credentials={"app_token": "sample-token", "secret_key": "sample-secret"}, ), lambda r: isinstance(r, SessionImportJob), lambda r: isinstance(r, SessionImportJob), @@ -4053,8 +4449,8 @@ def test_sessions_signatures_validate() -> None: "node_id": "sample", "status": "intro", "verdict": "Not Finished", - "level": "aes", - "format": "pades", + "level": "simple", + "format": "pdf", "profile": "sample", "signer": { "name": "sample", diff --git a/tests/generated/test_transactions.py b/tests/generated/test_transactions.py index e0dd89f..c7e3f3a 100644 --- a/tests/generated/test_transactions.py +++ b/tests/generated/test_transactions.py @@ -249,7 +249,12 @@ def test_transactions_list() -> None: path="/v3/transactions/", api="verification", auth="api_key", - query={"limit": ["1"], "offset": ["1"], "travel_rule_status": ["sample"]}, + query={ + "limit": ["1"], + "offset": ["1"], + "travel_rule_status": ["sample"], + "assignee": ["sample"], + }, status=200, response_json={ "count": 1, @@ -298,8 +303,12 @@ def test_transactions_list() -> None: ], }, ), - lambda c: c.transactions.list(limit=1, offset=1, travel_rule_status="sample"), - lambda c: c.transactions.list(limit=1, offset=1, travel_rule_status="sample"), + lambda c: c.transactions.list( + limit=1, offset=1, travel_rule_status="sample", assignee="sample" + ), + lambda c: c.transactions.list( + limit=1, offset=1, travel_rule_status="sample", assignee="sample" + ), lambda r: ( isinstance(r, SyncPage) and all(isinstance(x1, TransactionsListResponseResults) for x1 in r.results) diff --git a/tests/generated/test_travel_rule.py b/tests/generated/test_travel_rule.py index 4a90ccf..ecb709b 100644 --- a/tests/generated/test_travel_rule.py +++ b/tests/generated/test_travel_rule.py @@ -21,6 +21,7 @@ TravelRuleCounterpartyScreeningStatus, ) from didit.types.components.travel_rule_inbound_response import TravelRuleInboundResponse +from didit.types.components.travel_rule_manual_match_response import TravelRuleManualMatchResponse from didit.types.components.travel_rule_network_participant import TravelRuleNetworkParticipant from didit.types.components.travel_rule_network_questionnaire import TravelRuleNetworkQuestionnaire from didit.types.components.travel_rule_networks_overview import TravelRuleNetworksOverview @@ -1475,7 +1476,11 @@ def test_travel_rule_networks_update_questionnaire() -> None: path="/v3/travel-rule/networks/questionnaire/", api="verification", auth="api_key", - json_body={"legal_name": "sample"}, + json_body={ + "legal_name": "Example VASP Ltd", + "incorporation_country": "ES", + "aml_ctf_policy_attested": True, + }, status=200, response_json={ "status": "draft", @@ -1520,8 +1525,12 @@ def test_travel_rule_networks_update_questionnaire() -> None: }, strict_type=TravelRuleNetworkQuestionnaire, ), - lambda c: c.travel_rule.networks.update_questionnaire(legal_name="sample"), - lambda c: c.travel_rule.networks.update_questionnaire(legal_name="sample"), + lambda c: c.travel_rule.networks.update_questionnaire( + legal_name="Example VASP Ltd", incorporation_country="ES", aml_ctf_policy_attested=True + ), + lambda c: c.travel_rule.networks.update_questionnaire( + legal_name="Example VASP Ltd", incorporation_country="ES", aml_ctf_policy_attested=True + ), lambda r: isinstance(r, TravelRuleNetworkQuestionnaire), lambda r: isinstance(r, TravelRuleNetworkQuestionnaire), ) @@ -1614,6 +1623,165 @@ def test_travel_rule_transfers_list() -> None: ) +def test_travel_rule_unmatched_deposits_list() -> None: + """``GET /v3/travel-rule/unmatched/``""" + check_operation( + Expect( + method="GET", + path="/v3/travel-rule/unmatched/", + api="verification", + auth="api_key", + query={ + "direction": ["sample"], + "status": ["sample"], + "rail": ["sample"], + "kind": ["sample"], + "currency": ["sample"], + "start_date": ["2026-01-01"], + "end_date": ["2026-01-01"], + "counterparty": ["00000000-0000-4000-8000-000000000001"], + "limit": ["1"], + "offset": ["1"], + }, + status=200, + response_json={ + "count": 1, + "next": None, + "previous": None, + "results": [ + { + "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08", + "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91", + "txn_id": "dep-2026-10-20-0007", + "txn_date": "2026-10-19T08:41:12Z", + "kind": "deposit", + "direction": "INBOUND", + "status": "AWAITING_COUNTERPARTY", + "rail": "TRP", + "asset": "ETH", + "amount": "1.25", + "originator_vasp": "", + "beneficiary_vasp": "Example Counterparty VASP", + "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7", + "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", + "originator_memo": "", + "beneficiary_memo": "", + "originator_wallet_type": "vasp", + "beneficiary_wallet_type": "vasp", + "matched_transaction_id": None, + "deadline_at": None, + "created_at": "2026-10-19T08:41:13Z", + } + ], + }, + ), + lambda c: c.travel_rule.unmatched_deposits.list( + direction="sample", + status="sample", + rail="sample", + kind="sample", + currency="sample", + start_date="2026-01-01", + end_date="2026-01-01", + counterparty="00000000-0000-4000-8000-000000000001", + limit=1, + offset=1, + ), + lambda c: c.travel_rule.unmatched_deposits.list( + direction="sample", + status="sample", + rail="sample", + kind="sample", + currency="sample", + start_date="2026-01-01", + end_date="2026-01-01", + counterparty="00000000-0000-4000-8000-000000000001", + limit=1, + offset=1, + ), + lambda r: ( + isinstance(r, SyncPage) + and all(isinstance(x1, TravelRuleTransferRow) for x1 in r.results) + ), + lambda r: ( + isinstance(r, AsyncPage) + and all(isinstance(x1, TravelRuleTransferRow) for x1 in r.results) + ), + ) + + +def test_travel_rule_unmatched_deposits_match() -> None: + """``POST /v3/travel-rule/unmatched/{transaction_uuid}/match/``""" + check_operation( + Expect( + method="POST", + path="/v3/travel-rule/unmatched/00000000-0000-4000-8000-000000000001/match/", + api="verification", + auth="api_key", + json_body={"transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24"}, + status=200, + response_json={ + "deposit": { + "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08", + "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91", + "txn_id": "dep-2026-10-20-0007", + "txn_date": "2026-10-19T08:41:12Z", + "kind": "deposit", + "direction": "INBOUND", + "status": "AWAITING_COUNTERPARTY", + "rail": "TRP", + "asset": "ETH", + "amount": "1.25", + "originator_vasp": "Example Counterparty VASP", + "beneficiary_vasp": "Example Counterparty VASP", + "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7", + "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", + "originator_memo": "", + "beneficiary_memo": "", + "originator_wallet_type": "vasp", + "beneficiary_wallet_type": "vasp", + "matched_transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24", + "deadline_at": None, + "created_at": "2026-10-19T08:41:13Z", + }, + "message": { + "id": "2b8e6f10-9c3a-47d1-b5e2-0a4c7d9f3e66", + "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24", + "txn_id": "msg-2026-10-20-0003", + "txn_date": "2026-10-19T08:41:12Z", + "kind": "message", + "direction": "INBOUND", + "status": "COMPLETED", + "rail": "TRP", + "asset": "ETH", + "amount": "1.25", + "originator_vasp": "Origin CASP SL", + "beneficiary_vasp": "Example Counterparty VASP", + "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7", + "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb", + "originator_memo": "", + "beneficiary_memo": "", + "originator_wallet_type": "vasp", + "beneficiary_wallet_type": "vasp", + "matched_transaction_id": None, + "deadline_at": "2026-10-21T08:41:13Z", + "created_at": "2026-10-19T08:41:13Z", + }, + }, + ), + lambda c: c.travel_rule.unmatched_deposits.match( + "00000000-0000-4000-8000-000000000001", + transaction_id="e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24", + ), + lambda c: c.travel_rule.unmatched_deposits.match( + "00000000-0000-4000-8000-000000000001", + transaction_id="e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24", + ), + lambda r: isinstance(r, TravelRuleManualMatchResponse), + lambda r: isinstance(r, TravelRuleManualMatchResponse), + ) + + def test_travel_rule_wallet_addresses_bulk_import() -> None: """``POST /v3/travel-rule/wallet-addresses/import/``""" check_operation( @@ -1881,7 +2049,7 @@ def test_travel_rule_wallet_proofs_decide() -> None: path="/v3/travel-rule/wallet-proofs/00000000-0000-4000-8000-000000000001/decision/", api="verification", auth="api_key", - json_body={"decision": "approve"}, + json_body={"decision": "approve", "note": "Address matches the wallet app."}, status=200, response_json={ "proof_id": "00000000-0000-4000-8000-000000000003", @@ -1906,10 +2074,14 @@ def test_travel_rule_wallet_proofs_decide() -> None: strict_type=TravelRuleWalletProofReview, ), lambda c: c.travel_rule.wallet_proofs.decide( - "00000000-0000-4000-8000-000000000001", decision="approve" + "00000000-0000-4000-8000-000000000001", + decision="approve", + note="Address matches the wallet app.", ), lambda c: c.travel_rule.wallet_proofs.decide( - "00000000-0000-4000-8000-000000000001", decision="approve" + "00000000-0000-4000-8000-000000000001", + decision="approve", + note="Address matches the wallet app.", ), lambda r: isinstance(r, TravelRuleWalletProofReview), lambda r: isinstance(r, TravelRuleWalletProofReview), diff --git a/tests/generated/test_users.py b/tests/generated/test_users.py index 9831f88..288b8bc 100644 --- a/tests/generated/test_users.py +++ b/tests/generated/test_users.py @@ -432,7 +432,10 @@ def test_users_set_ongoing_monitoring() -> None: path="/v3/organization/0b5e8d2c-0000-4000-8000-0000000000aa/application/0b5e8d2c-0000-4000-8000-0000000000bb/vendor-users/toggle-ongoing-monitoring/", api="verification", auth="api_key", - json_body={"is_enabled": True}, + json_body={ + "is_enabled": True, + "didit_internal_id_list": ["5b9a0000-0000-4000-8000-00000000f00d"], + }, status=200, response_json={ "users_total": 1, @@ -446,8 +449,12 @@ def test_users_set_ongoing_monitoring() -> None: "balance_sufficient": True, }, ), - lambda c: c.users.set_ongoing_monitoring(is_enabled=True), - lambda c: c.users.set_ongoing_monitoring(is_enabled=True), + lambda c: c.users.set_ongoing_monitoring( + is_enabled=True, didit_internal_id_list=["5b9a0000-0000-4000-8000-00000000f00d"] + ), + lambda c: c.users.set_ongoing_monitoring( + is_enabled=True, didit_internal_id_list=["5b9a0000-0000-4000-8000-00000000f00d"] + ), lambda r: ( ( (isinstance(r, OngoingMonitoringToggleResultVariant1)) diff --git a/tests/generated/test_wallet_screening.py b/tests/generated/test_wallet_screening.py index 737165f..2d6c3a5 100644 --- a/tests/generated/test_wallet_screening.py +++ b/tests/generated/test_wallet_screening.py @@ -17,7 +17,7 @@ def test_wallet_screening_screen() -> None: auth="api_key", json_body={ "wallet_address": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a", - "blockchain": "BTC", + "blockchain": "ETH", }, status=200, response_json={ @@ -191,10 +191,10 @@ def test_wallet_screening_screen() -> None: }, ), lambda c: c.wallet_screening.screen( - wallet_address="0x94f1b9b64e2932f6a2db338f616844400cd58e8a", blockchain="BTC" + wallet_address="0x94f1b9b64e2932f6a2db338f616844400cd58e8a", blockchain="ETH" ), lambda c: c.wallet_screening.screen( - wallet_address="0x94f1b9b64e2932f6a2db338f616844400cd58e8a", blockchain="BTC" + wallet_address="0x94f1b9b64e2932f6a2db338f616844400cd58e8a", blockchain="ETH" ), lambda r: isinstance(r, WalletScreeningResult), lambda r: isinstance(r, WalletScreeningResult), diff --git a/tests/generated/test_workflows.py b/tests/generated/test_workflows.py index 69d41ad..7baa091 100644 --- a/tests/generated/test_workflows.py +++ b/tests/generated/test_workflows.py @@ -292,6 +292,7 @@ def test_workflows_update() -> None: "kyb_role_settings": [{}], "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z", + "signature_availability": {"simple": True, "aes": True, "qes": True}, "is_bank_verification_enabled": True, "bank_verification_config": {}, "is_geolocation_enabled": True,