Skip to main content
POST
/
v1
/
kyb
/
widgets
curl -X POST https://api.vouchmark.com/v1/kyb/widgets \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme KYB",
    "templateId": "blank",
    "environment": "sandbox",
    "config": {
      "branding": {
        "brandName": "Acme",
        "logoUrl": "",
        "accentColor": "#6466AE",
        "cornerRadius": "soft",
        "welcomeTitle": "Verify your business",
        "welcomeMessage": "This takes about 10 minutes.",
        "completionTitle": "All done!",
        "completionMessage": "We will review within 24 hours.",
        "supportEmail": "support@acme.com"
      },
      "modules": {
        "business_profile": { "enabled": true, "required": true },
        "cac_verification": { "enabled": true, "required": true },
        "tin_verification": { "enabled": true, "required": true }
      },
      "flow": {
        "order": ["business_profile", "cac_verification", "tin_verification"],
        "enableSavedProgress": true,
        "enableResume": true,
        "sessionTimeoutMinutes": 60,
        "successRedirectUrl": "",
        "failureRedirectUrl": "",
        "abandonRedirectUrl": ""
      },
      "security": {
        "allowedDomains": ["acme.com"],
        "allowedCountries": ["NG"],
        "enableIpAllowlist": false,
        "ipAllowlist": [],
        "requireSignedRequests": false
      },
      "risk": {
        "tier": "standard",
        "autoApproveThreshold": 80,
        "autoRejectThreshold": 30,
        "reviewOnPepMatch": true,
        "reviewOnAdverseMedia": true,
        "reviewOnSanctionsMatch": true
      },
      "notifications": {
        "notifyApplicantEmail": true,
        "notifyApplicantSms": false,
        "notifyAdminEmail": "compliance@acme.com",
        "webhookEvents": ["applicant.approved", "applicant.rejected"]
      }
    }
  }'
{
  "success": true,
  "data": {
    "id": "wgt_aBcD...",
    "name": "Acme KYB",
    "status": "draft",
    "environment": "sandbox",
    "templateId": "blank",
    "config": { "branding": { "...": "..." }, "modules": { "...": "..." }, "flow": { "...": "..." }, "security": { "...": "..." }, "risk": { "...": "..." }, "notifications": { "...": "..." } },
    "embedLinkToken": "elt_...",
    "createdAt": "2026-06-01T10:00:00Z",
    "updatedAt": "2026-06-01T10:00:00Z"
  }
}
Creates a new onboarding widget. New widgets are created in draft status. The full config object is required and must contain every section. Requires Authorization: Bearer $TOKEN.

Body

name
string
required
Human-readable name for this widget. 1–120 characters.
templateId
string
default:"blank"
Template identifier the widget was built from. 1–60 characters.
environment
string
default:"sandbox"
One of sandbox or live.
config
object
required
Full widget configuration. All six sections below are required.

config.branding

config.branding.brandName
string
required
1–120 characters.
config.branding.logoUrl
string
default:""
Logo URL, up to 2048 characters.
config.branding.logoPublicId
string
Storage public ID, up to 512 characters.
config.branding.accentColor
string
required
Hex colour, e.g. #6466AE.
config.branding.cornerRadius
string
required
One of sharp, soft, round.
config.branding.welcomeTitle
string
required
1–200 characters.
config.branding.welcomeMessage
string
required
1–600 characters.
config.branding.completionTitle
string
required
1–200 characters.
config.branding.completionMessage
string
required
1–600 characters.
config.branding.supportEmail
string
default:""
Up to 200 characters.

config.modules

config.modules
object
required
A map keyed by module ID (e.g. business_profile, cac_verification). Each value is { "enabled": boolean, "required": boolean }. See Module catalog for the 19 valid module IDs.

config.flow

config.flow.order
string[]
required
Ordered array of module IDs.
config.flow.enableSavedProgress
boolean
required
config.flow.enableResume
boolean
required
config.flow.sessionTimeoutMinutes
integer
required
5–240.
config.flow.successRedirectUrl
string
default:""
Up to 2048 characters.
config.flow.failureRedirectUrl
string
default:""
Up to 2048 characters.
config.flow.abandonRedirectUrl
string
default:""
Up to 2048 characters.

config.security

config.security.allowedDomains
string[]
required
Up to 50 entries, each up to 255 characters.
config.security.allowedCountries
string[]
required
Up to 250 two-letter country codes.
config.security.enableIpAllowlist
boolean
required
config.security.ipAllowlist
string[]
required
Up to 100 entries, each up to 64 characters.
config.security.requireSignedRequests
boolean
required

config.risk

config.risk.tier
string
required
One of low, standard, enhanced.
config.risk.autoApproveThreshold
integer
required
0–100.
config.risk.autoRejectThreshold
integer
required
0–100.
config.risk.reviewOnPepMatch
boolean
required
config.risk.reviewOnAdverseMedia
boolean
required
config.risk.reviewOnSanctionsMatch
boolean
required

config.notifications

config.notifications.notifyApplicantEmail
boolean
required
config.notifications.notifyApplicantSms
boolean
required
config.notifications.notifyAdminEmail
string
default:""
Up to 200 characters.
config.notifications.webhookEvents
string[]
required
Up to 20 entries, each up to 60 characters.
curl -X POST https://api.vouchmark.com/v1/kyb/widgets \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme KYB",
    "templateId": "blank",
    "environment": "sandbox",
    "config": {
      "branding": {
        "brandName": "Acme",
        "logoUrl": "",
        "accentColor": "#6466AE",
        "cornerRadius": "soft",
        "welcomeTitle": "Verify your business",
        "welcomeMessage": "This takes about 10 minutes.",
        "completionTitle": "All done!",
        "completionMessage": "We will review within 24 hours.",
        "supportEmail": "support@acme.com"
      },
      "modules": {
        "business_profile": { "enabled": true, "required": true },
        "cac_verification": { "enabled": true, "required": true },
        "tin_verification": { "enabled": true, "required": true }
      },
      "flow": {
        "order": ["business_profile", "cac_verification", "tin_verification"],
        "enableSavedProgress": true,
        "enableResume": true,
        "sessionTimeoutMinutes": 60,
        "successRedirectUrl": "",
        "failureRedirectUrl": "",
        "abandonRedirectUrl": ""
      },
      "security": {
        "allowedDomains": ["acme.com"],
        "allowedCountries": ["NG"],
        "enableIpAllowlist": false,
        "ipAllowlist": [],
        "requireSignedRequests": false
      },
      "risk": {
        "tier": "standard",
        "autoApproveThreshold": 80,
        "autoRejectThreshold": 30,
        "reviewOnPepMatch": true,
        "reviewOnAdverseMedia": true,
        "reviewOnSanctionsMatch": true
      },
      "notifications": {
        "notifyApplicantEmail": true,
        "notifyApplicantSms": false,
        "notifyAdminEmail": "compliance@acme.com",
        "webhookEvents": ["applicant.approved", "applicant.rejected"]
      }
    }
  }'
{
  "success": true,
  "data": {
    "id": "wgt_aBcD...",
    "name": "Acme KYB",
    "status": "draft",
    "environment": "sandbox",
    "templateId": "blank",
    "config": { "branding": { "...": "..." }, "modules": { "...": "..." }, "flow": { "...": "..." }, "security": { "...": "..." }, "risk": { "...": "..." }, "notifications": { "...": "..." } },
    "embedLinkToken": "elt_...",
    "createdAt": "2026-06-01T10:00:00Z",
    "updatedAt": "2026-06-01T10:00:00Z"
  }
}
Returns 201 with the full widget object. Set the widget to live with Set widget status when ready.