TypeScript SDK for the AffixIO agentic trust and verification API. Designed for AI agents, issuer processors, and fintech / payments teams that need reliable agent identity, consent verification, and trusted payment authorization across high-risk transactions.
- Agentic payments ready: Purpose-built helpers for issuer authorizations, merchant checkouts, and high-value payment flows.
- AI agent verification: Verify that an AI agent or automation is allowed to act on behalf of a human or business.
- Consent & policy enforcement: Check consent references and business rules before executing transactions.
- Composite verification circuits: Chain multiple circuits (e.g.
agentic-payment-permission,finance-account-standing,finance-fraud-indicator) into one decision. - Production-grade error handling: Distinct error types for transport, API, and validation failures.
- Full TypeScript support: Strongly-typed client, inputs, and responses.
- Stateless architecture: Each verification call is independent; easy to scale horizontally.
- Minimal dependencies: Uses native
fetch; ideal for Node.js services, edge runtimes, and serverless.
Use cases: AI agent payments, autonomous procurement, agentic checkout, delegated card controls, high-risk transaction decisioning.
npm install @affix-io/agentic-trustor with pnpm / yarn:
pnpm add @affix-io/agentic-trust
yarn add @affix-io/agentic-trustimport { AffixioClient } from '@affix-io/agentic-trust';
// Initialize with API key
const client = new AffixioClient({
apiKey: process.env.AFFIXIO_API_KEY!,
baseUrl: 'https://api.affix-io.com', // optional, default shown
timeoutMs: 5000, // optional, default shown
});
// Or load from environment variables: AFFIXIO_API_KEY, AFFIXIO_BASE_URL, AFFIXIO_TIMEOUT_MS
const clientFromEnv = AffixioClient.fromEnv();Verify if an AI agent / processor is authorized to perform a payment on behalf of an account holder:
const result = await client.verifyIssuerAgentAuthorization({
agentId: 'agent:procurement-001',
accountId: 'acct_12345',
consentReference: 'consent_abc_xyz',
amount: 14900, // in minor units (cents)
currency: 'USD',
merchantCategory: 'software_subscription',
merchantId: 'merchant_xyz',
channel: 'account_to_account',
additionalRiskContext: {
ip_country: 'US',
device_trust_score: 0.95,
},
});
if (result.eligible) {
console.log('Agent authorized; proof:', result.proof);
// Proceed with payment
} else {
console.log('Agent not authorized');
// Decline or step up authentication
}Verify if an agent can safely proceed with a checkout on behalf of a merchant:
const result = await client.verifyMerchantAgentCheckout({
agentId: 'agent:checkout-bot-001',
customerId: 'cust_456',
basketTotalCents: 5999,
currency: 'USD',
merchantId: 'merchant_xyz',
merchantCategory: 'software_subscription',
basketCategories: ['licenses', 'support'],
sessionId: 'sess_789',
policyReference: 'policy_tier_2',
});
if (result.eligible) {
// Safe to process checkout
recordTransaction(result.proof);
} else {
// Require merchant approval or additional steps
}Verify that valid consent exists for an agentic transaction:
const result = await client.verifyAgentConsent({
agentId: 'agent:travel-planner',
consentReference: 'consent_flight_booking_2024',
transactionContext: {
amount_cents: 2500,
currency: 'USD',
merchant_category: 'travel_agency',
purpose: 'flight_booking',
},
});
if (result.eligible) {
// Consent is valid; proceed
} else {
// Require fresh consent
}Chain multiple circuits and get a single overall eligibility decision. Useful for high-value or high-risk payments where you want to verify multiple risk factors in sequence:
const result = await client.verifyAgentPaymentComposite({
agentId: 'agent:high-value-processor',
accountId: 'acct_hv_001',
consentReference: 'consent_ref_xyz',
transactionContext: {
amount_cents: 500000, // $5,000
currency: 'USD',
merchant_category: 'travel_agency',
merchant_id: 'merchant_luxury',
},
// Optional: specify custom circuits; defaults to:
// ['agentic-payment-permission', 'finance-account-standing', 'finance-fraud-indicator']
circuits: [
'agentic-payment-permission',
'finance-account-standing',
'finance-fraud-indicator',
],
});
if (result.overallEligible) {
console.log('All checks passed; aggregate proof:', result.aggregatedProof);
// Proceed with payment
} else {
console.log('At least one circuit failed:');
result.perCircuit.forEach((r) => {
console.log(` ${r.circuitId}: ${r.eligible ? 'PASS' : 'FAIL'}`);
});
// Decline or escalate
}The SDK distinguishes between three error types:
Network failures, timeouts, or connection issues:
import { AffixioTransportError } from '@affix-io/agentic-trust';
try {
await client.verifyIssuerAgentAuthorization({ /* ... */ });
} catch (error) {
if (error instanceof AffixioTransportError) {
console.error('Network issue:', error.message);
// Retry with backoff; consider fallback
}
}4xx or 5xx responses from the server:
import { AffixioApiError } from '@affix-io/agentic-trust';
try {
await client.verifyIssuerAgentAuthorization({ /* ... */ });
} catch (error) {
if (error instanceof AffixioApiError) {
console.error(`API error ${error.status}:`, error.body);
console.error('Request ID:', error.requestId); // Use for support requests
// Log for alerting and debugging
}
}Missing or invalid fields on the client side:
import { AffixioValidationError } from '@affix-io/agentic-trust';
try {
await client.verifyIssuerAgentAuthorization({
agentId: 'agent:test',
// Missing required fields...
});
} catch (error) {
if (error instanceof AffixioValidationError) {
console.error(`Validation failed on ${error.field}: ${error.message}`);
// Fix your input and retry
}
}All verification responses include a proof field—a cryptographic proof or hash that uniquely identifies the verification. Use this for audit trails and transaction reconciliation:
const result = await client.verifyIssuerAgentAuthorization({...});
// Persist the proof with your transaction record
recordTransaction({
agentId: 'agent:procurement-001',
accountId: 'acct_12345',
verificationProof: result.proof,
circuitId: result.circuit_id,
latency_ms: result.latency_ms,
timestamp: new Date().toISOString(),
});For composite verifications, aggregatedProof combines proofs from all circuits:
const result = await client.verifyAgentPaymentComposite({...});
// Log composite result with per-circuit breakdown
logPaymentVerification({
overallEligible: result.overallEligible,
aggregatedProof: result.aggregatedProof,
circuitResults: result.perCircuit.map((r) => ({
circuitId: r.circuitId,
eligible: r.eligible,
proof: r.proof,
latencyMs: r.latency_ms,
})),
});Set these to use AffixioClient.fromEnv():
AFFIXIO_API_KEY(required): Bearer token for API authenticationAFFIXIO_BASE_URL(optional): API endpoint; defaults tohttps://api.affix-io.comAFFIXIO_TIMEOUT_MS(optional): Request timeout in milliseconds; defaults to5000
Provide a logger to track SDK activity:
const client = new AffixioClient({
apiKey: process.env.AFFIXIO_API_KEY!,
logger: {
info: (message, metadata) => console.log(`[INFO] ${message}`, metadata),
warn: (message, metadata) => console.warn(`[WARN] ${message}`, metadata),
error: (message, metadata) => console.error(`[ERROR] ${message}`, metadata),
},
});Returned by all verification methods.
interface VerifyResponse {
eligible: boolean; // Is the agent/user eligible?
proof: string; // Cryptographic proof of the verification
circuit_id: string; // Which circuit ran?
latency_ms?: number; // How long did the verification take?
logged?: boolean; // Was the result logged server-side?
raw?: unknown; // Raw API response (if needed for custom handling)
}Returned by verifyAgentPaymentComposite().
interface AgentPaymentCompositeResponse {
overallEligible: boolean; // Synthesis of all circuits
perCircuit: CompositeCircuitResult[];
aggregatedProof: string; // Combined proof from all circuits
}npm run buildCompiles TypeScript to ./dist with type declarations.
npm testRuns unit tests covering:
- Happy path verification calls
- Error handling and mapping
- Validation of required fields
- Composite verification logic
The SDK is organized as:
client.ts: MainAffixioClientclass with public verification methodstypes.ts: TypeScript type definitions (no runtime code)errors.ts: Custom error classes (Transport, API, Validation)http.ts: Low-level HTTP abstraction using nativefetchhelpers.ts: Request builders and utility functionsindex.ts: Public API exports
Zero dependencies beyond Node.js built-ins and TypeScript.
- Stateless: No sessions or stored state. Each call is independent.
- Strongly typed: Full TypeScript for safety and IDE support.
- Minimal: No unnecessary abstractions. One method per use case.
- Portable: Pattern is designed to be ported to Go, Java, Python with minimal changes.
- Observable: Every call generates a proof and optional latency metrics for audit trails.
MIT