Primeros pasosInicio rápido

Inicio rápido

Cree una clave de API y envíe su primera solicitud KYC en tres minutos.

Este es el camino más rápido desde «tengo una cuenta en Certivant» hasta «una solicitud de verificación está en curso». Si completa esta página, tendrá una integración funcional de principio a fin.

Lo que necesita

  • Una organización en Certivant (regístrese en la URL de su cliente; la prueba incluye créditos gratuitos).
  • El rol Propietario o Administrador en esa organización. Los miembros no pueden crear claves de API.
  • Una forma de realizar solicitudes HTTPS: curl, Postman o el cliente HTTP de su lenguaje.

1 — Cree una clave de API

Inicie sesión en el panel y abra su organización.
Vaya a KYC → Desarrollador en la barra lateral izquierda.

Haga clic en Nueva clave, asígnele una etiqueta, elija Producción o Pruebas (por ejemplo, una etiqueta como staging-server) y seleccione los ámbitos que necesite:

  • kyc:read: leer solicitudes, documentos y señales de fraude
  • kyc:write: crear solicitudes y cargar documentos
  • kyc:submit: enviar una solicitud para su procesamiento automatizado
  • kyc:manage: anular decisiones y eliminar solicitantes (RGPD)
Haga clic en Crear. La clave completa se muestra una sola vez y comienza con ck_live_ (o ck_test_ si eligió el entorno de pruebas). Cópiela ahora: Certivant solo almacena un hash, por lo que no podrá recuperarla más adelante. Si la pierde, revoque la clave y cree una nueva.

Trate las claves de API como contraseñas. Guárdelas en su gestor de secretos, nunca las incluya en git y use una clave distinta para cada entorno (staging frente a producción). Revoque una clave en cuanto sospeche que ha quedado expuesta.

2 — Cree una solicitud KYC

La carga mínima solo necesita un type. Añada los datos del solicitante en línea si los tiene; de lo contrario, el solicitante los completará mediante una sesión alojada. El mismo flujo de principio a fin (crear → cargar documentos → enviar → consultar) en ocho lenguajes:

# 1. Create a verification request
curl -X POST https://app.certivant.com/api/v1/kyc/requests \
  -H "Authorization: Bearer ck_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "INDIVIDUAL",
    "externalRef": "user_123",
    "applicant": {
      "fullName": "Jane Doe", "email": "jane@example.com", "nationality": "US",
      "emailVerified": false, "phoneVerified": false
    }
  }'
# -> { "id": "req_...", "status": "PENDING_UPLOAD", ... }

# 2 & 3. Upload an identity document (front) + a selfie
curl -X POST https://app.certivant.com/api/v1/kyc/requests/{requestId}/documents \
  -H "Authorization: Bearer ck_live_your_key_here" \
  -F "file=@passport.jpg" -F "documentType=PASSPORT" -F "side=front"
curl -X POST https://app.certivant.com/api/v1/kyc/requests/{requestId}/documents \
  -H "Authorization: Bearer ck_live_your_key_here" \
  -F "file=@selfie.jpg" -F "documentType=SELFIE"

# 4. Submit for AI processing (email + phone must already be verified if your org requires it)
curl -X POST https://app.certivant.com/api/v1/kyc/requests/{requestId}/submit \
  -H "Authorization: Bearer ck_live_your_key_here"

# 5. Poll for the decision (or just listen for the webhook)
curl https://app.certivant.com/api/v1/kyc/requests/{requestId} \
  -H "Authorization: Bearer ck_live_your_key_here"
const BASE = "https://app.certivant.com/api/v1/kyc";
const headers = { Authorization: "Bearer ck_live_your_key_here" };

// 1. Create
const { id } = await fetch(BASE + "/requests", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({
    type: "INDIVIDUAL",
    externalRef: "user_123",
    applicant: { fullName: "Jane Doe", email: "jane@example.com", nationality: "US" },
  }),
}).then((r) => r.json());

// 2 & 3. Upload documents
async function upload(file, documentType, side) {
  const form = new FormData();
  form.append("file", file);
  form.append("documentType", documentType);
  if (side) form.append("side", side);
  await fetch(BASE + "/requests/" + id + "/documents", { method: "POST", headers, body: form });
}
await upload(passportFile, "PASSPORT", "front");
await upload(selfieFile, "SELFIE");

// 4. Submit
await fetch(BASE + "/requests/" + id + "/submit", { method: "POST", headers });

