---
name: mixrpay
description: Agent payment infrastructure. Budget-controlled LLM calls, MCP server deployment, nested agent spawning, skill management, and autonomous payments via x402.
license: MIT
homepage: https://mixrpay.com
metadata:
  author: mixrpay
  version: "2.2.0"
  sdk_version: "0.8.8"
  repository: https://github.com/mixrpay/clawhub-skill-mixrpay
  skills_repo: https://github.com/mixrpay/agent-skills
compatibility: Requires node>=18. Set MIXRPAY_SESSION_KEY env var.
user-invocable: true
---

```
MIXRPAY AGENT SDK QUICK REFERENCE v2.2.0
SDK:    npm install @mixrpay/agent-sdk
Auth:   MIXRPAY_SESSION_KEY env var (auto-provisioned on platform, or claim via invite)
Docs:   This file is canonical — skills guide + SDK reference + platform features
Repo:   https://github.com/mixrpay/clawhub-skill-mixrpay

Capabilities: LLM calls + MCP servers + agent spawning + x402 payments + skills + cron + sandboxes + approvals
Catalog:  https://mixrpay.com/gateway (browse APIs and pricing)

LLM:
  wallet.complete(prompt, opts?)           -> one-shot LLM completion
  wallet.runAgent(opts)                    -> multi-turn agentic loop with tools
  wallet.getAgentRunStatus(runId)          -> check status of a previous run

Payments:
  wallet.callMerchantApi(opts)             -> session-based payment to MixrPay merchant
  wallet.fetch(url, opts?)                 -> HTTP with auto x402 payment on 402
  wallet.executeTransaction({ to, data, estimatedCostUsd });  // Execute on-chain transaction
  wallet.getOrCreateSession(opts)          -> create/get session with merchant
  wallet.chargeSession(id, amt, opts)      -> manual charge against session
  wallet.listSessions()                    -> list active sessions
  wallet.revokeSession(id)                 -> revoke a session

Budget:
  wallet.getSpendingStats()                -> spending stats (spent, remaining, tx count)
  wallet.getAvailableBudget()              -> detailed breakdown (available, allocated, spawn cap)
  wallet.getBalance()                      -> on-chain USDC balance
  wallet.canAfford(amountUsd)              -> pre-flight balance check
  wallet.getSessionKeyInfo()               -> session key details and limits
  wallet.getSessionStats()                 -> overview across all sessions

Spawning:
  wallet.spawnChildInvite(opts)            -> delegate budget to child agent (max 20%)
  wallet.getChildSessions()                -> list spawned children

MCP Servers:
  wallet.searchGlamaDirectory(query)       -> search 15,000+ MCP servers
  wallet.deployJitMcp(opts)                -> deploy JIT MCP server ($1/deploy)
  wallet.listJitInstances(opts?)           -> list deployed servers
  wallet.stopJitInstance(id)               -> stop a server

Skills:
  wallet.configureSkill(id, envVars)       -> save API key for a skill (hot-reload)
  wallet.useSkill(id)                      -> deploy and use skill's MCP tools
  wallet.getConnectedApps()                -> list OAuth-connected apps (Composio)
  wallet.listSkills()                      -> list available skills

Utility:
  wallet.runDiagnostics()                  -> health check (balance, latency, limits)
  wallet.setDebug(bool)                    -> toggle debug logging
  wallet.on('payment', cb)                 -> payment event listener
  AgentWallet.claimInvite(opts)            -> claim invite code to get session key

Platform (for deployed agents):
  Cron jobs & heartbeat tasks             -> schedule recurring work
  Code sandboxes                          -> isolated code execution (E2B)
  Human approval workflow                 -> request sign-off before sensitive actions
  LLM gateway                             -> OpenAI-compatible endpoint (with gateway key)
```

# MixrPay Agent SDK — Skills Guide

Give your agent a wallet with spending limits. Make LLM calls. Deploy MCP servers. Spawn child agents. Configure skills. Pay for external APIs automatically.

## What You Can Do

