Developer Documentation

Agent Protocol API Reference

A REST API for AI agents to discover restaurants, browse menus, and place orders. ACP-compliant checkout with Stripe Shared Payment Tokens.

Overview

The Menami Agent Protocol is a REST API that enables AI agents — personal assistants, custom GPTs, autonomous ordering bots — to discover restaurants, browse menus with full modifier details, and complete orders programmatically.

The checkout flow is ACP-compliant (Agentic Commerce Protocol by Stripe and OpenAI), meaning any ACP-compatible agent can complete purchases using Stripe Shared Payment Tokens without additional integration work.

Base URL: https://api.menami.mx/api/v1/agent

Format: All requests and responses use JSON. Set Content-Type: application/json on request bodies.

Pagination: List endpoints support page and limit query params (default: page 1, limit 20, max 100).

Authentication

Discovery endpoints (listing restaurants, viewing menus) require no authentication. Checkout, delivery, and order status endpoints require an API key.

API Key

Pass your API key via the X-Agent-Key header. For ACP compatibility, Authorization: Bearer <key> is also accepted.

Example request
curl -X POST https://api.menami.mx/api/v1/agent/checkout_sessions \
  -H "Content-Type: application/json" \
  -H "X-Agent-Key: ak_live_7f3a9b2c..." \
  -d '{ ... }'

Rate Limits

Default rate limit is 60 requests per minute per API key. Rate-limited responses return HTTP 429 with a Retry-After header (seconds).

Idempotency

All POST endpoints require an Idempotency-Key header (UUID v4). Same key + identical body returns the cached response. Same key + different body returns 422 idempotency_conflict. Keys are retained for 24 hours.

Discovery Endpoints

Browse and search the restaurant catalog. No authentication required.

GET/api/v1/agent/restaurantsNo auth

Search and filter restaurants.

ParamTypeDescription
qstringFree-text search (name, cuisine, description)
cuisinestringFilter by cuisine type
citystringFilter by city (case-insensitive, partial match)
latnumberLatitude for radius search
lngnumberLongitude for radius search
radius_kmnumberSearch radius in km (default: 8)
open_nowbooleanOnly currently open restaurants
dietarystringFilter by dietary tag
pagenumberPage number (default: 1)
limitnumberResults per page (default: 20, max: 100)
Response
{
  "total": 47,
  "page": 1,
  "limit": 20,
  "restaurants": [
    {
      "name": "Tacos El Padrino",
      "slug": "tacos-el-padrino",
      "cuisine": ["mexican", "tacos"],
      "city": "Mexico City",
      "country": "MX",
      "price_range": "$$",
      "currency": "MXN",
      "delivery": true,
      "pickup": true,
      "ordering_enabled": true,
      "min_order_amount": 150,
      "estimated_prep_minutes": 25,
      "open_now": true,
      "item_count": 34
    }
  ]
}
GET/api/v1/agent/restaurants/:slugNo auth

Full restaurant details including address, operating hours, and delivery zone.

Response
{
  "name": "Tacos El Padrino",
  "slug": "tacos-el-padrino",
  "cuisine": ["mexican", "tacos"],
  "address": {
    "street": "Av. Insurgentes Sur 1234",
    "city": "Mexico City",
    "state": "CDMX",
    "zip": "03100",
    "country": "MX"
  },
  "phone": "+525512345678",
  "currency": "MXN",
  "timezone": "America/Mexico_City",
  "operating_hours": {
    "monday": [{ "open": "11:00", "close": "22:00" }],
    "friday": [{ "open": "11:00", "close": "23:00" }],
    "sunday": [{ "open": "10:00", "close": "21:00" }]
  },
  "price_range": "$$",
  "delivery": true,
  "pickup": true,
  "ordering_enabled": true,
  "min_order_amount": 150,
  "estimated_prep_minutes": 25,
  "delivery_zone": {
    "type": "radius",
    "center": { "lat": 19.4126, "lng": -99.1703 },
    "radius_km": 8
  },
  "open_now": true,
  "website_url": "https://tacoselpadrino.menami.mx"
}
GET/api/v1/agent/restaurants/:slug/menuNo auth

Full menu with categories, items, dietary tags, and modifier groups (customization options).

