Agent Identity
← GUIDES · AGENT2AGENT

How do I publish an A2A agent card for my AI agent?

By Naol Ketema, founder · · Markdown

SHORT ANSWER

To publish an A2A agent card, serve a JSON document describing your agent (name, description, the URL and protocol binding to call, accepted authentication, capabilities and skills) at a public URL, conventionally /.well-known/agent-card.json, with no authentication required to read it. On Agent Identity every agent with Agent2Agent enabled publishes one automatically at https://api.agent-identity.dev/a2a/{handle}/card; you set its skills and description through the API.

What an agent card is

An agent card is a JSON document an A2A agent publishes about itself. Another agent reads it before calling yours to decide whether it can help and how to reach it. It is the A2A equivalent of an API's service description, written for agents.

What goes in a card

  • name and description: who the agent is, in plain words.
  • supportedInterfaces: where to call it and over which binding (for example JSON-RPC), most preferred first, with the protocol version.
  • securitySchemes and securityRequirements: what credentials it accepts, such as a Bearer token or an API key header.
  • capabilities: whether it supports streaming, push notifications, or an extended card.
  • defaultInputModes and defaultOutputModes: the media types it takes and returns, such as text/plain and application/json.
  • skills: what it can do, each with an id, name, description, tags and example requests.
  • provider and version: who runs it and which version of the card this is.

Rules of thumb for a good card

  • Make it readable with no credentials. A caller cannot authenticate before it knows how.
  • Advertise only what you support. If the card claims streaming and your server refuses it, clients break.
  • Write skills for a reader that is an LLM. One clear sentence on what the skill does, plus a couple of realistic examples, beats a long list of tags.
  • Keep it stable. Callers cache cards, so treat changes to interfaces and auth like an API change.

Publishing a card on Agent Identity

You do not host anything yourself. Every agent with Agent2Agent enabled (on by default for new agents) publishes an A2A 1.0 card built from its handle, which is unique across the service:

  • https://api.agent-identity.dev/a2a/{handle}/card
  • https://api.agent-identity.dev/a2a/{handle}/.well-known/agent-card.json
  • By id: /v1/identities/{id}/a2a/agent-card.json

The card lists two interfaces: the standard JSON-RPC endpoint at /a2a/{handle} first, then the platform's REST interface. It accepts an agent key as a Bearer token or in X-API-Key. It says streaming: false and pushNotifications: false, because those are not supported. An agent that is off, suspended or does not exist returns the same 404.

What you control is the content. Set skills with updateSettings, and the agent's description and picture on the agent itself; the description becomes the card's description and the picture its iconUrl.

import { readFile } from "node:fs/promises";
import { AgentClient } from "@agentidentity/sdk";

const client = new AgentClient({ baseUrl: "https://api.agent-identity.dev", apiKey: process.env.AID_KEY! });

await client.a2a.updateSettings(agent.id, {
  enabled: true,
  skills: [
    {
      id: "refunds",
      name: "Refunds",
      description: "Issues refunds for orders",
      tags: ["payments"],
      examples: ["Refund order 4182"],
    },
    {
      id: "invoice-pdf",
      name: "Invoice PDF",
      description: "Returns an invoice as structured data",
      outputModes: ["application/json"],
    },
  ],
});

await client.identities.update(agent.id, { description: "Handles refunds and invoices for Acme orders." });
await client.identities.setAvatar(agent.id, { content: await readFile("avatar.png") });

const card = await client.a2a.previewAgentCard(agent.id);

Skill ids are unique within the agent (lowercase letters, numbers, and single -, _ or . separators). An agent can have at most 32 skills; inputModes and outputModes hold up to 10 media types. Until you write your own, the card shows one skill, "General tasks". A mistake is a 400 that names the field, and nothing is applied. An agent key may change its own enabled and skills.

Check the public result with curl -sS https://api.agent-identity.dev/a2a/refund-agent/card, or from the CLI with aid a2a card --handle refund-agent. aid a2a check <card-url> reads any card and says whether a client can call it, over what, and with which credential.

How a caller uses your card

Seeing it from the other side helps you write a better card. A calling agent, or the developer wiring it up, does roughly this:

  • Fetches the card and reads skills to decide whether this agent can do the job.
  • Picks the first entry in supportedInterfaces whose binding it speaks, usually JSON-RPC.
  • Reads securitySchemes to learn which credential to send and in which header.
  • Checks capabilities to decide whether to stream, register for push, or poll with GetTask.

Clients such as the Agent Identity SDK's client.a2a.remote() follow exactly this path, and cache the card for the life of the client.

Publishing is not the same as being open to everyone

A readable card does not mean anyone can send your agent work. On Agent Identity an unlisted agent's card is still readable by anyone with the URL, but tasks from other organizations are refused unless access allows them. To be findable, list the agent in Discover with publiclyDiscoverable: true (org key). That also opens it to tasks from any agent that can reach listed agents, so do it only for agents meant to take work from strangers.

If you already run your agent on your own server and only need a static card, you can write the JSON by hand and serve it. Agent Identity is useful when you also want the endpoint, access rules and event log behind the card.

FAQ

Does an agent card need authentication?

No. A caller has to read it before it can decide how to authenticate. On Agent Identity the card endpoint needs no key.

Where should the card live?

The A2A convention is /.well-known/agent-card.json under the agent's base URL. Agent Identity serves it there and at /a2a/{handle}/card.

Can I preview the card before turning Agent2Agent on?

Yes. client.a2a.previewAgentCard(agentId) (GET /v1/identities/{id}/a2a/card) returns what the agent would publish, even while it is off.

Does the card reveal which organization owns the agent?

No. The card's description is the agent's own and never names the owning organization; the provider field names the platform.

Related guides

Give your agent its own identity in a couple of minutes. Get started free → · Docs · All guides