1. **Make LLM calls** — budget-controlled completions and multi-turn agentic loops with tool execution
2. **Pay for APIs** — call any MixrPay merchant with `callMerchantApi()` or any x402-compatible API with `fetch()`
3. **Deploy MCP servers** — search 15,000+ servers in the Glama directory and deploy on-demand with your own API keys
4. **Spawn child agents** — delegate up to 20% of your budget to child agents (10 levels deep)
5. **Configure skills** — save API keys for predefined skills (web-search, GitHub, Notion, etc.) or custom services
6. **Use OAuth apps** — access Gmail, Slack, Notion, GitHub, Linear, Google Calendar, and more via Composio
7. **Schedule recurring work** — cron jobs and heartbeat tasks for deployed agents
8. **Execute code** — E2B sandboxes for isolated code execution
9. **Request human approval** — propose actions and wait for human sign-off
10. **Share files** — generate signed download URLs from your workspace

## Deployment Context

When deployed via MixrPay, your agent runs on managed infrastructure powered by the OpenClaw runtime. Everything is pre-configured:

**Auto-provisioned (no setup needed):**
- `MIXRPAY_SESSION_KEY` — your session key with budget, ready to use
- LLM gateway access — built-in, no API keys required
- Channel tokens (`TELEGRAM_BOT_TOKEN`, etc.) — when Telegram/Slack/Discord channels are configured
- Skill system, cron jobs, heartbeat tasks, file sharing — all available out of the box

**Self-hosted agents** must claim an invite manually to get a session key (see Quick Start below).

## Quick Start

### 1. Install

```bash
npm install @mixrpay/agent-sdk
```

### 2. Initialize (Platform — Session Key Pre-Configured)

```javascript
import { AgentWallet } from '@mixrpay/agent-sdk';

const wallet = new AgentWallet({
  sessionKey: process.env.MIXRPAY_SESSION_KEY
});
```

### 3. Make an LLM Call

```javascript
const result = await wallet.complete('Summarize this article: ...');
console.log(result.text);
console.log(`Cost: $${result.costUsd.toFixed(4)}`);

// With options
const result = await wallet.complete('Write a haiku', {
  model: 'gpt-4o',
  systemPrompt: 'You are a poet.'
});
```

### 4. Check Budget

```javascript
const stats = await wallet.getSpendingStats();
console.log(`Spent: $${stats.totalSpentUsd}`);
console.log(`Remaining: $${stats.remainingTotalUsd ?? 'unlimited'}`);

if (stats.remainingTotalUsd !== null && stats.remainingTotalUsd < estimatedCost) {
  return "Need more budget from human";
}
```

### 5. Claim an Invite (Self-Hosted Only)

If not auto-provisioned, an agent can claim an invite manually:

```javascript
const result = await AgentWallet.claimInvite({
  inviteCode: 'mixr-abc123...',
  privateKey: process.env.AGENT_WALLET_KEY
});

// IMPORTANT: Save immediately — shown ONCE, cannot be recovered
// Store as env var: MIXRPAY_SESSION_KEY=sk_live_xxx
const wallet = new AgentWallet({
  sessionKey: result.sessionKey
});

console.log(`Budget: $${result.limits.budgetUsd}`);
console.log(`Invited by: ${result.inviterName}`);
```

## Constructor

```javascript
import { AgentWallet } from '@mixrpay/agent-sdk';

const wallet = new AgentWallet({
  sessionKey: string,            // Required: "sk_live_{hex}" or from env
  maxPaymentUsd?: number,        // Optional: client-side per-payment safety limit
  timeout?: number,              // Optional: request timeout in ms (default: 30000)
  logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none',
  onPayment?: (payment) => void  // Optional: callback on each payment
});
```

## Complete SDK Method Reference

### Static Methods

#### `AgentWallet.claimInvite(options)`

Claim an invite code to get a session key. Used for manual setup when not auto-provisioned.

```javascript
const result = await AgentWallet.claimInvite({
  inviteCode: string,        // e.g., "mixr-abc123..."
  privateKey: `0x${string}`, // Agent's private key (used for signing, NOT transmitted)
  baseUrl?: string           // Default: "https://www.mixrpay.com"
});
```