Response
{
  "restaurant_slug": "tacos-el-padrino",
  "currency": "MXN",
  "last_updated": "2026-02-24T10:00:00Z",
  "categories": [
    {
      "name": "Tacos",
      "slug": "tacos",
      "description": "Handmade corn tortillas",
      "items": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440001",
          "name": "Taco al Pastor",
          "description": "Marinated pork with pineapple, cilantro, onion",
          "price": 45.00,
          "currency": "MXN",
          "dietary_tags": ["gluten_free"],
          "allergens": [],
          "available": true,
          "image_url": "https://cdn.example.com/taco-pastor.jpg",
          "modifier_groups": [
            {
              "id": "group-uuid-1",
              "name": "Spice Level",
              "selection_type": "single_select",
              "required": true,
              "min_selections": 1,
              "max_selections": 1,
              "options": [
                { "id": "mod-1", "name": "Mild", "price_adjustment": 0 },
                { "id": "mod-2", "name": "Medium", "price_adjustment": 0 },
                { "id": "mod-3", "name": "Hot", "price_adjustment": 0 },
                { "id": "mod-4", "name": "Extra Hot", "price_adjustment": 5.00 }
              ]
            },
            {
              "id": "group-uuid-2",
              "name": "Extra Toppings",
              "selection_type": "multi_select",
              "required": false,
              "min_selections": 0,
              "max_selections": 3,
              "options": [
                { "id": "mod-5", "name": "Extra Cheese", "price_adjustment": 15.00 },
                { "id": "mod-6", "name": "Guacamole", "price_adjustment": 20.00 },
                { "id": "mod-7", "name": "Sour Cream", "price_adjustment": 10.00 }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Checkout Endpoints

ACP-compliant checkout flow. All endpoints require an API key via X-Agent-Key header and an Idempotency-Key header on POST requests.

POST/api/v1/agent/checkout_sessionsAPI key required

Create a checkout session with items, customer info, and optional delivery address. The server validates items, resolves modifiers, calculates totals (including tax and delivery), and returns an ACP-shaped session.

Request body
{
  "restaurant_slug": "tacos-el-padrino",
  "currency": "mxn",
  "line_items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "quantity": 3,
      "modifiers": [
        { "group_id": "group-uuid-1", "option_ids": ["mod-3"] },
        { "group_id": "group-uuid-2", "option_ids": ["mod-6"] }
      ]
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440010",
      "quantity": 1
    }
  ],
  "customer": {
    "name": "Carlos Martinez",
    "phone": "+525598765432",
    "email": "carlos@example.com"
  },
  "fulfillment_details": {
    "address": {
      "street": "Calle Amsterdam 45, Apt 3B",
      "city": "Mexico City",
      "state": "CDMX",
      "country": "MX",
      "zip": "06100",
      "lat": 19.4126,
      "lng": -99.1703
    }
  },
  "special_instructions": "Ring doorbell twice, second floor"
}

The response follows the ACP CheckoutSession schema with enriched line items, fulfillment options, totals breakdown (subtotal, tax, delivery, total), and payment capabilities.

Response (simplified)
{
  "id": "cs_abc123",
  "status": "ready_for_payment",
  "line_items": [ ... ],
  "fulfillment_options": [
    { "type": "pickup", "label": "Pickup" },
    { "type": "local_delivery", "label": "Delivery", "fee": 59.99, "eta_minutes": 35 }
  ],
  "totals": {
    "subtotal": 175.00,
    "tax": 28.00,
    "fulfillment": 59.99,
    "total": 262.99
  },
  "capabilities": {
    "payment": {
      "handlers": [
        { "id": "card_tokenized", "merchant_id": "acct_..." }
      ]
    }
  }
}
GET/api/v1/agent/checkout_sessions/:idAPI key required

Retrieve the current state of a checkout session, including status, line items, and totals.

POST/api/v1/agent/checkout_sessions/:id/completeAPI key required

Finalize the order with a Stripe Shared Payment Token (SPT). The server creates a PaymentIntent, processes payment, creates the order, and triggers the restaurant notification flow.

Request body
{
  "payment_data": {
    "handler_id": "card_tokenized",
    "instrument": {
      "type": "card",
      "credential": {
        "type": "spt",
        "token": "spt_abc123..."
      }
    }
  }
}
Response
{
  "status": "completed",
  "order": {
    "id": "order-uuid",
    "order_number": "ORD-20260224-XK9F2",
    "permalink_url": "https://tacoselpadrino.menami.mx/order/order-uuid",
    "status": "confirmed"
  }
}
POST/api/v1/agent/checkout_sessions/:id/cancelAPI key required

Cancel a checkout session. Optionally include an intent_trace string for analytics on why the agent abandoned the order.

Request body
{
  "intent_trace": "user_changed_mind"
}

Utility Endpoints

POST/api/v1/agent/delivery-quoteAPI key required

Get a delivery cost estimate and ETA before creating a checkout session.

Request body
{
  "restaurant_slug": "tacos-el-padrino",
  "delivery_address": {
    "street": "Calle Amsterdam 45",
    "city": "Mexico City",
    "state": "CDMX",
    "country": "MX",
    "zip": "06100",
    "lat": 19.4126,
    "lng": -99.1703
  }
}
Response
{
  "fee": 59.99,
  "currency": "MXN",
  "eta_minutes": 35,
  "available": true
}
GET/api/v1/agent/orders/:idAPI key required

Check order status and delivery tracking information.

Response
{
  "order_id": "order-uuid",
  "order_number": "ORD-20260224-XK9F2",
  "status": "preparing",
  "status_history": [
    { "status": "confirmed", "at": "2026-02-24T14:30:00Z" },
    { "status": "preparing", "at": "2026-02-24T14:32:00Z" }
  ],
  "delivery": {
    "status": "driver_assigned",
    "tracking_url": "https://uber.com/track/..."
  }
}

Error Handling

All errors return a consistent JSON structure:

Error response format
{
  "error": "Human-readable error message",
  "code": "error_code",
  "details": { ... }  // optional, endpoint-specific
}

Common Error Codes

HTTPCodeDescription
400invalid_requestMissing or invalid request parameters
400idempotency_key_requiredPOST request missing Idempotency-Key header
401unauthorizedMissing or invalid API key
404not_foundRestaurant, item, session, or order not found
409conflictIdempotent request already in flight (check Retry-After header)
422idempotency_conflictSame Idempotency-Key used with different body
422out_of_stockOne or more items are unavailable
422missing_modifierRequired modifier group has no selection
422below_minimumOrder total below restaurant minimum
422restaurant_closedRestaurant is currently closed
422outside_delivery_zoneDelivery address outside restaurant delivery range
422payment_declinedPayment could not be processed
429rate_limitedToo many requests (check Retry-After header)

Ready to integrate?

Get your API key and start building agent-powered ordering for your platform.

Get your API key