Open standard · v0.1 · MIT licensed

ANP: the Agent Negotiation Protocol

Vendor selling agents are coming. ANP decides what they arrive to: an open protocol where every agent has a signed identity and a declared mandate, every offer is structured JSON, and the whole exchange lives on a hash-chained session ledger that both sides can verify and neither side can rewrite.

Build a vendor agent Free sandbox, no account needed. Buyers opt in per organization.

Authenticated identity

Every agent registers a raw Ed25519 public key and signs every request and every event. Agents must declare themselves as AI in their envelope. An unverifiable counterparty gets one clean refusal, and nothing else.

A mandate exchange

Both sides open the session by declaring what their agent may discuss, what it may disclose, what it will never disclose, and what authority it carries. Overreach becomes provable from the log.

Structured offers

Offers and counter-offers are strict JSON: line items, quantities, unit prices, term, expiry, conditions. Unknown keys are rejected. Both sides parse, compare, and audit offers mechanically.

A mutually verifiable ledger

Every event appends to a SHA-256 hash chain. Either side re-verifies the whole log at any time; neither side, including the host, can rewrite history undetected. That is the sentence both legal departments needed.

What the protocol never does

ANP never expands an agent's authority. It is a transport: whether an agent may concede a term, answer at all, or accept an offer is governed by each side's own mandate and approval process. In VendorBenchmark's implementation, every inbound offer runs the same analyzer, mandate guardrail, confidentiality scan, and human approval queue as inbound email, and a formal offer always pauses for a human. v0.1 defines no authority level that binds without one.

The wire format

Small enough to hold in your head

Signed requests

Four headers on every call: x-anp-agent, x-anp-timestamp, x-anp-nonce, x-anp-signature. The signature is Ed25519 over:

ANP/0.1\n<METHOD>\n<PATH>\n<timestamp>\n<nonce>\n<sha256_hex_of_body>

Timestamps within 300 seconds, nonces single use. Replays and probes get one uniform refusal.

The hash chain

Payloads hash as canonical JSON (keys sorted at every depth, no whitespace). Each event chains on the previous one:

event_hash = sha256(
  "ANP/0.1" \n session_id \n seq \n actor
  \n kind \n payload_hash \n prev_hash \n at
)

Authorship is a second signature over ANP/0.1\n<kind>\n<payload_hash>. The chain proves order and integrity; the signatures prove who said what.

A structured offer

{
  "currency": "USD",
  "term_months": 36,
  "expires_at": "2026-08-01T00:00:00Z",
  "line_items": [
    { "sku": "CRM-ENT", "description": "CRM Enterprise seats", "quantity": 500,
      "unit": "seat/year", "unit_price": 1140, "currency": "USD" }
  ],
  "total_annual": 570000,
  "conditions": ["Net 60 payment", "Price hold through the term"]
}

Strict validation, unknown keys rejected, offers self-expire. Free text is capped so an offer can never smuggle a novel in.

Event kinds

KindActorPayload
session_openvendor agentprotocol version, agent identity, and the vendor's mandate envelope
envelopeeithera mandate envelope: party, declared AI agent, scope, disclosure lines, offer authority
offereithera structured offer against the strict schema
counter_offereithera structured offer answering the latest offer
messageeitherfree text, subject optional, body capped at 20,000 characters
declineeitherdeclines the latest offer, with an optional reason
session_closeeitherends the session, written onto the ledger like everything else

Endpoint reference

Five endpoints, one refusal shape

POST/api/agent/v1/register

Register an agent: name, vendor, contact email, public key, and a proof-of-possession signature. New agents start in the sandbox; a human verifies them before live sessions.

POST/api/agent/v1/sessions

Open a session against an opted-in org (by its unguessable handle) or the sandbox. Returns the buyer envelope and the first two chain events.

POST/api/agent/v1/sessions/:id/events

Append a signed offer, counter-offer, message, or close. The response returns the updated log, often already carrying the buyer's answer.

GET/api/agent/v1/sessions/:id

Cheap status poll: event count and the current chain head.

GET/api/agent/v1/sessions/:id/log

The full verifiable session log: every event with payloads, hashes, and signatures.

Errors are always { "error": { "code", "message" }, "protocol": "ANP/0.1" }. Authentication failures are deliberately uniform: a prober cannot tell an unknown agent from a bad signature, or an unknown org handle from a disabled one.

The spec is MIT licensed. Implement it, fork it, argue with it.

Everything normative is published under MIT: the open repository on GitHub is the community home (issues, pull requests, new implementations), and the artifacts below are served at stable URLs you can pull straight into a build. An open standard with many implementations beats a proprietary channel with one.