**Returns:**
```javascript
{
  sessionKey: string,       // "sk_live_{hex}" — STORE SECURELY
  address: string,          // Derived public address
  sessionKeyId: string,     // Database ID
  expiresAt: Date,
  limits: {
    budgetUsd: number,      // Total budget in USD
    budgetPeriod: string,   // 'daily' | 'monthly' | 'total'
    maxPerTxUsd: number | null,
  },
  allowedMerchants: string[],
  inviterName: string,
}
```

---

### LLM Methods

#### `wallet.complete(prompt, options?)`

Simple one-shot LLM completion. Recommended for basic tasks.

```javascript
const result = await wallet.complete('Summarize this article: ...', {
  model?: string,         // Default: 'gpt-4o-mini'
  systemPrompt?: string
});
```

**Returns:**
```javascript
{
  text: string,           // LLM response
  costUsd: number,        // Cost in USD
  tokens: { prompt: number, completion: number },
  model: string,
}
```

#### `wallet.runAgent(options)`

Multi-turn agentic loop with LLM reasoning and tool execution. MixrPay handles the loop, tool orchestration, and bundled billing.

```javascript
const result = await wallet.runAgent({
  messages: [{ role: 'user', content: 'Find top AI startups' }],
  config: {
    model: 'gpt-4o',
    maxIterations: 10,        // Max tool-use loops (default: 10, max: 25)
    tools: ['platform/exa-search', 'platform/firecrawl-scrape'],
    systemPrompt: 'You are a research assistant.'
  },
  stream: false,              // Enable SSE streaming (default: false)
  idempotencyKey: 'task_123', // Prevent duplicate runs
  onEvent: (event) => { ... } // Streaming event callback
});
```

**Returns:**
```javascript
{
  runId: string,
  status: 'completed' | 'failed',
  response: string,         // Final agent response
  iterations: number,
  toolsUsed: string[],
  cost: { llmUsd: number, toolsUsd: number, totalUsd: number },
  tokens: { prompt: number, completion: number },
}
```

**Streaming Events:**

When `stream: true`, the `onEvent` callback receives:

| Event Type | Description | Key Fields |
|------------|-------------|------------|
| `run_start` | Run started | `runId` |
| `llm_chunk` | LLM text chunk | `delta` |
| `tool_call` | Tool invoked | `tool` |
| `tool_result` | Tool completed | `tool`, `success`, `costUsd` |
| `complete` | Run finished | `totalCostUsd` |

#### `wallet.getAgentRunStatus(runId)`

Check the status of a previous agent run.

```javascript
const status = await wallet.getAgentRunStatus(runId);
console.log(status.status);        // 'running' | 'completed' | 'failed'
console.log(status.cost.totalUsd);
console.log(status.response);      // Final response (if completed)
```

---

### Payment Methods

#### `wallet.callMerchantApi(options)`

Call a MixrPay merchant's API with session-based payments. Sessions are created and reused automatically.

```javascript
const response = await wallet.callMerchantApi({
  url: 'https://api.merchant.com/generate',
  merchantPublicKey: 'pk_live_...',
  priceUsd: 0.05,
  method: 'POST',               // Optional, defaults to POST
  body: { prompt: 'Hello' },    // Optional
  headers: { 'X-Custom': '1' }  // Optional
});

const data = await response.json();
```

#### `wallet.fetch(url, options?)`

HTTP fetch with automatic x402 payment negotiation. Drop-in replacement for `fetch()` that handles 402 Payment Required responses automatically.

```javascript
const response = await wallet.fetch('https://api.example.com/paid-resource', {
  method: 'POST',
  headers: { 'X-Correlation-Id': 'my-task-123' },
  body: JSON.stringify({ query: 'test' })
});
```

#### `wallet.executeTransaction(params)`

Execute an on-chain transaction from the human's wallet. Supports any contract call (DeFi bridges, swaps, LP operations, etc.). Bounded by session key budget limits.

