@dossier-wiki/cloud-sdk (英语)
Dossiers API的官方TypeScript SDK版本.
包括AML筛选,KYC会话管理,AI动力文件处理, 窗体模板,以及 Webhook 校验 —— 全部都有 TypeScript 类型和 可选 Zod 运行时验证 .
目录
- 安装
- 快速启动
- 从平地 API (v0.1) 迁移
- 认证
- App Info, API 版本和合同通知
- 处理错误
- AML 筛选
- KYC 会话
- KYC 工作流程
- 文件处理
- 窗体模板
- 媒体
- 网络呼号
- 类型脚本
安装
bun add @dossier-wiki/cloud-sdk
测试了Bun. 它只使用一个全球 fetch 财务报告和审定财务报表 crypto.subtle,所以这也
运行在Node.js 18+和其他提供它们的运行时间上.
快速启动
import { DossiersAPIService } from '@dossier-wiki/cloud-sdk';
const service = new DossiersAPIService({
apiKey: process.env.DOSSIERS_API_KEY!,
});
// AML — search sanctions
const { totalHits, documents } = await service.aml.searchSanctions({
fullName: 'John Doe',
});
// KYC — create a session
const { sessionUrl } = await service.kyc.sessions.create({
customer: { name: 'Alice Brown', email: '[email protected]' },
workflowId: 'wf_abc123',
});
// Document processing
const instance = await service.documents.initiate({
processorId: 'INVOICE',
files: [{ url: 'https://example.com/invoice.pdf', mimeType: 'application/pdf' }],
});
从平地 API (v0.1) 迁移
0.1版本直接将每个操作作为服务上的方法曝光
(单位:千美元)service.searchSanctions(), (中文(简体) ), service.createKycSession()(中文(简体) ). 那个高层
表面长得太大,无法导航,所以现在将操作归为资源
名称空间.
老式的平面方法还有效 它们是薄薄而腐烂的包装 转发到新的资源方法,因此现有的代码运行不变. 您的编辑将显示它们被击中; 以自己的速度迁移。 他们会的 在未来的主要版本中删除.
| 折旧平方法 | 改为使用 |
|---|---|
service.searchSanctions(input) | service.aml.searchSanctions(input) |
service.searchDossiers(input) | service.aml.searchDossiers(input) |
service.createScreeningRequest(input) | service.aml.createScreeningRequest(input) |
service.createKycSession(input) | service.kyc.sessions.create(input) |
service.listKycSessions(filters?) | service.kyc.sessions.list(filters?) |
service.getKycSession(id) | service.kyc.sessions.get(id) |
service.deleteKycSession(id) | service.kyc.sessions.delete(id) |
service.initiateDocumentProcessing(input) | service.documents.initiate(input) |
service.listDocumentProcessingInstances(query?) | service.documents.list(query?) |
service.listDocumentProcessors() | service.documents.listProcessors() |
service.getDocumentProcessingInstance(id) | service.documents.get(id) |
service.getDocumentProcessingStage(id, stageId) | service.documents.getStage(id, stageId) |
service.deleteDocumentProcessingInstance(id) | service.documents.delete(id) |
service.streamDocumentProcessingEvents(id, init?) | service.documents.stream(id, init?) |
V0.1——KYC工作流程以来增加的新能力(service.kyc.workflows, (中文(简体) ),
窗体模板( e)service.formTemplates),媒体访问service.media),以及
KYC会话 Webhook 活动 - 仅在资源 API 上提供.
认证
所有请求都以您的 API 密钥认证为 Bearer 符号 。 准备 一次在服务实例中——从不将其包括在客户端代码中.
const service = new DossiersAPIService({
apiKey: process.env.DOSSIERS_API_KEY!,
// Optional: override the base URL (e.g. for local development)
baseUrl: 'http://localhost:4000',
// Optional: inject a custom fetch (useful for testing or proxying)
fetch: myCustomFetch,
});
App Info, API 版本和合同通知
每个请求都带有 云 API 版本 这个SDK建筑说话——一个日期
合同,导出为 DOSSIERS_API_VERSION (单位:千美元)2026-10-01()——在
Dossiers-Api-Version 头曰. API只会改变行为
版本;在一个版本中,更改是添加剂,所以忽略响应字段
不知所终.
告诉多赛尔斯 打电话的是什么 appInfo。它记录在 API 密钥上
(shown in the Developers Console) 并且从未改变 API 的行为:
const service = new DossiersAPIService({
apiKey: process.env.DOSSIERS_API_KEY!,
appInfo: {
name: 'dossiers-os',
version: '1.5.0',
commit: process.env.GIT_SHA, // optional, first 8 chars are sent
installationId: process.env.INSTALL_ID, // optional, sent as Dossiers-Installation-Id
},
// Called when the API says this SDK's API version is deprecated, has a
// sunset date, or is no longer accepted (426).
onContractNotice: (notice) => {
// { apiVersion, status, deprecation?, sunset?, link?, message?, minimumApiVersion? }
logger.warn('Dossiers API contract notice', notice);
},
});
然后,请求载有:
User-Agent: dossiers-os/1.5.0 (17bbc509) cloud-sdk/0.8.0 bun/1.3.14
Dossiers-Api-Version: 2026-10-01
Dossiers-Installation-Id: 6f1c…
User-Agent 从未在浏览器中设置( 他们禁止它) ; 其他头总是
对.
给API打电话 fetch 直接吗? 使用相同的帮助 :
import { buildDossiersRequestHeaders, readContractNotice } from '@dossier-wiki/cloud-sdk';
const res = await fetch(url, {
headers: { ...buildDossiersRequestHeaders(appInfo), Authorization: `Bearer ${key}` },
});
const notice = readContractNotice(res); // null unless Deprecation/Sunset or 426
CLOUD_SDK_VERSION 输出 SDK 自己的版本 .
处理错误
所有 SDK 方法丢出一个 DossiersAPIError 关于非-2xx的答复.
import { DossiersAPIService, DossiersAPIError } from '@dossier-wiki/cloud-sdk';
try {
const session = await service.kyc.sessions.get('ses_nonexistent');
} catch (err) {
if (err instanceof DossiersAPIError) {
console.error(err.status); // e.g. 404
console.error(err.message); // human-readable message from the API
console.error(err.body); // raw parsed response body
}
}
A 类 426 Upgrade Required ——API不再接受这个SDK的API版本
掷出 DossiersUpgradeRequiredError 联合国 DossiersAPIError 子类)
minimumApiVersion将SDK升级为能说话的版本.
AML 筛选
制裁搜索
搜索全球制裁清单(FOAC、联合国、FCDO、DFAT、CASL、国际刑警组织) 个人或实体.
const results = await service.aml.searchSanctions({
fullName: 'Jane Smith',
// Optional: narrow to specific lists
sources: ['ofac', 'un'],
// Optional: filter by country
countries: ['US', 'GB'],
// Optional: match against document numbers
idNumbers: ['P123456789'],
});
console.log(results.totalHits);
for (const sanction of results.documents) {
console.log(sanction.name, sanction.source, sanction.sanctionsProgramme);
}
PEP 不良媒体( 剂量)
搜索PEP登记和不良媒体数据库。 归还个人档案 有风险分数 职位和同伙.
const dossiers = await service.aml.searchDossiers({
fullName: 'Robert Jones',
onlyShowHighRiskProfiles: true,
noCache: false, // use cached results (default)
});
for (const dossier of dossiers) {
const score = dossier.riskScorecard?.overallRiskScore ?? 0;
console.log(dossier.fullName, score, dossier.riskScorecard?.riskCategory);
}
持续筛选请求
对个人进行持续监测。 Webhook 事件于 筛选完成或启动新的警报.
const { requestId } = await service.aml.createScreeningRequest({
fullName: 'Alice Brown',
externalId: 'cust_123', // your internal reference ID
dateOfBirth: '1985-06-15',
country: 'GB',
identificationDocument: {
type: 'passport',
number: 'AB123456',
country: 'GB',
},
});
KYC 会话
KYC会话是单一的客户验证行程. 客户收到
链接( e)sessionUrl他们访问完成已配置的工作流程步骤.
// Create a session
const { session, sessionUrl, token } = await service.kyc.sessions.create({
customer: {
name: 'Nimal Perera',
email: '[email protected]',
externalId: 'cust_001', // your internal reference
},
workflowId: 'wf_standard_kyc',
expiresInMs: 86_400_000, // 24 hours (default: 1 hour)
});
// Send the sessionUrl to your customer
await sendInvitationEmail(session.customer.email, sessionUrl);
// List sessions
const { sessions, totalCount } = await service.kyc.sessions.list({
isComplete: true,
sortBy: 'completedAt',
sortOrder: 'desc',
limit: 50,
offset: 0,
});
// Get a specific session (includes full step history & media)
const fullSession = await service.kyc.sessions.get(session.id);
console.log(fullSession.status); // 'complete' | 'in-progress' | 'approved' | ...
// Delete a session
await service.kyc.sessions.delete(session.id);
KYC 工作流程
一个工作流程定义了客户在会话中要经过的顺序步骤 (例如身份核实 活性 ).
建立工作流程
使用 stepDefaults() 以获得每个步骤类型的预建配置,然后
把它们组装成一个工作流程.
import type { WorkflowRules } from '@dossier-wiki/cloud-sdk';
// Fetch defaults for all step types
const defaults = await service.kyc.workflows.stepDefaults();
const idStep = defaults.find(d => d.type === 'id_verification')!;
const livenessStep = defaults.find(d => d.type === 'liveness')!;
// Create the workflow
const workflow = await service.kyc.workflows.create({
name: 'Standard KYC',
description: 'Identity check + liveness verification',
steps: [
{
stepId: idStep.defaultStepId,
type: 'id_verification',
input: idStep.defaultInput as { config?: Record<string, unknown> },
output: { schema: idStep.schema },
rules: idStep.defaultRules as WorkflowRules,
locales: idStep.defaultLocales,
skippable: idStep.skippable,
},
{
stepId: livenessStep.defaultStepId,
type: 'liveness',
input: livenessStep.defaultInput as { config?: Record<string, unknown> },
output: { schema: livenessStep.schema },
rules: livenessStep.defaultRules as WorkflowRules,
locales: livenessStep.defaultLocales,
skippable: livenessStep.skippable,
},
],
});
// Use the workflow when creating sessions
const { sessionUrl } = await service.kyc.sessions.create({
customer: { name: 'Bob Lee' },
workflowId: workflow.id,
});
Zod 验证
SDK出口了Zod计划 用于歧视工会,所以你可以 在运行时验证工作流程输入,然后发送到API.
import { schemas } from '@dossier-wiki/cloud-sdk';
// Validates the full workflow creation input including per-step type constraints
const validated = schemas.CreateWorkflowSchema.parse(rawInput);
const workflow = await service.kyc.workflows.create(validated);
// Validate a single step
const step = schemas.WorkflowStepSchema.parse({
stepId: 'step_liveness',
type: 'liveness',
input: { config: { challengeType: 'selfie', timeLimitSeconds: 30 } },
output: {},
rules: { onSuccess: 'COMPLETE_SESSION', onFailure: 'FAIL_SESSION' },
});
可用的步骤类型及其配置限制 :
| 类型 | 配置字段 |
|---|---|
id_verification | strategy, (中文(简体) ), allowedDocuments, (中文(简体) ), maxSubmissions, (中文(简体) ), allowUpload |
document_collection | allowedDocuments, (中文(简体) ), allowUpload, (中文(简体) ), maxSubmissions |
liveness | challengeType, (中文(简体) ), timeLimitSeconds, (中文(简体) ), minFaceLuminance, (中文(简体) ), minFaceDetectionConfidence |
form_collection | templateId, (中文(简体) ), fields |
esignature | signatureTypesAllowed |
action | actionType |
其他工作流程操作:
// List all workflows
const workflows = await service.kyc.workflows.list();
// Get a specific workflow
const wf = await service.kyc.workflows.get('wf_abc123');
// Update (creates a new version; existing sessions are unaffected)
const updated = await service.kyc.workflows.update('wf_abc123', {
name: 'Standard KYC v2',
});
// Delete
await service.kyc.workflows.delete('wf_old123');
文件处理
在上传文档上启动 AI 提取任务 。 管道验证 文档,提取结构化数据,并进行处理后检查.
可用的处理器ID :
processorId | 文档 |
|---|---|
INVOICE | 发票/账单 |
SRI_LANKA_ID | 斯里兰卡国民身份证 |
SRI_LANKA_FORM1_COMPANY_REGISTRATION | 公司登记表1 |
SRI_LANKA_FORM15_ANNUAL_RETURN | 年度返回表15 |
启动任务
const instance = await service.documents.initiate({
processorId: 'INVOICE',
files: [
{ url: 'https://example.com/invoice.pdf', mimeType: 'application/pdf' },
],
// Optional: arbitrary metadata stored on the instance
metadata: { orderId: 'ord_456' },
// Default: true — runs asynchronously; false waits for completion
backgroundProcessing: true,
});
console.log(instance.instanceId); // use this to poll or stream
争取结果榜
let instance = await service.documents.get(instanceId);
while (instance.status === 'pending' || instance.status === 'running') {
await new Promise(r => setTimeout(r, 2000));
instance = await service.documents.get(instanceId);
}
if (instance.status === 'completed') {
console.log(instance.result?.validation.passed);
console.log(instance.result?.normalizedData);
}
实时进度( SSE)
const res = await service.documents.stream(instanceId);
const reader = res.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
// Each SSE line is a DocumentProcessingEvent JSON payload
console.log(text);
}
已打入
使用通用参数键入 result.schema 字段:
import type {
DocumentProcessingExtractedField,
DocumentProcessingTransliteratedField,
} from '@dossier-wiki/cloud-sdk';
type SriLankaIdSchema = {
name: DocumentProcessingTransliteratedField;
idNumber: DocumentProcessingExtractedField<string>;
dateOfBirth: DocumentProcessingExtractedField<string>;
address: DocumentProcessingTransliteratedField;
gender: DocumentProcessingExtractedField<string>;
};
const instance = await service.documents.initiate<SriLankaIdSchema>({
processorId: 'SRI_LANKA_ID',
files: [{ base64Data: '...', mimeType: 'image/jpeg' }],
});
// result.schema is now typed as SriLankaIdSchema
const name = instance.result?.schema.name.enTransliterations[0].transliteratedText;
其他文件处理操作:
// List instances
const { instances, count } = await service.documents.list({
processorId: 'INVOICE',
status: 'completed',
limit: 20,
});
// Get a specific stage result
const stage = await service.documents.getStage(instanceId, 'post_validation');
console.log(stage.data.validation.passed);
// List available processors
const processors = await service.documents.listProcessors();
// Delete an instance
await service.documents.delete(instanceId);
窗体模板
格式模板定义可重复使用的一组字段 form_collection 韩国
工作流程步骤.
// Create a template
const template = await service.formTemplates.create({
name: 'Employment Details',
fields: [
{
id: 'employer',
type: 'text',
label: 'Employer Name',
required: true,
},
{
id: 'salary',
type: 'currency',
label: 'Annual Salary (LKR)',
required: true,
validation: { min: 0 },
},
{
id: 'employment_type',
type: 'select',
label: 'Employment Type',
required: true,
options: [
{ value: 'full_time', label: 'Full Time' },
{ value: 'part_time', label: 'Part Time' },
{ value: 'self_employed', label: 'Self Employed' },
],
},
],
});
// Reference the template in a form_collection step config
const workflowStep = {
type: 'form_collection' as const,
input: { config: { templateId: template.id } },
// ...
};
// List, get, update, delete
const { templates } = await service.formTemplates.list({ searchQuery: 'employment' });
const full = await service.formTemplates.get(template.id);
await service.formTemplates.update(template.id, { name: 'Employment Details v2' });
await service.formTemplates.delete(template.id);
可用的字段类型 : text, (中文(简体) ), long_text, (中文(简体) ), number, (中文(简体) ), currency, (中文(简体) ), country, (中文(简体) ),
language, (中文(简体) ), email, (中文(简体) ), phone, (中文(简体) ), date, (中文(简体) ), select, (中文(简体) ), multi_select, (中文(简体) ), dropdown, (中文(简体) ),
toggle, (中文(简体) ), boolean, (中文(简体) ), file, (中文(简体) ), heading, (中文(简体) ), paragraph, (中文(简体) ), description, (中文(简体) ), divider。 。 。 .
媒体
从会话结果获取二进制文件(图像、视频、 PDF 签名) 使用已签名的存储符处理文档.
// Tokens appear in session result media arrays and processing instance files
const token = session.result.steps[0].summary?.media[0]?.key;
if (token) {
const res = await service.media.get(token);
// Browser — convert to object URL for display
const blob = await res.blob();
const objectUrl = URL.createObjectURL(blob);
imageElement.src = objectUrl;
// Node.js — pipe to disk
const { createWriteStream } = await import('fs');
const { Readable } = await import('stream');
Readable.fromWeb(res.body!).pipe(createWriteStream('./capture.jpg'));
}
网络呼号
使用 DossiersWebhookRouter 以 HMAC-SHA256 处理即将到来的 Webhook 事件
签名验证.
import { DossiersWebhookRouter, DossiersWebhookEventTypes } from '@dossier-wiki/cloud-sdk';
const router = new DossiersWebhookRouter(process.env.DOSSIERS_WEBHOOK_SECRET!);
router
.on(DossiersWebhookEventTypes.DOCUMENT_VERIFICATION_INSTANCE_COMPLETED, async (event, ctx) => {
const { documentProcessorInstanceId } = event.data;
const instance = await service.documents.get(documentProcessorInstanceId);
await saveResult(instance);
})
.on(DossiersWebhookEventTypes.KYC_SESSION_COMPLETED, async (event, ctx) => {
// Payloads carry no PII — fetch the full session on demand.
const { kycSessionId, outcome } = event.data;
const session = await service.kyc.sessions.get(kycSessionId);
await recordVerification(session, outcome); // outcome: 'complete' | 'failed'
})
.on(DossiersWebhookEventTypes.AML_SCREENING_ALERT_TRIGGERED, async (event, ctx) => {
console.log('Alert triggered for screening request', event.data);
});
// Express
app.post('/webhooks/dossiers', async (req, res) => {
// Reconstruct a Web API Request from the Express request
const body = await getRawBody(req);
const webReq = new Request('https://your-server/webhooks/dossiers', {
method: 'POST',
headers: req.headers as HeadersInit,
body,
});
const response = await router.handle(webReq);
res.status(response.status).send(await response.text());
});
// Next.js App Router
export async function POST(req: Request) {
return router.handle(req, { waitUntil: (p) => context.waitUntil(p) });
}
在操作员运行前 慢处理器不会导致平台重试 。 如果你的操作员扔, 已记录错误,但没有重试。 在内部执行您自己的重试逻辑 如果需要,则由处理者处理.
SDK 架构中的事件类型并不知道 —— Dossiers 添加时没有新的 API 版本——与你登记的事件一样,有200个被承认和被忽略 没有处理者.
每一次交付给处理器的事件都有形状:
{
id: string; // e.g. "evt_1712345678_ab12cd34"
type: DossiersWebhookEventTypes;
organizationId: string;
apiVersion: string; // the destination's Cloud API version, e.g. "2026-10-01"
eventTriggeredAt: string; // ISO 8601
data: /* typed per event — see below */;
}
登记目的地
service.webhooks.destinations.upsert() 创建URL的目的地,或
更新现有的一个——每开始一次都安全。 它需要一个 API 密钥
与 网络呼号 权限( e)WEBHOOKS_MANAGE没有它,电话扔
(单位:千美元) DossiersAPIError 状态403.
const { id, secret, created } = await service.webhooks.destinations.upsert({
url: 'https://your-app.example.com/webhooks/dossiers',
events: [
DossiersWebhookEventTypes.KYC_SESSION_COMPLETED,
DossiersWebhookEventTypes.KYC_SESSION_REVIEWED,
],
name: 'My app', // optional; defaults to the URL's host
// apiVersion defaults to DOSSIERS_API_VERSION, and installationId to the
// Dossiers-Installation-Id header the SDK sends from appInfo.
});
const router = new DossiersWebhookRouter(secret);
签名密钥在创建时生成并保存( 并再次返回)
更新。 你留下的字段是原样的 目的地已禁用
在开发者控制台中保持禁用( E)isActive: false) (中文(简体) ).
这个 data 字段由事件完全输入 type 交给你 .on()导入
DossiersWebhookPayload 受歧视的结合所有事件形状.
可用事件类型
文件处理
| 数字 | 事件字符串 | data 类型 |
|---|---|---|
DOCUMENT_VERIFICATION_INSTANCE_CREATED | documentVerification.instance.created | DocumentVerificationInstanceCreatedData |
DOCUMENT_VERIFICATION_INSTANCE_UPDATED | documentVerification.instance.updated | DocumentVerificationInstanceUpdatedData |
DOCUMENT_VERIFICATION_INSTANCE_COMPLETED | documentVerification.instance.completed | DocumentVerificationInstanceCompletedData |
DOCUMENT_VERIFICATION_INSTANCE_DELETED | documentVerification.instance.deleted | DocumentVerificationInstanceDeletedData |
KYC 届会
| 数字 | 事件字符串 | data 类型 |
|---|---|---|
KYC_SESSION_CREATED | kycSessions.session.created | KycSessionEventData |
KYC_SESSION_UPDATED | kycSessions.session.updated | KycSessionEventData |
KYC_SESSION_COMPLETED | kycSessions.session.completed | KycSessionEventData (与 outcome(中文(简体) ) |
KYC_SESSION_REVIEWED | kycSessions.session.reviewed | KycSessionEventData (与 review(中文(简体) ) |
KYC_SESSION_DELETED | kycSessions.session.deleted | KycSessionDeletedData |
KYC_STEP_COMPLETED | kycSessions.step.completed | KycStepEventData |
KYC_STEP_FAILED | kycSessions.step.failed | KycStepEventData |
KYC_SESSION_COMMENT_ADDED | kycSessions.session.commentAdded | KycSessionCommentAddedData |
KYC_SESSION_COMMENT_UPDATED | kycSessions.session.commentUpdated | KycSessionCommentUpdatedData |
KYC_SESSION_COMMENT_DELETED | kycSessions.session.commentDeleted | KycSessionCommentDeletedData |
KYC 载荷 无 (没有客户名/电子邮件,没有分步输出)。 他们 参考文献a
kycSessionId- 获取你需要的细节service.kyc.sessions.get(kycSessionId)。 。 。 .
AML 筛选
| 数字 | 事件字符串 |
|---|---|
AML_SCREENING_REQUEST_CREATED | amlScreening.screeningRequest.created |
AML_SCREENING_REQUEST_COMPLETED | amlScreening.screeningRequest.completed |
AML_SCREENING_ALERT_TRIGGERED | amlScreening.screeningAlert.triggered |
AML_SCREENING_ALERT_STATUS_CHANGED | amlScreening.screeningAlert.statusChanged |
AML_SCREENING_ALERT_COMMENT_ADDED | amlScreening.screeningAlert.commentAdded |
AML_SCREENING_ALERT_COMMENT_UPDATED | amlScreening.screeningAlert.commentUpdated |
AML_SCREENING_ALERT_COMMENT_DELETED | amlScreening.screeningAlert.commentDeleted |
AML_SCREENING_ALERT_DELETED | amlScreening.screeningAlert.deleted |
系统
| 数字 | 事件字符串 |
|---|---|
SYSTEM_TEST_EVENT | system.testEvent |
SYSTEM_PRODUCT_ACCESS_GRANTED | system.product.accessGranted |
SYSTEM_PRODUCT_ACCESS_REVOKED | system.product.accessRevoked |
SYSTEM_API_KEY_CREATED | system.apiKey.created |
SYSTEM_API_KEY_INVALIDATED | system.apiKey.invalidated |
SYSTEM_USAGE_LIMIT_REACHED | system.usage.limitReached |
SYSTEM_USAGE_LIMIT_WARNING | system.usage.limitWarning |
类型脚本
所有API请求和响应形状被导出为TypeScript接口. 视需要导入:
import type {
// AML
SanctionSearchInput,
SanctionSearchResponse,
Sanction,
DossierSearchInput,
IndividualDossier,
CreateScreeningRequestDto,
// KYC Sessions
CreateKycSessionDTO,
KycSessionOutputDTO,
KycSessionFiltersDTO,
PaginatedKycSessionsDTO,
// KYC Workflows
CreateKycWorkflowInput,
KycWorkflow,
KycWorkflowStep,
KycWorkflowStepType,
WorkflowRules,
WorkflowStepDefault,
// Document Processing
InitiateDocumentProcessingInput,
DocumentProcessingInstance,
DocumentProcessingResult,
DocumentProcessingExtractedField,
DocumentProcessingTransliteratedField,
DocumentProcessorId,
// Form Templates
CreateFormTemplateInput,
FormTemplate,
FormField,
FormFieldType,
// Webhooks
DossiersWebhookPayload,
DossiersWebhookEvent,
UpsertWebhookDestinationInput,
UpsertWebhookDestinationResult,
// Client identity & API version contract
DossiersAppInfo,
DossiersContractNotice,
KycSessionEventData,
KycSessionDeletedData,
KycStepEventData,
KycSessionCommentAddedData,
KycSessionCommentUpdatedData,
KycSessionCommentDeletedData,
} from '@dossier-wiki/cloud-sdk';