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"
}Crear un link KYB para un cliente
Solo cuentas empresa: genera un link KYB hosteado para uno de TUS clientes finales (empresas). Cobra el fee fijo kyb_verification cuando está configurado (se reembolsa si la creación falla); idempotency_key obligatoria. country elige el corredor del wizard: us, cl, ve, br, mx, co, pe, bo, py, ar o generic (con generic_country ISO alpha-2 y currency opcional).
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"
}Autorizaciones
JWT de sesión (de register/login) o llave de API (pk_...).
X-API-Key: <token> se acepta como header alternativo.
Cuerpo
Tu referencia del cliente verificado (vuelve en cada webhook).
Solo KYB. Corredor del wizard (us, cl, ve, br, mx, co, pe, bo, py, ar, generic).
ISO alpha-2 cuando country=generic.
Respuesta
Link KYB creado.
kyc, kyb URL del wizard hosteado para compartir con la persona/empresa verificada.
pending, opened, completed, expired Presente cuando el link se completa.