**Parameters:**

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `to` | `0x${string}` | Yes | Target contract address |
| `data` | `0x${string}` | Yes | Encoded calldata |
| `value` | `bigint` | No | Native value in wei (default: 0) |
| `chainId` | `number` | No | Chain ID (default: 8453 = Base) |
| `estimatedCostUsd` | `number` | Yes | Estimated USD value being moved (for budget tracking) |
| `description` | `string` | No | Human-readable audit description |
| `idempotencyKey` | `string` | No | Prevent duplicate execution |

**Returns:** `{ success, txHash, chargeId, estimatedCostUsd, remainingBudgetUsd }`

**Errors:** `BUDGET_EXCEEDED`, `TX_FAILED`, `TX_REVERTED`, `CONCURRENT_TX`, `INSUFFICIENT_GAS`, `POLICY_REJECTED`

**Example:**
```javascript
const stats = await wallet.getSpendingStats();
if (stats.remainingTotalUsd >= 25) {
  const result = await wallet.executeTransaction({
    to: '0x...deBridgeContract',
    data: '0x...calldata',
    estimatedCostUsd: 25.0,
    description: 'Bridge 25 USDC Base -> Avalanche',
  });
  console.log('TX:', result.txHash);
}
```

---

### Session Management

#### `wallet.getOrCreateSession(options)`

Create or get an existing session with a merchant. For fine-grained control over session lifecycle.

```javascript
const session = await wallet.getOrCreateSession({
  merchantPublicKey: 'pk_live_...',
  spendingLimitUsd: 25,
  durationDays: 7,
});

console.log('Session ID:', session.id);
console.log('Remaining:', session.remainingLimitUsd);
```

#### `wallet.chargeSession(sessionId, amountUsd, options?)`

Manually charge against a session.

```javascript
const charge = await wallet.chargeSession(session.id, 0.05, {
  feature: 'ai-generation',
  idempotencyKey: 'unique-key-123',
});
```

#### `wallet.listSessions()`

List all active sessions.

```javascript
const sessions = await wallet.listSessions();
```

#### `wallet.revokeSession(sessionId)`

Revoke a session.

```javascript
await wallet.revokeSession(session.id);
```

#### `wallet.getSessionStats()`

Get an overview across all active sessions.

```javascript
const stats = await wallet.getSessionStats();
console.log(`Active sessions: ${stats.activeCount}`);
console.log(`Total authorized: $${stats.totalAuthorizedUsd.toFixed(2)}`);
console.log(`Total remaining: $${stats.totalRemainingUsd.toFixed(2)}`);
```

---

### Budget Methods

#### `wallet.getSpendingStats()`

Get spending statistics for the current session.

```javascript
const stats = await wallet.getSpendingStats();
```

**Returns:**
```javascript
{
  totalSpentUsd: number,
  txCount: number,
  remainingDailyUsd: number | null,   // null = no daily limit
  remainingTotalUsd: number | null,   // null = no total limit
  expiresAt: Date | null,
}
```

#### `wallet.getAvailableBudget()`

Get detailed budget breakdown including child allocation info.

```javascript
const budget = await wallet.getAvailableBudget();
```

**Returns:**
```javascript
{
  totalBudget: number,          // Total budget from session in USD
  spent: number,
  allocatedToChildren: number,
  available: number,            // Available for spending or spawning
  maxSpawnBudget: number,       // Max budget for next spawn (20% of available)
  canSpawn: boolean,
}
```

#### `wallet.getBalance()`

Get the parent wallet's USDC balance on-chain.

```javascript
const balance = await wallet.getBalance();
// Returns: { usdcBalance: string }
```

#### `wallet.canAfford(amountUsd)`

Pre-flight balance check before making a request.

```javascript
const check = await wallet.canAfford(0.50);

if (check.canAfford) {
  console.log(`Can afford! Remaining after: $${check.remainingAfter}`);
} else {
  console.log(`Cannot afford. Have: $${check.currentBalance}, Need: $0.50`);
  console.log(`Shortage: $${check.shortage}`);
}
```

