# KAIBEAUTY - Agent API Specifications ## Base URL Production: `https://platform.kaibeauty.me` (or `https://kaibeauty.me`) ## Data rules - Product knowledge comes from each product's fact sheet. `ingredients_status`: `known` (recorded source), `unknown`, `conflict` (source contradicts the product; not shown), `not_applicable` (sets). Unknown never means the product is free of an ingredient. - `evidence.review`: `reviewed` (checked by a person), `machine_checked` (verified against the source by code), `source_listed` (as the retailer lists it). `evidence.method` is the source kind. - `ingredients_inci` and `ingredients[].inci` come from the Korean standard ingredient dictionary. `unmatched_count` items are shown as printed (`raw`). - `properties` values are `present`, `absent` or `unknown`; `absent` only for a complete, fully matched list. Essential oils are never `absent`. - `markets`: countries with a finding. `sellable_with_warning` = an ingredient outside that country's list (warning only). Loaded today: US sunscreen active ingredients (FDA, as of 2026-10-16). - Items are sourced in Korea after the order is placed (`availability: "purchase_to_order"`). - Shipping, taxes and duties are calculated at Shopify checkout, not by this API. --- ## 1. Product Search & Discovery `GET /api/agent/products` ### Query Parameters - `q` (string, optional): Keywords in title or brand. Ingredient words (e.g., "niacinamide") match known ingredient lists only. - `concern` (string, optional): One of `hydration`, `barrier`, `soothing`, `tone`, `texture`, `elasticity`. Returns only products whose known list supports it. - `avoid_ingredient` (string, optional): A group (`fragrance`, `fragrance allergens`, `essential oils`, `alcohol`, `retinol`, `aha`, `bha`, `aerosol`) is decided by the matching property, which must be `absent`. Any other word needs a complete, fully matched list without it. - `category` (string, optional): `SKIN`, `CLEANSE`, `SUN` or `MASK` - `country` (string, optional): Two-letter destination country; adds `market` (that country's finding) to each product. It does not filter. - `limit` (integer, default 10, max 30): Max items to return ### Sample Response ```json { "total": 1, "products": [ { "id": 29408, "variant_id": "gid://shopify/ProductVariant/4491823910123", "title": "Example Brand Daily Watery Sun Cream SPF50+ PA++++ 50ml", "brand": "Example Brand", "category": "SUN", "subcategory": "Sunscreen", "price_usd": 15.42, "url": "https://kaibeauty.me/products/example-brand-daily-watery-sun-cream-50ml", "image_url": "https://cdn.shopify.com/...", "availability": "purchase_to_order", "fact_sheet": {"id": "kb-v-1201", "version": 2, "sha256": "..."}, "ingredients_status": "known", "evidence": {"review": "machine_checked", "method": "official_mall_page", "corroborated": false, "sources": ["kb-s-5001"], "checked_at": "2026-10-20T10:00:00+09:00"}, "ingredients_source_url": "https://www.example-brand.co.kr/product/123", "ingredients_label_text": "정제수, 부틸렌글라이콜, 에칠헥실트리아존, 징크옥사이드, 향료", "ingredients_scope": "full", "ingredients_inci": "Water, Butylene Glycol, Ethylhexyl Triazone, Zinc Oxide, Fragrance", "ingredients": [{"position": 1, "inci": "Water", "name_ko": "정제수", "raw": "정제수", "concentration": null}], "unmatched_count": 0, "properties": {"fragrance": "present", "ethanol": "absent", "uv_filters": "present", "essential_oils": "unknown"}, "goals": ["hydration"], "cautions": ["fragrance"], "markets": {"US": {"status": "sellable_with_warning", "reasons": [{"rule_id": "US-uv-allowlist@2026-10-16", "kind": "uv_filter_allowlist", "effect": "warn", "ingredient": "Ethylhexyl Triazone", "source_url": "https://www.fda.gov/..."}]}}, "market": {"status": "sellable_with_warning", "reasons": ["..."]} } ], "notes": ["..."] } ``` A product without a known list has `ingredients_status` other than `known` and null `evidence`, `ingredients_*`, `ingredients`, `unmatched_count`, `properties`, `goals` and `cautions`. --- ## 2. Item Price Quote `POST /api/agent/quote` Item prices in USD for products on sale. Shipping, taxes and duties are not included. ### Request Body ```json { "items": [{"product_id": 29408, "quantity": 1}], "country_code": "US" } ``` ### Response ```json { "currency": "USD", "items": [{"product_id": 29408, "variant_id": "gid://shopify/ProductVariant/4491823910123", "title": "Example Brand Daily Watery Sun Cream SPF50+ PA++++ 50ml", "unit_price_usd": 15.42, "quantity": 1, "line_total_usd": 15.42}], "subtotal_usd": 15.42, "shipping_fee_usd": null, "estimated_tax_duty_usd": null, "total_landed_cost_usd": null, "shipping_and_taxes": "calculated_at_checkout", "destination_country": "US", "origin": "South Korea", "availability": "purchase_to_order", "notes": ["..."] } ``` --- ## 3. Checkout Link `POST /api/agent/checkout` Creates a Shopify cart for products on sale and returns its checkout URL. The customer reviews shipping, taxes and the final total at checkout before paying. ### Request Body ```json { "items": [{"product_id": 29848, "quantity": 1}], "customer_email": "user@example.com" } ``` *(Note: You can provide either `product_id` or `variant_id`)* ### Response ```json { "checkout_url": "https://shop.kaibeauty.me/cart/c/.../checkout", "cart_id": "gid://shopify/Cart/c1-...", "total_amount_usd": 15.42, "currency": "USD", "status": "ready_for_payment", "instructions_for_agent": "Give checkout_url to the user as a link. total_amount_usd covers the items only; ..." } ``` --- ## 4. Product detail `GET /api/agent/products/{id}?country=US` Returns `{"product": {...as in search...}, "fact_sheet_document": {...}, "notes": [...]}`. `fact_sheet_document` is the complete fact sheet (schema 1.0): every ingredient with INCI name and position, every source with kind, URL, fetch date and hash, derived properties with the rule version that decided them, skin goals, and country findings. 404 when the product is not on sale. --- ## 5. MCP server `POST https://platform.kaibeauty.me/mcp` (Streamable HTTP, JSON responses, no authentication, `GET` and `DELETE` return 405). - **Versions:** 2026-07-28 (every request carries `_meta` with `io.modelcontextprotocol/protocolVersion` and `io.modelcontextprotocol/clientCapabilities`, plus the `MCP-Protocol-Version`, `Mcp-Method` and, for `tools/call`, `Mcp-Name` headers, which must match the body; `server/discover` lists the supported versions) and 2025-03-26 to 2025-11-25 (`initialize`, answered without a session). - **Tools:** - `search_products` (read-only): `q`, `concern`, `avoid_ingredient`, `category`, `country`, `limit` as in section 1. - `get_product` (read-only): `product_id`, optional `country`; returns what section 4 returns. - `get_price_quote` (read-only): `items` (1-20 of `product_id`, `quantity`), `country_code`; item prices only. - `create_checkout_link`: `items`, optional `customer_email`; returns a Shopify checkout link, charges nothing. - **Results:** `content` holds the JSON as text and `structuredContent` the same JSON. Invalid arguments, unknown products and rate limits are tool errors (`isError: true`) with a message the model can act on. - **Limits:** 60 read calls and 10 checkout links per minute per client address. Browsers calling from another origin must be on our allow-list.