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.
Machine-readable surfaces
Seller custom domains and self-hosted instances serve the same discovery documents and honor the same content negotiation, so an agent can treat any Milk Market storefront as a first-class endpoint.
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.versionandx-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
Deprecationresponse header and, once a removal date is set, theSunsetheader (RFC 8594), at least 90 days before removal.