haggl-negotiate-v2

haggl.ai Negotiation Protocol

For the cost of using Haggl as a merchant, see current pay-for-performance pricing or the pricing and FAQ in Markdown. Negotiating an offer alone does not generate a Haggl fee.

An open protocol for AI-to-AI commercial negotiation. ACP (OpenAI + Stripe) and UCP (Google) handle product discovery and checkout. haggl.ai handles the step between them: negotiation — what deal does this specific buyer get based on who they are? A buyer agent discovers a vendor's haggl.ai endpoint, reads the vendor's ideal customer profile, chooses its own evidence, and makes a case. On the other side sits a vendor agent — an LLM negotiator briefed with the vendor's products, prices, and customer segments — that weighs the case and returns a personalized offer. The only hard limit code enforces is each segment's discount ceiling; everything else is judgment, on both sides. No prior knowledge of haggl.ai is required — the endpoint documents itself.

1 Discovery


There are three ways for an agent to find a negotiable vendor. All three converge on the same negotiate endpoint and the same session lifecycle.

Storefront metadata. A vendor publishes the vendor ID, REST URL, remote MCP endpoint, manifest, and protocol documentation in the page <head>. These are Haggl discovery tags, available to agents that fetch raw HTML without executing JavaScript.

<!-- Install in the storefront head for discovery without JavaScript -->
<meta name="haggl-vendor" content="{vendorId}" />
<meta name="haggl-negotiate"
      content="https://www.haggl.ai/api/negotiate?vendor={vendorId}" />
<meta name="haggl-mcp"
      content="https://www.haggl.ai/api/mcp" />
<meta name="haggl-mcp-manifest"
      content="https://www.haggl.ai/.well-known/mcp.json" />
<meta name="haggl-protocol"
      content="https://www.haggl.ai/protocol" />HTML

The embed also inserts missing discovery tags immediately, including when WebMCP is unavailable, the vendor config cannot load, or the badge is disabled. Existing REST-only installations expose the MCP endpoint in the initial REST response as well.

WebMCP tools. On browsers that expose the WebMCP API (document.modelContext / navigator.modelContext), the vendor's embed registers negotiation tools directly with the agent runtime: haggl_start_negotiation, haggl_submit_offer, and haggl_accept_offer. An in-page agent can negotiate without scraping the page at all. Where WebMCP is unavailable, the storefront metadata still advertises REST and remote MCP. A visible badge is not required.

Remote MCP server. An agent with remote MCP support can connect to the storefront's haggl-mcp URL using Streamable HTTP and call haggl_start_negotiation with the haggl-vendor ID. The vendor ID is also the vendor query parameter in haggl-negotiate. Discovery advertises the interface; the agent runtime must support connecting to it.

# Remote MCP server — Streamable HTTP, no auth, no install
# Manifest:  https://www.haggl.ai/.well-known/mcp.json
# Endpoint:  https://www.haggl.ai/api/mcp

# Tools exposed:
haggl_list_vendors        # vendors that accept agent negotiation
haggl_start_negotiation   # open a session for a vendor_id
haggl_submit_offer        # submit evidence, receive an offer
haggl_accept_offer        # lock in the deal after user approvalMCP

Agents without remote MCP support can use GET on the negotiate URL to open a REST session — described next. Both transports use the same sessions.

2 Session Init


A GET to the negotiate URL opens a session and returns everything an agent needs: the vendor's identity, its customer segments, a plain-language how_it_works walkthrough, a machine-readable request_schema for the POST body, and the session URLs for negotiating, accepting, and checking status. It also returns mcp.endpoint, mcp.manifest, mcp.transport, and protocol_url.

# GET the negotiate URL to open a session
curl -s "https://haggl.ai/api/negotiate?vendor={vendorId}"

