codespar_kyc
Identity verification. Persona (default INTL), Sift (fraud-score), Konduto (BR fraud), Truora (LATAM-wide). Async — track via verificationStatus.
codespar_kyc
Meta-tool
codespar_kyc issues KYC inquiries across multiple providers. Use it as a gate before high-value codespar_charge / codespar_pay calls or when a regulated workflow demands proof of identity. The call returns immediately with an inquiry_id; track the verdict via verificationStatus(toolCallId) or the streaming sibling.
There is no typed wrapper for codespar_kyc itself — call via session.execute(). Tracking has typed wrappers: session.verificationStatus(toolCallId) and session.verificationStatusStream(toolCallId, opts).
Rails
| Rail | Coverage | Country | Provider | Notes |
|---|---|---|---|---|
| Persona | INTL | INTL | Persona | Default. inquiry_template_id stamped per-tenant in connection_metadata |
| Sift | Fraud-score | INTL | Sift | Risk-score variant. HTTP Basic auth |
| Konduto | BR fraud | BR | Konduto | BR-focused fraud signals. HTTP Basic auth |
| Truora | LATAM | LATAM | Truora | Wider LATAM ID-document coverage |
Direct execute
const inquiry = await session.execute("codespar_kyc", {
operation: "create_inquiry",
subject: {
name: "Maria Silva",
document: "12345678900",
email: "maria@example.com",
document_type: "cpf",
},
metadata: { order_id: "1234" },
});
console.log(inquiry.tool_call_id, inquiry.inquiry_id, inquiry.status); // "pending"Then poll until terminal:
let v = await session.verificationStatus(inquiry.tool_call_id);
while (v.status === "pending") {
await new Promise((r) => setTimeout(r, 3000));
v = await session.verificationStatus(inquiry.tool_call_id);
}
// v.status is now approved | rejected | review | expiredOr stream:
await session.verificationStatusStream(inquiry.tool_call_id, {
onUpdate: (s) => console.log("kyc:", s.status),
});Args shape
| Field | Type | Required | Description |
|---|---|---|---|
operation | string | Yes | create_inquiry (today) |
subject | object | Yes | { name, document, document_type, email?, phone?, address? } |
provider | string | No | Force a specific rail (persona, sift, konduto, truora) |
metadata | object | No | Arbitrary key-value pairs persisted on the tool_calls row |
Result shape
type KYCResult = {
tool_call_id: string;
inquiry_id: string;
status: "pending"; // always pending; terminal state via verificationStatus
inquiry_url?: string; // Persona hosted flow URL when subject must complete steps
};Terminal verification states (returned by verificationStatus), in poll-priority order:
approved— KYC passed.rejected— KYC failed.review— manual review pending (provider human-in-the-loop).expired— verification window timed out.pending— still processing.
The polling priority matters: when multiple events have landed for the same tool_call_id (e.g. review then approved), the endpoint returns the highest-priority terminal state.
Operator setup
- Persona (default) — API key (
api_keyauth_type). Important: stampinquiry_template_idinconnection_metadatawhen the operator connects Persona — this is per-tenant operator-stamped, not passed at execute time. Without it the inquiry creation will fail. - Sift — HTTP Basic auth (API key as username, blank password).
- Konduto — HTTP Basic auth.
- Truora — API key.
The Persona inquiry_template_id lives in connected_accounts.connection_metadata (jsonb) — the dashboard's Persona connect modal renders an extra input for it.
Async verification
Verification follows the same correlation chain as payments — idempotency_key ↔ external_reference resolved via webhook. See async settlement → Verification (KYC) sibling for the full flow.
See also
- SDK reference — verificationStatus
- Async settlement → KYC sibling
- SSE streaming —
verificationStatusStream - KYC Agent cookbook — end-to-end gating example
- Tools & meta-tools — full meta-tool list
Last updated on