<!-- Canonical HTML: https://autoagentprotocol.org/docs/v1.3/bindings/json-rpc -->
<!-- Immutable contract: v1.3. -->
# JSON-RPC 2.0 binding

A2A defines a JSON-RPC 2.0 binding in [Section 9](https://a2a-protocol.org/specification#section-9) of its specification. AAP rides on top of **A2A v1.0** without modification, and uses JSON-RPC 2.0 as its **sole** transport: every skill is invoked via the `SendMessage` JSON-RPC method, with the AAP request packaged as a typed `DataPart` inside `params.message.parts[]`.

![JSON-RPC request and response envelopes: SendMessage carries params.message in and result.message out](https://autoagentprotocol.org/docs/v1.3/img/jsonrpc-envelope.svg)

**Note: JSON-RPC is the SOLE binding**
A JSON-RPC interface is **REQUIRED** on every AAP agent card: `supportedInterfaces[]` MUST include at least one entry with `protocolBinding: "JSONRPC"`. JSON-RPC 2.0 is the **only** transport AAP defines — the HTTP+JSON (REST) binding was [removed in v1.1.0](https://autoagentprotocol.org/docs/v1.3/bindings/rest.md), and gRPC is out of scope.


**Info: A2A v1.0 wire format — the ProtoJSON form**
AAP rides on A2A v1.0, whose single canonical wire format is the ProtoJSON form: the method is `SendMessage`, `Role` is the enum name `"ROLE_USER"` / `"ROLE_AGENT"`, and a `Part` has no `kind` discriminator (it is typed by the member it carries — AAP uses the `data` member). A compliant AAP agent **MUST** emit and accept this form so any A2A v1.0 client can parse its replies.

| Aspect | A2A v1.0 (ProtoJSON) |
|---|---|
| Method name | `SendMessage` |
| Role | `"ROLE_USER"` / `"ROLE_AGENT"` |
| Part discriminator | member-name (no `kind`) |
| Message discriminator | (none — no `kind`) |
| `result` (JSON-RPC) | the `SendMessageResponse`, i.e. `{ "message": <Message> }` |
| `messageId` | required on every `Message` |
| `mediaType` on DataPart | `application/vnd.autoagent.<skill>-request+json` |


## Endpoint and method

A dealer agent advertises one or more JSON-RPC endpoints under `supportedInterfaces[]` of its [agent card](https://autoagentprotocol.org/docs/v1.3/discovery.md). Each entry has `protocolBinding: "JSONRPC"` and a `url`.

```
POST {jsonrpc-url}
Content-Type: application/json
```

All AAP skills use a single JSON-RPC method:

```
"method": "SendMessage"
```

`SendMessage` is the **only** A2A operation AAP uses (message-only pattern: request `Message` in, response `Message` out). The optional A2A surface — `SendStreamingMessage`, the `tasks` operations (Get/List/Cancel/Subscribe), push notification configs, and `GetExtendedAgentCard` — is out of scope for AAP: dealer agents do not need to implement it, and buyer agents MUST NOT require it.

The `id` field is the standard JSON-RPC request id; AAP does not constrain it. The `params.message` is an A2A `Message` whose first `parts[]` entry is the typed AAP `DataPart`. A buyer agent MUST also include `params.configuration.acceptedOutputModes` listing the AAP response media type it expects.

## Generic envelope

Every AAP request looks like this on the wire:

```json
{
  "jsonrpc": "2.0",
  "id": "req-1",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "01HZ9F4M7C0X3K5RN8B3WJTW2P",
      "role": "ROLE_USER",
      "parts": [
        {
          "data": {
            "type": "<scope>.<thing>.request",
            "...": "skill-specific fields"
          },
          "mediaType": "application/vnd.autoagent.<skill>-request+json"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": [
        "application/vnd.autoagent.<skill>-response+json"
      ]
    }
  }
}
```

The JSON-RPC `result` is the `SendMessageResponse`, which ProtoJSON serializes as `{ "message": <Message> }` — so the agent `Message` is wrapped under `result.message`:

```json
{
  "jsonrpc": "2.0",
  "id": "req-1",
  "result": {
    "message": {
      "messageId": "01HZ9F4N1JZ7QS8VKR2A3B4C5D",
      "role": "ROLE_AGENT",
      "parts": [
        {
          "data": {
            "type": "<scope>.<thing>.response",
            "data": {
              "...": "skill-specific response data"
            }
          },
          "mediaType": "application/vnd.autoagent.<skill>-response+json"
        }
      ]
    }
  }
}
```

The `messageId` on the response is generated by the dealer agent; it MUST differ from the `messageId` the buyer agent sent on the request.

The remainder of this page shows the full envelope for each of the five skills.

## `dealer.information`

### Request

```json
{
  "jsonrpc": "2.0",
  "id": "req-1",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "01HZ9G5N8D1Y4M6SP9C4XKVW3Q",
      "role": "ROLE_USER",
      "parts": [
        {
          "data": {
            "type": "dealer.information.request"
          },
          "mediaType": "application/vnd.autoagent.dealer-information-request+json"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": [
        "application/vnd.autoagent.dealer-information-response+json"
      ]
    }
  }
}
```

### Response

```json
{
  "jsonrpc": "2.0",
  "id": "req-1",
  "result": {
    "message": {
      "messageId": "01HZ9G5P2KA8RT9WMS3B4C5D6E",
      "role": "ROLE_AGENT",
      "parts": [
        {
          "data": {
            "type": "dealer.information.response",
            "data": {
              "name": "Demo Auto Group",
              "rooftops": [
                {
                  "name": "Demo Toyota San Francisco",
                  "legal_name": "Demo Toyota of San Francisco, LLC",
                  "website": "https://demo-toyota.example.com",
                  "geo": {
                    "latitude": 37.77,
                    "longitude": -122.41
                  },
                  "emails": [
                    {
                      "name": "Sales",
                      "value": "sales@demo-toyota.example.com"
                    }
                  ],
                  "phones": [
                    {
                      "name": "Sales",
                      "value": "+14155550100"
                    }
                  ],
                  "address": {
                    "country": "US",
                    "state": "CA",
                    "city": "San Francisco",
                    "address_line_1": "100 Market St",
                    "zip": "94105"
                  },
                  "timezone": "America/Los_Angeles",
                  "capabilities": [
                    "sales",
                    "service",
                    "financing",
                    "trade_in"
                  ]
                }
              ]
            }
          },
          "mediaType": "application/vnd.autoagent.dealer-information-response+json"
        }
      ]
    }
  }
}
```

## `inventory.facets`

### Request

```json
{
  "jsonrpc": "2.0",
  "id": "req-2",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "01HZ9H6P9E2Z5N7TQ0D5YMWX4R",
      "role": "ROLE_USER",
      "parts": [
        {
          "data": {
            "type": "inventory.facets.request",
            "filters": {
              "condition": [
                "used"
              ]
            }
          },
          "mediaType": "application/vnd.autoagent.inventory-facets-request+json"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": [
        "application/vnd.autoagent.inventory-facets-response+json"
      ]
    }
  }
}
```

### Response

```json
{
  "jsonrpc": "2.0",
  "id": "req-2",
  "result": {
    "message": {
      "messageId": "01HZ9H6Q3KB9SV0XNT4C5D6E7F",
      "role": "ROLE_AGENT",
      "parts": [
        {
          "data": {
            "type": "inventory.facets.response",
            "data": {
              "makes": [
                {
                  "value": "Honda",
                  "count": 12
                },
                {
                  "value": "Toyota",
                  "count": 27
                }
              ],
              "conditions": [
                {
                  "value": "used",
                  "count": 39
                }
              ],
              "year_range": {
                "min": 2015,
                "max": 2024
              },
              "price_range": {
                "min": 9990,
                "max": 38990
              }
            }
          },
          "mediaType": "application/vnd.autoagent.inventory-facets-response+json"
        }
      ]
    }
  }
}
```

## `inventory.search`

### Request

```json
{
  "jsonrpc": "2.0",
  "id": "req-3",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "01HZ9F4M7C0X3K5RN8B3WJTW2P",
      "role": "ROLE_USER",
      "parts": [
        {
          "data": {
            "type": "inventory.search.request",
            "filters": {
              "make": [
                "Honda"
              ],
              "condition": [
                "used",
                "cpo"
              ],
              "year_min": 2020,
              "price_max": 30000
            },
            "pagination": {
              "skip": 0,
              "limit": 20
            },
            "sort": {
              "field": "price",
              "order": "asc"
            },
            "privacy": {
              "anonymous": true
            }
          },
          "mediaType": "application/vnd.autoagent.inventory-search-request+json"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": [
        "application/vnd.autoagent.inventory-search-response+json"
      ]
    }
  }
}
```

### Response

```json
{
  "jsonrpc": "2.0",
  "id": "req-3",
  "result": {
    "message": {
      "messageId": "01HZ9F4N1JZ7QS8VKR2A3B4C5D",
      "role": "ROLE_AGENT",
      "parts": [
        {
          "data": {
            "type": "inventory.search.response",
            "data": {
              "total": 1,
              "skip": 0,
              "limit": 20,
              "vehicles": [
                {
                  "dealer_id": "dealer_demo_toyota",
                  "vin": "1HGCY2F57RA000001",
                  "stock": "T12345",
                  "year": 2022,
                  "make": "Honda",
                  "model": "Civic",
                  "trim": "EX",
                  "condition": "cpo",
                  "list_price": 24990,
                  "price": 26780,
                  "fees": [
                    { "name": "Documentation fee", "amount": 500 },
                    { "name": "Pre-installed theft protection", "amount": 1290 }
                  ],
                  "status": "available",
                  "rooftop": "Demo Toyota San Francisco",
                  "inventory_date": "2026-04-12",
                  "updated_at": "2026-04-30T10:15:00Z"
                }
              ]
            }
          },
          "mediaType": "application/vnd.autoagent.inventory-search-response+json"
        }
      ]
    }
  }
}
```

## `inventory.vehicle`

### Request

```json
{
  "jsonrpc": "2.0",
  "id": "req-4",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "01HZ9J7Q0F3A6P8VR1E6ZNXY5S",
      "role": "ROLE_USER",
      "parts": [
        {
          "data": {
            "type": "inventory.vehicle.request",
            "vin": "1HGCY2F57RA000001"
          },
          "mediaType": "application/vnd.autoagent.vehicle-detail-request+json"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": [
        "application/vnd.autoagent.vehicle-detail-response+json"
      ]
    }
  }
}
```

### Response

```json
{
  "jsonrpc": "2.0",
  "id": "req-4",
  "result": {
    "message": {
      "messageId": "01HZ9J7R4MC0TW1YPV5D6E7F8G",
      "role": "ROLE_AGENT",
      "parts": [
        {
          "data": {
            "type": "inventory.vehicle.response",
            "data": {
              "dealer_id": "dealer_demo_toyota",
              "vin": "1HGCY2F57RA000001",
              "stock": "T12345",
              "year": 2022,
              "make": "Honda",
              "model": "Civic",
              "trim": "EX",
              "condition": "cpo",
              "msrp": 26500,
              "list_price": 24990,
              "price": 26780,
              "fees": [
                { "name": "Documentation fee", "amount": 500 },
                { "name": "Pre-installed theft protection", "amount": 1290 }
              ],
              "status": "available",
              "rooftop": "Demo Toyota San Francisco",
              "city_mpg": 31,
              "highway_mpg": 40,
              "features": [
                "Adaptive Cruise Control",
                "Apple CarPlay",
                "Lane Keep Assist"
              ],
              "vdp_url": "https://demo-toyota.example.com/inventory/T12345",
              "inventory_date": "2026-04-12",
              "updated_at": "2026-04-30T10:15:00Z"
            }
          },
          "mediaType": "application/vnd.autoagent.vehicle-detail-response+json"
        }
      ]
    }
  }
}
```

## `lead.submit`

The unified lead carries customer info plus any combination of `vehicle_of_interest`, `trade_in`, and `appointment`. Below: a single test-drive lead that also queues the buyer's trade-in for in-person appraisal.

### Request

```json
{
  "jsonrpc": "2.0",
  "id": "req-5",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "01HZ9K8R1G4B7Q9WS2F7APYZ6T",
      "role": "ROLE_USER",
      "parts": [
        {
          "data": {
            "type": "lead.submit.request",
            "customer": {
              "first_name": "Anna",
              "last_name": "Lee",
              "email": "anna@example.com",
              "phone": "+14155550123",
              "preferred_contact": "phone",
              "address": {
                "address_line_1": "200 Folsom St",
                "city": "San Francisco",
                "state": "CA",
                "zip": "94105"
              }
            },
            "consent": {
              "granted_at": "2026-04-30T10:16:00Z",
              "allowed_channels": [
                "email",
                "phone"
              ],
              "consent_text": "I agree to share my contact info with Demo Toyota about VIN 1HGCY2F57RA000001, my Saturday test drive, and the trade-in of my 2014 Toyota Corolla.",
              "scope": [
                "lead_submission"
              ]
            },
            "vehicle_of_interest": {
              "vin": "1HGCY2F57RA000001",
              "year": 2022,
              "make": "Honda",
              "model": "Civic",
              "trim": "EX",
              "condition": "cpo"
            },
            "trade_in": {
              "year": 2014,
              "make": "Toyota",
              "model": "Corolla",
              "condition": "good",
              "mileage": 96000
            },
            "appointment": {
              "appointment_type": "test_drive",
              "appointment_at": "2026-05-02T17:00:00Z",
              "duration_minutes": 60
            },
            "message": "Interested in this Civic; is it still available? Please appraise my Corolla at the same visit.",
            "source_agent": {
              "name": "chatgpt-shopping",
              "url": "https://chatgpt.com",
              "agent_card_url": "https://chatgpt.com/.well-known/agent-card.json"
            },
            "submitted_at": "2026-04-30T10:16:05Z"
          },
          "mediaType": "application/vnd.autoagent.lead-submit-request+json"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": [
        "application/vnd.autoagent.lead-submit-response+json"
      ]
    }
  }
}
```

### Response

```json
{
  "jsonrpc": "2.0",
  "id": "req-5",
  "result": {
    "message": {
      "messageId": "01HZ9K8S5ND1VX2ZQW6E7F8G9H",
      "role": "ROLE_AGENT",
      "parts": [
        {
          "data": {
            "type": "lead.submit.response",
            "data": {
              "lead_id": "lead_2026_04_30_anna_001",
              "status": "received",
              "appointment": {
                "appointment_id": "appt_2026_04_30_anna_001",
                "status": "confirmed",
                "confirmed_at": "2026-05-02T17:00:00Z"
              },
              "dealer": {
                "name": "Demo Toyota",
                "phone": "+14155550100"
              }
            },
            "message": "Confirmed for Saturday at 10am Pacific. Please bring a valid driver's license. Your Corolla is queued for in-person appraisal at the same visit."
          },
          "mediaType": "application/vnd.autoagent.lead-submit-response+json"
        }
      ]
    }
  }
}
```

## Error mapping (A2A Section 9.5)

When a skill cannot be fulfilled, the dealer agent MUST return a JSON-RPC error envelope. AAP defines a typed error payload (`aap.error`) carried in `error.data`. The mapping uses the standard JSON-RPC `code` for transport errors and AAP's own `code` for business errors.

Validation errors (`SCHEMA_VALIDATION_FAILED`, `MISSING_REQUIRED_FIELD`, `INVALID_CONDITION`) MUST list **every** failing field at once in `details.errors[]` — each entry carrying `instanceLocation`, `keyword`, and `error` — so the buyer agent can fix the whole payload in a single retry instead of one round-trip per error. See [Errors](https://autoagentprotocol.org/docs/v1.3/errors.md) for the full shape.

```json
{
  "jsonrpc": "2.0",
  "id": "req-3",
  "error": {
    "code": -32602,
    "message": "Invalid params: 2 validation errors",
    "data": {
      "type": "aap.error",
      "error_id": "err_01HZ9EXAMPLE",
      "code": "SCHEMA_VALIDATION_FAILED",
      "message": "Request failed validation with 2 errors; see details.errors[].",
      "retryable": false,
      "details": {
        "errors": [
          { "instanceLocation": "/filters/year_min", "keyword": "type", "error": "must be integer" },
          { "instanceLocation": "/filters/condition/0", "keyword": "enum", "error": "must be one of: new, used, cpo" }
        ]
      },
      "created_at": "2026-04-30T10:15:30Z"
    }
  }
}
```

Recommended JSON-RPC code mapping:

| AAP `code` | JSON-RPC `code` | Notes |
|---|---|---|
| `SCHEMA_VALIDATION_FAILED` | -32602 | JSON-RPC "Invalid params". |
| `MISSING_REQUIRED_FIELD` | -32602 | "Invalid params". |
| `INVALID_CONDITION` | -32602 | "Invalid params" — a `condition` value is in the wrong vocabulary. |
| `UNSUPPORTED_SKILL` | -32601 | JSON-RPC "Method not found" — the dealer does not implement this skill (rare for AAP-compliant agents but allowed for forward compat). |
| `VEHICLE_NOT_FOUND` | -32000 | Application error. |
| `VEHICLE_UNAVAILABLE` | -32000 | Application error. |
| `CONTACT_CONSENT_REQUIRED` | -32000 | Application error. |
| `INVALID_CONSENT` | -32000 | Application error. |
| `APPOINTMENT_TIME_UNAVAILABLE` | -32000 | Application error. |
| `IDEMPOTENCY_CONFLICT` | -32000 | Application error — an `idempotency_key` was reused with a different payload. |
| `RATE_LIMITED` | -32002 | Reserved server-error range; AAP-specific. |
| `INTERNAL_ERROR` | -32603 | JSON-RPC "Internal error". |

See [Errors](https://autoagentprotocol.org/docs/v1.3/errors.md) for the full vocabulary and per-code semantics.
