Avvio rapido
Crei una chiave API e invii la Sua prima richiesta KYC in tre minuti.
Questa è la strada più rapida da "ho un account Certivant" a "una richiesta di verifica è in corso". Se completa questa pagina, avrà un'integrazione funzionante dall'inizio alla fine.
Di cosa ha bisogno
- Un'organizzazione Certivant (si registri sull'URL del Suo tenant — la prova include crediti gratuiti).
- Il ruolo Proprietario o Amministratore su tale organizzazione. I membri non possono creare chiavi API.
- Un modo per effettuare richieste HTTPS —
curl, Postman o il client HTTP del Suo linguaggio.
1 — Crei una chiave API
Clicchi Nuova chiave, assegni un'etichetta, scelga Produzione o Test (per esempio un'etichetta come staging-server) e selezioni gli ambiti necessari:
kyc:read— leggere richieste, documenti, segnali antifrodekyc:write— creare richieste, caricare documentikyc:submit— inviare una richiesta per l'elaborazione automaticakyc:manage— sovrascrivere le decisioni, eliminare i richiedenti (GDPR)
ck_live_ (oppure con ck_test_ se ha scelto l'ambiente di test). La copi subito — Certivant conserva solo un hash, quindi non potrà recuperarla in seguito. Se la perde, revochi la chiave e ne crei una nuova.Tratti le chiavi API come password. Le conservi nel Suo gestore di segreti, non le inserisca mai in git e usi una chiave separata per ogni ambiente (staging e produzione). Revochi una chiave non appena sospetta che sia stata esposta.
2 — Crei una richiesta KYC
Il payload minimo richiede solo il campo type. Aggiunga i dati del richiedente direttamente se li ha — altrimenti sarà il richiedente a compilarli tramite una sessione ospitata. Lo stesso flusso end-to-end (crea → carica i documenti → invia → interroga) in otto linguaggi:
# 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 risposta riuscita ha questo aspetto:
{
"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"
}
Salvi l'id — ogni chiamata successiva ne ha bisogno.
Il campo externalRef è la Sua chiave esterna. Usi il Suo ID ordine, il Suo ID
utente, qualsiasi valore che permetta di ricondurre la richiesta Certivant a una
riga del Suo database. Viene restituito in ogni evento webhook.
3 — Invii al richiedente una sessione ospitata
Il modo più semplice per raccogliere i documenti è inviare al richiedente un URL a breve scadenza. Certivant gestisce l'acquisizione del documento, il rilevamento di vivacità (liveness) e l'interfaccia di caricamento; Lei gli consegna semplicemente il link.
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"
}'
Restituisce:
{
"sessionUrl": "https://app.certivant.com/s/01HZ...",
"expiresAt": "2026-05-30T10:00:00.000Z"
}
Lo invii via email al richiedente, lo incorpori nel Suo flusso di onboarding o lo apra in un iframe — quello che si adatta meglio alla Sua esperienza utente. Quando il richiedente invia, Certivant porta la richiesta in PROCESSING, esegue i controlli e attiva il webhook.
Su questo percorso con sessione ospitata il richiedente completa anche la verifica
di email e telefono quando la Sua organizzazione lo richiede, quindi non è necessario
passare Lei emailVerified / phoneVerified. Nel percorso server-to-server (vedi
La Sua prima richiesta), verifichi ogni
canale richiesto — oppure imposti questi flag alla creazione — prima di chiamare submit.
4 — Ascolti il risultato
Configuri un endpoint webhook in KYC → Impostazioni → Webhook con un URL di Sua proprietà. Certivant invierà una richiesta POST a tale URL ogni volta che cambia lo stato della richiesta.
{
"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" }
}
Usi il externalRef per trovare la riga nel Suo database e procedere con l'onboarding. Consulti Webhook per la verifica delle firme, il comportamento dei nuovi tentativi e il catalogo completo degli eventi.
Cosa segue
- Autenticazione — ambiti, rotazione delle chiavi, igiene degli ambienti.
- La Sua prima richiesta — lo stesso flusso senza sessione ospitata (i documenti li carica Lei stesso).
- Riferimento richieste KYC — ogni endpoint, ogni campo.
- Webhook — configuri la verifica delle firme prima di andare in produzione.
Documentazione per sviluppatori di Certivant
Sviluppi con l'API di Certivant — KYC, KYB, caricamento dei documenti, sessioni ospitate ed eventi webhook.
Autenticazione
Autentichi ogni chiamata all'API di Certivant con una chiave API Bearer — copre la creazione della chiave, gli ambiti, il formato dell'intestazione Authorization, la rotazione senza interruzioni, la revoca e le best practice di sicurezza.