// 5. Poll (production: listen for the webhook instead)
let result;
do {
  await new Promise((r) => setTimeout(r, 3000));
  result = await fetch(BASE + "/requests/" + id, { headers }).then((r) => r.json());
} while (result.status === "PROCESSING");
console.log(result.status, result.riskScore);
const BASE = "https://app.certivant.com/api/v1/kyc";
const headers = { Authorization: "Bearer ck_live_your_key_here" };

type KycStatus = "PENDING_UPLOAD" | "DOCUMENTS_READY" | "PROCESSING"
  | "APPROVED" | "REJECTED" | "ESCALATED" | "CANCELLED";

interface KycRequest {
  id: string;
  status: KycStatus;
  riskScore?: { overallScore: number; decision: string } | null;
}

const created: KycRequest = await fetch(BASE + "/requests", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({
    type: "INDIVIDUAL",
    externalRef: "user_123",
    applicant: { fullName: "Jane Doe", email: "jane@example.com", nationality: "US" },
  }),
}).then((r) => r.json());

await fetch(BASE + "/requests/" + created.id + "/submit", { method: "POST", headers });
import time, requests

BASE = "https://app.certivant.com/api/v1/kyc"
headers = {"Authorization": "Bearer ck_live_your_key_here"}

# 1. Create
r = requests.post(f"{BASE}/requests", headers=headers, json={
    "type": "INDIVIDUAL",
    "externalRef": "user_123",
    "applicant": {"fullName": "Jane Doe", "email": "jane@example.com", "nationality": "US"},
})
request_id = r.json()["id"]

# 2 & 3. Upload documents
def upload(path, document_type, side=None):
    data = {"documentType": document_type}
    if side:
        data["side"] = side
    with open(path, "rb") as f:
        requests.post(f"{BASE}/requests/{request_id}/documents",
                      headers=headers, files={"file": f}, data=data)

upload("passport.jpg", "PASSPORT", "front")
upload("selfie.jpg", "SELFIE")

# 4. Submit
requests.post(f"{BASE}/requests/{request_id}/submit", headers=headers)

# 5. Poll
while True:
    result = requests.get(f"{BASE}/requests/{request_id}", headers=headers).json()
    if result["status"] != "PROCESSING":
        break
    time.sleep(3)
print(result["status"])
<?php
$BASE = "https://app.certivant.com/api/v1/kyc";
$auth = ["Authorization: Bearer ck_live_your_key_here"];

// 1. Create
$ch = curl_init("$BASE/requests");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => array_merge($auth, ["Content-Type: application/json"]),
  CURLOPT_POSTFIELDS => json_encode([
    "type" => "INDIVIDUAL",
    "externalRef" => "user_123",
    "applicant" => ["fullName" => "Jane Doe", "email" => "jane@example.com", "nationality" => "US"],
  ]),
]);
$req = json_decode(curl_exec($ch), true);
$id = $req["id"];

// 2. Upload a document
$ch = curl_init("$BASE/requests/$id/documents");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => $auth,
  CURLOPT_POSTFIELDS => [
    "file" => new CURLFile("passport.jpg"),
    "documentType" => "PASSPORT",
    "side" => "front",
  ],
]);
curl_exec($ch);

// 4. Submit
$ch = curl_init("$BASE/requests/$id/submit");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => $auth]);
curl_exec($ch);
using System.Net.Http;
using System.Net.Http.Json;
using System.Net.Http.Headers;

var http = new HttpClient { BaseAddress = new Uri("https://app.certivant.com/api/v1/kyc/") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "ck_live_your_key_here");

// 1. Create
var created = await http.PostAsJsonAsync("requests", new {
    type = "INDIVIDUAL",
    externalRef = "user_123",
    applicant = new { fullName = "Jane Doe", email = "jane@example.com", nationality = "US" }
});
var request = await created.Content.ReadFromJsonAsync<Dictionary<string, object>>();
var id = request["id"].ToString();

// 2. Upload a document
using var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(File.ReadAllBytes("passport.jpg")), "file", "passport.jpg");
form.Add(new StringContent("PASSPORT"), "documentType");
form.Add(new StringContent("front"), "side");
await http.PostAsync($"requests/{id}/documents", form);

// 4. Submit
await http.PostAsync($"requests/{id}/submit", null);
import java.net.http.*;
import java.net.URI;

var http = HttpClient.newHttpClient();
String BASE = "https://app.certivant.com/api/v1/kyc";
String auth = "Bearer ck_live_your_key_here";