#### `wallet.getSessionKeyInfo()`

Get details about the current session key.

```javascript
const info = await wallet.getSessionKeyInfo();
console.log('Session key:', info.address);
console.log('Spending from:', info.walletAddress); // Human's wallet
console.log('Expires:', info.expiresAt);
```

---

### Child Agent Methods

#### `wallet.spawnChildInvite(options)`

Spawn a child agent by creating a delegated invite. Max 20% of available budget. Supports 10 levels of nesting.

```javascript
const budget = await wallet.getAvailableBudget();
console.log(`Can spawn up to: $${budget.maxSpawnBudget}`);

if (budget.canSpawn) {
  const child = await wallet.spawnChildInvite({
    budgetUsd: 10.00,
    name: 'Research Agent',
    allowedMerchants: [],      // Must be subset of parent's list
    expiresInDays: 7           // Capped to parent's expiry
  });

  console.log(`Child invite: ${child.inviteCode}`);
  console.log(`Depth: ${child.depth}`); // 1 = child, 2 = grandchild, etc.
}
```

**Returns:**
```javascript
{
  inviteCode: string,       // Share with child agent
  inviteId: string,
  budgetUsd: number,        // Actual budget (may be capped)
  expiresAt: Date,
  depth: number,
  maxSpawnBudget: number,
  allowedMerchants: string[],
}
```

#### `wallet.getChildSessions()`

List all child sessions spawned by this session.

```javascript
const children = await wallet.getChildSessions();
children.forEach(c => console.log(`${c.name}: $${c.spentUsd}/$${c.budgetUsd}`));
```

**Returns:** `ChildSession[]` with `{ name, budgetUsd, spentUsd, availableUsd, status, depth, canSpawn, children? }`

---

### MCP Server Methods

#### `wallet.searchGlamaDirectory(query)`

Search the Glama MCP server directory (15,000+ servers).

```javascript
const results = await wallet.searchGlamaDirectory('notion');
console.log(results.servers.map(s => `${s.id}: ${s.name}`));
```

#### `wallet.deployJitMcp(options)`

Deploy a Just-In-Time MCP server with your own API keys. Costs $1.00 per deployment.

```javascript
const result = await wallet.deployJitMcp({
  glamaId: 'notion-mcp',
  glamaNamespace: 'notion',
  glamaSlug: 'notion-mcp',
  toolName: 'My Notion',
  toolDescription: 'Notion workspace access',
  envVars: { NOTION_API_KEY: 'secret_...' },
  ttlHours: 24                 // Default: 24, max: 168 (7 days)
});

// Use instance.instance.endpointUrl to connect
console.log(result.instance.endpointUrl);
console.log(`Paid: $${result.payment.amountUsd}`);
```

**Returns:**
```javascript
{
  instance: {
    id: string,
    endpointUrl: string,     // Private URL with secret token
    toolName: string,
    status: 'provisioning' | 'active' | 'stopped' | 'expired' | 'failed',
    ttlHours: number,
    expiresAt: Date,
  },
  payment: { method: string, amountUsd: number, txHash: string },
}
```

#### `wallet.listJitInstances(options?)`

```javascript
const instances = await wallet.listJitInstances({
  status: 'active'  // Optional filter
});
```

#### `wallet.stopJitInstance(instanceId)`

Stop a running server. No refund — billed at deploy time.

```javascript
await wallet.stopJitInstance(instance.instance.id);
```

---

### Skills Methods

#### `wallet.configureSkill(skillId, envVars)`

Save an API key for a skill. The key is encrypted, stored securely, and the skill activates immediately (hot-reload, persists through redeploys).

```javascript
// Predefined skill
await wallet.configureSkill('web-search', {
  BRAVE_API_KEY: 'BSA_abc123'
});

// Custom service (use custom- prefix)
await wallet.configureSkill('custom-polymarket', {
  POLYMARKET_API_KEY: 'pk_abc123'
});
// Access via process.env.POLYMARKET_API_KEY
```

**Available Predefined Skills:**

