{
  "openapi": "3.1.0",
  "info": {
    "title": "Santa Wish – kids' Christmas gift wishlist API (amazon.com + amazon.se)",
    "version": "1.4.0",
    "description": "Create a kids' Christmas gift wishlist in seconds from hand-picked products with shareable owner + shopper links. Curated by us (no customer reviews or ratings). Keywords: gift ideas, wishlist, gift list, shopping list, christmas gifts for kids, presenttips, önskelista, jul (barn), amazon.com, amazon.se. Quickstart: POST /api/v1/agent/create-and-fill → shopUrl.\n\nStores: amazon.com (US) — marketplace=amazon.com, or country=US, or Accept-Language en-US (automatic). English product names, no SEK prices, amazon.com search links tagged sw-santawish-20 (linkType search). amazon.se (Sweden, default) — /dp/{ASIN}?tag=santawishli03-21 product links with approx. SEK prices. Precedence: marketplace|domain|store (or X-Amazon-Marketplace header) → country → locale/Accept-Language → amazon.se. Missing store or query never returns 400; defaults are used. Catalog: ~600 items on amazon.se, ~560 English items on amazon.com. Age bands 0-2/3-5/6-8/9-12. CORS * on /api/v1/*. Token-based wishlist ids (mutations may return a new id). MCP: /api/mcp.",
    "contact": {
      "name": "maggat",
      "url": "https://santa-wish.vercel.app"
    }
  },
  "servers": [
    {
      "url": "https://santa-wish.vercel.app"
    }
  ],
  "tags": [
    {
      "name": "search"
    },
    {
      "name": "wishlists"
    },
    {
      "name": "catalog"
    },
    {
      "name": "agent"
    },
    {
      "name": "meta"
    }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "Health check",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog": {
      "get": {
        "tags": [
          "catalog"
        ],
        "summary": "Paginated gift catalog; /dp on amazon.se, search-ideas elsewhere",
        "operationId": "getCatalog",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ageBand",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/AgeBand"
            }
          },
          {
            "name": "interest",
            "in": "query",
            "description": "Single interest filter",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "interests",
            "in": "query",
            "description": "Comma-separated interests",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "marketplace",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "amazon.com"
            },
            "description": "Store: amazon.com (US) or amazon.se (Sweden, default); also ids us/se/uk/de… Omit to auto-detect (country, then en-US ⇒ amazon.com)."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alias for marketplace"
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "sv",
                "de",
                "fr",
                "es"
              ]
            },
            "description": "UI/search cue locale. Agents MUST pass the user's locale."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 48,
              "maximum": 100
            },
            "description": "Page size (default 48, max 100)"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Pagination offset"
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Shopper country (US ⇒ amazon.com, SE ⇒ amazon.se). Used when marketplace is omitted.",
            "schema": {
              "type": "string",
              "example": "US"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "en-US selects amazon.com when no marketplace/country is given.",
            "schema": {
              "type": "string",
              "example": "en-US"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogResponse"
                }
              }
            }
          }
        },
        "description": "Returns curated gift ideas for the store. amazon.se: catalogMode asin, Swedish names, /dp links, priceSek. amazon.com: catalogMode search-ideas, English names, amazon.com search links tagged sw-santawish-20, no SEK prices. Response includes total, offset, limit, marketplace, marketplaceSource, currency."
      }
    },
    "/api/v1/products/resolve": {
      "post": {
        "tags": [
          "catalog"
        ],
        "summary": "Resolve ASIN, pasted amazon.se URL, or keywords to buy / inspiration link",
        "operationId": "resolveProduct",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "asin": {
                    "type": "string",
                    "description": "10-char Amazon ASIN"
                  },
                  "keywords": {
                    "type": "string"
                  },
                  "marketplace": {
                    "type": "string",
                    "description": "Amazon storefront for the user"
                  },
                  "domain": {
                    "type": "string"
                  },
                  "locale": {
                    "type": "string"
                  },
                  "preferSearch": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resolved link",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "buyUrl": {
                      "type": "string",
                      "format": "uri"
                    },
                    "asin": {
                      "type": "string"
                    },
                    "linkType": {
                      "$ref": "#/components/schemas/LinkType"
                    },
                    "trackingTag": {
                      "type": "string"
                    },
                    "domain": {
                      "type": "string"
                    },
                    "catalogCount": {
                      "type": "integer",
                      "description": "Curated catalog size (~600 on amazon.se)"
                    },
                    "paapi": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "buyUrl",
                    "linkType"
                  ]
                }
              }
            }
          }
        },
        "description": "Accepts asin, url (amazon /dp link), and/or keywords plus optional marketplace/country/locale. Curated ASINs on amazon.com become English amazon.com search links. Empty or invalid body returns a default kids gift search link (no 400)."
      }
    },
    "/api/v1/agent/create-and-fill": {
      "post": {
        "tags": [
          "agent"
        ],
        "summary": "One-shot create wishlist and add ASINs/keywords",
        "operationId": "agentCreateAndFill",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentCreateAndFillBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WishlistCreateResponse"
                }
              }
            }
          }
        },
        "description": "Pass marketplace (amazon.com for US, amazon.se default) so buy links match the shopper's store; country / Accept-Language en-US also work. Response includes shopUrl, ownerUrl, marketplace."
      }
    },
    "/api/v1/wishlists": {
      "post": {
        "tags": [
          "wishlists"
        ],
        "summary": "Create wishlist",
        "operationId": "createWishlist",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWishlistBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WishlistCreateResponse"
                }
              }
            }
          }
        },
        "description": "Pass marketplace (amazon.com for US, amazon.se default) so buy links match the shopper's store; country / Accept-Language en-US also work. Response includes shopUrl, ownerUrl, marketplace."
      }
    },
    "/api/v1/wishlists/{id}": {
      "get": {
        "tags": [
          "wishlists"
        ],
        "summary": "Get wishlist",
        "operationId": "getWishlist",
        "parameters": [
          {
            "$ref": "#/components/parameters/WishlistId"
          }
        ],
        "responses": {
          "200": {
            "description": "Wishlist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WishlistGetResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          }
        }
      },
      "patch": {
        "tags": [
          "wishlists"
        ],
        "summary": "Update wishlist metadata or replace items",
        "operationId": "patchWishlist",
        "parameters": [
          {
            "$ref": "#/components/parameters/WishlistId"
          },
          {
            "$ref": "#/components/parameters/EditToken"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchWishlistBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated (token mode may return new id)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WishlistMutateResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing edit token"
          },
          "404": {
            "description": "Not found or bad token"
          }
        }
      }
    },
    "/api/v1/wishlists/{id}/items": {
      "post": {
        "tags": [
          "wishlists"
        ],
        "summary": "Add wish item (asin → /dp/ product link)",
        "operationId": "addWishlistItem",
        "parameters": [
          {
            "$ref": "#/components/parameters/WishlistId"
          },
          {
            "$ref": "#/components/parameters/EditToken"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddItemBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Item added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WishlistMutateResponse"
                }
              }
            }
          }
        },
        "description": "Accept name/title, asin, url (pasted /dp link), searchKeywords, or catalogId."
      }
    },
    "/api/v1/wishlists/{id}/items/{itemId}": {
      "delete": {
        "tags": [
          "wishlists"
        ],
        "summary": "Delete wish item",
        "operationId": "deleteWishlistItem",
        "parameters": [
          {
            "$ref": "#/components/parameters/WishlistId"
          },
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/EditToken"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WishlistMutateResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/search": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Open Amazon.se kids gift search",
        "description": "Kids-filtered store search link cards plus matching curated catalog items for the store (amazon.com English or amazon.se). q is optional; never returns 400.",
        "operationId": "searchAmazon",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search query (optional; defaults to a kids Christmas gifts query)"
          },
          {
            "name": "ageBand",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/AgeBand"
            }
          },
          {
            "name": "interest",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category/interest filter"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 10
            }
          },
          {
            "name": "marketplace",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "amazon.com"
            },
            "description": "Store: amazon.com (US) or amazon.se (Sweden, default); also ids us/se/uk/de… Omit to auto-detect (country, then en-US ⇒ amazon.com)."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alias for marketplace"
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "sv",
                "de",
                "fr",
                "es"
              ]
            },
            "description": "UI/search cue locale. Agents MUST pass the user's locale."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Shopper country (US ⇒ amazon.com, SE ⇒ amazon.se). Used when marketplace is omitted.",
            "schema": {
              "type": "string",
              "example": "US"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "en-US selects amazon.com when no marketplace/country is given.",
            "schema": {
              "type": "string",
              "example": "en-US"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing q"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "WishlistId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Short Redis id or t.* token id"
      },
      "EditToken": {
        "name": "X-Edit-Token",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "AgeBand": {
        "type": "string",
        "enum": [
          "0-2",
          "3-5",
          "6-8",
          "9-12"
        ]
      },
      "Interest": {
        "type": "string",
        "enum": [
          "toys",
          "books",
          "sports",
          "craft",
          "tech",
          "outdoor",
          "games"
        ]
      },
      "LinkType": {
        "type": "string",
        "enum": [
          "product",
          "search"
        ]
      },
      "WishlistItem": {
        "type": "object",
        "required": [
          "id",
          "title",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "catalogId": {
            "type": "string"
          },
          "asin": {
            "type": "string",
            "nullable": true
          },
          "searchKeywords": {
            "type": "string"
          },
          "emoji": {
            "type": "string"
          },
          "buyUrl": {
            "type": "string",
            "format": "uri"
          },
          "linkType": {
            "$ref": "#/components/schemas/LinkType"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Wishlist": {
        "type": "object",
        "required": [
          "id",
          "childName",
          "items",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "childName": {
            "type": "string"
          },
          "ageBand": {
            "$ref": "#/components/schemas/AgeBand"
          },
          "interests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Interest"
            }
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WishlistItem"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateWishlistBody": {
        "type": "object",
        "properties": {
          "childName": {
            "type": "string"
          },
          "ageBand": {
            "$ref": "#/components/schemas/AgeBand"
          },
          "interests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Interest"
            }
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "notes": {
                  "type": "string"
                },
                "catalogId": {
                  "type": "string"
                },
                "asin": {
                  "type": "string"
                },
                "searchKeywords": {
                  "type": "string"
                },
                "emoji": {
                  "type": "string"
                }
              }
            }
          },
          "marketplace": {
            "type": "string",
            "example": "amazon.com",
            "description": "amazon.com (US) or amazon.se (Sweden, default)"
          },
          "country": {
            "type": "string",
            "example": "US"
          },
          "locale": {
            "type": "string",
            "example": "en-US"
          }
        }
      },
      "AgentCreateAndFillBody": {
        "type": "object",
        "properties": {
          "childName": {
            "type": "string"
          },
          "ageBand": {
            "$ref": "#/components/schemas/AgeBand"
          },
          "interests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Interest"
            }
          },
          "itemAsins": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Amazon ASINs → /dp/ links"
          },
          "itemKeywords": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Free-text → search links"
          },
          "itemQueries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Free-text queries searched via PA-API or kids search links and added"
          },
          "marketplace": {
            "type": "string",
            "example": "amazon.com",
            "description": "amazon.com (US) or amazon.se (Sweden, default)"
          },
          "country": {
            "type": "string",
            "example": "US"
          },
          "locale": {
            "type": "string",
            "example": "en-US"
          },
          "count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12,
            "description": "When no items are given, auto-fill this many curated picks (default 6)."
          },
          "autoFill": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "PatchWishlistBody": {
        "type": "object",
        "properties": {
          "childName": {
            "type": "string"
          },
          "ageBand": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AgeBand"
              },
              {
                "type": "null"
              }
            ]
          },
          "interests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Interest"
            }
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WishlistItem"
            }
          }
        }
      },
      "AddItemBody": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "Alias for title"
          },
          "notes": {
            "type": "string"
          },
          "catalogId": {
            "type": "string"
          },
          "asin": {
            "type": "string",
            "description": "When set, buyUrl is /dp/ASIN?tag="
          },
          "searchKeywords": {
            "type": "string"
          },
          "emoji": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "description": "Pasted amazon.se/dp URL — ASIN extracted when possible"
          }
        }
      },
      "WishlistCreateResponse": {
        "type": "object",
        "required": [
          "id",
          "editToken",
          "parentUrl",
          "kidUrl",
          "wishlist",
          "storage"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "editToken": {
            "type": "string"
          },
          "parentUrl": {
            "type": "string",
            "format": "uri"
          },
          "kidUrl": {
            "type": "string",
            "format": "uri"
          },
          "wishlist": {
            "$ref": "#/components/schemas/Wishlist"
          },
          "storage": {
            "type": "string",
            "enum": [
              "redis",
              "token"
            ]
          }
        }
      },
      "WishlistGetResponse": {
        "type": "object",
        "required": [
          "id",
          "wishlist",
          "parentUrl",
          "kidUrl",
          "storage"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "wishlist": {
            "$ref": "#/components/schemas/Wishlist"
          },
          "parentUrl": {
            "type": "string",
            "format": "uri"
          },
          "kidUrl": {
            "type": "string",
            "format": "uri"
          },
          "storage": {
            "type": "string",
            "enum": [
              "redis",
              "token"
            ]
          }
        }
      },
      "WishlistMutateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WishlistCreateResponse"
          },
          {
            "type": "object",
            "properties": {
              "previousId": {
                "type": "string"
              },
              "item": {
                "$ref": "#/components/schemas/WishlistItem"
              }
            }
          }
        ]
      },
      "CatalogResponse": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "trackingTag": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "asin": {
                  "type": "string",
                  "nullable": true
                },
                "name": {
                  "type": "string"
                },
                "blurb": {
                  "type": "string"
                },
                "priceSek": {
                  "type": "number"
                },
                "category": {
                  "type": "string"
                },
                "emoji": {
                  "type": "string"
                },
                "ageBands": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "interests": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "searchKeywords": {
                  "type": "string"
                },
                "buyUrl": {
                  "type": "string",
                  "format": "uri"
                },
                "linkType": {
                  "$ref": "#/components/schemas/LinkType"
                }
              }
            }
          },
          "catalogCount": {
            "type": "integer",
            "description": "Curated catalog size (~600 on amazon.se)"
          },
          "paapi": {
            "type": "boolean"
          }
        }
      },
      "Health": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "service": {
            "type": "string"
          },
          "storage": {
            "type": "string"
          },
          "redisConfigured": {
            "type": "boolean"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "paapi": {
            "type": "boolean"
          },
          "trackingTag": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "catalogCount": {
            "type": "integer",
            "description": "Curated catalog size (~600 on amazon.se)"
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "q": {
            "type": "string"
          },
          "query": {
            "type": "string",
            "description": "Kids-rewritten query"
          },
          "paapi": {
            "type": "boolean"
          },
          "hint": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "trackingTag": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchResult"
            }
          },
          "catalogMatches": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "catalogCount": {
            "type": "integer",
            "description": "Curated catalog size (~600 on amazon.se)"
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "asin": {
            "type": "string"
          },
          "imageUrl": {
            "type": "string"
          },
          "price": {
            "type": "string"
          },
          "buyUrl": {
            "type": "string"
          },
          "linkType": {
            "type": "string",
            "enum": [
              "product",
              "search"
            ]
          },
          "query": {
            "type": "string"
          },
          "blurb": {
            "type": "string"
          },
          "emoji": {
            "type": "string"
          }
        }
      },
      "Product": {
        "type": "object",
        "required": [
          "asin",
          "title",
          "buyUrl",
          "linkType"
        ],
        "properties": {
          "asin": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "imageUrl": {
            "type": "string"
          },
          "price": {
            "type": "string"
          },
          "detailPageUrl": {
            "type": "string"
          },
          "buyUrl": {
            "type": "string"
          },
          "linkType": {
            "type": "string",
            "enum": [
              "product"
            ]
          }
        }
      }
    }
  }
}
