Skip to navigation

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?.

Before you begin

Complete these prerequisites before you create an A2A Surface:

  • Create a Product. See Creating a product.
  • Add at least one Capability to the Product. See 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? for an overview. For setup instructions, see 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 tools create_surface (with type a2a) and create_surface_key, or the 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:

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:

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 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. 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:

    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

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:

ErrorCauseFix
-32003 UnauthorizedThe 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 foundmetadata.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 foundThe method name isn’t supported. The error data lists the available methods.Use a listed method, such as SendMessage.
-32602 Invalid paramsThe request params are malformed.Check the request shape against Message format.
-32600 Invalid request with a test key limit messageA Test key reached its daily message cap.Wait until the count resets at midnight UTC, or use a Production key.
-32004 Rate limitedThe key exceeded a request limit.Wait for the Retry-After interval. See Request limits.
-32603 with Flow can pause, but this protocol does not support flow continuationThe 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.

Next steps

Continue with one of these guides: