The Agent Pricing & Monetization Playbook
Notice: This is an educational guide with illustrative code examples. It does not execute code or install dependencies. All examples use the GreenHelix sandbox (https://sandbox.greenhelix.net) which provides 500 free credits — no API key required to get started.
Referenced credentials (you supply these in your own environment):
STRIPE_API_KEY: Stripe API key for card payment processing (scoped to payment intents only)
You built the agent. It works. It summarizes legal contracts in three seconds, triages support tickets with 94% accuracy, or generates ad copy that converts 2x better than templates. Now comes the question that kills more agent startups than bad models: how do you charge for it? Traditional SaaS pricing -- $49/month for Pro, $149/month for Enterprise -- was designed for human users clicking buttons in a dashboard. Agent services operate in a fundamentally different economic reality. Your costs are variable per request, not fixed per seat. Your customers might be other agents, not humans with credit cards. A single enterprise customer might send 800,000 API calls in January and 12 calls in February. And the transaction values are often sub-cent -- a fraction of a penny per tool call, aggregated across millions of invocations into meaningful revenue. The numbers tell the story. Monetizely's 2026 AI Pricing Report found that 62% of AI-powered products are moving to usage-based pricing by 2027, up from 34% in 2024. McKinsey projects the autonomous agent market will reach $52.6 billion by 2030. Bain's 2026 analysis of 200 AI SaaS companies revealed that usage-based pricing models achieve 127% net revenue retention versus 108% for seat-based models -- a gap that compounds dramatically over three years. Yet the same report found that 71% of agent builders launch with flat-rate pricing because they do not know how to implement metering, escrow, or marketplace discovery.
What You'll Learn
- Chapter 1: The Agent Pricing Landscape
- Chapter 2: Usage-Based Metering with GreenHelix Billing
- Chapter 3: Outcome-Based Pricing and Settlement
- Chapter 4: Marketplace Listing and Agent Discovery
- Chapter 5: API Key Gating and Tiered Access
- Chapter 6: Agent-to-Agent Payments
- Chapter 7: Revenue Tracking and Analytics
- Chapter 8: Launch Checklist and Pricing Experiments
- Appendix: Tool Reference Quick Index
Full Guide
The Agent Pricing & Monetization Playbook: Usage Metering, Outcome Billing, Marketplace Listing & A2A Payment Wiring
You built the agent. It works. It summarizes legal contracts in three seconds, triages support tickets with 94% accuracy, or generates ad copy that converts 2x better than templates. Now comes the question that kills more agent startups than bad models: how do you charge for it?
Traditional SaaS pricing -- $49/month for Pro, $149/month for Enterprise -- was designed for human users clicking buttons in a dashboard. Agent services operate in a fundamentally different economic reality. Your costs are variable per request, not fixed per seat. Your customers might be other agents, not humans with credit cards. A single enterprise customer might send 800,000 API calls in January and 12 calls in February. And the transaction values are often sub-cent -- a fraction of a penny per tool call, aggregated across millions of invocations into meaningful revenue.
The numbers tell the story. Monetizely's 2026 AI Pricing Report found that 62% of AI-powered products are moving to usage-based pricing by 2027, up from 34% in 2024. McKinsey projects the autonomous agent market will reach $52.6 billion by 2030. Bain's 2026 analysis of 200 AI SaaS companies revealed that usage-based pricing models achieve 127% net revenue retention versus 108% for seat-based models -- a gap that compounds dramatically over three years. Yet the same report found that 71% of agent builders launch with flat-rate pricing because they do not know how to implement metering, escrow, or marketplace discovery.
This guide closes that gap. Every chapter contains production-ready Python code calling the GreenHelix A2A Commerce Gateway -- 128 tools accessible via a single HTTP endpoint at https://api.greenhelix.net/v1. By the end, you will have a metered billing system, outcome-based payment flows, a marketplace listing, tiered API key gating, agent-to-agent payment wiring, a revenue analytics dashboard, and a 14-day launch playbook. All of it working. All of it tested against the live gateway.
Table of Contents
- The Agent Pricing Landscape
- Usage-Based Metering with GreenHelix Billing
- Outcome-Based Pricing and Settlement
- Marketplace Listing and Agent Discovery
- API Key Gating and Tiered Access
- Agent-to-Agent Payments
- Revenue Tracking and Analytics
- Launch Checklist and Pricing Experiments
Chapter 1: The Agent Pricing Landscape
Why Traditional SaaS Pricing Breaks for AI Agents
Per-seat pricing assumes a predictable relationship between the number of users and the value delivered. A project management tool with 50 seats serves 50 humans who each log in roughly daily, use roughly similar features, and generate roughly similar infrastructure costs. The marginal cost of adding seat 51 is near zero. Gross margins sit at 80-90%, and the pricing math is straightforward: charge enough per seat to cover the averaged cost with healthy margin, then grow by adding seats.
Agent services violate every assumption in that model.
Variable compute costs per request. When your agent calls GPT-4o to summarize a legal contract, the cost depends on the input token count. A 2-page NDA costs $0.003 to process. A 200-page merger agreement costs $0.31. If you charge a flat monthly fee, the customer who sends you merger agreements all day is unprofitable, and the customer who sends NDAs is subsidizing them. This is adverse selection -- the customers who use you most are the ones who cost you the most, and flat pricing attracts exactly those customers.
Sub-cent micro-transactions. Many agent services deliver value in tiny increments. A data enrichment call costs $0.002 to execute and delivers $0.008 of value. You need to charge $0.005 per call to maintain a healthy margin. Traditional payment processors cannot handle this -- Stripe's $0.30 per-transaction fee would consume 60x your revenue on a single call. You need a billing system designed for micro-transactions that aggregates usage and settles periodically.
Compressed gross margins. Traditional SaaS companies enjoy 80-90% gross margins because the marginal cost of serving an additional user is negligible. Agent services that depend on LLM inference typically operate at 50-60% gross margins because the primary cost -- model API calls -- scales linearly with usage. Some compute-heavy agent services operate at 30-40% margins. This compression means pricing errors are fatal faster. A 15% pricing mistake in traditional SaaS reduces margin from 85% to 70% -- painful but survivable. The same mistake in an agent service reduces margin from 55% to 40% -- potentially below the viability threshold.
Customers are machines. When your customers are other AI agents, not humans, the buying decision is algorithmic. An orchestrator agent evaluating your translation service against a competitor will switch the moment the competitor's quality-adjusted price drops below yours. There is no brand loyalty, no switching friction from learned habits, no reluctance to migrate. The agent changes one URL and one API key. This means your pricing must be continuously competitive, not just competitive at the moment of sale.
Three Pricing Models for Agent Services
| Model | How It Works | Best For | Gross Margin | Revenue Predictability | Implementation Complexity |
|---|---|---|---|---|---|
| Subscription | Fixed monthly fee for a tier of access | Stable, predictable workloads; human-facing dashboards | 70-85% | High | Low |
| Usage-Based | Pay per call, per token, per task | Variable workloads; agent-to-agent services | 50-65% | Medium | Medium |
| Outcome-Based | Pay only when a measurable outcome is achieved | High-value tasks; trust-sensitive buyers | 40-70% (varies) | Low | High |
Most successful agent services use a hybrid. A subscription base fee covers fixed infrastructure costs and provides revenue predictability. Usage-based charges on top capture value from high-volume customers without subsidizing them. Outcome-based pricing applies to premium features where the agent can guarantee measurable results.
The Pricing Decision Framework
Answer these four questions to choose your model:
Is your cost per request variable or fixed? If variable (LLM inference, external API calls), usage-based pricing protects your margins. If fixed (static model, cached responses), subscription pricing maximizes simplicity.
Are your customers humans or agents? Human customers prefer predictable bills -- lean toward subscription with usage caps. Agent customers optimize on price-per-unit -- lean toward transparent usage-based pricing.
Can you measure outcomes reliably? If your agent solves support tickets and you can programmatically verify resolution (customer confirms, no reopens within 48 hours), outcome-based pricing commands a premium. If output quality is subjective, stick with usage-based.
What is your competitive landscape? If competitors charge per-call, you must offer per-call pricing or demonstrate clearly why your subscription is cheaper at the customer's expected volume. Price structure mismatch is a sales killer.
The GreenHelix Pricing Client
Every code example in this guide calls the GreenHelix A2A Commerce Gateway via the REST API (POST /v1/{tool}) with a JSON body of {"tool": "tool_name", "input": {...}}. Authentication is via Bearer token. Define the core client once and reference it throughout.
import requests
from typing import Any
GATEWAY_URL = os.environ.get("GREENHELIX_API_URL", "https://sandbox.greenhelix.net")
class GreenHelixClient:
"""Client for the GreenHelix A2A Commerce Gateway."""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = GATEWAY_URL
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
def execute(self, tool: str, input_data: dict[str, Any]) -> dict:
"""Execute a tool on the gateway."""
response = requests.post(
f"{self.base_url}/v1",
json={"tool": tool, "input": input_data},
headers=self.headers,
timeout=30,
)
response.raise_for_status()
return response.json()
def execute_batch(self, calls: list[dict[str, Any]]) -> list[dict]:
"""Execute multiple tool calls sequentially."""
results = []
for call in calls:
result = self.execute(call["tool"], call["input"])
results.append(result)
return results
# Initialize once, use everywhere
client = GreenHelixClient(api_key="your-greenhelix-api-key")
This client handles authentication, serialization, and error propagation. Every subsequent code example assumes this client is available in scope.
Key Takeaways
- Traditional per-seat SaaS pricing fails for agent services due to variable compute costs, sub-cent transactions, compressed margins, and algorithmic buyers.
- Three models dominate: subscription (simple, predictable), usage-based (fair, scalable), and outcome-based (premium, trust-building). Most services should hybrid.
- 62% of AI products are moving to usage-based pricing by 2027. The market is $52.6B by 2030. Pricing infrastructure is the bottleneck, not demand.
- Use the four-question decision framework: cost variability, customer type, outcome measurability, and competitive landscape.
Chapter 2: Usage-Based Metering with GreenHelix Billing
The Metering Problem
Usage-based pricing requires three capabilities that traditional billing systems lack: sub-cent precision, real-time aggregation, and retroactive volume discounts. When your agent processes 1.2 million calls in a month at $0.003 per call, you need a billing system that tracks every call, aggregates them accurately, applies volume tiers, and generates an invoice for $3,600 -- not $3,599.97, not $3,600.03, and definitely not a system that rounds each individual call to the nearest cent and charges $0.00 for most of them.
GreenHelix Billing tools solve this with three primitives: create_billing_plan defines pricing tiers, record_usage logs each metered event, and estimate_cost calculates the bill at any point in the billing cycle. Combined with set_volume_discount for rewarding high-volume customers, these four tools form a complete metering pipeline.
Designing Your Billing Plan
Before writing code, define your metering dimensions. A metering dimension is any axis along which you want to charge differently. Common dimensions for agent services:
| Dimension | Unit | Example Rate | Use Case |
|---|---|---|---|
| API calls | Per call | $0.001 - $0.01 | General-purpose tools |
| Input tokens | Per 1K tokens | $0.002 - $0.03 | LLM-backed services |
| Output tokens | Per 1K tokens | $0.005 - $0.06 | Generation-heavy services |
| Tasks completed | Per task | $0.05 - $5.00 | Multi-step workflows |
| Compute seconds | Per second | $0.0001 - $0.001 | Resource-intensive processing |
| Storage (MB) | Per MB/month | $0.01 - $0.10 | Data persistence services |
The golden rule: meter the dimension your customer can predict and control. Customers hate surprises. If your agent's token consumption varies wildly based on input complexity, meter per-task instead of per-token -- the customer can predict how many tasks they will submit but cannot predict your token usage.
Creating a Billing Plan
def create_metered_billing_plan(client: GreenHelixClient) -> dict:
"""Create a usage-based billing plan with tiered pricing."""
plan = client.execute("create_billing_plan", {
"agent_id": "my-summarizer-agent",
"plan_name": "summarizer-usage-v1",
"billing_type": "usage",
"currency": "USD",
"metering_dimensions": [
{
"name": "api_calls",
"unit": "call",
"tiers": [
{"up_to": 1000, "rate": 0.008},
{"up_to": 10000, "rate": 0.006},
{"up_to": 100000, "rate": 0.004},
{"up_to": None, "rate": 0.002}, # unlimited
],
},
{
"name": "input_tokens",
"unit": "1k_tokens",
"tiers": [
{"up_to": 500, "rate": 0.015},
{"up_to": 5000, "rate": 0.010},
{"up_to": None, "rate": 0.006},
],
},
],
"billing_period": "monthly",
"invoice_day": 1,
})
print(f"Created billing plan: {plan['plan_id']}")
return plan
plan = create_metered_billing_plan(client)
This plan uses graduated tiering: the first 1,000 calls cost $0.008 each, the next 9,000 cost $0.006, and so on. This rewards growth without giving away the first calls. An alternative is volume tiering where the entire volume is billed at the tier the customer reaches -- simpler but less predictable for the customer during the billing period.
Recording Usage in Real Time
The key to accurate metering is recording usage at the point of execution, not in a batch job. Every time your agent processes a request, record it immediately.
import time
from functools import wraps
from typing import Callable
class UsageMeter:
"""Records usage against a GreenHelix billing plan."""
def __init__(self, client: GreenHelixClient, agent_id: str, plan_id: str):
self.client = client
self.agent_id = agent_id
self.plan_id = plan_id
self._buffer: list[dict] = []
self._buffer_limit = 50 # flush every 50 events
def record(self, customer_id: str, dimension: str, quantity: float,
metadata: dict | None = None) -> None:
"""Record a single usage event."""
event = {
"agent_id": self.agent_id,
"plan_id": self.plan_id,
"customer_id": customer_id,
"dimension": dimension,
"quantity": quantity,
"timestamp": time.time(),
"metadata": metadata or {},
}
self._buffer.append(event)
if len(self._buffer) >= self._buffer_limit:
self.flush()
def flush(self) -> list[dict]:
"""Flush buffered events to the gateway."""
if not self._buffer:
return []
results = []
for event in self._buffer:
result = self.client.execute("record_usage", event)
results.append(result)
self._buffer.clear()
return results
def metered(self, dimension: str, quantity_fn: Callable | None = None):
"""Decorator that automatically meters function calls."""
def decorator(func):
@wraps(func)
def wrapper(customer_id: str, *args, **kwargs):
result = func(customer_id, *args, **kwargs)
qty = quantity_fn(result) if quantity_fn else 1
self.record(customer_id, dimension, qty, {
"function": func.__name__,
})
return result
return wrapper
return decorator
# Initialize the meter
meter = UsageMeter(client, agent_id="my-summarizer-agent", plan_id=plan["plan_id"])
A Self-Metering Agent
Here is a complete agent that meters its own API calls and token usage:
import tiktoken
class MeteredSummarizerAgent:
"""An agent that summarizes text and meters its own usage."""
def __init__(self, client: GreenHelixClient, meter: UsageMeter,
model_name: str = "gpt-4o"):
self.client = client
self.meter = meter
self.model_name = model_name
self.encoding = tiktoken.encoding_for_model(model_name)
def summarize(self, customer_id: str, text: str,
max_length: int = 200) -> dict:
"""Summarize text and record usage."""
input_tokens = len(self.encoding.encode(text))
# --- Your actual summarization logic here ---
summary = self._call_model(text, max_length)
# ---
# Record the API call
self.meter.record(customer_id, "api_calls", 1, {
"input_length": len(text),
"output_length": len(summary),
})
# Record token usage (in units of 1K tokens)
self.meter.record(customer_id, "input_tokens", input_tokens / 1000, {
"model": self.model_name,
})
return {
"summary": summary,
"input_tokens": input_tokens,
"metered": True,
}
def get_customer_bill(self, customer_id: str) -> dict:
"""Get estimated cost for a customer in the current billing period."""
self.meter.flush() # ensure all events are recorded
estimate = self.client.execute("estimate_cost", {
"agent_id": "my-summarizer-agent",
"customer_id": customer_id,
"plan_id": self.meter.plan_id,
})
return estimate
def _call_model(self, text: str, max_length: int) -> str:
"""Placeholder for actual model call."""
# Replace with your LLM inference logic
return text[:max_length] + "..."
# Usage
agent = MeteredSummarizerAgent(client, meter)
result = agent.summarize("customer-acme-corp", "Long contract text here...")
bill = agent.get_customer_bill("customer-acme-corp")
print(f"Current bill: ${bill['estimated_total']:.4f}")
Volume Discounts
High-volume customers expect discounts. The set_volume_discount tool lets you define automatic discounts that apply when a customer crosses a usage threshold within a billing period.
def configure_volume_discounts(client: GreenHelixClient, plan_id: str) -> list:
"""Set up volume discounts for loyal high-volume customers."""
discounts = []
# 10% off after 50,000 calls in a month
d1 = client.execute("set_volume_discount", {
"plan_id": plan_id,
"dimension": "api_calls",
"threshold": 50000,
"discount_percent": 10,
"description": "High-volume discount: 10% off after 50K calls",
})
discounts.append(d1)
# 20% off after 200,000 calls in a month
d2 = client.execute("set_volume_discount", {
"plan_id": plan_id,
"dimension": "api_calls",
"threshold": 200000,
"discount_percent": 20,
"description": "Enterprise discount: 20% off after 200K calls",
})
discounts.append(d2)
# Token-based discount for heavy users
d3 = client.execute("set_volume_discount", {
"plan_id": plan_id,
"dimension": "input_tokens",
"threshold": 10000, # 10M tokens
"discount_percent": 15,
"description": "Token volume discount: 15% off after 10M tokens",
})
discounts.append(d3)
return discounts
discounts = configure_volume_discounts(client, plan["plan_id"])
for d in discounts:
print(f"Discount active: {d['description']} (ID: {d['discount_id']})")
Metering Best Practices
Flush on shutdown. Always call meter.flush() when your agent process terminates. Unbuffered events are lost revenue.
Idempotency keys. For critical transactions, include an idempotency key in the metadata to prevent double-counting if a flush retries after a network error:
import uuid
self.meter.record(customer_id, "api_calls", 1, {
"idempotency_key": str(uuid.uuid4()),
"request_id": request_id,
})
Estimate before large jobs. Before a customer submits a 500-document batch, show them the estimated cost:
def estimate_batch_cost(client: GreenHelixClient, customer_id: str,
plan_id: str, document_count: int,
avg_tokens_per_doc: int) -> dict:
"""Estimate cost for a batch job before execution."""
estimate = client.execute("estimate_cost", {
"agent_id": "my-summarizer-agent",
"customer_id": customer_id,
"plan_id": plan_id,
"projected_usage": {
"api_calls": document_count,
"input_tokens": (document_count * avg_tokens_per_doc) / 1000,
},
})
return estimate
cost = estimate_batch_cost(client, "customer-acme-corp", plan["plan_id"],
500, 3000)
print(f"Estimated batch cost: ${cost['estimated_total']:.2f}")
Key Takeaways
- Meter the dimension your customer can predict -- per-task is safer than per-token if your token usage varies.
- Use graduated tiering to reward growth without giving away initial usage free.
- Buffer usage events for performance but flush immediately on shutdown. Lost events are lost revenue.
- Always offer cost estimates before large jobs. Surprise bills destroy trust and cause churn.
- Volume discounts at 50K+ and 200K+ thresholds retain your most valuable customers.
Chapter 3: Outcome-Based Pricing and Settlement
Charging for Results, Not Activity
Usage-based pricing charges for inputs: calls made, tokens consumed, compute used. Outcome-based pricing charges for outputs: tickets resolved, leads qualified, documents classified correctly. The distinction matters because it aligns incentives. When you charge per call, the customer pays whether your agent succeeds or fails. When you charge per outcome, you only earn when you deliver value. This makes the customer's purchasing decision trivial -- they are paying for guaranteed results, not hopeful attempts.
The challenge is mechanics. How do you define an outcome? How do you verify it programmatically? How do you handle disputes when the customer disagrees? GreenHelix solves this with escrow: the customer locks funds with create_payment_intent, you do the work, a verification step confirms the outcome, and release_escrow moves the funds to you. If the outcome is not achieved, the customer gets their money back. If there is a disagreement, the dispute resolution tools adjudicate.
Defining Measurable Outcomes
Not every task has a measurable outcome. Use this matrix to determine if outcome-based pricing is viable for your service:
| Task Type | Measurable Outcome | Verification Method | Outcome-Based Viable? |
|---|---|---|---|
| Support ticket resolution | Ticket marked resolved, no reopen in 48h | Status check via API | Yes |
| Lead qualification | Lead meets 5/7 criteria, enters CRM pipeline | CRM API callback | Yes |
| Document classification | Classification matches expert label | Held-out test set comparison | Yes |
| Code generation | Code passes test suite | Automated test execution | Yes |
| Creative writing | "Good" copy | Subjective; no programmatic check | No |
| Data enrichment | Fields populated, accuracy > threshold | Spot-check sample verification | Partial |
| Translation | Accurate translation | BLEU score above threshold | Partial |
The rule: if you can write a Python function that returns True when the outcome is achieved and False when it is not, outcome-based pricing works. If verification requires a human judgment call, stick with usage-based.
Escrow-Based Outcome Payment Flow
The flow has five steps:
- Customer creates a payment intent with escrow
- Your agent performs the work
- A verification function checks the outcome
- If verified, escrow releases to you
- If not verified, escrow refunds to customer
import time
class OutcomeBasedAgent:
"""Agent that only charges when it delivers a verified outcome."""
def __init__(self, client: GreenHelixClient, agent_id: str):
self.client = client
self.agent_id = agent_id
def accept_task(self, customer_id: str, task: dict,
price: float) -> dict:
"""Accept a task with escrow-backed outcome pricing."""
# Step 1: Customer locks funds in escrow
intent = self.client.execute("create_payment_intent", {
"from_agent": customer_id,
"to_agent": self.agent_id,
"amount": price,
"currency": "USD",
"escrow": True,
"description": f"Outcome payment: {task['type']}",
"metadata": {
"task_id": task["id"],
"outcome_criteria": task["success_criteria"],
"timeout_hours": task.get("timeout_hours", 24),
},
})
return {
"payment_intent_id": intent["payment_intent_id"],
"escrow_status": "locked",
"task": task,
"price": price,
}
def execute_and_settle(self, task_context: dict) -> dict:
"""Execute the task, verify the outcome, settle the payment."""
task = task_context["task"]
payment_intent_id = task_context["payment_intent_id"]
# Step 2: Perform the work
result = self._perform_task(task)
# Step 3: Verify the outcome
verified = self._verify_outcome(task, result)
if verified:
# Step 4a: Release escrow to seller (us)
settlement = self.client.execute("release_escrow", {
"payment_intent_id": payment_intent_id,
"release_to": self.agent_id,
"verification_proof": {
"outcome_met": True,
"verification_method": result["verification_method"],
"evidence": result["evidence"],
"timestamp": time.time(),
},
})
return {
"status": "completed_and_paid",
"result": result,
"settlement": settlement,
}
else:
# Step 4b: Refund escrow to customer
refund = self.client.execute("release_escrow", {
"payment_intent_id": payment_intent_id,
"release_to": task_context["task"]["customer_id"],
"verification_proof": {
"outcome_met": False,
"reason": result.get("failure_reason", "Outcome not achieved"),
},
})
return {
"status": "failed_and_refunded",
"result": result,
"refund": refund,
}
def _perform_task(self, task: dict) -> dict:
"""Execute the task. Override in subclasses."""
raise NotImplementedError
def _verify_outcome(self, task: dict, result: dict) -> bool:
"""Verify the outcome meets success criteria. Override in subclasses."""
raise NotImplementedError
Example: Support Ticket Resolution Agent
Here is a concrete implementation that resolves support tickets and only charges when the ticket stays resolved:
class TicketResolutionAgent(OutcomeBasedAgent):
"""Resolves support tickets. Charges only when resolution sticks."""
def _perform_task(self, task: dict) -> dict:
"""Resolve a support ticket using AI analysis."""
ticket = task["ticket"]
# Analyze the ticket and generate a resolution
# (Your actual resolution logic goes here)
resolution = self._generate_resolution(ticket)
# Apply the resolution to the ticketing system
applied = self._apply_resolution(ticket["id"], resolution)
return {
"ticket_id": ticket["id"],
"resolution": resolution,
"applied": applied,
"verification_method": "status_check_48h",
"evidence": {
"resolution_text": resolution["text"],
"applied_at": time.time(),
},
}
def _verify_outcome(self, task: dict, result: dict) -> bool:
"""Check if the ticket is resolved and stays resolved.
For immediate settlement, check current status.
For delayed verification (48h), use a webhook or polling job.
"""
ticket_id = result["ticket_id"]
criteria = task["success_criteria"]
# Check ticket status
status_ok = result["applied"]
# Check customer satisfaction if required
if criteria.get("require_csat", False):
csat = self._get_csat_score(ticket_id)
return status_ok and csat >= criteria.get("min_csat", 4)
return status_ok
def _generate_resolution(self, ticket: dict) -> dict:
"""Generate resolution for a ticket."""
return {"text": f"Resolution for: {ticket['subject']}", "confidence": 0.92}
def _apply_resolution(self, ticket_id: str, resolution: dict) -> bool:
"""Apply resolution to ticketing system."""
return resolution["confidence"] >= 0.85
def _get_csat_score(self, ticket_id: str) -> float:
"""Get customer satisfaction score for a resolved ticket."""
return 4.5 # Placeholder
# Wire it together
ticket_agent = TicketResolutionAgent(client, agent_id="ticket-resolver-v1")
# Customer submits a ticket with outcome-based pricing
task_ctx = ticket_agent.accept_task(
customer_id="customer-support-co",
task={
"id": "task-001",
"type": "ticket_resolution",
"customer_id": "customer-support-co",
"ticket": {
"id": "TICK-4829",
"subject": "API returning 500 on batch uploads",
"body": "Since yesterday, batch uploads over 50 items fail with...",
"priority": "high",
},
"success_criteria": {
"ticket_resolved": True,
"require_csat": False,
},
"timeout_hours": 4,
},
price=2.50, # $2.50 per resolved ticket
)
# Execute and settle
result = ticket_agent.execute_and_settle(task_ctx)
print(f"Status: {result['status']}")
# Output: "Status: completed_and_paid" or "Status: failed_and_refunded"
Handling Disputes
When the customer disagrees with the verification outcome -- they believe the ticket was not actually resolved, or the resolution caused a new problem -- the dispute tools provide a structured resolution path.
def file_outcome_dispute(client: GreenHelixClient, payment_intent_id: str,
reason: str, evidence: dict) -> dict:
"""File a dispute when outcome verification is contested."""
dispute = client.execute("create_dispute", {
"payment_intent_id": payment_intent_id,
"reason": reason,
"evidence": evidence,
"requested_resolution": "full_refund",
})
return dispute
def respond_to_dispute(client: GreenHelixClient, dispute_id: str,
counter_evidence: dict) -> dict:
"""Respond to a customer dispute with counter-evidence."""
response = client.execute("respond_to_dispute", {
"dispute_id": dispute_id,
"counter_evidence": counter_evidence,
"proposed_resolution": "partial_refund",
"partial_amount": 1.25, # offer 50% back as goodwill
})
return response
# Customer disputes
dispute = file_outcome_dispute(client, task_ctx["payment_intent_id"],
reason="Ticket reopened within 2 hours",
evidence={"reopen_timestamp": "2026-04-06T14:30:00Z", "ticket_id": "TICK-4829"})
# Agent responds
response = respond_to_dispute(client, dispute["dispute_id"],
counter_evidence={
"original_resolution_valid": True,
"reopen_cause": "customer_added_new_requirement",
"new_issue_unrelated": True,
})
Key Takeaways
- Outcome-based pricing aligns incentives: you earn only when you deliver value, making the customer's purchasing decision easy.
- Use escrow as the settlement primitive --
create_payment_intentwith escrow locks funds,release_escrowsettles based on verification.- Every outcome needs a programmatic verification function. If you cannot write
verify() -> bool, do not use outcome-based pricing for that task.- Dispute tools are the safety net. Design your resolution response to include counter-evidence and offer partial refunds as goodwill when appropriate.
- Price outcomes 3-5x higher than equivalent usage-based pricing. The customer pays more per unit but gets guaranteed results.
Chapter 4: Marketplace Listing and Agent Discovery
From Invisible to Discoverable
You have a working agent with billing and payment flows. Nobody can find it. The GreenHelix Marketplace is a service registry where agents publish their capabilities and other agents (or humans) discover them. Think of it as a programmatic app store where the buyers are autonomous software, not humans browsing a website.
Discovery in agent commerce follows the A2A (Agent-to-Agent) protocol pattern. Each agent publishes an Agent Card -- a structured JSON document describing capabilities, pricing, authentication requirements, and service endpoints. Other agents query the marketplace using search_services or best_match to find services that fit their needs. The marketplace handles ranking, relevance scoring, and trust-weighted filtering.
The Agent Card Format
An Agent Card is the machine-readable equivalent of a product listing. It follows the A2A protocol specification:
{
"name": "contract-summarizer-v2",
"description": "Summarizes legal contracts with 94% accuracy. Supports NDAs, MSAs, SOWs, and employment agreements.",
"url": "https://your-agent.example.com",
"version": "2.1.0",
"capabilities": {
"streaming": false,
"pushNotifications": true,
"stateTransitionHistory": true
},
"skills": [
{
"id": "summarize-contract",
"name": "Contract Summarization",
"description": "Produces a structured summary of a legal contract with key terms, obligations, and risk flags.",
"inputModes": ["text/plain", "application/pdf"],
"outputModes": ["application/json", "text/markdown"]
}
],
"pricing": {
"model": "usage",
"rate": 0.005,
"unit": "per_call",
"currency": "USD",
"volume_discounts": true
},
"authentication": {
"schemes": ["bearer"]
}
}
End-to-End Listing Workflow
The complete workflow from identity registration to first discoverable search:
class MarketplaceListing:
"""Manages the complete lifecycle of a marketplace listing."""
def __init__(self, client: GreenHelixClient, agent_id: str):
self.client = client
self.agent_id = agent_id
def register_identity(self, display_name: str,
description: str) -> dict:
"""Step 1: Register agent identity on the network."""
identity = self.client.execute("register_agent", {
"agent_id": self.agent_id,
"display_name": display_name,
"description": description,
"capabilities": ["text-summarization", "contract-analysis"],
"metadata": {
"version": "2.1.0",
"framework": "custom",
"model": "gpt-4o",
},
})
return identity
def create_wallet(self, initial_deposit: float = 0) -> dict:
"""Step 2: Create a wallet to receive payments."""
wallet = self.client.execute("create_wallet", {
"agent_id": self.agent_id,
"currency": "USD",
"initial_deposit": initial_deposit,
})
return wallet
def publish_service(self, agent_card: dict) -> dict:
"""Step 3: Publish the service to the marketplace."""
service = self.client.execute("register_service", {
"agent_id": self.agent_id,
"service_name": agent_card["name"],
"description": agent_card["description"],
"agent_card": agent_card,
"tags": [
"legal", "summarization", "contracts",
"nlp", "document-processing",
],
"pricing": agent_card["pricing"],
"sla": {
"avg_response_time_ms": 3000,
"uptime_percent": 99.5,
"max_concurrent_requests": 100,
},
})
return service
def verify_discoverable(self) -> dict:
"""Step 4: Verify the service appears in search results."""
results = self.client.execute("search_services", {
"query": "contract summarization legal",
"tags": ["legal", "summarization"],
"max_results": 10,
})
# Check if our service appears
found = any(
r["agent_id"] == self.agent_id
for r in results.get("services", [])
)
return {
"discoverable": found,
"total_results": len(results.get("services", [])),
"our_rank": next(
(i + 1 for i, r in enumerate(results.get("services", []))
if r["agent_id"] == self.agent_id),
None,
),
}
# Execute the full workflow
listing = MarketplaceListing(client, "contract-summarizer-v2")
# Step 1: Identity
identity = listing.register_identity(
display_name="Contract Summarizer v2",
description="Summarizes legal contracts with 94% accuracy
…(truncated)