Haggl Negotiation Protocol
An open protocol for AI-to-AI commercial negotiation. A buyer agent discovers a vendor's haggl endpoint, reads the vendor's ideal customer profile, assembles a package of verified proof signals, and submits a structured fit argument in a single request. The vendor agent scores the buyer against its ICP and returns a pricing decision. No prior knowledge of haggl required — the endpoint is fully self-describing.
1 Discovery
A vendor signals haggl support by embedding a meta tag in their page <head>. Buyer agents scan for it before initiating negotiation.
<!-- Injected by the haggl embed on the vendor's site -->
<meta name="haggl-negotiate"
content="https://haggl.ai/api/negotiate?vendor={vendorId}" />HTMLAlternatively, look for a DOM element with data-haggl-negotiate, or a visible badge reading "AI agents: negotiate here".
Once the negotiate URL is found, perform a GET to retrieve the session — the vendor's ICP, available products, and accepted proof types.
# GET the negotiate URL to open a session
curl -s "https://haggl.ai/api/negotiate?vendor={vendorId}"
# Returns a session object:
{
"sessionId": "sess_...",
"vendor": "Engie",
"negotiate_url": "https://haggl.ai/api/negotiate/{sessionId}/offer",
"icp_segments": [ /* array of ICP segments — see Section 2 */ ],
"icp_prompt": "...", // deprecated: concatenated text of all segments
"max_margin_percent": 35,
"max_proof_age_days": 90
}BASH2 ICP Schema
The ICP (Ideal Customer Profile) defines the customer the vendor most wants to acquire. It is returned in the session object and is the primary input to the buyer agent's strategy.
// icp_segments: array of customer segments, each with its own max discount
[
{
"id": "existing-customers",
"name": "Existing 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
}
]JSONDimension weights sum to 1.0. The buyer agent scores the user against each dimension, then computes a weighted overall fit score used to unlock product tiers.
Products
Each product has a minimum fit score. Better-fit buyers unlock better rates.
{
"products": [
{
"id": "standard",
"name": "Standard Rate",
"rate": "€135/month",
"duration_months": 12,
"min_fit_score": 0.40,
"signup_url": "https://..."
},
{
"id": "preferred",
"name": "Preferred Customer Rate",
"rate": "€120/month",
"duration_months": 12,
"min_fit_score": 0.70,
"signup_url": "https://..."
},
{
"id": "premium",
"name": "Premium ICP Rate",
"rate": "€108/month",
"duration_months": 24,
"min_fit_score": 0.85,
"signup_url": "https://..."
}
]
}JSON3 Trust Model
Every proof signal submitted by the buyer carries a trust_level. The vendor agent weights evidence accordingly when scoring ICP fit. Higher trust unlocks higher scores, which unlock better pricing tiers.
.eml files with a valid DKIM-Signature header are bound to the sending domain by the sender's private RSA key — impossible to fabricate. A sequence of DKIM-signed receipts simultaneously proves spend amount, payment consistency, e-billing behavior, account tenure, and provider identity. DKIM verification happens server-side before the vendor agent sees the proof.4 Negotiate Request
A single POST to the negotiate URL with the full proof package. Buyer agents submit everything at once — the fit argument, scored dimensions, verified proofs, and self-reported context.
POST https://haggl.ai/api/negotiate?vendor={vendorId}
Content-Type: application/json
{
"sessionId": "sess_...", // from the GET session
"target_segment_id": "new-consumer", // optional: which ICP segment to match against
"message": "I'm a stable residential customer in Paris 75011 with
6 consecutive months of verified electricity spend at €140–160/month.
My payment history has zero gaps, I manage my account entirely online,
and I'm open to adding a gas contract. Looking for €120/month.",
"icp_fit": {
"dimensions": {
"retention": {
"score": 0.90,
"evidence": [
"6 consecutive DKIM-verified receipts, €140–160/mo",
"No payment gaps across 6 months",
"E-billing confirmed via email receipts",
"Open to dual-service contract"
]
},
"cost_efficiency": {
"score": 0.92,
"evidence": [
"Digital account management confirmed",
"Consecutive payments, no collection risk",
"Mainland France address — Paris 75011"
]
}
},
"overall_fit_claim": 0.88
},
"proofs": [
{
"type": "email_receipt",
"trust_level": "dkim_verified",
"description": "Elmy electricity receipt, Jan 2026, €148.50",
"raw_content": "..." // full raw .eml content
},
// ... additional proofs
],
"self_reported": {
// free-form key-value pairs relevant to this vendor's ICP
"location": "Paris 75011",
"open_to_additional_services": true,
"target_monthly": 120
}
}JSONThe self_reported object is free-form — its keys are driven by the vendor's ICP dimensions, not a fixed schema. Buyer agents should derive the right fields from the ICP they read in Step 2.
5 Negotiate Response
The vendor agent always responds with structured JSON. The status field determines which additional fields are populated.
{
"status": "offer", // offer | rejected | proof_requested | pending
"sessionId": "sess_...",
"matched_segment": {
"id": "new-consumer", "name": "Residential Customers", "max_margin_percent": 20
},
// Always present
"fit_score": 0.84,
"fit_score_breakdown": {
"retention": 0.90,
"expansion": 0.50,
"cost_efficiency": 0.92,
"network_value": 0.20
},
"message": "Strong retention and cost-efficiency profile. Expansion
potential is low — adding a second service would unlock a better tier.",
// Present when status === "offer"
"offer": {
"plan_name": "Preferred Customer Rate",
"rate": "€120/month",
"duration_months": 12,
"conditions": ["Green electricity included"],
"signup_url": "https://...",
"expires_at": "2026-03-18T00:00:00Z"
},
// Present when status === "proof_requested"
"proof_request": {
"reason": "insufficient_evidence",
"message": "Consumption history is thin. Additional receipts
covering a longer period would improve your retention score."
},
// Present when status === "rejected"
"rejection": {
"reason": "fit_score_too_low",
"message": "Your current fit score (0.38) is below the minimum
threshold. Verified spend history would significantly improve it."
}
}JSONfit_score_breakdown is always returned, including on rejections. Buyer agents use it to understand exactly where they scored low and whether additional evidence could change the outcome.6 Status Codes
offer object contains the plan, rate, and signup URL.proof_request object explains what's missing. Buyer agent should search for additional evidence and resubmit.rejection object explains why and what would change the outcome.sessionId can be used to poll for a decision or resume the session.7 Error Codes
| Code | Meaning | Resolution |
|---|---|---|
| dkim_failed | DKIM signature on a submitted .eml could not be verified | Fetch a fresh copy directly from Gmail — the file may have been modified in transit |
| proof_too_old | A submitted proof is outside the vendor's max_proof_age_days window | Find a more recent document covering the same signal |
| session_expired | The sessionId is no longer valid | Perform a new GET to open a fresh session |
| payload_too_large | The proof bundle exceeds the size limit | Reduce the number of proofs; 3–6 high-quality receipts are sufficient |
| outside_service_area | The buyer's location is not served by this vendor | No resolution — this vendor cannot serve this buyer |
↗ Vendor Setup
To add haggl negotiation to your site, register at haggl.ai, define your ICP and product tiers in the onboarding portal, and embed the snippet on your site. The negotiate endpoint is generated and hosted automatically — no backend changes required.
When a vendor updates their ICP or pricing in the portal, the next buyer agent session reflects the change immediately. No deployment needed.
dkim_verified, its authenticity has already been confirmed cryptographically.↗ Buyer Agents
Any agent that can read a meta tag and make HTTP requests can negotiate on any haggl-enabled site. No prior knowledge of the vendor is needed — the session object is fully self-describing.
The reference buyer skill is available at nexus.moojo.id/skill. It handles vendor discovery, ICP parsing, proof signal inventory across Gmail and local files, fit scoring, package assembly, and result reporting.
The core principle: email inboxes are proof vaults. DKIM signatures on commercial emails are cryptographic bindings to the sending domain. A buyer agent that knows how to find and surface these signals will consistently negotiate better rates than one that relies on self-reported context alone.