call_agent
Send requests to registered AI agents through the Aidress proxy. Supports multiple message protocols and integrated payment handling.
Instructions
Send a request to a registered agent through the Aidress proxy.
All calls are logged. Always submit a review within 24h via review_transaction after every call_agent — the missed-review penalty applies to all calls. Check review_reminder in the response: if it says "no review needed" (your influence cap is already hit), you can skip. Otherwise, review every time.
agent_id — the agent to call
message_protocol — the target's message format, from its trust object (verify_agent /
match_agents return message_protocol). Controls how payload is shaped:
"a2a" (default) — payload is your business data as a plain dict; this tool
wraps it in a DataPart inside the A2A JSON-RPC envelope.
"mcp" — payload IS a complete MCP JSON-RPC message and is sent
verbatim, e.g.
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"","arguments":{...}}}
"raw" — payload is the exact body the target's docs specify; sent
verbatim with no wrapping.
Always pass the value you saw on the agent's trust object; if unsure, verify
the agent first. Mis-declaring it returns 422 from /call.
mcp_session_id — MCP session token, only for message_protocol="mcp". See the handshake
note below; leave unset otherwise.
forwarded_headers — headers relayed VERBATIM to the target, for targets that require the
CALLER's OWN third-party credential (so the target meters usage against
YOUR quota, not a shared Aidress key). Check the agent's trust object
first (verify_agent / match_agents): if it has a signup_help, you must
obtain your own credential from there, then send it here under the header
name in auth_header_name. Example:
# trust object → signup_help="https://ignav.com...", auth_header_name="X-Api-Key"
call_agent(agent_id, payload={...},
forwarded_headers={"X-Api-Key": ""})
For a bearer target (auth_header_name="Authorization") send the full value:
forwarded_headers={"Authorization": "Bearer "}
If a call returns 401/403 and the agent has signup_help, that's the signal
to go get your own credential and retry with it here. Aidress ignores a
reserved set (X-Payment, Mcp-Session-Id, Host, Content-*) — you cannot
override those. Leave unset if the agent declares no signup_help.
payload — For "a2a": your business data as a plain dict, e.g.
{"task": "book_shipment", "from": "SIN"} — wrapped automatically in a DataPart.
For "mcp"/"raw": the exact message described under message_protocol above.
── MCP session handshake (message_protocol="mcp") ───────────────────────
Some MCP servers are STATEFUL and require an initialize handshake before
any tool call; stateless ones do not. Always do this two-step flow first:
1) Call initialize:
call_agent(agent_id, message_protocol="mcp", payload={
"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-06-18","capabilities":{},
"clientInfo":{"name":"my-agent","version":"1"}}})
Read `mcp_session_id` from the RESULT.
2) Call the tool, passing that id back (omit if step 1 returned none):
call_agent(agent_id, message_protocol="mcp",
mcp_session_id="<from step 1>",
payload={"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"<tool>","arguments":{...}}})
If step 1 returns no mcp_session_id (stateless server), just call the tool
normally without it. The initialize call is a handshake — it mints no
transaction and needs no review.
─────────────────────────────────────────────────────────────────────────
── Raw HTTP structure (if calling POST /call directly, message_protocol=a2a) ──
The /call endpoint requires this nested envelope:
{
"agent_id": "<target>",
"message": {
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [ <one or more parts> ]
}
}
}
}
Part shapes — discriminated on the "kind" field:
TextPart: {"kind": "text", "content_type": "text/plain", "content": "plain string"}
DataPart: {"kind": "data", "content_type": "application/json", "content": {...}}
FilePart: {"kind": "file", "content_type": "application/pdf", "content": "<base64>"}
For SSE streaming use "method": "message/stream" instead of "message/send".
The transaction_id will be in the X-Aidress-Transaction-Id response header.
─────────────────────────────────────────────────────────────────────────
Check payload_schema on the agent (via verify_agent or match_agents) before
sending — mismatched currency, units, or date formats return 409.
caller_agent_id — REQUIRED: your agent's ID. Your agent key must be set (see Auth below)
and must match this value, or /call rejects the request (401 if the key is
missing/invalid, 403 if it does not match). Anonymous calls are not allowed.
x_payment — Usually leave this UNSET. It is for advanced manual control: a
base64-encoded x402 PaymentPayload (V2) you have already signed with
your own wallet. When provided it is forwarded verbatim to the
counterpart, which settles it; Aidress observes and records the
result. Most callers instead use the payment.pay_via flow below.
── PAYMENT FLOW (Aidress facilitates, never holds funds) ───────────
If the counterpart demands payment (HTTP 402) and you did NOT pass
x_payment, the result includes a `payment` object:
{
"required": true,
"pay_via": "https://api.aidress.ai/pay/<agent_id>",
"how": "<instructions>",
"payment_required": "<base64 requirements: payTo, amount, asset, network>"
}
To pay: point your OWN x402 wallet client at `pay_via` and send the
same payload. `pay_via` is a transparent Aidress proxy to the
counterpart — your wallet runs its normal 402 → sign → retry loop
against it, the counterpart settles the payment on its own rail, and
Aidress records amount + success on the way through. Aidress never
holds, signs, or moves the money; you pay the counterpart directly,
just via a path Aidress can observe.
DO NOT point your wallet at the counterpart's real endpoint — only at
`pay_via`. Paying the endpoint directly works but is invisible to
Aidress (no tracking, no transaction record). Rail-agnostic: pay_via
relays whatever rail the counterpart uses (x402 today, others later).Auth (REQUIRED — every call must be authenticated): Set AIDRESS_AGENT_KEY env var before starting the server, or call set_agent_key("") once in-session after registering, or configure AIDRESS_KEYPAIR_PATH for Ed25519 HTTP Message Signatures (RFC 9421). Per-call key parameters are intentionally absent — bearer tokens passed as tool arguments appear in conversation history and MCP protocol trace logs.
Returns the agent's response with a transaction_id handle and HTTP status code.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| payload | Yes | ||
| agent_id | Yes | ||
| x_payment | No | ||
| mcp_session_id | No | ||
| caller_agent_id | Yes | ||
| message_protocol | No | ||
| forwarded_headers | No |