跳转到主要内容

OpenAPI · REST 参考

REST primitives for every WIDTH OpenAPI call — request envelope, signing, errors, idempotency, configuration, and file upload. Workflow endpoints (KYC, KYB, transactions, monitoring) are documented in their own pages.

请求结构

所有 OpenAPI 调用使用相同的请求结构。接口名称、该接口适用的 API 版本、密钥和签名通过查询参数传递;请求正文使用 JSON。

POST {base_url}?api={apiName}&apiVersion={apiVersion}&apiKey={apiKey}&sign={sign}
Content-Type: application/json
x-domain: {domainId}

{
  ...request body...
}
ParameterWhereDescription
apiqueryAPI name, e.g. workflow.apply.submit
apiVersionquery按具体接口指定的版本。workflow.apply.submit 使用 2.0.0;请勿假设所有接口使用同一默认版本。
apiKeyqueryYour public key (prefixed ak_)
signqueryHMAC-SHA256 hex string of the body, keyed by apiSecret
x-domainheaderBusiness unit (domain) identifier

提交工作流

接口:workflow.apply.submit(POST)。用于启动当前已发布工作流的一次执行。使用 apiVersion=2.0.0 时,可选传入 workflowId,以明确指定要执行的已发布工作流。如果 workflowId 为空或未传入,WIDTH 将继续按照 eventType + source 自动路由请求。

API 版本行为

apiVersion行为
1.0.0按照 eventType + source 自动路由。
2.0.0包含 1.0.0 的全部行为,并支持可选的 workflowId,用于明确指定已发布工作流。如果 workflowId 为空或未传入,则其路由行为与 1.0.0 完全一致。推荐使用。

请求正文

{
  "eventType": "{eventType}",
  "source": "API",
  "data": {
    "customerId": "demo-customer-001"
  },
  "workflowId": "{publishedWorkflowId}"
}
字段类型必填说明
eventTypestring用于启动或路由工作流的事件类型。
sourcestring请求来源。服务端集成使用 API
dataobject工作流业务数据。请包含工作流入口事件所要求的字段。
workflowIdstring仅适用于 2.0.0。用于指定要执行的已发布工作流。如果为空或未传入,WIDTH 将按照 eventType + source 自动路由。
如何查找 Workflow ID: 在 WIDTH One Platform 中打开工作流页面。Workflow ID 会显示在工作流列表中、工作流名称旁边。复制该值,并在请求中作为 workflowId 传入。

响应格式

All responses share the same envelope:

{
  "apiCode": 200,
  "apiMsg": "OK",
  "data": { ... }
}

Errors use the same shape with a non-200 apiCode and a null data field:

{
  "apiCode": 999001,
  "apiMsg": "SIGN_ERROR",
  "data": null
}

Error codes

CodeMessageDescriptionAction
200OKSuccess
999000GATEWAY_ERRORGeneral gateway errorContact support
999001SIGN_ERRORSignature verification failedSee authentication
999301API_INVALID_REQUESTMalformed requestCheck request body
999302API_NOT_FOUNDAPI not foundVerify api parameter
999303API_NON_AUTHORIZEDUnauthorizedCheck tenant permissions
999401SERVICE_TIME_OUTBackend timeoutRetry with backoff
999402SERVICE_INVOKE_ERRORInvocation failedRetry or contact support

身份验证

Every request is signed with HMAC-SHA256 over the raw request body. The signature is sent as the sign query parameter.

sign = HmacSHA256(apiSecret, requestBody)

Both the key and body use UTF-8 encoding. The result is a 64-character lowercase hexadecimal string.

import hmac, hashlib

sign = hmac.new(
    api_secret.encode('utf-8'),
    request_body.encode('utf-8'),
    hashlib.sha256
).hexdigest()
const crypto = require('crypto');

const sign = crypto
  .createHmac('sha256', apiSecret)
  .update(requestBody, 'utf8')
  .digest('hex');
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(apiSecret.getBytes("UTF-8"), "HmacSHA256"));
byte[] hash = mac.doFinal(requestBody.getBytes("UTF-8"));
String sign = HexFormat.of().formatHex(hash);
Never expose apiSecret in client code. Signing must happen on a server you control. The SDKs use a session-scoped sdkToken instead.

幂等性

All node-data submission APIs are idempotent by callbackKey. Submitting the same callbackKey multiple times is safe — the workflow advances only once.

Use idempotency for safe retries on network failure or timeouts. Persist your callbackKey with the original request and reuse it on retry.

交互模式

客户端:链式流程

前端根据每次提交响应返回的 nextStep 对象推进。每个步骤会说明下一个节点及界面需要收集的数据。

服务端:状态查询

服务端对服务端的流程在自动处理期间应每 3–5 秒查询一次 workflow.execution.status。当 caseStatusUNASSIGNEDUNDER_REVIEWRETURNED 时,将间隔放宽至 30–60 秒。执行达到终止状态后停止。请参阅 KYC 状态与审核结果执行状态

Configuration

Endpoint: prepare.avira.config (POST). Returns reference data used by workflow nodes — country lists, document types, industry codes.

KeyDescriptionUsed by
particularPersonal / corporate field definitionsParticular nodes
required-formForm templates with validation rulesRequired Forms nodes
avira_countriesCountry list (ISO codes + names)Nationality, residence
avira_document_masterSupported documents per countryOCR & upload
avira_ssicIndustry classification codesIndustry field
avira_ssocOccupation classification codesOccupation field
avira_phone_codeCountry phone codesPhone verification
avira_entity_typesCorporate entity typesKYB particular
Cache configuration locally. The data changes infrequently. Refresh daily or on a deploy signal.

File upload

Two-step upload: request a short-lived token, then POST the file.

Step 1 — get upload token

Endpoint: storage.upload.token (POST). Body: {}.

{
  "apiCode": 200,
  "data": {
    "uploadToken": "a1b2c3d4...",
    "expiresIn": 900
  }
}

Tokens are valid for 15 minutes.

Step 2 — upload the file

Multipart:

curl -X POST "${STORAGE_URL}/api/v1/upload/file" \
  -F "uploadToken=a1b2c3d4..." \
  -F "file=@passport_front.jpg"

Base64 (for in-memory images):

curl -X POST "${STORAGE_URL}/api/v1/upload" \
  -H "Content-Type: application/json" \
  -d '{
    "uploadToken": "a1b2c3d4...",
    "image": "data:image/jpeg;base64,/9j/4AAQ...",
    "filename": "passport_front.jpg"
  }'

Supported types: PNG, JPG, JPEG, GIF, WEBP, TIFF, PDF. Max size: 20 MB.

Error handling & retry strategy

ScenarioRecommendation
Signature error (403)Do not retry; fix signing implementation
Server error (500)Retry 3× with exponential backoff (1s → 2s → 4s)
Status pollingEvery 2–5 seconds, max 30 minutes
Upload token 401Get a new token, retry once
OTP verify failResend OTP if max attempts exhausted
Network timeoutSafe to retry — all submission APIs are idempotent