Skip to main content
Meta-tools

codespar_kyc

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

3 min read
View MarkdownEdit on GitHub

codespar_kyc

Meta-tool

Sell-side. Your agent is the merchant: it collects from, invoices, ships to, or verifies a counterparty.

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 a verification_id; track the verdict via verificationStatus(toolCallId) or the streaming sibling. For onboarding, poll with codespar_kyc and check_type: "status".

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
identityINTLINTLPersonaDefault. inquiry_template_id stamped per-tenant in connection_metadata
risk-scoreFraud-scoreINTLSiftRisk-score variant. HTTP Basic auth
risk-scoreBR fraudBRKondutoBR-focused fraud signals. HTTP Basic auth
identityLATAMINTLTruoraWider LATAM ID-document coverage
onboardingBRBRLicensed BaaS partnercheck_type: "onboarding". Verifies (background check + documentoscopy) AND provisions a real payment account for the consumer, which becomes the codespar_wallet funding source. Poll with check_type: "status".

Direct execute

const inquiry = await session.execute("codespar_kyc", {
  check_type: "identity",
  buyer: {
    name: "Maria Silva",
    document: "12345678900",
    country: "BR",
    email: "maria@example.com",
  },
  metadata: { order_id: "1234" },
});

console.log(inquiry.tool_call_id, inquiry.data.verification_id, inquiry.data.status);

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
check_typestringYesidentity, document, risk-score, sanctions, onboarding (open a BR payment account), or status (poll a prior onboarding)
buyerobjectYesThe subject. For verification: { name, document, country, email }. For onboarding: { fullName, document (CPF), email, phoneNumber (+55…), birthDate (DD-MM-YYYY), motherName, address, country }
verification_idstringNoReturned when a check is created. With check_type: "status" it narrows the lookup to that onboarding; document_number alone also resolves it
document_numberstringWith statusCPF, the account lookup key when polling an onboarding
consumer_idstringNoWhose account or verification. Defaults to the session user (onboarding and status).
metadataobjectNoProvider-specific overrides

For onboarding, check_type: "status" returns pending, documentscopy_pending (with a hosted_url where the consumer finishes document capture), approved (with the funding source and the Pix key), rejected, or unknown when the provider state cannot be resolved yet. In sandbox, a phoneNumber ending in 1 auto-approves both gates.

Result shape

type ToolResult = {
  success: boolean;
  data: {
    verification_id: string;
    status: string;        // provider status on create (e.g. CREATED, PROCESSING); the verdict comes from polling
    hosted_url: string | null; // hosted-flow URL when the provider needs the subject to complete steps
    check_type: string;
  };
  error: string | null;
  tool_call_id?: string;
};

For onboarding, the create call returns hosted_url: null; the document-capture link is surfaced by check_type: "status" while the state is documentscopy_pending.

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

codespar_kyc | CodeSpar