TypeScript SDK

One line of code. Every service. Automatic payments.

Installation

npm install @indiegent/sdk

Requires Node.js 18+ or any runtime with a global fetch implementation. Works in Node, Bun, Deno, Cloudflare Workers, and browser environments.


Quick Start

import { IndieGent } from "@indiegent/sdk";

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",
});

// Call any paid API — payment is handled automatically
const res = await agent.fetch("https://api.exa.ai/search");
const data = await res.json();

That's it. One API key, one agent name, and your agent can call any paid service. No private keys. No wallet addresses. No crypto setup. IndieGent handles billing on the backend.


Exports

The SDK exports the following:

// Main class
import { IndieGent } from "@indiegent/sdk";

// Convenience function (same as new IndieGent(config))
import { createAgent } from "@indiegent/sdk";

// Types
import type {
  IndieGentConfig,
  PaymentProtocol,
  PaymentChallenge,
  PaymentEvent,
} from "@indiegent/sdk";

Configuration

const agent = new IndieGent({
  // Authentication
  apiKey: "ig_live_...",              // Your IndieGent API key
  agentWallet: "my-research-agent",   // Which agent's budget to charge

  // Sessions (optional)
  sessionId: "session_abc123",        // Use a pre-funded session for batched payments

  // Safety
  maxAutoPayPerRequest: 1.00,         // Max USD per request (default: $1.00)

  // Advanced
  apiUrl: "https://api.indiegent.com", // API base URL (default)

  // Callbacks
  onPayment: (event) => {
    console.log(`Paid $${event.amount} for ${event.url}`);
  },
  onPaymentRequired: (details) => {
    console.log(`Payment of $${details.amount} required but couldn't be auto-handled`);
  },
});

All Options

OptionTypeDefaultDescription
apiKeystringYour IndieGent API key. Prefix ig_live_ for production, ig_test_ for testnet.
agentWalletstringThe name of the agent whose budget to charge (e.g. "my-research-agent").
sessionIdstringActive session ID for batched payments. When set, calls debit from the session balance instantly instead of per-call on-chain payments.
apiUrlstringhttps://api.indiegent.comOverride the API base URL (useful for local development or self-hosted instances).
maxAutoPayPerRequestnumber1.00Maximum USD the agent will automatically pay per request. If a service charges more than this, the request is not paid and the onPaymentRequired callback fires instead.
onPayment(event: PaymentEvent) => voidCalled after every successful payment. Useful for logging, auditing, or tracking spend in real time.
onPaymentRequired(details: PaymentChallenge) => voidCalled when a payment is required but could not be auto-handled (e.g. cost exceeds maxAutoPayPerRequest, or insufficient balance).

Calling External Services

This is the core feature. agent.fetch() works like the standard fetch() API, but when you call an external URL, the request is routed through IndieGent's backend. If the API requires payment (via MPP, x402, or any supported protocol), IndieGent pays automatically from your agent's budget and returns the result. Your code just gets the data.

import { IndieGent } from "@indiegent/sdk";

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",
});

// Call any paid API — payment is automatic
const flights = await agent.fetch(
  "https://aviationstack.mpp.tempo.xyz/v1/flights?flight_iata=BR67"
);
const data = await flights.json();

// Works with any HTTP method
const analysis = await agent.fetch("https://api.example.com/analyze", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ text: "Analyze this document" }),
});

// GET requests work too
const weather = await agent.fetch(
  "https://weather-api.mpp.tempo.xyz/v1/current?q=London"
);

No API keys to manage per service. No payment code to write. No accounts to create with each provider. One IndieGent API key unlocks every compatible service.


Marketplace Services

Use agent.service() to call APIs in the IndieGent marketplace. This is a shorthand that constructs the URL and sends a POST request for you.

// agent.service(serviceId, endpoint, body)

// Search the web
const search = await agent.service("exa", "/search", {
  query: "flights Bangkok to Chiang Mai",
  numResults: 10,
});
const results = await search.json();

// Book a flight
const booking = await agent.service("vakayo", "/flights/book", {
  offer_id: "offer_abc123",
});

// Send an email
await agent.service("pontius", "/send", {
  to: "me@email.com",
  subject: "Flight booked!",
  body: "Your confirmation details...",
});

// Generate an image
const image = await agent.service("supermachine", "/generate", {
  prompt: "sunset over Chiang Mai temples",
});

agent.service() returns a standard Response object, just like fetch(). Call .json(), .text(), or .blob() to read the response.

