§ Protocol · A2A · v0

AgentDraft speaks A2A.

AgentDraft exposes the Agent2Agent (A2A) protocol at /.well-known/agent.json for discovery and /v1/a2a/rpc for JSON-RPC dispatch. This v0 surface covers three skills — check availability, propose (HOLD), and commit — so any A2A client can coordinate with the same priority-ranked conflict engine that powers the REST protocol.

Updated


§ 01

What is A2A?

A2A is an open protocol for agents to discover and call other agents. Each agent publishes an agent card at /.well-known/agent.json describing its capabilities, skills, authentication, and endpoint. Tasks are exchanged over JSON-RPC 2.0 with a message/parts structure that supports text, data, and file payloads. The wire format is intentionally narrow so any A2A client can call any A2A server without per-vendor adapters.

AgentDraft is an A2A server. We do not become a participant in another agent's reasoning loop — we offer scheduling skills that any A2A client can call.


§ 02

How does discovery work?

Fetch the card from the root, no auth:

GET https://api.agentdraft.io/.well-known/agent.json

The response declares three skills (check_availability, propose, commit), the JSON-RPC URL (/v1/a2a/rpc), and the authentication scheme (Bearer avs_live_* API key — the same key your agent already uses for the REST surface). capabilities.pushNotifications is true because the existing webhooks pipeline is reused; capabilities.streaming is false in v0.


§ 03

How does a client call a skill?

Skills are dispatched by sending a task whose message.parts include a data part with an operation field. The v0 contract is deliberately small — one data part, one operation, immediate completion.

POST /v1/a2a/rpc
Authorization: Bearer avs_live_…

{
  "jsonrpc": "2.0",
  "id": "rpc-1",
  "method": "tasks/send",
  "params": {
    "id": "task-001",
    "message": {
      "role": "agent",
      "parts": [{
        "type": "data",
        "data": {
          "operation": "commit",
          "start": "2026-05-26T14:00:00Z",
          "end":   "2026-05-26T14:30:00Z"
        }
      }]
    }
  }
}

Successful response: a task with status.state = "completed" and a single artifact carrying the booking id, status, expiry, and audit-event id — the same fields POST /v1/bookings returns over REST.


§ 04

What happens when an agent loses the race?

When a higher-priority agent already holds (or has recently committed) the same slot, the task fails. The failure carries the winner's identity so the calling agent can counter-propose a different slot in the same turn:

{
  "id": "task-001",
  "status": {
    "state": "failed",
    "message": { "role": "agent",
                 "parts": [{ "type": "text", "text": "outranked" }] },
    "data": {
      "winning_booking_id": "bk_01J…",
      "winning_agent_id":   "agt_higher",
      "winning_agent_priority": 1,
      "your_priority": 5,
      "audit_event_id": "aud_01J…"
    }
  }
}

This is the same 409 contract the REST protocol exposes, re-cast in A2A task-status form. The losing agent should either accept the outcome, retry with a different slot, or defer to the user — never blind-retry the same slot.


§ 05

Which skills are in v0?

  • check_availability. Returns open slots for a date range. Inputs: range_start, range_end, duration_minutes, granularity_minutes, include_holds. Output: a slots[] array. Same response as GET /v1/availability.
  • propose. Creates a HOLD via the conflict engine. The hold expires by default in 30 seconds, or earlier if a higher-priority agent outranks it. Inputs: start, end, and optional buffer_before_min, buffer_after_min, metadata.
  • commit. Same inputs as propose; produces a COMMITTED booking. Atomic — succeeds entirely or returns the winner's identity (no double-writes).

§ 06

What's not in v0?

  • Streaming.tasks/sendSubscribe is not implemented — every operation completes synchronously.
  • tasks/get history. A2A task ids are echoed for spec conformance but not indexed; the durable record for any A2A operation is the underlying booking (GET /v1/bookings/{id}) or audit event (GET /v1/audit).
  • tasks/cancel. Holds release automatically on TTL; commits cancel via DELETE /v1/bookings/{id}. A tasks/cancel wrapper is on the roadmap.
  • Multi-part counter-proposals. Today a losing agent retries by sending a new tasks/send with a different slot. The richer "agent A counters with these three alternatives, agent B picks one" handshake is a future revision.

§ 07

Why bother with A2A if you already have REST?

Three reasons. First, discoverability: an A2A client can find AgentDraft without per-vendor docs — point it at the agent card and it learns the surface. Second, composability: an orchestrator agent can chain a check-availability against AgentDraft with a confirm-email against another A2A server without rewriting both transports. Third, portability: when the broader A2A ecosystem matures, AgentDraft is already a participant — the switching cost of pointing N agents at AgentDraft compounds across both transports.


§ 08

How is this versioned?

AgentDraft v0 of A2A is frozen against the 2026-04 spec revision. We will not break the agent-card shape or the tasks/send contract without a versioned URL bump (/v2/a2a/rpc). The agent card's schemaVersion field tracks the protocol revision we conform to; the version field tracks AgentDraft's own release.


§ 09

Where should I read next?