Overview
Peristyle turns a recipe into a ready-to-checkout grocery cart. Search a recipe, and it pulls the ingredient list, matches each item to real products at Kroger or Walmart, and shows you the options — with size, price, and brand — before anything is added to a cart. Connect your Kroger account once to shop directly through the assistant, or use Walmart's catalog with no sign-in at all. Peristyle remembers your default store, pickup or delivery preference, dietary needs, and preferred brands, so repeat shopping gets faster over time. You always see and approve product matches before they're added — Peristyle fills the cart but never places the order or handles payment. Checkout happens on Kroger's or Walmart's own site.
Tools
amazon_household_options
ChatGPTitems is what the shopper asked for, e.g. ["paper towels", "dish soap"]. Returns the matching product for each from Peristyle's short household list (paper towels, toilet paper, paper napkins, trash bags, dish soap, dishwasher detergent, laundry detergent, aluminum foil, plastic wrap, gallon storage bags) and lists anything not available. No prices: Amazon shows them on its own confirm page. Tell the shopper which product each item maps to (label and size) in plain terms — don't call any product "best" or "recommended" — then call amazon_build_household_cart_link with the product_ids they want.confirm_purchase
ChatGPTpurchased=False. The cart was never bought. modified* — purchased=True, modified=True. It went through but was changed outside the chat: swaps, drops, store substitutions. Use this the moment they say something changed, without interrogating them for the list; nothing is stocked from the cart, because a cart known not to match the order is a set of guesses. When they do name the lines that didn't make it, pass those in removed_refs and the rest stocks as usual. A receipt settles everything at once: read the one they paste in chat (nothing is uploaded), pass removed_refs for carted lines it doesn't show, and put substitutions or extras it does show into update_pantry as "have". Pass its printed basket total as receipt_total — the only money figure in the system that isn't an estimate of a cart that may never have been bought. Only ever a number printed on a receipt: not a sum you compute, not the cart's own prices, and never a guess. Omit it if the total isn't legible. For a pantry user the purchased items land as fresh "have" (the response's stocked says which); without a pantry the answer is simply recorded — stocked comes back empty and nothing about their kitchen is stored. Confirmations are housekeeping: building or adding a new cart works the same whether or not any are pending, so this call can come after the cart task.connect_kroger
ChatGPTdelete_account
ChatGPTdisable_pantry
ChatGPTdisconnect_kroger
ChatGPTenable_pantry
ChatGPTfind_kroger_stores
ChatGPTfinish_kroger_connection
ChatGPTget_pantry
ChatGPTenabled: false and still carries that confirmation — the question reaches every signed-in shopper. Do not call this before matching: every match result (shop_recipe, match_*) already folds in the pantry snapshot as pantry. Use it only when the user asks about their pantry directly, or to resolve a pending confirmation outside a cart flow. Returns {"enabled": false} if the user hasn't opted in — offer enable_pantry once, don't nag. Use it to: (1) skip ingredients the user already has (confirm before skipping anything marked probably_out); (2) bias product picks toward loves and away from hates; (3) resolve pending confirmations — a "did that order go through?" aside answered via confirm_purchase, which fits alongside or after the current cart task and never gates it.get_recipe
ChatGPTkroger_add_to_cart
ChatGPTitems is a list of {"upc": "0001111041700", "quantity": 1}. Use the UPCs the user confirmed from match_recipe_to_kroger or match_items_to_kroger, and the quantity each matched line carried (a shopping list's "x3" or "2 cans" — quantity is how many of the package to add). Always include "price" per item (the store price you showed the user — promo price if on sale); it powers order-value analytics. If the user has pantry enabled, also include "description" (product name) and "ingredient_name" per item — the purchase confirmation and resulting pantry entries are built from them. modality is PICKUP or DELIVERY (defaults to the user's saved preference, then PICKUP). Pass recipe_id so the order is attributed to its source recipe and added to local history. The cart is filled but NOT checked out — the user completes checkout in Kroger. Only a success response with cart_status: "confirmed_in_cart" means items are in the cart — relay its items_added to the user as an explicit receipt (added / skipped / still unresolved). On an error, tell the user plainly that nothing was confirmed added; never describe matched or reviewed items as "added" on the strength of earlier calls. This is ADD-ONLY: the Kroger API cannot remove items, change quantities, or clip coupons. If the user wants something removed or resized, tell them to do it in the Kroger app/site — never promise a rebuild or removal you can't do. If the response includes pantry_confirmation_id, keep the id internal (never show it) and tell the user to come back after checkout to confirm the purchase (then call confirm_purchase) so their pantry stays current.kroger_auth_status
ChatGPTactive field: when it's true the account is connected and usable right now — do NOT call connect_kroger(). A short-lived access token that lapsed between sessions is refreshed automatically, so a past connection stays valid; only reconnect when needs_reauth is true. A 401 here means this client has no API key yet — NOT that a Kroger session expired. If a connect is mid-flight (the user just signed in), the fix is to call finish_kroger_connection() to pull the key, not to reconnect — and if you still have the link_token connect_kroger() returned earlier in this conversation, pass it to finish_kroger_connection(link_token=...) even if this tool reports "No Kroger account connected": that message only reflects what the server session currently remembers, which can lag what you know.kroger_get_product
ChatGPTon_sale, and stock (pass/omit location_id same as search). A 404 here — not an empty keyword search — is what "Kroger doesn't have it" actually looks like.kroger_search_products
ChatGPTquery to 8 words or fewer — Kroger rejects longer search terms, so anything past the 8th word is dropped before the search (the result then carries query_truncated: true and the query_searched actually used). Prefer a short product phrase plus size over a sentence. Write a size the way the catalog writes it — a pack count is "12 count" or "12 ct", never a word like "dozen": "eggs 12 count" returns five cartons where "large eggs dozen" returns nothing at all (live 2026-09-10). When a sized query comes back empty, drop the size and search the product alone before telling the user anything is unavailable. When the user wants a specific brand, pass brand (e.g. "Fage") with a generic query — that surfaces the brand's full size range instead of burying it under other products. Raise limit (up to 50) to see more sizes/pack options. If a specific product still doesn't show up but the user can see it on kroger.com, use kroger_get_product with the UPC or URL — never conclude the store doesn't carry it from keyword search alone. To find SALES, search the product category ("ribeye steak" — never words like "steak sale", which just keyword-match product names) and check each result's on_sale flag / compare price_promo to price_regular. Skip products whose stock is "Not available" — that store doesn't carry them right now. Returns products with description, brand, size, price, on_sale, stock, and upc; pass the chosen UPCs straight to kroger_add_to_cart (after the user confirms). Requires a connected Kroger account. Omit location_id to use the saved default store (auto-resolved from default_zip when needed), since prices, sizes, and availability vary by store.match_items_to_kroger
ChatGPTquantity (packages to add, parsed from the line's "x3" / "2 cans" / trailing count) and size (the pack size of one, e.g. "12 oz") — pass quantity through to kroger_add_to_cart and check the pick's size against size. Nothing is added to the cart; show the user the picks and pass confirmed UPCs to kroger_add_to_cart. Items where matched is false or stock is "Not available" need a swap — try kroger_search_products with different words, or ask the user. Omit location_id to use the saved default store.match_items_to_walmart
ChatGPTquantity (packages to add, parsed from the line's "x2" / "2 cans" / trailing count) and size (the pack size of one, e.g. "12 oz") — pass quantity through to walmart_build_cart_link and check the pick's size against size. Nothing is added to the cart; show the user the picks and pass confirmed product_ids to walmart_build_cart_link. Items where matched is false need a swap — try walmart_search_products with different words, or ask the user. offer_type: STORE_ONLY and sold-by-weight picks add fine for pickup/delivery — don't warn about them. No Walmart sign-in is required.match_recipe_to_kroger
ChatGPTstock: "Not available" candidates as not carried at this store and pick an alternative. Ingredients listed in unmatched just need a follow-up search (kroger_search_products or match_items_to_kroger with different wording) — they never mean the connector can't search or add to cart. Each item carries BOTH numbers: quantity/unit are what the dish needs ("2 lb"), and cart_quantity is how many packages to add — pass cart_quantity to kroger_add_to_cart, never quantity. Pass servings to shop for a different number of people; the amounts and cart_quantity are scaled for you and the scaling block has the math to show. Omit location_id to use the user's saved default store (set via set_preference). If no default_location_id is saved but default_zip is, the nearest Kroger is used automatically (not saved — save the user's pick with set_preference).match_recipe_to_walmart
ChatGPTquantity/unit are what the dish needs ("2 lb"), and cart_quantity is how many packages to add — pass cart_quantity to walmart_build_cart_link, never quantity. Pass servings to shop for a different number of people; amounts and cart_quantity are scaled from the recipe's own yield and the scaling block has the math. Each product also carries stock ("Available"/"Not available"), available_online, and offer_type ("ONLINE_ONLY"/"ONLINE_AND_STORE"/ "STORE_ONLY") — catalog-level signals from Walmart, not live inventory at any one store (the affiliate API has no per-store stock lookup). The suggested pick already skips "Not available" candidates when a better one exists. If the user wants pickup, flag any offer_type: ONLINE_ONLY item before adding it — it won't be on a physical shelf. offer_type: STORE_ONLY does NOT mean the item can't be carted: store-only and sold-by-weight items add fine for pickup or delivery through the cart link. Never describe such an item as unavailable or "store-only" to the user; the only thing that blocks an add is the item being out of stock at their store, which Walmart reports when the link opens.record_product_feedback
ChatGPTsearch_term_feedback on the line), so record it as the specific label, not a note. A hated ingredient flags the line (ingredient_feedback: "hate") so you ask about a swap. Meal-level preferences ("loves crockpot meals") don't fit here; keep those in chat. Never ask the user to fill in likes/dislikes as a survey — one signal at the moment it's said is the whole job.review_shopping_list
ChatGPTsearch_recipes
ChatGPTquery may be a recipe page's address (https://...): the recipe is resolved directly, indexed first if we've never seen it. Otherwise it's a ranked full-text search over title, description, creator and ingredient lines, with fuzzy fallbacks. Check match_kind: exact/url hits are the answer; ingredient hits are fuzzy candidates found via ingredient names because nothing matched directly — confirm with the user before shopping one. When a URL yields nothing, url_error says why (the site blocked the fetch, the address 404s, the page has no recipe data, sign-in needed) — pass that reason on to the user rather than "nothing found". A single recipe rarely covers a multi-part ask (a main plus specific sides or a named ingredient). Before treating any hit — exact or fuzzy — as settling the request, check it covers every part the user named; a match on the main dish alone isn't a match on the whole ask.set_preference
ChatGPTdietary, default_location_id (Kroger), default_walmart_store_id, default_modality (PICKUP/DELIVERY), preferred_brands, default_zip (ZIP code used to auto-resolve the nearest store for whichever of Kroger/Walmart doesn't have a saved store id yet — shared between both). Pass an empty value to clear a preference.shop_recipe
ChatGPTmatch, then kroger_add_to_cart). An account with NO Kroger link — e.g. someone who signed in with the email magic link — gets Walmart picks instead (walmart_match, then walmart_build_cart_link; no store sign-in needed), so never answer "connect Kroger first" unless the user asks for Kroger by name. Pass location_id to force Kroger at that store. Omit it to use the saved default store.update_pantry
ChatGPTitems is a list of {"name": "whole milk", "state": "have"|"out"|"remove", "staple": true|false (optional)}. Marking "have" restarts the item's freshness clock (shelf life is inferred from the name — milk decays in days, flour in months). Use "staple": true for things the user always keeps on hand. Use this whenever the user mentions their kitchen in passing ("we're out of eggs", "I picked up basil at the farmers market") — low-friction capture is what keeps the pantry alive. Requires pantry to be enabled.walmart_build_cart_link
ChatGPTitems is a list of {"product_id": "12345", "quantity": 1}. Use the product_ids the user confirmed from match_recipe_to_walmart. Always include "price" per item (the price you showed the user); it powers order-value analytics. Include "description" too — it labels the cart in the post-checkout confirmation. store_id sets pickup context on the link; if omitted, falls back to the saved default_walmart_store_id, else the nearest store to the saved default_zip (resolved and cached automatically — no need to ask the user again once set). Returns a checkout_url the user opens in a browser while signed in to Walmart — the API does not place the order or take payment. IMPORTANT: this builds a LINK — nothing is in the user's cart yet, so never say an item "was added". Tell the user to open the link in the Walmart session where their pickup or delivery store is already selected: Walmart adds the items for that store, checks its stock as the link opens, and shows an "Unable to add to Cart" notice naming anything out of stock there — so they should glance at the cart before checkout. Store-only and sold-by-weight items are NOT a problem for the link; don't warn about them. If the response includes pantry_confirmation_id, keep the id internal (never show it) and tell the user they can come back after checkout to say whether the order went through (then call confirm_purchase).walmart_search_products
ChatGPT/ip/.../<itemId>) or a bare numeric Walmart item id, pass it as query verbatim: the tool resolves that exact listing instead of keyword-searching, so the product_id you add is the one the user picked. Use for freeform lookups: a particular brand, size, pantry staples, or anything the user wants to add directly. Returns products with description, brand, size, price, product_id, and availability signals (stock, offer_type, available_online); pass chosen ids to walmart_build_cart_link after the user confirms. offer_type: STORE_ONLY items add fine for pickup/delivery — never present one as unavailable. An exact lookup that returns no products means Walmart's items catalog can't resolve that id; next_steps then says what to search for. No Walmart sign-in is required.Capabilities
Example Prompts
Click any prompt to copy it.
Links
App Stats
28
Tools
3
Prompts
ChatGPT
Platforms
Category
Grocery ShoppingWorks with
Data refreshed daily





