Skip to Content
KnowaKYC
Tenant API (KYC)

Authentication

API status. The KnowaKYC Tenant API is in beta. Endpoints, data formats, and API versions may change. Track documentation updates.

To call the KnowaKYC API from a server, you need to authenticate. Two mechanisms are supported: HMAC signing for server-to-server interaction (Tenant API) and a JWT token for verification-session access (used by the verification page when the end user opens a link).

HMAC (server-to-server with the KnowaKYC API)

Server-side requests are signed with HMAC-SHA256. This mechanism proves that the request came from an authorised API key holder.

Required headers:

  • Authorization — HMAC-SHA256 Credential={key_id}, Signature={signature}
  • X-Timestamp — current Unix time (seconds). Requests with clock drift over 5 minutes are rejected (replay protection).

Signature algorithm:

  1. Build the string to sign (components are joined by a newline \n):

    stringToSign = timestamp + "\n" + method + "\n" + path + "\n" + bodyHash

    where:

    • timestamp — value of the X-Timestamp header (Unix seconds)
    • method — HTTP method in upper case (GET, POST, PUT, DELETE, etc.)
    • path — full request path with query parameters (for example, /tenant/v1/kyc/applicants?page=1)
    • bodyHash — SHA256 hash of the request body in hex (empty string for GET requests and other bodyless requests)
  2. Compute HMAC-SHA256 using the API key secret:

    signature = HMAC-SHA256(stringToSign, api_secret)

    Encode the result in hex (a 64-character string).

  3. Build and send the request with the headers above. Example endpoint for creating a verification link:

POST
/v1/kyc/verification-links

Authorization

ApiKeyAuth
headerAuthorization<token>

HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.

Header Parameters

X-Timestamp*string

Unix timestamp (seconds, max 5 min drift)

Request Body

Link options (flow_id required)

application/json
  1. body
expires_in?integer

seconds

external_reference?string
external_user_id?string
flow_id?string
locale?string
metadata?
prefilled?
redirect_url?string
utm_campaign?string
utm_medium?string
utm_source?string

Response Body

Created or reused link

application/json
  1. response
data?
success?boolean
Example Request
curl -X POST 'https://example.com/tenant/v1/kyc/verification-links' \  -H 'X-Timestamp: string' \  -H 'Content-Type: application/json' \  -d '{}'
Example Response
{  "success": true,  "data": {    "created_at": "string",    "delivery_eligible": true,    "expires_at": "string",    "external_reference": "string",    "external_user_id": "string",    "flow_id": "string",    "id": "string",    "link_url": "string",    "locale": "string",    "qr_code_url": "string",    "redirect_url": "string",    "reuse_reason": "external_reference",    "reused": true,    "session_id": "string",    "session_resumable": true,    "session_status": "string",    "short_url": "string",    "status": "string",    "url": "string",    "verification_link": "string",    "verification_url": "string"  }}

Example (JavaScript / Node.js):

const crypto = require("crypto");

// 1. Compute bodyHash (SHA256 hash of the request body)
const body = JSON.stringify({ flow_id: "uuid-here" });
const bodyHash = crypto.createHash("sha256").update(body).digest("hex");

// 2. Build the string to sign
const timestamp = Math.floor(Date.now() / 1000).toString();
const method = "POST";
const path = "/tenant/v1/kyc/verification-links";
const stringToSign = `${timestamp}\n${method}\n${path}\n${bodyHash}`;

// 3. Compute the HMAC-SHA256 signature
const apiSecret = "your_api_secret_here";
const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(stringToSign)
  .digest("hex");

// 4. Build the request headers
const headers = {
  "Content-Type": "application/json",
  "X-Timestamp": timestamp,
  Authorization: `HMAC-SHA256 Credential=kyc_test_<your_key_id>, Signature=${signature}`,
};

Example (Go):

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "strconv"
    "time"
)