| Skill ID | Primary Env Var | Description |
|----------|----------------|-------------|
| `web-search` | `BRAVE_API_KEY` or `TAVILY_API_KEY` | Web search |
| `web-scrape` | `FIRECRAWL_API_KEY` | Web scraping |
| `github` | `GITHUB_TOKEN` | GitHub API |
| `notion` | `NOTION_API_KEY` | Notion API |
| `browser` | `BROWSERBASE_API_KEY` | Browser automation |
| `calendar` | (via Composio OAuth) | Google Calendar |
| `spotify` | (via Composio OAuth) | Spotify |
| `trello` | (via Composio OAuth) | Trello |
| `social-media` | (via Composio OAuth) | Social media platforms |
| `smart-home` | (via Composio OAuth) | Smart home devices |

#### `wallet.useSkill(skillId)`

Deploy and use a skill's MCP tools.

```javascript
const { endpoint, tools } = await wallet.useSkill('composio');
// Returns the MCP endpoint URL and available tool list
```

#### `wallet.getConnectedApps()`

List OAuth-connected apps via Composio.

```javascript
const apps = await wallet.getConnectedApps();
// Returns: [{ appId: 'gmail', status: 'connected', ... }, ...]
```

#### `wallet.listSkills()`

List all available skills with their configuration status.

```javascript
const skills = await wallet.listSkills();
```

---

### Utility Methods

#### `wallet.runDiagnostics()`

Run a full health check on the wallet, session key, and connectivity.

```javascript
const diag = await wallet.runDiagnostics();
console.log(`Wallet: ${diag.walletAddress}`);
console.log(`Balance: $${diag.balanceUsd}`);
console.log(`Latency: ${diag.latencyMs}ms`);

if (diag.sessionLimits) {
  console.log(`Daily remaining: $${diag.sessionLimits.dailyRemaining}`);
  console.log(`Total remaining: $${diag.sessionLimits.totalRemaining}`);
}

diag.recommendations.forEach(r => console.log(`  - ${r}`));
```

#### `wallet.setDebug(boolean)`

Toggle debug logging at runtime.

```javascript
wallet.setDebug(true);
```

#### `wallet.on('payment', callback)`

Listen for payment events.

```javascript
wallet.on('payment', (event) => {
  console.log(`Paid $${event.amountUsd} to ${event.recipient}`);
  console.log(`TX: ${event.txHash}`);
  console.log(`Request ID: ${event.requestId}`);
  if (event.correlationId) {
    console.log(`Correlation: ${event.correlationId}`);
  }
});
```

---

## Agent Runtime — Available Tools

When using `wallet.runAgent()`, these tools are available:

**Platform MCP Tools (pay-per-use):**

| Tool | Description |
|------|-------------|
| `platform/exa` | Semantic web search — find content by meaning |
| `platform/tavily` | AI-optimized search for RAG pipelines |
| `platform/firecrawl` | Web scraping, crawling, and AI extraction |
| `platform/jina` | URL to clean markdown conversion |
| `platform/brave` | Privacy-focused web and news search |
| `platform/serper` | Google Search results as structured API |
| `platform/unstructured` | Document parsing (PDF, images, Word) |
| `platform/wolfram` | Computational knowledge and math |
| `platform/resend` | Transactional email delivery |
| `platform/notion` | Notion workspace read/write |
| `platform/qdrant` | Vector search and embeddings storage |
| `platform/agentmail` | Email inbox (list, send, reply). Uses platform API by default; pass `use_x402: true` to pay from delegation. |

Browse all available services and pricing at https://mixrpay.com/gateway

**AgentMail (email):** Use provider `agentmail` with mixrpay-tool or MCP. Email uses the platform API by default (no charge to your delegation budget). For isolated billing (e.g., multi-agent setups), pass **`use_x402: true`** to pay from your delegation budget instead.

**Wallet Tools (free):**

| Tool | Description |
|------|-------------|
| `get_wallet_info` | Get wallet balance and address |
| `search_marketplace` | Search available services |
| `get_active_sessions` | List active spending sessions |

---

