curl --request POST \
--url https://api.qbank.cl/platform/v1/kyb/links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"external_customer_id": "cust_456",
"country": "cl",
"label": "Comercial Andina SpA",
"expires_in_days": 14,
"idempotency_key": "kyb-link-cust-456-1"
}
'import requests
url = "https://api.qbank.cl/platform/v1/kyb/links"
payload = {
"external_customer_id": "cust_456",
"country": "cl",
"label": "Comercial Andina SpA",
"expires_in_days": 14,
"idempotency_key": "kyb-link-cust-456-1"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
external_customer_id: 'cust_456',
country: 'cl',
label: 'Comercial Andina SpA',
expires_in_days: 14,
idempotency_key: 'kyb-link-cust-456-1'
})
};
fetch('https://api.qbank.cl/platform/v1/kyb/links', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.qbank.cl/platform/v1/kyb/links",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_customer_id' => 'cust_456',
'country' => 'cl',
'label' => 'Comercial Andina SpA',
'expires_in_days' => 14,
'idempotency_key' => 'kyb-link-cust-456-1'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.qbank.cl/platform/v1/kyb/links"
payload := strings.NewReader("{\n \"external_customer_id\": \"cust_456\",\n \"country\": \"cl\",\n \"label\": \"Comercial Andina SpA\",\n \"expires_in_days\": 14,\n \"idempotency_key\": \"kyb-link-cust-456-1\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.qbank.cl/platform/v1/kyb/links")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"external_customer_id\": \"cust_456\",\n \"country\": \"cl\",\n \"label\": \"Comercial Andina SpA\",\n \"expires_in_days\": 14,\n \"idempotency_key\": \"kyb-link-cust-456-1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qbank.cl/platform/v1/kyb/links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_customer_id\": \"cust_456\",\n \"country\": \"cl\",\n \"label\": \"Comercial Andina SpA\",\n \"expires_in_days\": 14,\n \"idempotency_key\": \"kyb-link-cust-456-1\"\n}"
response = http.request(request)
puts response.read_body{
"link_id": "d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f80",
"kind": "kyb",
"external_customer_id": "cust_456",
"url": "https://verify.example.com/on/cl/business/new?invite=ghi789",
"status": "pending",
"country": "cl",
"label": "Comercial Andina SpA",
"expires_at": 1721209600,
"verification_fee": "2.000000",
"idempotency_key": "kyb-link-cust-456-1",
"created_at": "2026-07-10T12:00:00Z",
"updated_at": "2026-07-10T12:00:00Z"
}{
"error": "idempotency_key_required",
"message": "provide idempotency_key (body or Idempotency-Key header)"
}{
"error": "unauthorized",
"message": "invalid or missing credentials"
}{
"error": "insufficient_funds",
"message": "account balance is not enough for this operation"
}{
"error": "company_account_required",
"message": "third-party KYC/KYB verification is available to company accounts only"
}Create a KYB link for a customer
Company accounts only: generates a hosted KYB link for one of YOUR end customers (businesses). Bills the fixed kyb_verification fee when configured (refunded if creation fails); idempotency_key is required. country picks the wizard corridor: us, cl, ve, br, mx, co, pe, bo, py, ar or generic (send generic_country ISO alpha-2, optional currency).
curl --request POST \
--url https://api.qbank.cl/platform/v1/kyb/links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"external_customer_id": "cust_456",
"country": "cl",
"label": "Comercial Andina SpA",
"expires_in_days": 14,
"idempotency_key": "kyb-link-cust-456-1"
}
'import requests
url = "https://api.qbank.cl/platform/v1/kyb/links"
payload = {
"external_customer_id": "cust_456",
"country": "cl",
"label": "Comercial Andina SpA",
"expires_in_days": 14,
"idempotency_key": "kyb-link-cust-456-1"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
external_customer_id: 'cust_456',
country: 'cl',
label: 'Comercial Andina SpA',
expires_in_days: 14,
idempotency_key: 'kyb-link-cust-456-1'
})
};
fetch('https://api.qbank.cl/platform/v1/kyb/links', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.qbank.cl/platform/v1/kyb/links",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_customer_id' => 'cust_456',
'country' => 'cl',
'label' => 'Comercial Andina SpA',
'expires_in_days' => 14,
'idempotency_key' => 'kyb-link-cust-456-1'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.qbank.cl/platform/v1/kyb/links"
payload := strings.NewReader("{\n \"external_customer_id\": \"cust_456\",\n \"country\": \"cl\",\n \"label\": \"Comercial Andina SpA\",\n \"expires_in_days\": 14,\n \"idempotency_key\": \"kyb-link-cust-456-1\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.qbank.cl/platform/v1/kyb/links")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"external_customer_id\": \"cust_456\",\n \"country\": \"cl\",\n \"label\": \"Comercial Andina SpA\",\n \"expires_in_days\": 14,\n \"idempotency_key\": \"kyb-link-cust-456-1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.qbank.cl/platform/v1/kyb/links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_customer_id\": \"cust_456\",\n \"country\": \"cl\",\n \"label\": \"Comercial Andina SpA\",\n \"expires_in_days\": 14,\n \"idempotency_key\": \"kyb-link-cust-456-1\"\n}"
response = http.request(request)
puts response.read_body{
"link_id": "d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f80",
"kind": "kyb",
"external_customer_id": "cust_456",
"url": "https://verify.example.com/on/cl/business/new?invite=ghi789",
"status": "pending",
"country": "cl",
"label": "Comercial Andina SpA",
"expires_at": 1721209600,
"verification_fee": "2.000000",
"idempotency_key": "kyb-link-cust-456-1",
"created_at": "2026-07-10T12:00:00Z",
"updated_at": "2026-07-10T12:00:00Z"
}{
"error": "idempotency_key_required",
"message": "provide idempotency_key (body or Idempotency-Key header)"
}{
"error": "unauthorized",
"message": "invalid or missing credentials"
}{
"error": "insufficient_funds",
"message": "account balance is not enough for this operation"
}{
"error": "company_account_required",
"message": "third-party KYC/KYB verification is available to company accounts only"
}Authorizations
Session JWT (from register/login) or API key (pk_...).
X-API-Key: <token> is accepted as an alternative header.
Body
Your reference for the customer being verified (echoed on every webhook).
KYB only. Wizard corridor (us, cl, ve, br, mx, co, pe, bo, py, ar, generic).
ISO alpha-2 when country=generic.
Response
KYB link created.
kyc, kyb Hosted wizard URL to share with the verified person/business.
pending, opened, completed, expired Present once the link is completed.