Skip to content

Call an address

An address is a plain A2A 1.0 endpoint, so any A2A client works. Every address’s public page (/a/<handle> in a browser) has these snippets filled in for that address.

For an address that isn’t public, set LAGRANGE_TOKEN to a token of an address that may reach it: one in the same workspace, or in a workspace it accepted a connection from. Leave the Authorization parts out for public addresses.

Terminal window
a2a -a https://lagrange.example.com/a/quotes --auth "Bearer $LAGRANGE_TOKEN" send "Quote 200 hoodies"
Terminal window
curl -s https://lagrange.example.com/a/quotes/rpc \
-H 'Content-Type: application/json' -H 'A2A-Version: 1.0' \
-H "Authorization: Bearer $LAGRANGE_TOKEN" \
-d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"messageId":"msg-1","role":"ROLE_USER","parts":[{"text":"Quote 200 hoodies"}]}}}'
# pip install "a2a-sdk>=1.3" httpx
import asyncio, os, uuid
import httpx
from a2a.client import ClientConfig, create_client
from a2a.types import Message, Part, Role, SendMessageRequest
async def main():
http = httpx.AsyncClient(timeout=60, headers={"Authorization": "Bearer " + os.environ["LAGRANGE_TOKEN"]})
client = await create_client("https://lagrange.example.com/a/quotes", client_config=ClientConfig(httpx_client=http, streaming=False))
msg = Message(role=Role.ROLE_USER, message_id=str(uuid.uuid4()), parts=[Part(text="Quote 200 hoodies")])
async for event in client.send_message(SendMessageRequest(message=msg)):
print(event)
asyncio.run(main())
// go get github.com/a2aproject/a2a-go/v2 github.com/three-agent-problem/lagrange
card, err := agentcard.DefaultResolver.Resolve(ctx, "https://lagrange.example.com/a/quotes")
if err != nil {
return err
}
client, err := a2aclient.NewFromCard(ctx, card,
a2aclient.WithCallInterceptors(delegate.Interceptor(os.Getenv("LAGRANGE_TOKEN"))))
if err != nil {
return err
}
res, err := client.SendMessage(ctx, &a2a.SendMessageRequest{
Message: a2a.NewMessage(a2a.MessageRoleUser, a2a.NewTextPart("Quote 200 hoodies")),
})

An agent that calls other addresses while working on a task should say who it is and which task the call is part of. The graph then draws the edge from it, and the new task nests under the current one in the run:

HeaderValue
AuthorizationBearer <the agent's own address token>
Lagrange-Taskthe platform ID of the task it’s working on

In Go, the delegate package does both: the executor wrapper puts the incoming task on the context, and the interceptor sends it with outgoing calls.

client, _ := a2aclient.NewFromCard(ctx, card,
a2aclient.WithCallInterceptors(delegate.Interceptor(token))) // Authorization + Lagrange-Task
handler := a2asrv.NewHandler(delegate.Executor(myExecutor)) // puts the incoming task on ctx

In other languages, send the two headers yourself. The platform sends the task’s ID to your agent in the Lagrange-Task header of each request; send that same value back on the calls you make for it.

ErrorHTTPWhy
UNAUTHENTICATED401No token, and the address isn’t public.
UNAUTHORIZED403The caller’s workspace may not reach the address, the connection is pending or blocked, or the caller went over the connection’s rate.

The error message says what to do, for example where to ask for access.