OpenAjanMerchants

For agents & developers

OpenAjan is an open gateway to small local shops — restaurants, cafés, barbers, florists, repair shops, clinics — launching in Denmark, Germany and Türkiye; any country can be enabled. Agents can discover a shop, read its live catalog and opening hours, and place an order or booking on the user's behalf. Payment happens at the shop; OpenAjan never touches money.

1. MCP server (recommended)

Endpoint: https://openajan.com/mcp — Streamable HTTP, JSON-RPC 2.0, protocol 2025-06-18. Authentication: OAuth 2.1 with PKCE (dynamic client registration, no client secret). Discovery: /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server. Unauthenticated requests get 401 with a WWW-Authenticate header. Works out of the box as a custom connector in Claude, ChatGPT and any MCP client.

ToolTypePurpose
find_shopsreadSearch by name, city, zip, type. Forgiving matching ("examplepizzeria" finds "Example Pizzeria").
get_shopreadFull card: address, phone, hours, catalog with item ids and prices incl. VAT.
place_orderwriteOrder or booking. Requires confirmed=true after the user explicitly said yes; supports idempotency_key.
order_statusreadnew / confirmed / done / cancelled for the user's orders.
search, fetchreadChatGPT-style search/fetch aliases.

Rules every agent must follow

2. Shop cards (no auth)

Every shop has a human page and a machine card: https://openajan.com/@slug and https://openajan.com/@slug.json. The HTML page carries schema.org LocalBusiness (subtype by trade), openingHoursSpecification, Menu/OfferCatalog and an OrderAction pointing at the REST endpoint.

{
  "openajan_version": "1.0",
  "merchant": { "id": "oa_example-pizzeria", "name": "Example Pizzeria", "type": "restaurant", "address": {…}, "phone": "…", "currency": "DKK", "url": "…" },
  "hours":   [ { "day": "mon", "closed": false, "opens": "11:00", "closes": "22:00" }, … ],
  "catalog": [ { "id": 812, "name": "1. Margherita (Alm.)", "price": 75.0, "currency": "DKK", "category": "Pizza" }, … ],
  "ordering": { "modes": ["order"], "payment": "at_merchant", "endpoint": "https://openajan.com/api/order.php?merchant=example-pizzeria" }
}

3. REST order endpoint

GET https://openajan.com/api/order.php?merchant=slug describes the schema; POST JSON places an order. Rate-limited per IP and per customer phone. OpenAPI: /openapi.json.

POST /api/order.php
{ "merchant": "example-pizzeria", "kind": "order", "agent": "MyAgent",
  "items": [ { "id": 812, "qty": 2 } ],
  "customer": { "name": "Anna", "phone": "+45 …", "email": "anna@…", "lang": "da" },
  "wanted_at": "2026-09-17T18:00:00+02:00", "note": "no onions", "idempotency_key": "b1f…" }

→ { "ok": true, "order_id": "oa_ord_15", "status": "new", "total": 150.0, "currency": "DKK", "payment": "at_merchant" }

4. Webhooks to merchant systems

Merchants with their own POS receive every order and status change as JSON, signed with X-OpenAjan-Signature (HMAC-SHA256 of the raw body), plus X-OpenAjan-Timestamp and X-OpenAjan-Delivery. Reject signatures that don't match and timestamps older than 5 minutes. Merchant systems report status back to /api/status_hook.php with the same secret. Reference implementation: the Febego POS bridge.

5. Standards & roadmap

Contact

Integration questions, partnerships, security reports: hej@openajan.com · security.txt · llms.txt