## Gateway Keys

Gateway keys (`gw_live_xxx`) provide direct access to the LLM gateway — an OpenAI-compatible endpoint for any model.

**Endpoint:** `POST /api/v1/llm/chat/completions`

Use it with any OpenAI-compatible SDK:

```javascript
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'gw_live_xxx',
  baseURL: 'https://www.mixrpay.com/api/v1/llm'
});

const completion = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Hello' }],
  stream: true
});
```

Gateway keys use post-charge billing — usage is tracked per-token and charged automatically. No pre-approval needed per request.

---

## E2B Sandboxes

Create isolated code execution environments via E2B. The platform provides REST endpoints to:

- **Create** a sandbox with a specified template and TTL
- **List** active sandboxes
- **Get details** for a specific sandbox
- **Terminate** a sandbox
- **Extend** a sandbox's TTL
- **Send messages** to a sandbox (chat-style interaction)

Sandboxes are billed hourly. Each sandbox gets an auto-provisioned gateway key for LLM access. Endpoints are authenticated automatically for deployed agents.

---

## Cron Jobs & Heartbeat Tasks

Deployed agents can schedule recurring work.

### Cron Jobs

The platform provides REST endpoints to manage cron jobs:

- **List** all cron jobs
- **Create** a new cron job (with cron expression and handler)
- **Get / Update / Delete** a specific job
- **Manually trigger** a job
- **View execution history** for a job
- **Check cron system status**

### Heartbeat Tasks

Periodic background tasks that run on a configurable interval. The platform provides REST endpoints to:

- **Get / Replace** the full set of heartbeat tasks
- **Append** a new task
- **Get / Update** heartbeat configuration (interval, enabled state)

Auth for all cron/heartbeat endpoints is handled automatically for deployed agents.

---

## Human Approval Workflow

Request human sign-off before executing sensitive actions.

The platform provides REST endpoints to:

- **List** pending approvals
- **Respond** to an approval (approve or reject with optional message)

Use case: agent proposes an action (e.g., a large purchase, a deployment, sending a message), submits it for approval, and waits for the human owner to approve or reject before proceeding.

---

## File Sharing

Share workspace files with your owner via signed download links. Links are secure (HMAC-signed) and expire after 24 hours by default.

### Generate a Download Link

Deployed agents can call the platform's workspace share endpoint to generate a signed URL for any file in their workspace.

**Parameters:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `path` | string | Yes | Relative path within workspace |
| `expiresIn` | number | No | Lifetime in seconds (default: 86400 = 24h, max: 604800 = 7d) |

**Returns:** a signed URL, filename, file size, and expiration timestamp.

**Notes:**
- Links expire after 24 hours. Generate a new one if needed.
- Credential files (`.env`, `.key`, `.pem`, `.token`, `.secret`, dotfiles) cannot be shared.
- Maximum file size: 50MB.

---

## Available Models

| Model | Provider | Best For | Approx. Cost |
|-------|----------|----------|-------------|
| `gpt-4o-mini` | OpenAI | Fast, cheap (default) | ~$0.15/1M input |
| `gpt-4o` | OpenAI | Complex reasoning | ~$2.50/1M input |
| `gpt-4-turbo` | OpenAI | Large context | ~$10.00/1M input |
| `claude-sonnet-4-5` | Anthropic | Long context, analysis | ~$3.00/1M input |
| `claude-haiku-4-5` | Anthropic | Fast, light tasks | ~$0.80/1M input |
| `claude-3-opus-latest` | Anthropic | Highest quality | ~$15.00/1M input |

---

## Error Handling

All methods throw typed errors from `@mixrpay/agent-sdk`:

