Agent-friendly REST + MCP API for restaurants, menus, and orders across the US. Built for AI agents (Claude, ChatGPT, Operator, Mariner) and partner backends.
All /api/v1/* and /api/mcp calls require an API key:
Authorization: Bearer bmt_live_xxxxxxxxxxxx
Email api@bringmethat.com to request a partner key. Rate limits are per-key (default 60 req/min, 500 orders/day).
| Method | Path | What it does |
|---|---|---|
| GET | /api/v1/restaurants | Search by city/state/cuisine/zip/lat-lng |
| GET | /api/v1/restaurants/{id}/menu | Structured menu w/ item IDs + price_cents |
| POST | /api/v1/orders | Create order (Idempotency-Key required) |
| POST | /api/v1/orders/{id}/pay | Charge via Spreedly / PayPal |
| GET | /api/v1/orders/{id} | Status polling |
| POST | /api/mcp | MCP JSON-RPC 2.0 tools |
Order total = subtotal × 1.10 + $4.99. Premium members pay exactly the restaurant price (no markup, no service fee). Pass contact.emailof a known Premium user and the server waives both automatically.
// agent-order-demo.ts — end-to-end order via BMT v1 API
// Run: API_KEY=bmt_live_xxx npx tsx agent-order-demo.ts
const BASE = "https://bringmethat.com/api/v1";
const KEY = process.env.API_KEY!;
const H = { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" };
async function main() {
// 1. search
const r = await fetch(`${BASE}/restaurants?city=Chicago&state=IL&cuisine=pizza&limit=5`, { headers: H });
const { restaurants } = await r.json();
const pick = restaurants[0];
console.log("picked", pick.name, pick.id);
// 2. menu
const m = await fetch(`${BASE}/restaurants/${pick.id}/menu`, { headers: H });
const menu = await m.json();
const item = menu.sections[0].items[0];
// 3. create order (idempotent)
const idem = crypto.randomUUID();
const o = await fetch(`${BASE}/orders`, {
method: "POST",
headers: { ...H, "Idempotency-Key": idem },
body: JSON.stringify({
restaurant_id: pick.id,
items: [{ variant_id: item.id, quantity: 1 }],
contact: { email: "agent@example.com", phone: "+13125551212" },
address: { line1: "1 N State St", city: "Chicago", state: "IL", zip: "60602" },
fulfillment: "delivery",
}),
});
const order = await o.json();
console.log("order total $", (order.total_cents / 100).toFixed(2));
// 4. pay
const p = await fetch(`${BASE}/orders/${order.order_id}/pay`, {
method: "POST", headers: H,
body: JSON.stringify({ payment_method: "spreedly_token", token: "test_token" }),
});
console.log(await p.json());
}
main();# agent_order_demo.py — end-to-end order via BMT v1 API
# Run: API_KEY=bmt_live_xxx python agent_order_demo.py
import os, uuid, requests
BASE = "https://bringmethat.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['API_KEY']}", "Content-Type": "application/json"}
# 1. search
r = requests.get(f"{BASE}/restaurants",
params={"city": "Chicago", "state": "IL", "cuisine": "pizza", "limit": 5},
headers=H).json()
pick = r["restaurants"][0]
print("picked", pick["name"], pick["id"])
# 2. menu
menu = requests.get(f"{BASE}/restaurants/{pick['id']}/menu", headers=H).json()
item = menu["sections"][0]["items"][0]
# 3. create order (idempotent)
order = requests.post(f"{BASE}/orders",
headers={**H, "Idempotency-Key": str(uuid.uuid4())},
json={
"restaurant_id": pick["id"],
"items": [{"variant_id": item["id"], "quantity": 1}],
"contact": {"email": "agent@example.com", "phone": "+13125551212"},
"address": {"line1": "1 N State St", "city": "Chicago", "state": "IL", "zip": "60602"},
"fulfillment": "delivery",
}).json()
print("order total $", order["total_cents"] / 100)
# 4. pay
paid = requests.post(f"{BASE}/orders/{order['order_id']}/pay",
headers=H,
json={"payment_method": "spreedly_token", "token": "test_token"}).json()
print(paid)POST to /api/mcp with a JSON-RPC 2.0 envelope:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_restaurants",
"arguments": { "city": "Chicago", "state": "IL", "cuisine": "pizza" }
}
}Tools: search_restaurants, get_menu, create_order, pay_order, check_order_status.
/api/v1/…) — never a breaking change without a new version.{error: {code, message, retriable}}.