> For the complete documentation index, see [llms.txt](https://finext.gitbook.io/one-kyc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://finext.gitbook.io/one-kyc/api/authentication.md).

# Authentication

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

To call the OneKYC 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 OneKYC 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:

<mark style="color:green;">`POST`</mark> `undefined/v1/kyc/verification-links`

**Example (JavaScript / Node.js):**

```javascript
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):**

```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](/one-kyc/api/review.md).

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, OneKYC issues a short-lived JWT token. The OneKYC 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](/one-kyc/api/sessions.md) and [API reference (OpenAPI)](/one-kyc/api/api-reference.md).
