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

# A2A Protocol

> Agent-to-agent workflow invocation on the org runtime — capability discovery, JSON-RPC invoke, and OAuth 2.1 + RAR AgentCaller credentials (ADR-3RWY4P).

HASP AI Studio supports **agent-to-agent (A2A) workflows**: external agents and services invoke published **agent-callable** workflows over HTTPS on your org runtime host (`*.usehasp.run`). Discovery is public; invocation is authenticated.

## The AgentCaller (substrate model)

Every caller in the HASP system — human, API key, or agent — is classified for audit and policy. The agent caller type is **`AgentCaller`** (OAuth 2.1 + RAR–aligned credentials under delegated human authority per ADR-3RWY4P):

```
UserCaller     → human at a keyboard (session-backed)
ApiKeyCaller   → programmatic integration (API key)
AgentCaller    → AI agent under delegated authority (scoped credential)
```

`AgentCaller` is distinguished by three properties that the others lack:

1. **Delegating user** — the human whose authority the agent acts under. Audit liability flows here.
2. **Granted scopes** — an explicit, bounded set of what the agent is authorized to do. Not *"whatever seems right."*
3. **Delegation chain** — when an agent delegates to another agent, the full chain of authority is captured and preserved.

## Authentication for `POST /a2a/...`

The A2A route accepts **either** credential type as a bearer token:

```http theme={null}
Authorization: Bearer hasp_agt_live_<credential_secret>    # delegated agent credential
Authorization: Bearer hasp_api_live_<key_secret>           # org API key
```

In both cases the token's org must match the **runtime subdomain** org (`acme.usehasp.run` → org `acme`), and the caller must hold the `workflow.run` capability. An org API key gets it from the `workflow:invoke` or `control:workflows` scope; an agent credential gets it from a [`workflow.invoke`](/ai-api/agents/scope-grants#workflowinvoke) grant. A credential whose grant names specific `workflow_ids` may invoke only those. Any failure is rejected with JSON-RPC `-32002`.

Issue and rotate agent credentials through the [Agents API](/ai-api/agents/overview) or **Settings → Agent Access**; create org API keys under **Settings → API Keys**. Invoke against the `endpoint` URL from `/.well-known/agents.json` (see below).

<Note>
  Prefer a delegated agent credential (`hasp_agt_*`) for agent traffic: it carries the delegating user, an expiry, and a revocation handle, so the audit chain records who the agent acted for. An org API key carries none of that.
</Note>

## AgentCaller credential shape (ADR-3RWY4P)

A credential issuance includes:

