v0.2Poppy draft 0.3 conformant · 99/99 official checks

The approval layer for agentic commerce in India.

Haat connects any personal AI agent to sellers on ONDC, understands requests in 11 Indian languages, and never places an order without a human yes.

Built on open standards

PoppyBecknONDCEd25519SQLiteNode.js 22
0/99

Official Poppy validator checks passed, zero warnings

0

Automated tests across signing, sessions and orders

0

Indian languages, native script and Latin spellings

0

Runtime dependencies. A tiny surface to audit

Why Haat

Agents can talk to sellers. They shouldn't spend without you.

Consumer AI agents speak Poppy. India's open commerce network speaks Beckn. Haat sits between them, translates every call, and owns the one decision that must never be automated: the purchase.

Understand how India types

A data-driven lexicon turns everyday requests in native scripts or Latin spellings into structured search terms and quantities.

"do kilo aata" → wheat flour · 2000 g

Bridge Poppy to Beckn

Signed Beckn search fans out to sellers from the ONDC registry, then builds the best single-seller basket with the least wasted pack size.

Poppy 0.3 → Beckn · Ed25519 signed

Stop at the gate

Orders and cancels return 403 approval_required with an exact summary. The person approves one revision. Confirm runs at most once.

403 approval_required → 201 once
Live demo

Type like you talk. Approve like you mean it.

Pick a language and watch the gateway understand the request, build a basket, and wait for your decision. Replayed from real Haat output against the mock ONDC network in this repo.

Language

What the gateway is doing

  1. 1Discover the company (/.well-known/poppy.json)
  2. 2Verify the signed Poppy-Session JWT
  3. 3Lexicon: text → search terms and quantities
  4. 4Beckn search fan-out, best-seller basket
  5. 5Approval gate: 403 approval_required
  6. 6Beckn confirm, at most once
// responses appear here as the demo runs

Sandbox only. No real seller or money is touched.

How it works

Four steps from a sentence to a single, approved order.

01

Understand

"2 kilo aata" or "இரண்டு கிலோ அரிசி" becomes wheat flour · 2000 g.

02

Search

Signed Beckn search to registry sellers. Pick pack sizes that waste least.

03

Ask

Gateway returns an exact summary. The human approves one specific revision.

04

Confirm once

Persisted across restarts. Unknown outcome means 503 Retry-After, never a double order.

Architecture diagram
Platform

Everything the buyer side needs. Nothing it doesn't.

Built so small sellers don't become invisible as consumer agents adopt Poppy, with the same safety guarantees for every agent.

Human approval gate

Operations extension v2. Approval binds to one revision, one session, and expires. Orders and cancels both need a yes.

HTTP/1.1 403 Forbidden
"error": "approval_required",
"summary": "Kashi Kirana · ₹197 · COD"

Exactly-once orders

Idempotency is persisted in SQLite across restarts. Retrying the same approval returns the same order, never a second one.

retry #1 → 201 order KKS-1001
retry #2 → 201 order KKS-1001 (replayed)

Beckn buyer app

Ed25519 + BLAKE2b-512 signing, signed ONDC v2 registry lookups, search through cancel.

Poppy conformant

Official validator over real HTTPS: 99 passed, 0 failed. Direct Sign-In with PKCE.

Conversations and SSE

Cursors, long polling, server-sent events with Last-Event-ID, idempotent message IDs.

Smart baskets

Picks the single seller that covers most of the list and says clearly what is missing.

Zero runtime deps

Node 22.18+ runs TypeScript directly. SQLite via node:sqlite. No build step.

Domain packs

Grocery and food today. Add a vertical with two JSON files, no TypeScript needed.

Security model

The model never holds the keys.

The company-side agent is rule-based on purpose. No language model touches signing keys, session tokens or the approval step.

  • Signed sessions on every requestPoppy-Session JWT bound to aud, htm, htu, ath, replay-protected by jti.
  • SSRF-safe fetchingOutbound URLs are HTTPS-only and private address ranges are refused.
  • Scoped, expiring approvalsOne approval covers one revision in one session, then expires.
  • Bounded storageEvery namespace has a cap. No unbounded growth under load.
approval-gate.svgoperations v2
Approval gate state machine
POST/operations · order from Kashi Kirana
403approval_required · revision r_3f9a
201approved r_3f9a · confirm sent once
Languages

Built for the way Bharat actually types.

Native scripts and Latin spellings in every language. Hindi is hand-written; the rest is machine-drafted and open for native-speaker review.

आटा
Hindireviewed
pyaz
Hinglishreviewed
कोहड़ा
Bhojpuridraft
भोपळा
Marathidraft
চাল
Bengalidraft
அரிசி
Tamildraft
బియ్యం
Telugudraft
લોટ
Gujaratidraft
ಅಕ್ಕಿ
Kannadadraft
അരി
Malayalamdraft
ਆਟਾ
Punjabidraft
ଚାଉଳ
Odiadraft
Developers

One minute to a running network.

Node.js 22.18 or newer. No build step. A local mock ONDC network with three sellers ships in the repo.


    
~/haat-gateway — npm run demo -- --yes

    
Walkthrough

See Haat in one minute.

A Hinglish request is understood, searched across sellers, stopped at the approval gate, and confirmed exactly once.

Project status

Early, and clear about it.

Haat is production-grade in its guarantees and pre-production in its connections. Here is exactly where it stands.

Shipped in v0.2 Available

  • Full order flow on a local mock ONDC network
  • Official Poppy validator: 99 passed, 0 failed
  • 126 tests, lint and typecheck clean
  • ONDC onboarding pieces following official reference code

On the roadmap Next

  • Live ONDC connection (legal entity, whitelisting, approval)
  • Production SMS provider for sign-in codes
  • Staffed human handoff
  • Native-speaker review of non-Hindi lexicons
Read the limitations

Bring every ONDC seller to every personal agent.

Open source and MIT licensed. Most contributions need no TypeScript: lexicon variants, language review, domain packs and docs.