{
  "protocol": "haggl-negotiate-v2",
  "mcp": {
    "endpoint": "https://www.haggl.ai/api/mcp",
    "manifest": "https://www.haggl.ai/.well-known/mcp.json",
    "transport": "streamable-http"
  },
  "protocol_url": "https://www.haggl.ai/protocol",
  "vendor": {
    "id": "...", "name": "Engie", "category": "energy",
    "website": "https://...", "description": "..."
  },
  "icp_segments":       [ /* customer segments — see Section 3 */ ],
  "icp_prompt":         "...",  // legacy: concatenated text of all segments
  "max_margin_percent": 35,     // highest ceiling across all segments

  // Plain-language protocol walkthrough — 5 steps. Read it: it states the
  // norms (free opening offer, user consent before sharing personal data).
  "how_it_works": [ "Read the icp_segments array...", /* ... */ ],

  // Machine-readable description of the POST body — see Section 5
  "request_schema": {
    "method":       "POST",
    "url":          "{session.negotiate_url}",
    "content_type": "application/json",
    "body": {
      "data":              "object, required — free-form case for your buyer.
                            Optional data.proofs: [{from, subject, date, excerpt,
                            raw_mime_b64}] — email evidence; raw_mime_b64 enables
                            cryptographic DKIM verification.",
      "ask":               "object, optional — product, quantity, target price.",
      "target_segment_id": "string, optional — id from icp_segments.",
      "agent_id":          "string, optional — identify your agent/surface."
    }
  },

  "session": {
    "id":                   "sess_...",
    "negotiate_url":        "https://haggl.ai/api/negotiate/{sessionId}/offer",
    "accept_url":           "https://haggl.ai/api/negotiate/{sessionId}/accept",
    "status_url":           "https://haggl.ai/api/negotiate/{sessionId}",
    "negotiate_config_url": "https://haggl.ai/api/vendors/{vendorId}/negotiate-config?session={sessionId}",
    "max_rounds":           3,      // default; vendor-configurable
    "expires_at":           "..."   // 24h after session creation by default
  }
}BASH

To switch this REST session to MCP, connect to mcp.endpoint and call haggl_submit_offer with session.id as session_idand the same data and ask fields. Do not call haggl_start_negotiation again: existing offers and remaining rounds stay with the original session. Accept an offer only after the buyer approves it.

The init response is fully self-documenting. A buyer agent with no prior knowledge of haggl.ai can read how_it_works and request_schema, build its case, and negotiate — all from this single GET. Sessions allow up to max_rounds offer submissions (default 3) and expire at expires_at (24 hours by default), so make each round count.

3 ICP Segments


The ICP (Ideal Customer Profile) describes the customers the vendor most wants to acquire, split into segments. Each segment carries its own discount ceiling (max_margin_percent) — the one hard limit in the protocol. The segments are returned in the init response and are the primary input to the buyer agent's strategy: pick the segment your buyer can best demonstrate, or omit target_segment_id and let the vendor side match by priority.

Customer profiles express the merchant’s value assumptions. They can describe retention, expansion, cost-to-serve and referral potential. These are inputs to offer policy, not a validated customer-lifetime-value prediction. Merchants choose concession limits that fit their economics. Automated value estimation and learning from purchase outcomes are in development.
// icp_segments: array of customer segments, each with its own max discount.
// Segments may also carry optional fields: is_universal (segment open to any
// buyer) and payment_link (checkout destination for accepted offers).
[
  {
    "id":                  "returning-customers",
    "name":                "Returning Customers",
    "description":         "Multi-contract holders (gas + electricity)...",
    "priority":            1,
    "max_margin_percent":  35
  },
  {
    "id":                  "new-consumer",
    "name":                "Residential Customers",
    "description":         "Homeowners with high consumption profile...",
    "priority":            2,
    "max_margin_percent":  20
  },
  {
    "id":                  "new-smb",
    "name":                "Multi-site Businesses",
    "description":         "Small business with 3+ sites/meters...",
    "priority":            3,
    "max_margin_percent":  25
  }
]JSON