| Field                      | Description                                                                                                                                 |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent_id`                 | Persistent identity for the agent. One agent can have many credential issuances (one per shift, one per session); they share an `agent_id`. |
| `credential_id`            | Per-issuance identity. The revocation key.                                                                                                  |
| `delegating_user`          | The human who granted this credential.                                                                                                      |
| `granted_scopes`           | Structured authority — RAR-style.                                                                                                           |
| `issued_at` / `expires_at` | Time-bounded; no permanent agent credential.                                                                                                |
| `consent_record_id`        | Integrity-anchored consent event.                                                                                                           |
| `delegation_chain`         | Populated for agent-to-agent delegation; `null` for direct user-to-agent.                                                                   |

See [Issuing credentials](/ai-api/agents/issuing-credentials) for the request/response shape and [Revocation](/ai-api/agents/revocation) for kill vs. drain semantics.

## Scope grants

Resource-action scope types describe the RAR-style grants attached to an `AgentCaller` credential — see [Scope grants](/ai-api/agents/scope-grants) for the full grammar and constraint syntax.

| Type                   | Description                                                                                              |
| ---------------------- | -------------------------------------------------------------------------------------------------------- |
| `hasp.data.read`       | Read records from an app, optionally narrowed to specific entities, fields, and filters.                 |
| `hasp.data.write`      | Write records to an app, optionally narrowed to specific entities and fields.                            |
| `external.tool.invoke` | Invoke one named external tool. One grant per tool.                                                      |
| `tool.destructive`     | Invoke one named destructive capability. Wildcards are rejected — the tool must be named.                |
| `agent.delegate`       | Delegate authority to another agent, bounded by `max_chain_depth` (1–10).                                |
| `agent.compose`        | Compose with another agent by `agent_id`.                                                                |
| `human.escalate`       | Escalate to a human — exactly one of `to_role` or `to_user_id`.                                          |
| `workflow.schedule`    | Create scheduled runs for named workflows, bounded by horizon, interval, live-schedule count, and depth. |
| `workflow.invoke`      | Invoke named workflows over A2A. The wildcard `*` is permitted only as the sole element.                 |

## Agent-callable workflows

In AI Studio, a workflow with audience **Agent-callable** can be listed in discovery and invoked via A2A. Author it in chat:

> *"Create a workflow that can be invoked by an agent to look up a patient's current status and return the summary."*

When a client calls `POST /a2a/{project_slug}/{workflow_slug}`, the platform:

1. Resolves the bearer token to a caller, ensures its org matches the request's org subdomain, and requires the `workflow.run` capability.
2. Resolves the workflow, then narrows against the credential's granted `workflow_ids` if it names any.
3. Runs policy, PHI guard, and audit as for other gateway executions.
4. Dispatches the workflow run and returns a JSON-RPC result (or error).

Invocation metadata — including the caller identity and, for a delegated agent credential, the delegating user and delegation chain — is recorded in the audit chain for compliance review.

## Capability discovery

Public **org-level** discovery is served on your **runtime host**, not on `api.usehasp.com`. No authentication is required.

```http theme={null}
GET https://{org}.usehasp.run/.well-known/agents.json
```

The response matches what the platform serves today (`CapabilityDiscoveryController`): top-level **`org_id`**, **`org_slug`**, and an **`agents`** array of **capability cards** (not the older TypeSpec `AgentsDiscoveryDocument` sample shape). Illustrative example:

```json theme={null}
{
  "org_id": "01JA7QG2...",
  "org_slug": "acme",
  "agents": [
    {
      "agent_id": "acme/patient-ops/patient-status-lookup",
      "name": "Patient Status Lookup",
      "version": "1.0.0",
      "endpoint": "https://acme.usehasp.run/a2a/patient-ops/patient-status-lookup",
      "auth": { "type": "bearer" },
      "input_schema": { },
      "output_schema": { },
      "supports_streaming": false,
      "phi_handling": "strict"
    }
  ]
}
```

Only **agent-callable** workflows in **org-visible** projects appear. The manifest is cacheable (`Cache-Control: public, max-age=300`); send `If-None-Match` against the response **ETag** for conditional requests. Use each card’s **`endpoint`** as the JSON-RPC URL.

## Invoking a workflow (JSON-RPC 2.0)

**V1 contract:** the JSON-RPC **`method` must be the literal string `"invoke"`**. Workflow-specific names are not accepted as `method` (other values yield JSON-RPC `-32601`). Pass workflow inputs inside **`params`**.

```http theme={null}
POST https://acme.usehasp.run/a2a/patient-ops/patient-status-lookup
Authorization: Bearer hasp_agt_live_<credential_secret>
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "method": "invoke",
  "params": {
    "patient_id": "pat_01JA7QG2..."
  },
  "id": "req-001"
}
```

Long-running workflows may return a run identifier for polling; trace APIs on the [Internal API](/studio/api-reference) cover run inspection.

## Multi-agent delegation

Under the **AgentCaller** model, an agent can delegate to another agent for a sub-task. The delegating agent's credential produces a child credential bounded by its own scopes. The delegation chain is preserved and audited.

```
User
  └─ Agent A (credential: grants = [hasp.data.read, agent.delegate{max_chain_depth: 2}])
       └─ Agent B (sub-credential: grants = [hasp.data.read] — subset of A's grants)
```

The chain is recorded on the child credential's `delegation_chain` and emitted as a handoff event in the audit chain. `agent.delegate` carries a `max_chain_depth` (1–10); exceeding it fails with `AGENT_DELEGATION_CHAIN_DEPTH_EXCEEDED`.

## Standards alignment

HASP's agent identity layer aligns with:

* **OAuth 2.1** — delegated authorization for agent credentials
* **Rich Authorization Requests (RAR)** — structured scopes
* **MCP authorization specification** — agent-to-server patterns

External products should consume these standards; prefer **`AgentCaller`** credentials over org-wide API keys for sensitive agent flows.

## Revoking access

Revoke an agent credential per issuance via [`POST /v1/agents/{agent_id}/credentials/{credential_id}/revoke`](/ai-api/agents/revocation) or from **Settings → Agent Access**. Revocation supports **kill** (terminate in-flight runs) and **drain** (let in-flight runs finish, refuse new ones) — see [Revocation](/ai-api/agents/revocation).

Org API keys are rotated or revoked in **Settings → API Keys**. New invocations fail immediately with an invalid key; in-flight runs started before revocation complete normally.
