{
 "openapi": "3.1.0",
 "info": {
  "title": "Scarves.si shopping API for AI agents",
  "version": "1.0.0",
  "description": "Free, read-only shopping helper for AI assistants. Built for AI shopping assistants like Grok Bot. Not affiliated with or endorsed by xAI. Safe for AI shoppers: We never take payment or card data. Checkout happens on the seller's site (Etsy) with the owner approving. Photo try-on requires consent; photos are processed by our image partner and we don't store them. Every response carries a transparent affiliate disclosure. Prices, shipping, returns and stock are confirmed on the seller's page. Rate limit: about 60 calls per IP per day (shop+bundle); try-on shares the site's daily image caps."
 },
 "servers": [
  {
   "url": "https://scarves.si"
  },
  {
   "url": "https://scarves-si.pages.dev"
  }
 ],
 "paths": {
  "/api/shop": {
   "post": {
    "operationId": "shop",
    "summary": "Get gift/product picks with reasons and seller links",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ShopRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ShopResponse"
        }
       }
      }
     },
     "400": {
      "description": "bad_input",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "get": {
    "operationId": "shopGet",
    "summary": "Same as POST with query-string parameters (avoid comma-separated)",
    "parameters": [
     {
      "name": "query",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "recipient",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "occasion",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "size",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "budget",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "avoid",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "count",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ShopResponse"
        }
       }
      }
     },
     "400": {
      "description": "bad_input",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/bundle": {
   "post": {
    "operationId": "proposeBundle",
    "summary": "Propose a 3-6 item gift bundle (approve-to-build). Nothing is purchased.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ShopRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Bundle"
        }
       }
      }
     },
     "400": {
      "description": "bad_input",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "rate_limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/bundle/refine": {
   "post": {
    "operationId": "refineBundle",
    "summary": "Approve or reject items; rejected items are swapped for alternates within budget",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "bundle_id"
        ],
        "properties": {
         "bundle_id": {
          "type": "string",
          "description": "Opaque stateless token from /api/bundle or a previous refine"
         },
         "approve": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "reject": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Bundle"
        }
       }
      }
     },
     "400": {
      "description": "bad_input",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/agent-tryon": {
   "post": {
    "operationId": "agentTryOn",
    "summary": "AI try-on preview of a described style on a consenting person's photo; returns up to N images with shop links",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "image_base64",
         "style",
         "consent"
        ],
        "properties": {
         "image_base64": {
          "type": "string",
          "description": "JPEG or PNG, \u22641.5MB (\u22641024px long side recommended); data: URL prefix allowed"
         },
         "style": {
          "type": "string",
          "maxLength": 80,
          "description": "Clothing/accessory description, e.g. 'black and white striped sweater'"
         },
         "who": {
          "type": "string",
          "enum": [
           "one",
           "left",
           "middle",
           "right",
           "all"
          ],
          "default": "one"
         },
         "variations": {
          "type": "integer",
          "minimum": 1,
          "maximum": 5,
          "default": 1
         },
         "consent": {
          "type": "boolean",
          "const": true,
          "description": "Asserts the photo owner/person consented"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Images",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "images": {
           "type": "array",
           "items": {
            "type": "object",
            "properties": {
             "index": {
              "type": "integer"
             },
             "style": {
              "type": "string"
             },
             "variation": {
              "type": [
               "string",
               "null"
              ]
             },
             "mime": {
              "type": "string"
             },
             "image_base64": {
              "type": "string"
             },
             "shop_url": {
              "type": "string"
             }
            }
           }
          },
          "stopped_early": {
           "type": [
            "object",
            "null"
           ]
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "bad_input / consent_required / bad_style",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "422": {
      "description": "flagged: the image model's safety filter refused this photo",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "daily_cap",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "502": {
      "description": "transient",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "ShopRequest": {
    "type": "object",
    "properties": {
     "query": {
      "type": "string",
      "maxLength": 300,
      "description": "Free-text request, e.g. 'red silk scarf for mom'"
     },
     "recipient": {
      "type": "string"
     },
     "occasion": {
      "type": "string"
     },
     "size": {
      "type": "string",
      "description": "Clothing size, e.g. M"
     },
     "budget": {
      "type": "number",
      "description": "USD, total"
     },
     "avoid": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "maxItems": 10
     },
     "count": {
      "type": "integer",
      "minimum": 1,
      "maximum": 6,
      "default": 3
     }
    },
    "anyOf": [
     {
      "required": [
       "query"
      ]
     },
     {
      "required": [
       "recipient"
      ]
     },
     {
      "required": [
       "occasion"
      ]
     }
    ]
   },
   "Item": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "category": {
      "type": "string"
     },
     "why": {
      "type": "string"
     },
     "est_price": {
      "type": "number"
     },
     "est_price_range": {
      "type": "string"
     },
     "shop_url": {
      "type": "string"
     },
     "image_hint": {
      "type": "string"
     }
    }
   },
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "enum": [
       "bad_input",
       "rate_limited",
       "consent_required",
       "bad_style",
       "daily_cap",
       "flagged",
       "transient",
       "method_not_allowed"
      ]
     },
     "message": {
      "type": "string"
     }
    }
   },
   "ShopResponse": {
    "type": "object",
    "properties": {
     "site": {
      "type": "string"
     },
     "query_echo": {
      "type": "object"
     },
     "picks": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Item"
      }
     },
     "outfit": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Item"
      }
     },
     "disclosure": {
      "type": "string"
     },
     "safety": {
      "type": "string"
     }
    }
   },
   "Bundle": {
    "type": "object",
    "properties": {
     "bundle_id": {
      "type": "string"
     },
     "query_echo": {
      "type": "object"
     },
     "items": {
      "type": "array",
      "items": {
       "allOf": [
        {
         "$ref": "#/components/schemas/Item"
        },
        {
         "type": "object",
         "properties": {
          "slot": {
           "type": "string"
          },
          "status": {
           "type": "string",
           "enum": [
            "proposed",
            "approved"
           ]
          },
          "alternates": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Item"
           }
          }
         }
        }
       ]
      }
     },
     "running_total": {
      "type": "number"
     },
     "budget": {
      "type": [
       "number",
       "null"
      ]
     },
     "within_budget": {
      "type": [
       "boolean",
       "null"
      ]
     },
     "shop_the_whole_gift": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "title": {
         "type": "string"
        },
        "shop_url": {
         "type": "string"
        }
       }
      }
     },
     "swaps": {
      "type": "array",
      "items": {
       "type": "object"
      }
     },
     "disclosure": {
      "type": "string"
     }
    }
   }
  }
 }
}