Under the hood, agent.service("exa", "/search", body) is equivalent to:

agent.fetch("https://api.indiegent.com/services/exa/search", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(body),
});

Checking Balance

Check your agent's current balance at any time:

const balance = await agent.getBalance();

console.log(balance.usdc); // "25.00" — USDC balance
console.log(balance.eth);  // "0.001" — ETH for gas (platform-sponsored)

Returns an object with usdc and eth as string values. The ETH balance is for gas fees and is automatically sponsored by the platform — you never need to manage it.


Sessions

For high-volume workloads, sessions let you pre-fund a batch of calls. Each call deducts from the session balance instantly — no per-call payment delay. This is ideal for agents making dozens or hundreds of API calls in a single task.

// Create a session via the API or CLI first, then pass the ID:
const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",
  sessionId: "session_abc123",  // Pre-funded with $5
});

// Each call deducts instantly from the session balance
const queries = [
  "AI agent infrastructure",
  "autonomous payment protocols",
  "machine-to-machine commerce",
];

for (const query of queries) {
  const result = await agent.service("exa", "/search", { query });
  const data = await result.json();
  // No delay — session balance is debited immediately
  console.log(`Found ${data.results.length} results for "${query}"`);
}

Session Lifecycle

  1. Open a session via the REST API (POST /sessions) or the CLI. USDC is deposited from the agent wallet.
  2. Use the session by passing sessionId in the SDK config. Every call debits from the session balance instantly.
  3. Close the session when done. Unused balance is automatically refunded to the agent wallet.

Sessions auto-expire after their configured duration (default 1 hour, max 24 hours). Expired sessions can still be closed to trigger a refund.


Safety Controls

IndieGent is designed to give you full control over what your agents spend. Multiple layers of protection prevent runaway costs.

Per-Request Cap

maxAutoPayPerRequest sets the maximum amount the agent will automatically pay for a single request. If a service charges more than this, the payment is blocked and onPaymentRequired fires instead.

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",
  maxAutoPayPerRequest: 0.50, // Block anything over $0.50

  onPaymentRequired: (details) => {
    console.warn(
      `Blocked: ${details.amount} ${details.currency} exceeds safety cap`
    );
    // Decide whether to proceed, escalate, or skip
  },
});

Payment Logging

The onPayment callback fires after every successful payment, giving you real-time visibility into spend.

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",

  onPayment: (event) => {
    console.log(`[${new Date(event.timestamp).toISOString()}] Paid $${event.amount} USDC`);
    console.log(`  Service: ${event.url}`);
    console.log(`  Protocol: ${event.protocol}`);
    console.log(`  Tx: ${event.txHash}`);

    // Send to your observability stack
    metrics.increment("agent.spend", parseFloat(event.amount));
  },
});

Additional Safeguards

  • Agent wallet isolation — Each agent has its own budget. One agent cannot spend another agent's funds.
  • Spending caps — Set per-agent spending caps in the dashboard or via the API to limit total exposure.
  • Agent policies — Restrict which services an agent can access, set daily/monthly limits, and require sessions for certain agents.
  • Balance checks — The backend verifies sufficient funds before executing any payment.

Environment Variables

Your agent only needs one environment variable:

INDIEGENT_API_KEY=ig_live_abc123def456...

Get your API key from the dashboard (Settings → API Keys) or the CLI:

# Generate an API key via CLI
indiegent api-keys create --name "my-agent-key"

# Or export it directly into your agent's environment
eval $(indiegent agents env "my-research-agent")

The agentWallet parameter identifies which agent's budget to charge and is set in code (not as an environment variable), so a single API key can be used across multiple agents if needed.


Framework Examples

Plain TypeScript

import { IndieGent } from "@indiegent/sdk";

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",
});

async function research(topic: string) {
  // Search for information
  const searchRes = await agent.service("exa", "/search", {
    query: topic,
    numResults: 5,
  });
  const { results } = await searchRes.json();

  // Summarize with an LLM
  const summaryRes = await agent.fetch(
    "https://api.openai.com/v1/chat/completions",
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        model: "gpt-4",
        messages: [
          {
            role: "user",
            content: `Summarize these results about "${topic}":\n${JSON.stringify(results)}`,
          },
        ],
      }),
    }
  );

  return summaryRes.json();
}

await research("autonomous AI agent infrastructure");

CrewAI (Python with TypeScript SDK)

Use the SDK as a tool provider for CrewAI agents. The agent calls IndieGent-powered services through a simple wrapper.

