Documentation Index
Fetch the complete documentation index at: https://agentref.co/docs/llms.txt
Use this file to discover all available pages before exploring further.
This page provides ready-to-use patterns for common agent workflows. Each example shows the complete tool sequence or SDK code an AI agent would use, with both Node.js and Python implementations.
Pattern 1: Set Up a Complete Affiliate Program
This workflow creates a program, connects Stripe, checks readiness, publishes marketplace settings, and invites the first affiliates — everything a merchant needs to go live from the REST/SDK surface.
import { AgentRef } from 'agentref';
const client = new AgentRef({ apiKey: process.env.AGENTREF_API_KEY });
// Step 1: Create the program
const program = await client.programs.create({
name: 'Acme Pro Referrals',
commissionType: 'recurring',
commissionPercent: 25,
cookieDuration: 60,
payoutThreshold: 5000, // $50.00 in cents
autoApproveAffiliates: true,
currency: 'USD',
}, { idempotencyKey: 'setup-acme-pro-v1' });
console.log(`Program created: ${program.id}`);
// Step 2: Connect Stripe
const stripe = await client.programs.connectStripe(program.id);
console.log(`Complete Stripe OAuth at: ${stripe.authUrl}`);
// The merchant opens this URL in a browser to connect their Stripe account
// Step 3: Check readiness
const detail = await client.programs.get(program.id);
console.log(`Readiness: ${detail.readiness}`);
// Step 4: Publish to marketplace
await client.programs.updateMarketplace(program.id, {
status: 'public',
category: 'SaaS',
description: 'Earn 25% recurring commission on every referral.',
});
// Step 5: Invite affiliates
const invite = await client.programs.createInvite(program.id, {
email: 'top-affiliate@example.com',
name: 'Top Affiliate',
expiresInDays: 14,
}, { idempotencyKey: 'invite-top-affiliate-v1' });
console.log(`Invite sent: ${invite.token}`);
// Step 6: Create a public invite link for broader distribution
const publicInvite = await client.programs.createInvite(program.id, {
isPublic: true,
usageLimit: 100,
expiresInDays: 30,
}, { idempotencyKey: 'public-invite-v1' });
Pattern 2: Monitor Conversions and Flag Fraud
This workflow checks recent conversions, reviews fraud flags, and takes action on suspicious activity. Ideal for a scheduled agent task.
import { AgentRef } from 'agentref';
const client = new AgentRef({ apiKey: process.env.AGENTREF_API_KEY });
// Step 1: Check conversion stats for the last 7 days
const stats = await client.conversions.stats({ period: '7d' });
console.log(`Last 7 days: ${stats.total} conversions, $${stats.totalRevenue / 100} revenue`);
console.log(`Pending: ${stats.pending}, Approved: ${stats.approved}`);
// Step 2: List recent conversions that need review
const { data: conversions } = await client.conversions.list({
status: 'pending',
limit: 50,
});
console.log(`${conversions.length} pending conversions to review`);
// Step 3: Check for open fraud flags
const flagStats = await client.flags.stats();
console.log(`Open fraud flags: ${flagStats.open}`);
if (flagStats.open > 0) {
const { data: flags } = await client.flags.list({
status: 'open',
limit: 20,
});
for (const flag of flags) {
console.log(`Flag ${flag.id}: ${flag.type} for affiliate ${flag.affiliateId}`);
// Step 4: Auto-dismiss low-risk flags, escalate high-risk
if (flag.type === 'high_click_frequency') {
// Get the affiliate's full stats for context
const affiliate = await client.affiliates.get(flag.affiliateId, {
include: 'stats',
});
if (affiliate.totalConversions > 0) {
// Has real conversions -- likely legitimate traffic
await client.flags.resolve(flag.id, {
status: 'dismissed',
note: `Auto-dismissed: ${affiliate.totalConversions} conversions confirm legitimate traffic`,
blockAffiliate: false,
}, { idempotencyKey: `resolve-${flag.id}` });
} else {
// No conversions -- suspicious, confirm the flag
await client.flags.resolve(flag.id, {
status: 'confirmed',
note: 'Zero conversions with high click volume -- confirmed suspicious',
blockAffiliate: true,
}, { idempotencyKey: `resolve-${flag.id}` });
}
}
}
}
Pattern 3: Generate Weekly Payout Report
This workflow lists pending payouts, aggregates stats, and generates a report. Useful for weekly cron jobs or scheduled agent tasks.
import { AgentRef } from 'agentref';
const client = new AgentRef({ apiKey: process.env.AGENTREF_API_KEY });
// Step 1: Get payout stats
const payoutStats = await client.payouts.stats({ period: '30d' });
console.log(`Total paid (30d): $${payoutStats.totalPaid / 100}`);
console.log(`Total pending: $${payoutStats.totalPending / 100}`);
// Step 2: List all pending affiliates across programs
const pending = await client.payouts.listPending();
const report = {
generatedAt: new Date().toISOString(),
totalPending: pending.meta.total,
affiliates: pending.data.map(aff => ({
name: aff.name ?? aff.email,
program: aff.programName,
amount: `$${aff.pendingAmount / 100}`,
currency: aff.currency,
method: aff.payoutMethod ?? 'Not set',
meetsThreshold: aff.meetsThreshold,
commissionCount: aff.commissionCount,
})),
};
console.log('--- Weekly Payout Report ---');
console.log(JSON.stringify(report, null, 2));
// Step 3: For affiliates who meet the threshold and have a payout method,
// create the payout
const eligible = pending.data.filter(
aff => aff.meetsThreshold && aff.hasPayoutMethod
);
console.log(`\n${eligible.length} affiliates eligible for payout`);
for (const aff of eligible) {
const payout = await client.payouts.create({
affiliateId: aff.affiliateId,
programId: aff.programId,
method: aff.payoutMethod!,
notes: `Weekly payout - ${new Date().toISOString().split('T')[0]}`,
}, { idempotencyKey: `weekly-payout-${aff.affiliateId}-${Date.now()}` });
console.log(`Created payout for ${aff.name}: $${aff.pendingAmount / 100}`);
}
// Step 4: Get recent completed payouts for the report footer
const { data: recentPayouts } = await client.payouts.list({
status: 'completed',
limit: 10,
});
console.log(`\nRecent completed payouts: ${recentPayouts.length}`);
Idempotency Patterns for Safe Agent Retries
AI agents may retry operations due to timeouts, network failures, or tool-calling loops. Idempotency keys ensure these retries are safe.
Deterministic Keys
Generate idempotency keys from the operation’s intent, not random values:
// Good: deterministic key based on intent
const key = `create-program-${programName}-${Date.now()}`;
// Better: based on a stable external identifier
const key = `invite-${email}-to-${programId}`;
// Best: includes a version for intentional re-runs
const key = `setup-acme-program-v2`;
Retry-Safe Workflows
When chaining multiple operations, use a unique key for each step:
const workflowId = 'onboard-acme-2026-03';
// Each step gets its own scoped key
const program = await client.programs.create({
name: 'Acme Referrals',
commissionType: 'recurring',
commissionPercent: 25,
}, { idempotencyKey: `${workflowId}-create-program` });
await client.programs.createInvite(program.id, {
email: 'partner@example.com',
}, { idempotencyKey: `${workflowId}-invite-partner` });
// Review pending applications through the Applications API or MCP review_application tool.
// Use a separate key such as `${workflowId}-approve-application-${applicationId}`.
Error Handling Patterns
Graceful Degradation
When an agent encounters an error, it should attempt recovery before giving up:
import { AgentRef, NotFoundError, RateLimitError, AgentRefError } from 'agentref';
const client = new AgentRef();
async function safeGetProgram(id: string) {
try {
return await client.programs.get(id);
} catch (error) {
if (error instanceof NotFoundError) {
// Program doesn't exist -- list all programs and pick the first
const { data } = await client.programs.list({ status: 'active', limit: 1 });
return data[0] ?? null;
}
if (error instanceof RateLimitError) {
// Wait and retry
await new Promise(r => setTimeout(r, error.retryAfter * 1000));
return await client.programs.get(id);
}
throw error;
}
}
async function safeResolveFlag(flagId: string) {
try {
await client.flags.resolve(flagId, {
status: 'reviewed',
note: 'Reviewed by automated agent',
}, { idempotencyKey: `auto-review-${flagId}` });
return { success: true };
} catch (error) {
if (error instanceof AgentRefError) {
return {
success: false,
error: error.code,
message: error.message,
requestId: error.requestId,
};
}
throw error;
}
}
Logging and Observability
Always capture the requestId from errors for debugging:
try {
await client.conversions.list({ status: 'invalid_status' });
} catch (error) {
if (error instanceof AgentRefError) {
console.error(`AgentRef error [${error.requestId}]: ${error.code} - ${error.message}`);
// Send to your observability platform
sentry.captureException(error, {
extra: { requestId: error.requestId, code: error.code },
});
}
}