Pular para o conteúdo principal

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

Exemplos

O mesmo fluxo em três linguagens: abrir um dossiê, esperar o resultado e listar. Todos leem a chave da variável de ambiente ZABIT_KEY — nunca a escreva no código. Nos exemplos, zbt_SUA_CHAVE é um marcador.

export ZABIT_API=https://api.v3.zabit.com.br
export ZABIT_KEY=zbt_SUA_CHAVE

Abrir um dossiê​

curl -s -X POST "$ZABIT_API/kyc/v1/dossiers" \
-H "x-api-key: $ZABIT_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"document": "12345678909", "subtype": "kyc", "name": "Maria Exemplo"}'
import os
import requests # pip install requests

API = os.environ.get("ZABIT_API", "https://api.v3.zabit.com.br")
HEADERS = {"x-api-key": os.environ["ZABIT_KEY"]}


def abrir_dossie(documento: str, nome: str | None = None, chave_idempotencia: str | None = None) -> dict:
"""`chave_idempotencia`: um id único por pedido (16–128 caracteres). Guarde-o para repetir."""
corpo = {"document": documento, "subtype": "kyc"}
if nome:
corpo["name"] = nome
headers = {**HEADERS, **({"Idempotency-Key": chave_idempotencia} if chave_idempotencia else {})}
r = requests.post(f"{API}/kyc/v1/dossiers", json=corpo, headers=headers, timeout=30)
if r.status_code not in (200, 202): # 200 = repetição de um dossiê que já terminou
erro = r.json().get("error", {})
raise RuntimeError(f"{r.status_code} {erro.get('code')}: {erro.get('message')}")
return r.json() # status == "processing"
const API = process.env.ZABIT_API ?? "https://api.v3.zabit.com.br";
const HEADERS = { "x-api-key": process.env.ZABIT_KEY };

// `chaveIdempotencia`: um id único por pedido (16–128 caracteres). Guarde-o para repetir.
export async function abrirDossie(documento, nome, chaveIdempotencia) {
const corpo = { document: documento, subtype: "kyc", ...(nome && { name: nome }) };
const r = await fetch(`${API}/kyc/v1/dossiers`, {
method: "POST",
headers: {
...HEADERS,
"content-type": "application/json",
...(chaveIdempotencia && { "Idempotency-Key": chaveIdempotencia }),
},
body: JSON.stringify(corpo),
signal: AbortSignal.timeout(30_000),
});
if (r.status !== 202 && r.status !== 200) { // 200 = repetição de um dossiê que já terminou
const { error } = await r.json().catch(() => ({}));
throw new Error(`${r.status} ${error?.code}: ${error?.message}`);
}
return r.json(); // status === "processing"
}
Repetir com segurança

Para repetir este POST após um timeout, envie o header Idempotency-Key (16–128 caracteres, uma chave por pedido). Sem ele, cada tentativa que chega ao servidor abre outro dossiê e consome outra cota. Veja Idempotência.

Esperar o resultado​

Preferível: receber o evento onboarding.kyc.completed por webhook. Se precisar de polling, use intervalo crescente e um limite de tempo:

ID=0b6f1c1e-3f6e-4a53-9f43-2c1f1d5f9a10
for espera in 2 4 8 16 30; do
status=$(curl -s "$ZABIT_API/kyc/v1/dossiers/$ID" -H "x-api-key: $ZABIT_KEY" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("status"))')
echo "status: $status"
[ "$status" != "processing" ] && break
sleep "$espera"
done
import time


def esperar_resultado(dossie_id: str, limite_s: int = 300) -> dict:
espera, inicio = 2, time.monotonic()
while True:
r = requests.get(f"{API}/kyc/v1/dossiers/{dossie_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
dossie = r.json()
if dossie["status"] != "processing":
return dossie # "vigente" ou "error"
if time.monotonic() - inicio > limite_s:
raise TimeoutError(f"dossiê {dossie_id} ainda em processamento")
time.sleep(espera)
espera = min(espera * 2, 30)
const dormir = (ms) => new Promise((ok) => setTimeout(ok, ms));

export async function esperarResultado(dossieId, limiteMs = 300_000) {
let espera = 2000;
const inicio = Date.now();
for (;;) {
const r = await fetch(`${API}/kyc/v1/dossiers/${dossieId}`, { headers: HEADERS });
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const dossie = await r.json();
if (dossie.status !== "processing") return dossie; // "vigente" ou "error"
if (Date.now() - inicio > limiteMs) throw new Error(`dossiê ${dossieId} ainda em processamento`);
await dormir(espera);
espera = Math.min(espera * 2, 30_000);
}
}

Percorrer todas as páginas​

curl -s "$ZABIT_API/kyc/v1/dossiers?limit=100&offset=0" -H "x-api-key: $ZABIT_KEY"
# próxima página: offset=100, 200… até offset >= page.total
def todos_os_dossies(limite: int = 100):
offset = 0
while True:
r = requests.get(f"{API}/kyc/v1/dossiers", params={"limit": limite, "offset": offset},
headers=HEADERS, timeout=30)
r.raise_for_status()
pagina = r.json()
yield from pagina["items"]
offset += len(pagina["items"])
if not pagina["items"] or offset >= pagina["page"]["total"]:
return
export async function* todosOsDossies(limite = 100) {
let offset = 0;
for (;;) {
const r = await fetch(`${API}/kyc/v1/dossiers?limit=${limite}&offset=${offset}`, { headers: HEADERS });
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const pagina = await r.json();
yield* pagina.items;
offset += pagina.items.length;
if (pagina.items.length === 0 || offset >= pagina.page.total) return;
}
}

Checar se já existe KYC válido (não consome cota)​

curl -s -X POST "$ZABIT_API/kyc/v1/current-dossier/lookup" \
-H "x-api-key: $ZABIT_KEY" -H "content-type: application/json" \
-d '{"document": "12345678909", "subtype": "kyc"}'
def kyc_vigente(documento: str) -> str:
r = requests.post(f"{API}/kyc/v1/current-dossier/lookup",
json={"document": documento, "subtype": "kyc"}, headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()["situacao"] # nenhum | valido | vencido | em_andamento | erro
export async function kycVigente(documento) {
const r = await fetch(`${API}/kyc/v1/current-dossier/lookup`, {
method: "POST",
headers: { ...HEADERS, "content-type": "application/json" },
body: JSON.stringify({ document: documento, subtype: "kyc" }),
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return (await r.json()).situacao; // nenhum | valido | vencido | em_andamento | erro
}