```javascript
import {
  AgentWallet,
  MixrPayError,
  InsufficientBalanceError,
  SessionLimitExceededError,
  SpendingLimitExceededError,
  SessionExpiredError,
  SessionNotFoundError,
  SessionRevokedError,
  SessionKeyExpiredError,
  InvalidSessionKeyError,
  PaymentFailedError,
  X402ProtocolError,
  isMixrPayError,
  getErrorMessage,
} from '@mixrpay/agent-sdk';

try {
  const result = await wallet.complete('...');
} catch (error) {
  if (error instanceof InsufficientBalanceError) {
    console.log(`Need $${error.required}, have $${error.available}`);
    console.log(`Top up: ${error.topUpUrl}`);
  }
  if (error instanceof SessionLimitExceededError) {
    console.log(`Remaining: $${error.remaining}`);
  }
  if (error instanceof SpendingLimitExceededError) {
    console.log(`Limit type: ${error.limitType}`);
  }
  if (error instanceof SessionExpiredError) {
    console.log('Session expired, retrying...');
  }
  if (error instanceof PaymentFailedError) {
    console.log(`TX: ${error.txHash}`);
  }
}
```

### Retryability

All errors have `isRetryable()` and `retryAfterMs`:

```javascript
try {
  await wallet.callMerchantApi({ ... });
} catch (error) {
  if (error instanceof MixrPayError && error.isRetryable()) {
    const delay = error.retryAfterMs || 1000;
    await new Promise(r => setTimeout(r, delay));
    return retry();
  }
  throw error;
}
```

| Error | Retryable | Notes |
|-------|-----------|-------|
| `InsufficientBalanceError` | No | User needs to add funds |
| `SessionLimitExceededError` | No | Create new session |
| `SpendingLimitExceededError` | Daily only | Daily limits reset at midnight UTC |
| `PaymentFailedError` | Yes | Often transient network issues |
| `X402ProtocolError` | Yes | Server may recover |
| `SessionExpiredError` | No | Create new session |
| `InvalidSessionKeyError` | No | Fix the key |

### Utility Functions

```javascript
if (isMixrPayError(error)) {
  console.log(`[${error.code}]: ${error.message}`);
}

const message = getErrorMessage(error); // User-friendly message from any error
```

---

## Configuration Options

```javascript
new AgentWallet({
  sessionKey: string,              // Required
  maxPaymentUsd?: number,          // Client-side limit per payment
  timeout?: number,                // Request timeout (default: 30000ms)
  logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'none',
  onPayment?: (payment) => void,   // Payment callback
});
```

---

## Security Best Practices

1. **Store session keys securely** — use environment variables, never commit to version control
2. **Set client-side limits** — `maxPaymentUsd` prevents runaway spending
3. **Use appropriate key limits** — set per-transaction, daily, and total limits when creating access codes
4. **Test with test keys first** — `sk_test_...` keys use Base Sepolia (testnet)
5. **Never expose keys in responses** — keys are stored encrypted, don't echo them back

---

## Environment Variables

| Variable | Auto-Set on Platform | Self-Hosted | Description |
|----------|---------------------|-------------|-------------|
| `MIXRPAY_SESSION_KEY` | Yes | Claim via invite | Session key `sk_live_...` or `sk_test_...` |
| `TELEGRAM_BOT_TOKEN` | Yes (if configured) | Manual | Telegram channel token |
| `SLACK_BOT_TOKEN` | Yes (if configured) | Manual | Slack channel token |
| `DISCORD_BOT_TOKEN` | Yes (if configured) | Manual | Discord channel token |
| `MIXRPAY_BASE_URL` | Not needed | Optional | MixrPay server URL (default: https://www.mixrpay.com) |
| `AGENT_WALLET_KEY` | Not needed | For invite claim | Agent's private key for signing |

---

## Links

- **Dashboard**: https://mixrpay.com/manage
- **App**: https://mixrpay.com/app
- **API Catalog**: https://mixrpay.com/gateway
- **Developer Guide**: https://mixrpay.com/llms.txt
- **SDK Docs**: https://mixrpay.com/docs/sdk
- **npm**: `npm install @mixrpay/agent-sdk`
- **GitHub — Skill**: https://github.com/mixrpay/clawhub-skill-mixrpay
- **GitHub — Agent Skills**: https://github.com/mixrpay/agent-skills
- **GitHub — SDK**: https://github.com/mixrpay/mixrpay-js

---

Built for agents.
