How to Add ATXP to Google Agent Development Kit (ADK)

How to Add ATXP to Google Agent Development Kit (ADK)

Google ADK (Agent Development Kit) shipped in March 2026 as Google’s first-party framework for building production agents — and google adk agent payments are already the first gap developers hit. ADK gives you tool definitions, multi-step reasoning, and Gemini out of the box. It gives you nothing for spending money, managing API credentials across paid services, or producing an audit trail that compliance will accept.

This guide connects ATXP to a Google ADK agent from scratch. By the end you’ll have per-task budget enforcement, credential management across external services, and receipts attached to every tool call — in under 30 minutes of setup.


What Does Google ADK Actually Give You — and Where Does It Stop?

ADK is a Python-first orchestration framework. It excels at the coordination layer: routing tool calls, managing multi-step reasoning, and delegating between agents using AP2 and UCP hooks. Google positioned it as the enterprise-grade alternative to third-party frameworks — and the adoption numbers reflect that. Since its launch, ADK has been deployed across more Google Cloud enterprise accounts in its first month than LangChain reached in its first quarter (Google Cloud Next, March 2026).

What ADK does not include:

CapabilityADKATXP
Multi-step reasoning
Tool call orchestration
Agent-to-agent authorization (AP2/UCP)
Payment execution across external APIs
Per-task spending caps
API credential management
Receipts + audit trail

AP2 handles authorization between agents — which agent is allowed to delegate to which, and with what scope. It does not execute payments or cap spending. You still need infrastructure that can move money, enforce limits, and produce a record of what happened. That’s the gap ATXP fills underneath ADK.

For more on why this layer is missing from every major framework, see Every Agent Payment Protocol Compared — the payment execution problem is distinct from the protocol coordination problem.


Prerequisites

Before you start:

  • ATXP account — Sign up at atxp.ai. You’ll receive an API key and a starter credit balance.
  • Google ADKpip install google-adk
  • Python 3.10+ — required by ADK
  • ATXP SDKpip install atxp

If you haven’t read What Is an Agent Account?, do that first. ATXP’s agent account model is what makes per-task budget isolation possible — each ADK agent gets its own spending ceiling, not a share of a global pool.


Step 1 — Create an ATXP Agent Account

Every ADK agent that touches paid services needs its own ATXP agent account. Two budget parameters matter:

  • budget_cap — the total this agent can spend before it halts and requests approval
  • per_task_cap — the ceiling on any single tool call execution
from atxp import ATXPClient

client = ATXPClient(api_key="your_atxp_api_key")

agent_account = client.agents.create(
    name="adk-research-agent-v1",
    budget_cap=5.00,        # $5.00 total per session
    per_task_cap=0.50,      # $0.50 max per individual tool call
    currency="USD"
)

print(agent_account.agent_id)       # → "agt_abc123"
print(agent_account.wallet_address)

Setting both caps prevents the most common failure mode: a looping agent that drains your entire balance on a single runaway task. Monthly caps alone don’t catch this — the per-task budgeting guide explains why the granularity matters.


Step 2 — Define ATXP Tool Functions for ADK

ADK registers tools via Python decorators. ATXP tools drop in the same way as any other tool definition — three functions cover the core payment use cases:

from google.adk.tools import tool
from atxp import ATXPClient

client = ATXPClient(api_key="your_atxp_api_key")
AGENT_ID = "agt_abc123"

@tool
def atxp_check_budget(task_description: str) -> dict:
    """
    Check remaining budget before executing a task that costs money.
    Call this before any tool call expected to cost more than $0.05.

    Args:
        task_description: Plain-language description of what the agent is about to do.

    Returns:
        dict with remaining_usd, per_task_cap, and within_budget boolean.
    """
    budget = client.agents.get_budget(agent_id=AGENT_ID)
    return {
        "remaining_usd": budget.remaining,
        "per_task_cap": budget.per_task_cap,
        "within_budget": budget.remaining > 0
    }