// 1. Compute bodyHash (SHA256 hash of the request body)
body := map[string]string{"flow_id": "uuid-here"}
bodyBytes, _ := json.Marshal(body)
hash := sha256.Sum256(bodyBytes)
bodyHash := hex.EncodeToString(hash[:])

// 2. Build the string to sign
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
method := "POST"
path := "/tenant/v1/kyc/verification-links"
stringToSign := fmt.Sprintf("%s\n%s\n%s\n%s", timestamp, method, path, bodyHash)

// 3. Compute the HMAC-SHA256 signature
apiSecret := "your_api_secret_here"
mac := hmac.New(sha256.New, []byte(apiSecret))
mac.Write([]byte(stringToSign))
signature := hex.EncodeToString(mac.Sum(nil))

// 4. Build the request headers
// Authorization: HMAC-SHA256 Credential=kyc_test_<your_key_id>, Signature={signature}
// X-Timestamp: {timestamp}

The API key secret is shown once when you create the key in the admin panel — store it in a secure vault. Keep the secret on the server side; do not ship it to client applications.

Key formats:

  • KYC keys: prefix kyc_live_ for production, kyc_test_ for the test environment. Grant access to /tenant/v1/kyc/ endpoints.
  • KYB keys: prefix kyb_live_ for production, kyb_test_ for the test environment. Grant access to /tenant/v1/kyb/ endpoints only.

The key secret carries the sk_ prefix. Keys are created and revoked in the API keys section of the admin panel.

Test and live modes:

  • Test keys (kyc_test_*, kyb_test_*) — for development and testing. No real verifications are run.
  • Live keys (kyc_live_*, kyb_live_*) — for production. Process real user verifications.
  • Keys are isolated: test keys do not access live data and vice versa.
  • KYC keys cannot call KYB endpoints and vice versa — the server returns HTTP 403.

Scopes: when you create a key, you select scopes that determine the available operations.

KYC scopes (for kyc_* keys):

ScopeDescription
applicants:readRead applicant data
applicants:writeModify and delete applicants
sessions:createCreate verification sessions and create, batch-create, or revoke KYC verification links
verifications:readRead verification and AML results
documents:readRead documents
media:readRead media files
webhooks:readRead webhook configuration
webhooks:writeManage webhooks
metrics:readRead metrics and analytics
audit:readRead the audit log
verification-links:readRead verification links
documents:uploadUpload documents
reviews:readRead the manual review queue, tasks, comments, and reject reasons
reviews:writeAssign, decide, comment, priority, and resubmit on KYC review tasks

KYB scopes (for kyb_* keys):

ScopeDescription
businesses:readRead business data
businesses:writeModify business data
kyb.sessions:readRead KYB sessions
kyb.verification-links:readRead KYB verification links
kyb.verification-links:writeCreate and manage KYB verification links
kyb.documents:readRead KYB documents
kyb.media:readRead KYB media files (also required for review document URLs)
kyb.webhooks:readRead KYB webhook configuration
kyb.webhooks:writeManage KYB webhooks
kyb.metrics:readRead KYB metrics
kyb.audit:readRead the KYB audit log
kyb.reviews:readRead the KYB manual review queue and tasks
kyb.reviews:writeAssign, decide, comment, priority, and resubmit on KYB review tasks

Manual review for integrators: Review tasks.

Each endpoint requires the matching scope; if access is insufficient, the server returns HTTP 403. Wildcard scopes are supported: * (full access) or applicants:* (all applicant operations).

JWT (verification-session access)

When a verification link is activated, KnowaKYC issues a short-lived JWT token. The KnowaKYC verification page uses this token: when the end user opens the link, every API request (fetching session data, uploading documents, executing steps) carries the Authorization: Bearer <token> header. The token lifetime is set when you create the link (for example, 600 seconds).


Summary: server-side integration uses HMAC signing with an API key to call the Tenant API; the end user's verification access uses a JWT token issued when the link is activated. For full endpoint reference, see Sessions and API reference (OpenAPI).

On this page