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:
-
Build the string to sign (components are joined by a newline
\n):stringToSign = timestamp + "\n" + method + "\n" + path + "\n" + bodyHashwhere:
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)
-
Compute HMAC-SHA256 using the API key secret:
signature = HMAC-SHA256(stringToSign, api_secret)Encode the result in hex (a 64-character string).
-
Build and send the request with the headers above. Example endpoint for creating a verification link:
ApiKeyAuthAuthorization<token>HMAC-SHA256 Credential=<key_id>, Signature=<hex_signature>. SignedHeaders=x-timestamp is optional. Requires X-Timestamp header.
X-Timestamp*stringUnix timestamp (seconds, max 5 min drift)
Link options (flow_id required)
application/json- body
expires_in?integerseconds
external_reference?stringexternal_user_id?stringflow_id?stringlocale?stringmetadata?prefilled?redirect_url?stringutm_campaign?stringutm_medium?stringutm_source?stringCreated or reused link
application/json- response
data?success?booleancurl -X POST 'https://example.com/tenant/v1/kyc/verification-links' \ -H 'X-Timestamp: string' \ -H 'Content-Type: application/json' \ -d '{}'{ "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):
| Scope | Description |
|---|---|
applicants:read | Read applicant data |
applicants:write | Modify and delete applicants |
sessions:create | Create verification sessions and create, batch-create, or revoke KYC verification links |
verifications:read | Read verification and AML results |
documents:read | Read documents |
media:read | Read media files |
webhooks:read | Read webhook configuration |
webhooks:write | Manage webhooks |
metrics:read | Read metrics and analytics |
audit:read | Read the audit log |
verification-links:read | Read verification links |
documents:upload | Upload documents |
reviews:read | Read the manual review queue, tasks, comments, and reject reasons |
reviews:write | Assign, decide, comment, priority, and resubmit on KYC review tasks |
KYB scopes (for kyb_* keys):
| Scope | Description |
|---|---|
businesses:read | Read business data |
businesses:write | Modify business data |
kyb.sessions:read | Read KYB sessions |
kyb.verification-links:read | Read KYB verification links |
kyb.verification-links:write | Create and manage KYB verification links |
kyb.documents:read | Read KYB documents |
kyb.media:read | Read KYB media files (also required for review document URLs) |
kyb.webhooks:read | Read KYB webhook configuration |
kyb.webhooks:write | Manage KYB webhooks |
kyb.metrics:read | Read KYB metrics |
kyb.audit:read | Read the KYB audit log |
kyb.reviews:read | Read the KYB manual review queue and tasks |
kyb.reviews:write | Assign, 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).