// tools/search.ts — expose as an MCP tool or HTTP endpoint
import { IndieGent } from "@indiegent/sdk";

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "crewai-researcher",
});

export async function webSearch(query: string) {
  const res = await agent.service("exa", "/search", { query, numResults: 10 });
  return res.json();
}

export async function sendEmail(to: string, subject: string, body: string) {
  const res = await agent.service("pontius", "/send", { to, subject, body });
  return res.json();
}

LangGraph / LangChain

import { IndieGent } from "@indiegent/sdk";

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "langgraph-agent",
  maxAutoPayPerRequest: 0.25,
});

// Use as a tool in your LangGraph workflow
const searchTool = {
  name: "web_search",
  description: "Search the web for current information",
  execute: async (query: string) => {
    const res = await agent.service("exa", "/search", { query });
    return res.json();
  },
};

Claude Agent SDK

import { IndieGent } from "@indiegent/sdk";

const agent = new IndieGent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "claude-agent",
});

// Provide as a tool to Claude
const tools = [
  {
    name: "paid_api_call",
    description: "Call any external API. IndieGent handles payment.",
    input_schema: {
      type: "object",
      properties: {
        url: { type: "string" },
        method: { type: "string", default: "GET" },
        body: { type: "object" },
      },
      required: ["url"],
    },
    execute: async (input: { url: string; method?: string; body?: unknown }) => {
      const res = await agent.fetch(input.url, {
        method: input.method || "GET",
        headers: input.body ? { "Content-Type": "application/json" } : undefined,
        body: input.body ? JSON.stringify(input.body) : undefined,
      });
      return res.json();
    },
  },
];

Error Handling

The SDK returns standard Response objects, so you handle errors the same way you would with fetch().

try {
  const res = await agent.fetch("https://api.example.com/data");

  if (!res.ok) {
    const error = await res.json();
    console.error(`Request failed (${res.status}): ${error.message}`);
    return;
  }

  const data = await res.json();
  console.log(data);
} catch (err) {
  // Network errors, DNS failures, etc.
  console.error("Network error:", err);
}

Common Status Codes

StatusMeaningWhat to Do
200SuccessRequest completed, payment handled automatically if needed.
401UnauthorizedCheck that your API key is valid and not revoked.
402Payment requiredInsufficient balance to pay for the request. Fund the agent wallet and retry.
422Cost exceeds capThe service charges more than maxAutoPayPerRequest. Increase the cap or handle via onPaymentRequired.
429Rate limitedToo many requests. Back off and retry after a delay.
500Server errorRetry the request. If persistent, check the service status.

Balance Check Before Work

For long-running tasks, check your balance upfront to avoid failures mid-execution:

const balance = await agent.getBalance();
const available = parseFloat(balance.usdc);

if (available < 5.0) {
  console.warn(`Low balance: $${available}. Fund the agent before proceeding.`);
  process.exit(1);
}

// Safe to proceed with work
await runResearchPipeline();

TypeScript Types

PaymentEvent

Passed to the onPayment callback after every payment.

interface PaymentEvent {
  protocol: "mpp" | "x402" | "indiegent" | "unknown";
  amount: string;      // USD amount paid
  currency: string;    // Always "USDC"
  recipient: string;   // Payment recipient address
  txHash: string;      // Transaction hash or "proxy"
  url: string;         // The URL that was called
  timestamp: number;   // Unix timestamp (ms)
}

PaymentChallenge

Passed to the onPaymentRequired callback when a payment cannot be auto-handled.

interface PaymentChallenge {
  protocol: "mpp" | "x402" | "indiegent" | "unknown";
  amount: string;
  currency: string;
  recipient: string;
  chain?: string;
  chainId?: number;
  memo?: string;
  raw: unknown;        // Raw response for custom handling
}

createAgent Helper

If you prefer a functional style, createAgent() is a convenience wrapper around new IndieGent():

import { createAgent } from "@indiegent/sdk";

const agent = createAgent({
  apiKey: process.env.INDIEGENT_API_KEY,
  agentWallet: "my-research-agent",
});

// Identical to: new IndieGent({ ... })

Related

  • Quickstart — Create your first agent wallet in 2 minutes
  • API Reference — REST API for sessions, wallets, and more
  • CLI — Terminal-based wallet management
  • Marketplace — Browse available services
  • Security — How keys and payments are protected
IndieGent— Independent wallets for independent agents

npm install -g @indiegent/cli