@tool
def atxp_get_credentials(service: str) -> dict:
    """
    Retrieve API credentials for an external service through ATXP.
    Use this instead of hardcoded API keys.

    Args:
        service: Service identifier (e.g., 'serper-api', 'openweather', 'clearbit').

    Returns:
        dict with api_key and auth_headers for the requested service.
    """
    creds = client.credentials.get(agent_id=AGENT_ID, service=service)
    return {
        "api_key": creds.api_key,
        "auth_headers": creds.auth_headers
    }


@tool
def atxp_pay(
    service: str,
    amount_usd: float,
    description: str,
    task_id: str
) -> dict:
    """
    Record a payment through ATXP after executing a billable service call.
    Always call this after a paid API call completes — before returning results.

    Args:
        service: The service that was called (e.g., 'serper-api').
        amount_usd: The actual amount charged by the service.
        description: Human-readable description of what was purchased.
        task_id: Unique identifier for this task run (format: 'task-{unix_timestamp}').

    Returns:
        dict with transaction_id, receipt_url, remaining_budget, and status.
    """
    result = client.payments.execute(
        agent_id=AGENT_ID,
        service=service,
        amount=amount_usd,
        currency="USD",
        description=description,
        idempotency_key=task_id   # prevents double-charge on ADK retries
    )
    return {
        "transaction_id": result.transaction_id,
        "receipt_url": result.receipt_url,
        "remaining_budget": result.agent_remaining_budget,
        "status": result.status
    }

The idempotency_key on atxp_pay is not optional in production. ADK retries tool calls on transient network failures — without a deterministic key, each retry creates a new charge. Use task_id + call_index as your key, not a random UUID.


Ready to set up your agent account? Start at atxp.ai — takes two minutes, and your first tool calls are covered by the starter balance.


Step 3 — Wire the Tools Into an ADK Agent

from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService

# import tools from above
from tools import atxp_check_budget, atxp_get_credentials, atxp_pay

research_agent = Agent(
    name="research_agent",
    model="gemini-2.0-flash",
    instruction="""You are a research agent with access to paid external data services.

    Payment protocol — follow this sequence for every billable tool call:
    1. Call atxp_check_budget with a description of what you're about to do.
       If within_budget is false, stop immediately and tell the user their budget is exhausted.
    2. Call atxp_get_credentials to retrieve the API key for the target service.
    3. Execute the API call using the retrieved credentials.
    4. Call atxp_pay with the service name, actual charge amount, a clear description,
       and a task_id in the format 'task-{unix_timestamp}'.

    Never hardcode credentials. Never skip atxp_pay after a billable call.
    If atxp_pay returns status: budget_exceeded, stop the current task and report to the user.
    """,
    tools=[
        atxp_check_budget,
        atxp_get_credentials,
        atxp_pay,
        # ... your domain tools: web_search, browse_url, run_sql, etc.
    ]
)

session_service = InMemorySessionService()
runner = Runner(
    agent=research_agent,
    app_name="research-app",
    session_service=session_service
)

The instruction block is where the payment discipline lives. Be explicit: the agent should check budget, fetch credentials, call the service, then record payment — in that order. Agents that skip the sequence will either fail on missing credentials or produce transactions with no audit trail.


Step 4 — Run a Payment-Aware Task

from google.genai import types
import asyncio

async def run_paid_research(query: str):
    session = await session_service.create_session(
        app_name="research-app",
        user_id="dev-test",
        session_id="session-001"
    )

    content = types.Content(
        role="user",
        parts=[types.Part(text=query)]
    )

    async for event in runner.run_async(
        user_id="dev-test",
        session_id="session-001",
        new_message=content
    ):
        if event.is_final_response():
            print(event.content.parts[0].text)

asyncio.run(run_paid_research(
    "Pull current pricing for Claude, GPT-4o, and Gemini 1.5 Pro and return a cost-per-million-tokens table."
))

When this executes, the agent checks budget, retrieves credentials for your data source via ATXP, calls the source, records the payment, and returns results. The receipt_url in the payment response is permanent — log it alongside the task output for your audit trail.


