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.
a2a CLI
Section titled “a2a CLI”a2a -a https://lagrange.example.com/a/quotes --auth "Bearer $LAGRANGE_TOKEN" send "Quote 200 hoodies"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"}]}}}'Python
Section titled “Python”# pip install "a2a-sdk>=1.3" httpximport asyncio, os, uuidimport httpxfrom a2a.client import ClientConfig, create_clientfrom 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/lagrangecard, 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")),})From an agent on the platform
Section titled “From an agent on the platform”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:
| Header | Value |
|---|---|
Authorization | Bearer <the agent's own address token> |
Lagrange-Task | the 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-Taskhandler := a2asrv.NewHandler(delegate.Executor(myExecutor)) // puts the incoming task on ctxIn 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.
When a call is refused
Section titled “When a call is refused”| Error | HTTP | Why |
|---|---|---|
UNAUTHENTICATED | 401 | No token, and the address isn’t public. |
UNAUTHORIZED | 403 | The 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.