> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent2Agent

> Connect your code or multi-agent system to StackOne's pre-built agents via the Agent2Agent (A2A) protocol.

<Warning>
  **Open Beta Feature**: StackOne A2A agents are currently in open beta. While fully functional, the API and features may evolve based on user feedback.
</Warning>

**[Agent2Agent (A2A)](https://a2a-protocol.org/latest/)** is an open protocol that standardizes agent communication — sending and receiving messages in any format (text, audio, images, files, etc.), along with discovery, collaboration, and authentication. Essentially, if MCP provides a standard interface for agents to use tools, A2A provides a standard interface for users and agents to use agents.

StackOne exposes a **pre-built A2A agent** for each linked account. Use these agents from your own code, from multi-agent frameworks, or from [agent platforms](/embed/call-actions/agent2agent/agent-platforms) like Gemini Enterprise and Microsoft Foundry.

<Tip>
  **Not sure if A2A is right for you?** Check out [Call Actions](/embed/call-actions/overview) to understand when to use A2A vs MCP vs the Agent SDK.
</Tip>

<Accordion title="A2A: Understanding the Protocol" icon="graduation-cap">
  **What is A2A?** The Agent2Agent (A2A) Protocol is an open standard originally developed by Google and now maintained by the Linux Foundation. It defines how AI agents discover each other, authenticate, and exchange messages - regardless of what framework they were built with or who built them. Think of it as a common language that lets any agent talk to any other agent.

  **Why does A2A exist?** Without a standard protocol, connecting agents requires custom integrations for every pair of agents. A2A solves this by providing a single, universal interface. Your agent built with LangGraph can collaborate with an agent built with CrewAI, ADK, or any other framework - all using the same protocol.

  **How does it work?** A2A uses familiar web standards: HTTP for transport, JSON-RPC 2.0 for message format, and standard authentication methods. Agents publish an **Agent Card** (a JSON document describing their capabilities and skills) at a well-known URL. Clients fetch this card to discover what an agent can do, then send **Messages** to request work. The agent processes the request and returns either a direct response or a **Task** for longer-running operations.

  **A2A vs MCP**: These protocols are complementary, not competing. MCP (Model Context Protocol) standardizes how agents connect to **tools** - stateless functions like calculators or database queries. A2A standardizes how agents communicate with **other agents** - autonomous systems that can reason, plan, and have multi-turn conversations. Use MCP when you need tools; use A2A when you need to collaborate with other agents.
</Accordion>

<Accordion title="How StackOne A2A works" icon="layer-group">
  Each agent's skills are generated from the actions enabled on the account's connector. Behind the scenes, the agent routes through the same [MCP server](/embed/call-actions/mcp) and actions as every other protocol StackOne offers.

  ```mermaid theme={null}
  %%{init: {'theme':'base','themeVariables':{'actorBkg':'#10b981','actorBorder':'#047857','actorTextColor':'#ffffff','signalColor':'#334155','signalTextColor':'#334155','noteBkgColor':'#ecfdf5','noteBorderColor':'#10b981','noteTextColor':'#065f46'}}}%%
  sequenceDiagram
      autonumber
      participant C as Your client or agent
      participant S as StackOne A2A server
      participant A as StackOne actions
      C->>S: A2A request
      S->>A: run actions
      A-->>S: result
      S-->>C: response (SSE)
      Note over S: continually improving
  ```

  The server is built on Google's [Agent Development Kit (ADK)](https://google.github.io/adk-docs/): each request runs an agent on a Gemini model through an ADK Runner. The [StackOne ADK plugin](https://adk.dev/integrations/stackone/) exposes your account's actions through a search-and-execute tool model — the model gets one tool to search the action catalog and one to execute a chosen action, so the prompt stays a constant size as you link more connectors. When the model runs a tool, the [StackOne SDK](https://github.com/StackOneHQ/stackone-ai-python) executes it against the StackOne Actions API.

  The protocol itself is implemented with Google's [A2A Python SDK](https://github.com/a2aproject/a2a-python), which handles `message/send`, `message/stream`, and tasks. Conversation and task state is persisted, so multi-turn conversations and long-running tasks survive across requests.

  Building on ADK keeps StackOne agents interoperable with the wider Google agent ecosystem. It is the same plugin and SDK StackOne ships to customers — use them to build your own A2A agent with the [Agent SDK](/embed/call-actions/agent-sdk).
</Accordion>

## Calling actions

Before starting you need to have followed the previous setup steps described in the [Getting Started](/embed/getting-started). Then the full protocol round-trip with cURL:

<Steps>
  <Step title="Build your authentication headers">
    Every request goes to `https://a2a.stackone.com` with your API key and account ID as headers (the public agent card routes need no authentication):

    ```bash theme={null}
    Authorization: Basic <BASE64_ENCODED_STACKONE_API_KEY>
    x-account-id: <ACCOUNT_ID>
    Content-Type: application/json
    ```

    <Warning>
      A2A does **not** support query parameters for authentication. Headers only.
    </Warning>

    To build the **Basic token**, append a colon to your API key, then base64 encode the result (see the [API Keys guide](/embed/api-keys) if you need to generate a new key):

    <CodeGroup>
      ```bash Terminal theme={null}
      echo -n "<stackone_api_key>:" | base64
      ```

      ```javascript JavaScript theme={null}
      btoa("<stackone_api_key>:");
      ```

      ```python Python theme={null}
      import base64
      token = base64.b64encode(b"<stackone_api_key>:").decode('ascii')
      ```
    </CodeGroup>

    Account IDs are on each linked account under **Accounts**, or via the [List Accounts endpoint](/platform/api-reference/accounts/list-accounts).

    <Accordion title="Multiple accounts in one request">
      A single request can span multiple connected accounts. Pass more than one account ID in the `x-account-id` header — comma-separated or as repeated headers. The agent fans out across the accounts in parallel and routes each action back to its originating account; if one account is unavailable, the remaining accounts are still served.

      <CodeGroup>
        ```bash Comma-separated theme={null}
        x-account-id: <account_id_1>,<account_id_2>
        ```

        ```bash Repeated headers theme={null}
        x-account-id: <account_id_1>
        x-account-id: <account_id_2>
        ```
      </CodeGroup>
    </Accordion>
  </Step>

  <Step title="Get the agent card">
    StackOne serves two agent cards. The **public discovery card** describes the agent in general, needs no authentication, and advertises `supportsAuthenticatedExtendedCard: true`. The **authenticated extended card** is specific to your account and lists the skills for your connected accounts — A2A clients read the public card and fetch the extended card automatically.

    ```bash theme={null}
    # Public discovery card — no authentication, use this route to connect
    curl -X GET https://a2a.stackone.com/.well-known/agent-card.json

    # Authenticated extended card — your account's skills
    curl -X GET https://a2a.stackone.com/agent/authenticatedExtendedCard \
      -H 'Authorization: Basic <BASE64_APIKEY_COLON>' \
      -H 'x-account-id: <ACCOUNT_ID>'
    ```

    <Accordion title="Example extended card response">
      ```json theme={null}
      {
        "name": "StackOne (1 connector)",
        "description": "A StackOne agent with access to: HiBob.",
        "protocolVersion": "0.3.4",
        "version": "0.1.0",
        "url": "https://a2a.stackone.com",
        "skills": [
          {
            "id": "hibob_search_employees",
            "name": "Search Employees",
            "description": "Get a list of employees",
            "tags": ["stackone", "hibob"]
          },
          {
            "id": "hibob_get_employee",
            "name": "Get Employee",
            "description": "Get details of a specific employee",
            "tags": ["stackone", "hibob"]
          }
        ],
        "capabilities": {
          "streaming": true
        },
        "defaultInputModes": ["text/plain"],
        "defaultOutputModes": ["text/plain"]
      }
      ```
    </Accordion>

    <Note>
      Connector-specific routes like `https://a2a.stackone.com/hibob/agent-card.json` are public reference cards for inspecting one connector's skills — for reference only, not for agent connections.
    </Note>
  </Step>

  <Step title="Send a message">
    `message/send` initiates a new interaction or continues an existing one. Each message needs a unique `messageId` (a UUID — on macOS/Linux: `uuidgen | tr '[:upper:]' '[:lower:]'`):

    ```bash theme={null}
    curl -X POST https://a2a.stackone.com \
      -H 'Authorization: Basic <BASE64_APIKEY_COLON>' \
      -H 'x-account-id: <ACCOUNT_ID>' \
      -H 'Content-Type: application/json' \
      -d '{
        "jsonrpc": "2.0",
        "id": "msg-1",
        "method": "message/send",
        "params": {
          "message": {
            "messageId": "550e8400-e29b-41d4-a716-446655440000",
            "role": "user",
            "parts": [
              {
                "kind": "text",
                "text": "List the first 10 employees"
              }
            ],
            "kind": "message"
          },
          "configuration": {
            "blocking": true
          }
        }
      }'
    ```

    The response is a task with `status.state` and the agent's answer in `artifacts`. For long-running operations, pass `"configuration": { "blocking": false }` and poll instead.
  </Step>

  <Step title="Poll task status">
    Use `tasks/get` with the task id from the previous response:

    ```bash theme={null}
    curl -X POST https://a2a.stackone.com \
      -H 'Authorization: Basic <BASE64_APIKEY_COLON>' \
      -H 'x-account-id: <ACCOUNT_ID>' \
      -H 'Content-Type: application/json' \
      -d '{
        "jsonrpc": "2.0",
        "id": "task-query-1",
        "method": "tasks/get",
        "params": {
          "id": "task-123"
        }
      }'
    ```
  </Step>
</Steps>

## Test it

The fastest way to try the agent, no setup:

1. Go to [a2a-ui.stackone.com](https://a2a-ui.stackone.com)
2. Click the gear "⚙️" icon and enter your StackOne API key and account ID (multiple accounts: comma-separated, no spaces)
3. Click **+ Agent**, enter `https://a2a.stackone.com/.well-known/agent-card.json`, and click **Add Agent**
4. Start chatting — the agent's skills reflect the connectors and actions enabled on your linked accounts

## Troubleshooting

<AccordionGroup>
  <Accordion title="401/403 authentication errors">
    * Check the API key is valid and enabled under **Configuration → API Keys** — see the [API Keys guide](/embed/api-keys)
    * Verify the key is correctly base64 encoded (including the trailing colon) in the `Authorization` header
    * Ensure all required headers are present — `Authorization`, `x-account-id`, and `Content-Type`
    * Confirm the `x-account-id` matches your linked account and the account belongs to the same project as your API key
    * Remember: A2A only supports headers for authentication, never query parameters
    * To validate credentials, fetch the authenticated extended card — the public discovery card needs no authentication, so it cannot confirm them
  </Accordion>

  <Accordion title="Agent has no skills">
    * Check that the account is active (not in an error state or disabled)
    * Verify the connector is properly configured — skills are generated from the actions enabled for the account's connector
  </Accordion>
</AccordionGroup>

## Build with A2A

StackOne speaks the open A2A protocol, so anything that can act as an A2A client can talk to the StackOne agent:

### Agent frameworks

<CardGroup cols={2}>
  <Card title="A2A SDK" icon="code" href="/embed/call-actions/agent2agent/a2a-sdk">
    Official A2A SDKs for Python, JavaScript, Go, and more.
  </Card>

  <Card title="Google ADK" icon="google" href="/embed/call-actions/agent2agent/adk">
    Connect agents built in Google's Agent Development Kit.
  </Card>

  <Card title="AG2" icon="users" href="/embed/call-actions/agent2agent/ag2">
    Connect AG2 agents with `A2aRemoteAgent`.
  </Card>

  <Card title="BeeAI" icon="diagram-project" href="/embed/call-actions/agent2agent/beeai">
    Connect BeeAI Framework agents with `A2AAgent`.
  </Card>

  <Card title="Strands" icon="aws" href="/embed/call-actions/agent2agent/strands">
    Connect Strands Agents (AWS) with the A2A client tools.
  </Card>
</CardGroup>

### Agent platforms

Register the agent by its card URL — no code required:

<CardGroup cols={2}>
  <Card title="Gemini Enterprise" icon="google" href="/embed/call-actions/agent2agent/gemini-enterprise">
    Register the agent in Google Agent Platform & Gemini Enterprise.
  </Card>

  <Card title="Microsoft Foundry" icon="microsoft" href="/embed/call-actions/agent2agent/microsoft-foundry">
    Register the agent in Microsoft Foundry.
  </Card>
</CardGroup>
