> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Setting up an A2A Surface

Use an A2A (Agent-to-Agent) Surface to expose your Runtype Product to external agents through the A2A protocol. External agents discover your Product through an Agent Card and invoke its exposed Capabilities through a JSON-RPC endpoint.

Use an A2A Surface when you want multiple AI systems to discover and call your Capabilities without a separate integration for each system. For example:

* **Cross-platform collaboration**: An external sales agent queries an inventory Capability for availability.
* **Specialized routing**: A customer support agent routes complex questions to domain-specific Capabilities.
* **Multi-agent orchestration**: Platforms such as LangChain, CrewAI, or Vercel AI SDK discover and call your Capabilities in larger workflows.

For a Surface overview, see [What are Surfaces?](/user-guide/products-surfaces/what-are-surfaces).

## Before you begin

Complete these prerequisites before you create an A2A Surface:

* Create a Product. See [Creating a product](/user-guide/products-surfaces/creating-a-product).
* Add at least one Capability to the Product. See [Adding capabilities to a Product](/user-guide/products-surfaces/adding-capabilities-to-a-product).
* Prepare a name and description for each Capability that you expose.
* Check that each Capability can run to completion without pausing. A2A doesn't resume paused runs, so a Flow that contains approval steps, client-executed tools, wait-until steps, or crawl steps fails on every A2A call. An Agent that requires approval before it uses a tool fails the same way.

If you use an Agent as a Capability, create and configure it before you start. Read [What are Agents?](/user-guide/agents/what-are-agents) for an overview. For setup instructions, see [Creating and configuring Agents](/user-guide/agents/creating-and-configuring-agents).

## Create an A2A Surface

To create and connect an A2A Surface, follow these steps:

1. On the **Products** page, open your **Product**.
2. In **Product surfaces**, click **Add Surface**.
3. Select **A2A Agent**. The Product editor opens a draft Surface.
4. In **Overview**, enter a name for the Surface, such as `Public Agent API`.
5. In **Visual view**, drag a connection from a Capability node to the Surface node.
6. In the page header, click **Save**. The Product editor saves the Surface and its connection.
7. In the **Product surfaces** list, use the status menu to set the Surface to **Active**.

Only connected and enabled Capabilities appear as skills in the Agent Card. The Product editor doesn't connect existing Capabilities to a new Surface automatically.

To automate this setup, use the [Runtype MCP server](/developer-guides/integrations/runtype-mcp-server) tools `create_surface` (with type `a2a`) and `create_surface_key`, or the [API reference](/api-reference).

## Configure the Surface

Open the Surface editor and use these tabs:

* **Overview**: Edit the Surface name, status, and basic settings.
* **Agent Card**: Configure the Agent Card name, description, icon URL, provider information, streaming, and push notifications.
* **Endpoints**: Copy the **A2A Endpoint** and **Agent Card** URLs.
* **Orchestration**: Choose which skills appear and whether an orchestrator skill routes requests.
* **Keys**: Generate and manage API keys for the Surface.

## Configure the Agent Card

Your A2A Surface publishes an A2A Protocol v1.0 Agent Card. The Agent Card is a JSON document that describes your Product identity, skills, supported interface, security schemes, and invocation URL. External agents fetch the card before they send an authenticated request.

Use the following public URL to retrieve the Agent Card:

```text
https://api.runtype.com/v1/products/YOUR_PRODUCT_ID/surfaces/YOUR_SURFACE_ID/a2a/.well-known/agent-card.json
```

External agents send JSON-RPC requests to the A2A endpoint:

```text
https://api.runtype.com/v1/products/YOUR_PRODUCT_ID/surfaces/YOUR_SURFACE_ID/a2a
```

Replace the placeholders in the URLs as follows:

* `YOUR_PRODUCT_ID`: The ID of your Product.
* `YOUR_SURFACE_ID`: The ID of your A2A Surface.

Runtype also serves the same Agent Card at `.../a2a/.well-known/agent.json`, the path that older A2A clients request. The A2A endpoint also accepts the older method names, such as `message/send`.

The Agent Card includes the following fields:

* **Agent metadata**: The name, description, icon URL, and provider information from the **Agent Card** tab. The name and description default to your Product name and description.
* **Capabilities**: Whether the Surface supports streaming and push notifications.
* **Skills**: Each connected and enabled Capability or exposed external-agent skill, with its name, description, and input and output modes.
* **Supported interfaces**: The A2A endpoint URL and JSON-RPC protocol binding.
* **Security schemes**: The authentication scheme that the external agent uses.

Write clear descriptions for your Capabilities. External agents select skills based on these descriptions.

## Configure orchestration

The **Orchestration** tab controls which skills appear on the Agent Card and how requests reach them:

* **Skills**: Lists each skill that the Surface exposes. The calling agent selects among the skills on the Agent Card. For an external Agent, turn off a skill to remove it from the Agent Card and from the orchestrator skill. The switch next to a Flow or Agent Capability doesn't remove that skill from the Agent Card. To remove a Flow or Agent skill, disconnect its Capability from the Surface.
* **Orchestrator Skill**: Turn on this switch to add one managed skill that routes requests to the visible skills. Set its **Skill name**, **Description**, and **Model**. You can also add a **System prompt (optional)**.

Keep **Orchestrator Skill** off when the calling agent selects among distinct Capabilities. Turn it on when you want one entry point that routes requests for you. [Surface orchestration modes](/user-guide/products-surfaces/surface-orchestration-modes) calls these setups Delegate mode and Managed mode.

## Generate an API key

The Agent Card discovery endpoint is public. External agents must authenticate JSON-RPC requests with an A2A API key. When you test from the dashboard, your signed-in session authenticates the request instead of a key.

To generate and share an A2A API key, follow these steps:

1. On the Surface editor, click **Keys**.
2. Click **Generate Key**.
3. In **Name (optional)**, enter a name such as `Partner Agent`.
4. In **Key Type**, select the key type:
   * **Test: revealable, daily-capped (50/day)**: You can reveal the key again later. The key can send up to 50 messages a day.
   * **Production: hash-only, uncapped**: Use for a live integration. Runtype stores only a hash, so you can't reveal the key again.
5. Optional: In **Rate Limit (requests/minute)**, enter a per-minute limit. Leave it empty for no limit.
6. Click **Generate Key**.
7. Copy or download the key from the success dialog. The dialog doesn't show the key again after you close it.

To show a Test key again, click **Reveal** next to the key in the **Keys** tab.

Use either of these headers for an authenticated request:

* `Authorization: Bearer a2a_YOUR_API_KEY`
* `X-API-Key: a2a_YOUR_API_KEY`

Replace `a2a_YOUR_API_KEY` with the generated key. A2A API keys use the `a2a_` prefix. Runtype ignores a header value without that prefix and treats the request as unauthenticated.

Create a separate key for each external agent or partner. Separate keys help you track usage and revoke one integration without affecting the others.

A key created through the API or the MCP `create_surface_key` tool accepts more options: an expiry time, a per-day request limit, and scopes that restrict the key to specific skills. A scoped key can't call the orchestrator skill.

## Revoke an API key

To revoke an A2A API key, follow these steps:

1. On the Surface editor, click **Keys**.
2. Next to the key, click the delete icon.
3. In the **Delete API Key?** dialog, click **Delete Key**.

Revocation takes effect immediately and can't be undone. Any agent that uses the key loses access.

## Request limits

Each API key can have per-minute and per-day request limits. An empty limit leaves that window unlimited. You set the per-minute limit in the key dialog; the per-day limit can be set only through the API or MCP tools.

The limits apply to every authenticated JSON-RPC request, including task reads, list requests, cancellation, and subscriptions. A subscription counts when it starts, not for each streamed event. A request counts the same whether a client uses `SendMessage` or `message/send`. Requests that you send from the dashboard and public Agent Card discovery don't count against key limits.

The limits are best-effort throttles, not strict concurrency limits. Concurrent requests can briefly exceed the configured count.

An over-limit request returns a JSON-RPC error with code `-32004` and reason `RATE_LIMITED`. Streaming sends and subscriptions receive that error in an SSE stream; other methods receive a JSON response. Both use HTTP `200`. The `Retry-After` response header gives the wait in seconds. Back off before retrying and reduce polling frequency. Counters reset at the next UTC minute or UTC day boundary for the window that rejected the request. Key request limits are separate from your account's daily execution quota.

Cancellation also uses this budget. An over-limit cancellation doesn't stop the running task. Retry after the indicated wait, or cancel with another authorized key that has request capacity.

## Agents that require end-user identity

The A2A endpoint doesn't carry a verified end-user identity, so an Agent that isolates data per end user or tenant rejects A2A requests with error `-32003`. An orchestrator skill request is also rejected when any skill that it can route to runs such an Agent. To call such an Agent, use a path described in [End-user identity and credentials](/developer-guides/guides/end-user-identity). Don't remove isolation from an Agent only to make A2A calls succeed.

## Verify the Surface

To verify the setup, follow these steps:

1. Open the **Endpoints** tab and copy the **Agent Card** URL.
2. Open the URL without an authentication header. The response includes a `supportedInterfaces` entry with `protocolVersion` set to `1.0` and a `skills` array.
3. Send an authenticated `SendMessage` request to the **A2A Endpoint** URL:

   ```bash
   curl -X POST "https://api.runtype.com/v1/products/YOUR_PRODUCT_ID/surfaces/YOUR_SURFACE_ID/a2a" \
     -H "Authorization: Bearer a2a_YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{
       "jsonrpc": "2.0",
       "method": "SendMessage",
       "id": "request-1",
       "params": {
         "message": {
           "role": "ROLE_USER",
           "parts": [{"text": "Hello"}],
           "messageId": "message-1"
         },
         "metadata": {"skill": "YOUR_SKILL_NAME"}
       }
     }'
   ```

   A successful response contains `result.task` with a terminal status in `status.state`. An `error` object instead means the request failed; see [Troubleshoot](#troubleshoot).

## Troubleshoot

If the Agent Card has no skills, confirm that at least one Capability is connected to the Surface and enabled. For an external Agent, also confirm that at least one of its skills is turned on in **Orchestration**.

If the Agent Card URL returns `404`, set the Surface to **Active**.

If a skill that you added, renamed, or turned off still shows the old state, wait for the client cache to expire. Clients can cache the Agent Card for up to one hour.

A2A errors arrive as JSON-RPC `error` objects with HTTP status `200`. Use this table to find the cause:

| Error                                                                                | Cause                                                                                                                                                                                                              | Fix                                                                                                                         |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `-32003` Unauthorized                                                                | The key is missing, lacks the `a2a_` prefix, belongs to another Surface, or has expired (`API key has expired`), or the Surface isn't **Active**. The skill can also run an Agent that requires end-user identity. | Send a current key for this Surface in an `Authorization: Bearer` or `X-API-Key` header, and set the Surface to **Active**. |
| `-32002` Skill not found                                                             | `metadata.skill` doesn't match a skill that the key can use. The error data lists the available skills. If the request omits `metadata.skill` and the key can use no skill, the message is `No skills available`.  | Use a name from the Agent Card, or create a key whose scopes include the skill.                                             |
| `-32601` Method not found                                                            | The method name isn't supported. The error data lists the available methods.                                                                                                                                       | Use a listed method, such as `SendMessage`.                                                                                 |
| `-32602` Invalid params                                                              | The request `params` are malformed.                                                                                                                                                                                | Check the request shape against [Message format](/user-guide/products-surfaces/how-a2a-works#message-format).               |
| `-32600` Invalid request with a test key limit message                               | A Test key reached its daily message cap.                                                                                                                                                                          | Wait until the count resets at midnight UTC, or use a Production key.                                                       |
| `-32004` Rate limited                                                                | The key exceeded a request limit.                                                                                                                                                                                  | Wait for the `Retry-After` interval. See [Request limits](#request-limits).                                                 |
| `-32603` with `Flow can pause, but this protocol does not support flow continuation` | The Capability can pause. The reasons follow the colon, such as `approval` or `wait-until`.                                                                                                                        | Remove the pausing step or the required tool approval, or disconnect the Capability from this Surface.                      |

For the full error reference, see [How A2A works](/user-guide/products-surfaces/how-a2a-works#errors).

## Next steps

Continue with one of these guides:

* [How A2A works](/user-guide/products-surfaces/how-a2a-works): review the protocol format and task lifecycle
* [Connecting external agents](/user-guide/products-surfaces/connecting-external-agents): connect an A2A-compatible client
* [Surface orchestration modes](/user-guide/products-surfaces/surface-orchestration-modes): compare routing modes