How to Add ATXP to Google Agent Development Kit (ADK)
How to Add ATXP to Google Agent Development Kit (ADK)
Google Agent Development Kit gives Gemini-powered agents a production-ready tool-use model. What it doesn’t give them is any way to pay for the things those tools actually cost.
This guide is about google adk agent payments — specifically, how to integrate ATXP as the payment layer for ADK tool calls, set per-task spend limits that prevent runaway agents, and navigate the IAM-vs-credential tradeoff that comes up when you deploy ADK workloads in enterprise Google Cloud environments.
What Is Google ADK?
Google ADK is Google’s official Python framework for building Gemini-based agents. Released in early 2025 alongside Gemini 2.0’s expanded function calling capabilities, it gives teams a structured runtime for orchestrated agent workflows rather than stitching together raw API calls.
The model is tool-centric: you define Python functions as tools, register them with an LlmAgent, and Gemini decides which tools to invoke and in what order. The framework handles the run loop, session state, and tool dispatch. As of Q1 2026, ADK is the recommended framework for new Gemini agent workloads on Google Cloud (Google Cloud documentation, March 2026).
It supports:
- Single-agent and multi-agent (Agent-to-Agent / A2A) topologies
- Stateful sessions via
SessionService - Built-in tools (Google Search, code execution) and custom tools via
@tooldecorators - Vertex AI deployment for enterprise-grade hosting
Why Google ADK Agent Payments Need a Dedicated Layer
Every tool an ADK agent calls has a bill attached. Web search. Image generation. External enrichment APIs. Specialized LLM calls. ADK dispatches these fluently — but payment infrastructure is left entirely to the developer.
The default approach most teams reach for:
# Don't do this
import os
SEARCH_API_KEY = os.environ["SEARCH_API_KEY"]
IMAGE_API_KEY = os.environ["IMAGE_API_KEY"]
ENRICHMENT_API_KEY = os.environ["ENRICHMENT_API_KEY"]
Three APIs, three keys, three billing accounts, three separate blast radii if any one leaks. When your ADK agent is running autonomously — handling hundreds of tool calls per day across a fleet — this is a credential management problem masquerading as a deployment problem.
The deeper issue: ADK provides no native way to cap what a single agent run spends. An agent stuck in a retry loop against a paid search API will keep spending until it succeeds or you kill the process. There’s no built-in circuit breaker.
See Blast Radius: Why Agent Credentials Need Hard Walls and How Agents Pay for API Calls for the full anatomy of this problem.
How ATXP Maps Onto ADK’s Tool Interface
ATXP is an agent payment infrastructure layer. You fund one ATXP wallet — ATXP handles authentication and billing for every external service underneath. Your ADK tools call ATXP endpoints instead of individual APIs. One credential, one billing ledger, one place to set spend limits.
The integration point is clean: ATXP wraps directly onto ADK’s @tool decorator pattern. From Gemini’s perspective, these are standard Python tools. From a billing perspective, every call flows through ATXP.
Setup
pip install google-adk atxp-sdk
Initialize the ATXP client. This is the only external credential your agent needs:
import atxp
import os
client = atxp.Client(agent_token=os.environ["ATXP_AGENT_TOKEN"])
Defining Payment-Gated ADK Tools
from google.adk.tools import tool
@tool
def search_web(query: str) -> dict:
"""Search the web and return relevant results for a query."""
response = client.search(query=query, max_results=5)
return {
"results": response.results,
"credits_used": response.credits_used,
}
@tool
def generate_image(prompt: str, style: str = "photorealistic") -> dict:
"""Generate an image from a text prompt and return the image URL."""
response = client.image.generate(prompt=prompt, style=style)
return {
"url": response.url,
"credits_used": response.credits_used,
}
@tool
def enrich_company(domain: str) -> dict:
"""Look up firmographic data for a company domain."""
response = client.enrich.company(domain=domain)
return {
"data": response.data,
"credits_used": response.credits_used,
}
Returning credits_used in each tool response isn’t required, but it lets Gemini reason about spend inline — the model can factor budget remaining into its tool-call decisions if you reference it in your system prompt.
Wiring Into an ADK Agent
from google.adk.agents import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai.types import GenerateContentConfig
agent = LlmAgent(
name="research_agent",
model="gemini-2.0-flash",
tools=[search_web, generate_image, enrich_company],
instruction="""
You are a research agent. Each tool call consumes credits from a shared budget.
Be efficient — avoid redundant calls. Report credits_used per tool at the end.
""",
generate_content_config=GenerateContentConfig(temperature=0.2),
)
session_service = InMemorySessionService()
runner = Runner(
agent=agent,
session_service=session_service,
app_name="research_app",
)
Your ADK agent now calls paid services through a single ATXP credential. No key sprawl. No per-service billing accounts.
Get your ATXP_AGENT_TOKEN and fund a wallet at atxp.ai. The quickstart takes under five minutes.
How Do You Set a Per-Task Budget for ADK Runs?
Per-task budget limits are the piece most teams skip until they get burned. Without them, a misbehaving agent runs up an unlimited tab with no automatic stop.
ATXP supports task-scoped sessions with a hard credit ceiling. When the ceiling is hit, the tool call returns a BudgetExceededError as a structured response — Gemini interprets it and typically wraps up the task with data already collected rather than crashing.
def run_with_budget(task: str, budget_credits: int) -> dict:
"""Run an agent task with a hard spend ceiling."""
session = client.sessions.create(budget=budget_credits)
# Scoped client enforces the budget for this run only
scoped_client = atxp.Client(
agent_token=os.environ["ATXP_AGENT_TOKEN"],
session_id=session.id,
)
@tool
def search_web_scoped(query: str) -> dict:
"""Search the web within the current task budget."""
try:
resp = scoped_client.search(query=query, max_results=5)
return {"results": resp.results, "credits_used": resp.credits_used}
except atxp.BudgetExceededError:
return {"error": "Budget ceiling reached. Returning results collected so far."}
scoped_agent = LlmAgent(
name="budgeted_research_agent",
model="gemini-2.0-flash",
tools=[search_web_scoped],
instruction=agent.instruction,
)
response = runner.run(
user_id="user_001",
session_id=session.id,
new_message={"role": "user", "parts": [{"text": task}]},
)
summary = client.sessions.get(session.id)
return {
"response": response,
"credits_used": summary.credits_used,
"budget": budget_credits,
"under_budget": summary.credits_used < budget_credits,
}
# Research task capped at 500 credits (~$0.50)
result = run_with_budget(
task="Find the top 5 agent infrastructure competitors and summarize their positioning.",
budget_credits=500,
)
This is meaningfully better than monitoring spend externally and killing the process. The agent handles the limit gracefully; you get a partial result instead of a crash.
IAM vs. ATXP: The Enterprise Credential Question
Teams deploying ADK on Google Cloud will hit this question: you already have IAM service accounts. Why introduce another credential model?
IAM is excellent at governing access to Google Cloud resources. It’s not designed for what ATXP solves.
| Dimension | IAM Service Account | ATXP Agent Token |
|---|---|---|
| Scope | Google Cloud resources only | Any external API (100+) |
| Credential sprawl | One per GCP service | One token, all services |
| Per-task spend limits | Not supported | Native |
| Billing granularity | GCP billing (aggregate) | Per-task, per-tool-call |
| Works outside GCP | No | Yes |
| Multi-cloud agent support | No | Yes |
| Credential revocation | IAM key rotation | Token-level, instant |
The practical answer for enterprise ADK deployments: use both. IAM governs what your ADK agent can do inside Google Cloud — access BigQuery, read from Cloud Storage, write to Firestore. ATXP governs what your agent can spend on external services — web search, enrichment APIs, image generation, third-party LLM calls. They operate in different layers and don’t conflict.
Store your ATXP_AGENT_TOKEN in Secret Manager alongside your IAM service account key. Both are injected at runtime; both have distinct revocation paths.
Multi-Agent Budget Allocation in ADK
ADK’s A2A patterns let an orchestrator agent dispatch tasks to specialist sub-agents. When you have multiple agents sharing a budget, isolation matters — a runaway sub-agent shouldn’t exhaust credits for the entire pipeline.
ATXP’s session hierarchy handles this cleanly:
def run_pipeline(task: str, total_budget: int):
parent_session = client.sessions.create(budget=total_budget)
# Allocate budget slices per sub-agent
research_session = client.sessions.create(
budget=int(total_budget * 0.6),
parent_session_id=parent_session.id,
)
synthesis_session = client.sessions.create(
budget=int(total_budget * 0.4),
parent_session_id=parent_session.id,
)
# Each sub-agent gets its own scoped ATXP client
# Budget overruns in research don't touch synthesis's allocation
research_client = atxp.Client(
agent_token=os.environ["ATXP_AGENT_TOKEN"],
session_id=research_session.id,
)
synthesis_client = atxp.Client(
agent_token=os.environ["ATXP_AGENT_TOKEN"],
session_id=synthesis_session.id,
)
...
Parent session tracks total pipeline spend; child sessions enforce per-agent ceilings. If the research sub-agent burns through its allocation, the synthesis agent continues unaffected with its own budget intact.
See How to Build a Multi-Agent System With ATXP for the full multi-agent architecture.
ADK Tool Cost Reference
Setting realistic budgets requires knowing what tool calls actually cost. Approximate ATXP credit costs for common ADK tool types:
| Tool Type | Credits/Call | Calls/Day (moderate) | Daily Estimate |
|---|---|---|---|
| Web search (5 results) | 10–25 | 50 | 500–1,250 |
| Image generation (1024×1024) | 50–120 | 20 | 1,000–2,400 |
| LLM call (GPT-4o, ~2K tokens) | 15–40 | 100 | 1,500–4,000 |
| Company enrichment | 5–15 | 100 | 500–1,500 |
| Email send | 2–5 | 30 | 60–150 |
1,000 ATXP credits ≈ $1.00 at standard pricing. A focused single-task agent run fits comfortably in 500 credits. A longer autonomous research pipeline might need 5,000+. Set your per-task budget accordingly and review credits_used in session summaries after early runs to calibrate.
See How to Give an AI Agent a Budget for the full budget-design framework, and Financial Zero Trust for AI Agents for the principles behind hard-limit enforcement.
FAQ
Does ATXP work with ADK agents deployed on Vertex AI?
Yes. ATXP uses standard HTTPS — it’s network-agnostic. ADK agents running on Vertex AI, Cloud Run, or GKE use the same integration pattern. Store ATXP_AGENT_TOKEN in Secret Manager; inject it at runtime via environment variables. No changes to the ATXP integration code regardless of where ADK runs.
What happens when an ADK agent hits its ATXP budget mid-run?
The tool call that would breach the ceiling returns a BudgetExceededError. ADK surfaces this to Gemini as a structured tool response. In practice, Gemini typically interprets it as a resource constraint, wraps up the task with data already collected, and returns a partial result with an explanation. The agent doesn’t crash — it concludes gracefully. The behavior is cleaner if your system prompt explicitly instructs the agent on how to handle budget exhaustion.
Can I use ATXP alongside ADK’s built-in Google Search tool?
Yes. ADK’s built-in Google Search runs against your GCP quota — appropriate for general-purpose search within Google’s index. ATXP’s search tool is useful when you need results from providers outside Google’s index, want per-call cost attribution, or need all external tool costs flowing through one billing ledger. Register both in the same LlmAgent; Gemini selects based on context and your tool descriptions.
Should ATXP be abstracted as a single generic tool or individual service tools?
Individual service tools. Gemini’s function calling is most reliable when tools have narrow, specific signatures. A search_web(query: str) tool is called more predictably than an atxp_call(service: str, params: dict) tool that Gemini has to reason about structurally at every invocation. Keep tools specific; keep ATXP as the shared payment layer underneath them.
How do I handle ATXP token rotation in a long-running ADK deployment?
Token rotation is handled at the Secret Manager level. Update the secret value; your ADK agents pick up the new token on their next cold start or explicitly on restart. ATXP tokens can be revoked instantly from the dashboard if a token is compromised — revocation takes effect within seconds across all active sessions using that token.
ADK gives you a solid foundation for production Gemini agents. The missing piece is always the same: who pays for the tools, how much can they spend, and what stops a misbehaving agent from running up an unlimited tab.
If you’re building across multiple agent frameworks — not just ADK — How to Build an AI Agent Without API Keys covers the general case for collapsing credential sprawl across any stack.
Register your ADK agent at atxp.ai. One wallet, one token, real spend limits.