| name | b2a-agents |
| description | Builds agents that serve other AI agents (B2A). Use when designing x402 agents
for agent-to-agent data sales, evaluating if a data niche is suitable for agents,
or when asked to "build something agents would pay for".
|
B2A Agents: Building for Agent Consumers
Build x402 agents that other AI agents need and will pay for.
Why B2A Wins
| Consumer (B2C) | Agent (B2A) |
|---|
| Friction to pay micropayments | Programmatic, zero friction |
| Irregular usage patterns | Consistent, predictable calls |
| High churn | Sticky once integrated |
| Needs UI/UX | Needs clean JSON |
| One user = one user | One agent = many end users |
Core insight: Build data infrastructure, not consumer apps.
B2A Evaluation Gate
Before building, answer YES to ALL:
- Would another AI agent pay $0.001+ for this? (not "would a human think this is cool")
- Is the data unique, aggregated, or hard to get?
- Does it solve a recurring need? (called repeatedly, not once)
- Can it be called programmatically without human context?
If any answer is NO → find a different niche.
High-Value B2A Categories
| Category | What Agents Need | Example Endpoints |
|---|
| Price Aggregation | Normalized multi-source prices | GET /prices/crypto/{symbol}, GET /prices/forex/{pair} |
| Entity Resolution | Company/person/domain context | GET /entity/company/{domain}, GET /entity/person/{handle} |
| News & Events | Filtered real-time feeds | GET /news/breaking?topic=X, GET /events/earnings |
| Social Signals | Trending/sentiment data | GET /social/trending, GET /social/sentiment/{topic} |
| Geocoding | Location intelligence | GET /geo/lookup?address=X, GET /geo/timezone/{coords} |
| Content Analysis | Pre-computed classification | GET /analyze/toxicity, GET /analyze/language |
| Rate-Limit Caching | Wrapped scarce APIs | Any limited free API with caching layer |
| Cross-Platform | Identity correlation | GET /identity/resolve?handle=X |
Design Principles
1. Optimize for Programmatic Access
addEntrypoint({
key: 'lookup',
input: z.object({
symbol: z.string(),
exchanges: z.array(z.string()).optional()
}),
handler: async (ctx) => {
return { output: { symbol, prices, timestamp } };
}
});
addEntrypoint({
key: 'search',
input: z.object({ query: z.string() }),
handler: async (ctx) => {
return { output: { message: "Here's what I found..." } };
}
});
2. Return Structured Data, Not Prose
return {
output: {
entity: "Apple Inc",
domain: "apple.com",
type: "public_company",
ticker: "AAPL",
employees: 164000,
founded: 1976
}
};
return {
output: {
description: "Apple Inc is a technology company founded in 1976..."
}
};
3. Include Metadata Agents Need
return {
output: {
data: results,
fetchedAt: new Date().toISOString(),
source: "coingecko+binance",
cacheAge: 30,
nextUpdate: "2025-01-30T12:00:00Z"
}
};
4. Price by Value, Not Compute
| Endpoint Type | Suggested Price | Rationale |
|---|
| Health/status | FREE | Discovery |
| Single lookup | $0.001 | Basic utility |
| Filtered list | $0.002 | More data |
| Multi-source aggregation | $0.003-0.005 | Unique value |
| Premium analysis | $0.005-0.01 | High compute or rare data |
5. One Free Endpoint (Always)
addEntrypoint({
key: 'overview',
description: 'Free overview - see what data is available',
price: { amount: 0 },
handler: async () => {
return {
output: {
available: ['lookup', 'search', 'aggregate', 'analyze'],
dataSource: 'Multi-exchange aggregated',
updateFrequency: '30 seconds',
sampleData: await fetchSample()
}
};
}
});
Anti-Patterns (Avoid)
| Pattern | Why It Fails |
|---|
| Consumer novelty (games, trivia) | Agents don't play games |
| Single API wrapper | No unique value over calling directly |
| Static/mock data | Agents need live data |
| Human-oriented output | "Here's what I found..." |
| One-time use | No recurring revenue |
| Vague inputs | query: string with no schema |
| Missing timestamps | Agents can't assess freshness |
B2A Agent Template
import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { createAgentApp } from '@lucid-agents/hono';
import { payments, paymentsFromEnv } from '@lucid-agents/payments';
import { z } from 'zod';
const agent = await createAgent({
name: 'data-feed-agent',
version: '1.0.0',
description: 'Aggregated data feed for AI agents',
})
.use(http())
.use(payments({ config: paymentsFromEnv() }))
.build();
const { app, addEntrypoint } = await createAgentApp(agent);
const cache = new Map<string, { data: any; timestamp: number }>();
const CACHE_TTL = 30_000;
async function fetchWithCache() {
cached = cache.(key);
(cached && .() - cached. < ) {
{ ...cached., : };
}
data = ();
cache.(key, { data, : .() });
{ ...data, : };
}
({
: ,
: ,
: z.({}),
: { : },
: () => ({
: {
: [, , ],
: [, ],
: ,
: ().()
}
})
});
({
: ,
: ,
: z.({ : z.() }),
: { : },
: (ctx) => {
result = (, () => {
().( r.());
});
{ : { ...result, : ().() } };
}
});
({
: ,
: ,
: z.({
: z.(z.()).(),
: z.(z.()).()
}),
: { : },
: (ctx) => {
results = .(
ctx...( (,
(id, ctx..)
))
);
{
: {
: results,
: results.,
: ().()
}
};
}
});
{ : (process.. ?? ), : app. };
Validation Checklist
Before deploying a B2A agent: