Developers & AI Agents

Milk Market is built to be operated by machines: search the catalog, place orders, and run a stall through documented, machine-readable interfaces.

Quickstart

The fastest way in is the Model Context Protocol server at /api/mcp. The initialize handshake, tool listing, and the public read tools (product search and details) work without an API key:

curl -X POST https://milk.market/api/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": { "name": "my-agent", "version": "0.1.0" }
    }
  }'

The response carries an mcp-session-id header. Send it back on every follow-up request:

curl -X POST https://milk.market/api/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: <session id from the initialize response>" \
  -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'

To buy, manage orders, or administer a stall, create an API key under Settings → API keys and send it as Authorization: Bearer sk_…. Keys come in three scopes: read, read_write (adds purchasing), and full_access (adds stall/account management).

REST alternative: UCP

Prefer plain REST? The Universal Commerce Protocol endpoints expose the same catalog and order pipeline: GET /api/ucp/catalog/search and GET /api/ucp/catalog/lookup read products, and POST /api/ucp/checkout/sessions places an order (requires a read_write key). Response shapes are published as JSON Schema at /api/ucp/schemas/product.json and /api/ucp/schemas/checkout-session.json, and referenced from the OpenAPI document.

Error model

Every error response carries a human-readable error string. Agent-facing endpoints add a stable machine-readable code plus discovery links — branch on code, never on prose. Rate limiting returns 429 with retryAfterSeconds in the body and a Retry-After header. The MCP endpoint speaks JSON-RPC 2.0, so its errors arrive in the JSON-RPC error envelope (error.code / error.message) instead of this REST shape.

{
  "error": "Not found",
  "code": "not_found",
  "status": 404,
  "documentation": {
    "openapi": "https://milk.market/openapi.json",
    "mcp": "https://milk.market/.well-known/mcp.json",
    "agents": "https://milk.market/agents.txt"
  }
}

Unknown routes are content-negotiated: send Accept: text/markdown and a 404 comes back as markdown with links to the documents above; otherwise it comes back as the JSON shape shown here.

Versioning policy

  • The OpenAPI document is semantically versioned (current: 2.x, see info.version and x-versioning-policy).
  • Additive changes — new endpoints, new optional fields, new enum values — can ship at any time. Clients must ignore unknown fields.
  • Breaking changes — removed or renamed fields or endpoints, newly required parameters — ship only in a new major version.
  • Deprecated operations carry the Deprecation response header and, once a removal date is set, the Sunset header (RFC 8594), at least 90 days before removal.