Skip to main content
ConceptsMeta-tools

codespar_kyc

Identity verification. Persona (default INTL), Sift (fraud-score), Konduto (BR fraud), Truora (LATAM-wide). Async — track via verificationStatus.

2 min read · updated

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

RailCoverageCountryProviderNotes
PersonaINTLINTLPersonaDefault. inquiry_template_id stamped per-tenant in connection_metadata
SiftFraud-scoreINTLSiftRisk-score variant. HTTP Basic auth
KondutoBR fraudBRKondutoBR-focused fraud signals. HTTP Basic auth
TruoraLATAMLATAMTruoraWider 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 | expired

Or stream:

await session.verificationStatusStream(inquiry.tool_call_id, {
  onUpdate: (s) => console.log("kyc:", s.status),
});

Args shape

FieldTypeRequiredDescription
operationstringYescreate_inquiry (today)
subjectobjectYes{ name, document, document_type, email?, phone?, address? }
providerstringNoForce a specific rail (persona, sift, konduto, truora)
metadataobjectNoArbitrary 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:

  1. approved — KYC passed.
  2. rejected — KYC failed.
  3. review — manual review pending (provider human-in-the-loop).
  4. expired — verification window timed out.
  5. 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_key auth_type). Important: stamp inquiry_template_id in connection_metadata when 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_keyexternal_reference resolved via webhook. See async settlement → Verification (KYC) sibling for the full flow.

See also

Edit on GitHub

Last updated on