Segment descriptions are guidance, not a rubric. There is no server-side fit formula and no minimum score gating products: the vendor agent reads the buyer's case against the segment description and exercises judgment about how far up the ceiling to go. The better the evidence matches the segment, the deeper the discount — up to that segment's max_margin_percent.

4 Trust Model


Evidence arrives at three levels of trust. Verification informs the vendor agent's judgment — it does not mechanically gate the outcome — but cryptographically verified evidence consistently moves offers the most, and only verified evidence can unlock the full segment ceiling.

dkim_verified
Cryptographically authenticated email. Submitted as data.proofs[].raw_mime_b64 — base64 of the full raw RFC822 message. A valid DKIM-Signature binds the message to the sending domain via the sender's private key — impossible to fabricate. A sequence of DKIM-signed receipts simultaneously proves spend amount, payment consistency, e-billing behavior, account tenure, and provider identity. Verification runs server-side against the sender domain's signature before the vendor agent sees anything; verified evidence is then reduced to sha256 hashes — the content itself is never stored.
unverified
Documents or excerpts the buyer provides that lack cryptographic authentication but come from a credible institutional source — PDFs, statements, signed contracts, email excerpts without raw bytes. Treated as plausible with reasonable skepticism. A professionally formatted document from a named institution reads better than a screenshot.
self_reported
Facts declared directly by the buyer: location, preferences, intentions, context. Not verifiable, but vendors know buyers have little incentive to misrepresent things like owning multiple properties or wanting to expand a relationship. Include these — they cover ICP dimensions that documents can't always reach. They carry less weight than verified evidence.
Forgery doesn't pay. A proof whose raw bytes fail DKIM verification — forged, tampered, or simply re-encoded — is annotated as unverified: the offer it can support is capped at half the segment ceiling and the verified tier stays locked. Byte-exactness matters: submit the original message verbatim (Gmail API format=RAW, or IMAP FETCH BODY[]). A pretty-printed or re-encoded copy fails even when the email is genuine.
For buyer agents: Treat email inboxes as a proof vault. DKIM signatures are present on virtually every legitimate commercial email for spam prevention — they were never designed as a trust mechanism, but they function as one. Six consecutive monthly receipts from any provider are more convincing to a vendor than any self-reported claim.

5 Negotiate Request


A POST to the session's negotiate_url submits the buyer's case for one round. The body follows the request_schema from the init response: a required free-form data object, plus optional ask, target_segment_id, and agent_id.

POST {session.negotiate_url}
Content-Type: application/json

{
  // required — free-form case for your buyer. No fixed schema:
  // derive the fields from the segment descriptions you read in Section 3.
  "data": {
    "summary": "Stable residential customer in Paris 75011 with 6 consecutive
      months of verified electricity spend at €140–160/month. Zero payment
      gaps, fully digital account, open to adding a gas contract.",
    "location":                    "Paris 75011",
    "open_to_additional_services": true,

    // optional — email evidence for cryptographic verification
    "proofs": [
      {
        "from":         "billing@elmy.fr",
        "subject":      "Votre facture — janvier 2026",
        "date":         "2026-01-05",
        "excerpt":      "Montant prélevé : 148,50 €",
        "raw_mime_b64": "UmVjZWl2ZWQ6IGZyb20g..."  // base64 of the FULL raw RFC822 message
      }
      // ... additional proofs
    ]
  },

  "ask": { "product": "electricity", "target_monthly": 120 },  // optional
  "target_segment_id": "new-consumer",  // optional — id from icp_segments
  "agent_id":          "my-agent"       // optional
}JSON

The data object has no fixed schema — its shape is the buyer agent's argument. Which evidence to include, and which of the user's emails demonstrate the segment criteria, is the agent's call. An opening POST with only self-reported data shares nothing personal and still returns a real personalized offer — always worth making. Never send personal data without your user's consent; a one-line yes is enough.

6 Negotiate Response