How Does AP2/UCP Interop Work With ATXP?

If you’re building multi-agent ADK systems, you’ll encounter AP2 (agent-to-agent authorization) and UCP (Universal Commerce Protocol for purchase formatting). These handle which agent can delegate to which — but neither executes payments or caps spending. ATXP operates below both:

ProtocolWhat It HandlesATXP Integration Point
AP2Agent-to-agent authorization grants and delegation scopeATXP reads AP2 delegation tokens to verify calling agent’s spending authority
UCPStandardized purchase request format for commerce transactionsATXP accepts UCP-formatted requests natively
ATXPPayment execution, credential management, receiptsExecutes after AP2/UCP authorization is confirmed

For multi-agent setups where an orchestrator delegates tasks to subagents, you can create a scoped sub-budget tied to an AP2 delegation token:

# Orchestrator creates a sub-budget for a delegated subagent
sub_budget = client.agents.create_delegation(
    parent_agent_id="agt_orchestrator",
    child_agent_id="agt_subagent_research",
    delegation_cap=1.00,            # $1.00 max for this delegation
    ap2_token=ap2_delegation_token  # from ADK's AP2 auth flow
)

This prevents a subagent two levels deep from spending beyond what the orchestrator authorized — even if the orchestrator’s own balance could cover it. The multi-agent system guide covers the full orchestration pattern with working code.


Production Checklist

Before you ship an ADK + ATXP agent:

  • Agent account created with explicit budget_cap and per_task_cap
  • idempotency_key set on every atxp_pay call using a deterministic key
  • atxp_check_budget called in instruction block before any payment > $0.05
  • Explicit handling in instruction block for status: budget_exceeded
  • receipt_url logged for every transaction
  • AP2 delegation tokens configured if using orchestrator/subagent pattern
  • Tested end-to-end with a $0.01 budget cap before live deployment

The most common production failure is an agent with no budget_exceeded handling. Without it, ADK either throws and crashes or loops retrying the payment. Define the fallback explicitly: stop the current task and report the limit to the user.


Frequently Asked Questions

Does ATXP work with Gemini models or only OpenAI?

ATXP is model-agnostic. It’s a payment infrastructure layer, not a model integration. It works with ADK’s default Gemini models, with OpenAI models swapped in via ADK’s model parameter, or with any other LLM you route through the framework. The ATXP tools are plain Python functions — the model doesn’t affect how they execute.

What happens if my ADK agent hits its ATXP budget cap mid-task?

The atxp_pay call returns a structured error with status: "budget_exceeded" and the current remaining balance. Your ADK instruction block should handle this explicitly — without handling, ADK surfaces it as a tool call failure and may retry. Define a fallback: stop the task and report the limit to the user rather than looping.

Can I use ATXP with ADK’s built-in tool retry logic?

Yes, but the idempotency_key on every atxp_pay call is non-negotiable. ADK retries tool calls on transient network errors — without idempotency keys you’ll be charged for each retry. Use task_id + tool_call_index as a deterministic key, not a random UUID generated at call time.

Is ATXP compatible with ADK’s multi-agent AP2 delegation model?

Yes. ATXP supports AP2 delegation tokens for multi-agent budget chains. An orchestrator creates a capped sub-budget for a delegated subagent — the subagent cannot exceed its delegated ceiling even if the orchestrator’s balance has headroom. This is the correct primitive for preventing runaway spend in deep agent hierarchies.

How do I see what my ADK agent spent across multiple sessions?

Every atxp_pay call returns a receipt_url. Pull a full spending history with client.agents.get_transactions(agent_id=AGENT_ID) — filterable by task_id, date range, or service name. You can also pull session-level summaries to see total cost per run rather than individual call costs.


For comparison across other frameworks, how to build an agent without API keys walks the same credential management pattern for LangChain and CrewAI. The ATXP tool definitions are consistent — drop them in the same way regardless of framework.