// 1. Create
var createBody = """
  {"type":"INDIVIDUAL","externalRef":"user_123",
   "applicant":{"fullName":"Jane Doe","email":"jane@example.com","nationality":"US"}}""";
var created = http.send(HttpRequest.newBuilder(URI.create(BASE + "/requests"))
    .header("Authorization", auth).header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(createBody)).build(),
    HttpResponse.BodyHandlers.ofString());
// parse created.body() -> id with your JSON library (Jackson/Gson)

// 4. Submit
http.send(HttpRequest.newBuilder(URI.create(BASE + "/requests/" + id + "/submit"))
    .header("Authorization", auth).POST(HttpRequest.BodyPublishers.noBody()).build(),
    HttpResponse.BodyHandlers.ofString());
package main

import (
	"bytes"
	"net/http"
)

const base = "https://app.certivant.com/api/v1/kyc"
const auth = "Bearer ck_live_your_key_here"

func main() {
	// 1. Create
	body := []byte(`{"type":"INDIVIDUAL","externalRef":"user_123",
		"applicant":{"fullName":"Jane Doe","email":"jane@example.com","nationality":"US"}}`)
	req, _ := http.NewRequest("POST", base+"/requests", bytes.NewReader(body))
	req.Header.Set("Authorization", auth)
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
	// decode resp.Body -> { "id": "..." }

	// 4. Submit
	submit, _ := http.NewRequest("POST", base+"/requests/"+id+"/submit", nil)
	submit.Header.Set("Authorization", auth)
	http.DefaultClient.Do(submit)
}

Una respuesta correcta tiene este aspecto:

{
  "id": "req_01HXY...",
  "status": "PENDING_UPLOAD",
  "type": "INDIVIDUAL",
  "externalRef": "order-12345",
  "pendingDocTypes": ["GOVERNMENT_ID", "SELFIE"],
  "applicant": { "fullName": "Jane Doe", "email": "jane@example.com" },
  "createdAt": "2026-05-27T10:00:00.000Z"
}

Guarde el id: todas las llamadas posteriores lo necesitan.

El campo externalRef es su clave externa. Use su ID de pedido, su ID de usuario o cualquier dato que le permita relacionar la solicitud de Certivant con un registro de su propia base de datos. Se devuelve en cada evento de webhook.

3 — Envíe al solicitante una sesión alojada

La forma más sencilla de recopilar documentos es enviar al solicitante una URL de corta duración. Certivant se encarga de la captura de documentos, la comprobación de vida (liveness) y la interfaz de carga; usted solo le entrega el enlace.

curl -X POST https://app.certivant.com/api/v1/kyc/requests/req_01HXY.../session-url \
  -H "Authorization: Bearer ck_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "expiresInHours": 72,
    "redirectUrl": "https://yourapp.example.com/onboarding/complete"
  }'

Devuelve:

{
  "sessionUrl": "https://app.certivant.com/s/01HZ...",
  "expiresAt": "2026-05-30T10:00:00.000Z"
}

Envíeselo por correo electrónico al solicitante, insértelo en su propio flujo de incorporación o ábralo en un iframe, según lo que mejor se adapte a su experiencia de usuario. Cuando el solicitante envía la información, Certivant pasa la solicitud a PROCESSING, ejecuta las comprobaciones y envía el webhook.

En esta ruta de sesión alojada, el solicitante también completa la verificación de correo electrónico y teléfono cuando su organización lo requiere, así que no necesita pasar usted emailVerified ni phoneVerified. En la ruta de servidor a servidor (consulte Su primera solicitud), verifique cada canal requerido, o establezca esas marcas al crear la solicitud, antes de llamar a submit.

4 — Escuche el resultado

Configure un endpoint de webhook en KYC → Configuración → Webhooks con una URL que usted controle. Certivant enviará una solicitud POST a esa URL cada vez que cambie el estado de la solicitud.

{
  "event": "kyc.request.approved",
  "requestId": "req_01HXY...",
  "organizationId": "org_01HW...",
  "externalRef": "order-12345",
  "status": "APPROVED",
  "timestamp": "2026-05-27T10:04:21.000Z",
  "data": { "score": 92, "decision": "approve" }
}

Use el externalRef para encontrar el registro en su base de datos y continuar con la incorporación. Consulte Webhooks para la verificación de firmas, el comportamiento de los reintentos y el catálogo completo de eventos.

Qué sigue