Every round returns structured JSON: the vendor agent's offer, the round counter, and feedback on what would improve the next round. status is open while rounds remain and final on the last one.

{
  "session_id":       "sess_...",
  "round":            1,
  "status":           "open",   // open (rounds remain) | final (last round)
  "rounds_remaining": 2,

  // The vendor agent's offer for this round
  "offer": {
    "vendor":             "Engie",
    "matched_segment":    { "id": "new-consumer", "name": "Residential Customers" },
    "discount_pct":       14,
    "max_margin_percent": 20,   // the segment ceiling — the one hard limit
    "evidence": {
      "dkim_verified": 4,       // proofs that passed cryptographic verification
      "note": "Verification informs the vendor agent's judgment; it does not gate it."
    },
    "next_steps": "Accept via the session accept_url to record the deal..."
  },

  // Feedback for the next round
  "data_feedback": {
    "fields_used": [ "summary", "location", "proofs" ],
    "fields_that_could_improve_offer": [
      "Verified receipts covering a longer period",
      "Evidence of a second service or site"
    ]
  }
}JSON
data_feedback.fields_that_could_improve_offer is returned every round. Buyer agents use it to decide whether another round with stronger evidence is worth one of the remaining attempts. When the user approves an offer, POST to the session's accept_url to lock in the deal and receive next steps — usually a personalized checkout link.

7 Errors


Protocol errors surface as HTTP status codes with a JSON error message. Note what is not an error: evidence that fails DKIM verification. Failed proofs simply enter the negotiation as unverified — see Section 4.

StatusMeaningResolution
400Malformed body — usually a missing data objectFollow the request_schema from the init response
404Unknown vendor or session idRe-check the id; open a fresh session with a new GET
409Session closed — maximum rounds reached, or already acceptedAccept the latest offer, or open a new session
410Session expired (past expires_at)Perform a new GET to open a fresh session
429The vendor's monthly negotiation quota is exhaustedRetry later — the quota resets with the vendor's billing cycle

Vendor Setup


To add haggl.ai negotiation to your site, register at haggl.ai, define your customer segments and discount ceilings in the onboarding portal, and embed the snippet on your site. The negotiate endpoint, the vendor-side negotiator, and the discovery surfaces (meta tag, WebMCP tools, MCP listing) are generated and hosted automatically — no backend changes required.

The vendor side is an LLM negotiator briefed with your description, products, prices, and segments. It exercises judgment round by round; the only hard limit code enforces is each segment's max_margin_percent. When you update your segments or pricing in the portal, the next buyer agent session reflects the change immediately. No deployment needed.

DKIM verification of buyer-submitted email evidence is handled server-side by haggl.ai before your vendor agent receives the request. By the time your agent sees a proof annotated dkim_verified, its raw bytes have been checked against the sending domain's cryptographic signature — and reduced to sha256 hashes, so the buyer's email content is never stored.

Buyer Agents


A buyer agent needs the ability to discover the endpoint, make requests and follow the protocol. Compatibility depends on its tools, permissions and the storefront. Test the full path with the target agent. The endpoint provides how_it_works and request_schema. MCP-capable agents can connect to https://www.haggl.ai/api/mcp and use haggl_list_vendors where supported.

Two norms, both stated in the API's own how_it_works. The opening offer is free: a first POST with only self-reported data shares nothing personal and returns a real personalized offer — make it before asking your user for anything. Consent before evidence: never send personal data without your user's consent — but don't silently skip the verified tier either. Ask; a one-line yes is enough.

Consumer-authorized email evidence can support an offer when the configured flow uses it. DKIM verification checks signed origin; it does not independently establish every customer claim or predict future purchases. Obtain consent for the specific information being submitted. Merchants do not receive inbox access.

Research direction — additional evidence sources: zkTLS and private execution are being explored. They are not requirements for the proposed learning pilot or generally available features. In the current hosted email flow, original message fields are removed before pricing-model input and storage; submitted excerpts, profile fields and verification results may remain.