# Agents over A2A (/docs/a2a)



```ts
import { createA2aClient } from "@nylorun/agents/a2a";

const a2a = createA2aClient({
  url: `${process.env.NYLORUN_RUNTIME_URL}/v1/a2a/agents/support`,
  key: process.env.NYLORUN_SERVER_KEY!,
  subject: "a2a:billing",
});

const task = await a2a.send({
  messageId: crypto.randomUUID(),
  contextId: "ticket-4821",
  parts: [{ text: "Refund order demo-123 and tell me when it is done." }],
  returnImmediately: true,
  push: { url: "https://app.example.com/a2a/push" },
});
// task.status.state: "TASK_STATE_SUBMITTED"; updates arrive at the push URL
```

The Runtime serves every [Agent](/docs/run/agents) over
[A2A 1.0](https://a2a-protocol.org/latest/specification/) on the JSON-RPC
binding. A context is one session per caller, Agent, and `contextId`; a task
is one turn of that session. Updates reach the caller as signed
[push notifications](/docs/a2a/push), once the operator sets the Runtime's
push secret, and a [change feed](/docs/a2a/client#the-change-feed) catches up
on any it missed.

A2A leaves some questions open, such as which state an approval uses. The
[Nylorun profile](/docs/a2a/profile/v2) answers them for every Agent, and its
five extensions carry what a client shows a person: approvals, plan steps,
cost, a trace id, and file versions. Every extension is optional, so any A2A
1.0 client can call an Agent.

## Where callers reach an Agent [#where-callers-reach-an-agent]

| Caller                 | Endpoint                                                                                                                   | Credentials                                                                                                         |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Your own server        | `POST /v1/a2a/agents/{agentId}` on the Runtime; the card at `GET /v1/a2a/agents/{agentId}/card`                            | An application key with the `Nylorun-Subject` header, as `client.as()` sends it. Scope `sessions:own`.              |
| A partner's A2A client | `createA2aHandler()` on your server, at `{basePath}/{agent}`; the card at `{basePath}/{agent}/.well-known/agent-card.json` | Whatever your server checks. The handler forwards each request as the subject you name. See [A2A](/docs/build#a2a). |

A caller sees only its own contexts and tasks: another subject's task answers
as not found. Request and response shapes are on
[Call an agent over A2A](/reference/runtime/sessions/a2a/call-an-agent-over-a2a).

## Versions [#versions]

Profile v2 needs `@nylorun/runtime` 0.37.0-beta or later, which lists the Host
feature `a2a-profile-v2`, and the change feed the Host feature `turns`. The
A2A client is in `@nylorun/agents` 0.31.0-beta or later.

```ts
const features = await client.hostFeatures(); // client from createClient()
const v2 = features.includes("a2a-profile-v2");
```

## Pages [#pages]

| Page                                                                                                                                                                                                     | What it covers                                                                      |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| [Profile v2](/docs/a2a/profile/v2)                                                                                                                                                                       | The rules, the extensions, what a v2 Agent serves, and what a client gets           |
| [Push notifications](/docs/a2a/push)                                                                                                                                                                     | Push configs, delivery, Standard Webhooks signing, and retries                      |
| [A2A client](/docs/a2a/client)                                                                                                                                                                           | `createA2aClient()`, reading the extensions, verifying pushes, and the change feed  |
| [Conformance](/docs/a2a/conformance)                                                                                                                                                                     | What the Runtime claims for A2A 1.0, its documented choices, and the TCK results    |
| [`interactions/v1`](/docs/a2a/interactions/v1), [`effects/v1`](/docs/a2a/effects/v1), [`progress/v1`](/docs/a2a/progress/v1), [`telemetry/v1`](/docs/a2a/telemetry/v1), [`files/v1`](/docs/a2a/files/v1) | One page per extension. Its URI, `https://docs.nylorun.com/a2a/<name>/v1`, opens it |

## Next step [#next-step]

<Cards>
  <Card title="Profile v2" description="The rules every Agent follows over A2A, and its extensions." href="/docs/a2a/profile/v2" />

  <Card title="A2A client" description="Send a task, answer an approval, and verify pushes." href="/docs/a2a/client" />
</Cards>
