Skip to main content
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, retrieves the tracking snippet, connects Stripe, and invites the first affiliates — everything a merchant needs to go live.
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: Get the tracking snippet
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` });

await client.affiliates.approve(affiliateId, {
  idempotencyKey: `${workflowId}-approve-${affiliateId}`,
});

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 },
    });
  }
}