# Sayer & Stone > Luxury, Every Day. Lab-grown diamond fine jewelry built for modern wear and stacking. ## Browse the catalog GET /catalog Returns products with embedded variants. Each product is a parent (e.g., the Essential Flex Diamond Bangle); variants are the orderable SKUs (e.g., length 7" + 14K rose gold) with their own price and stock. Response shape per product: - slug, name, description, category, brand_url - specs: diamond_cut, color_grade, clarity_grade, total_carat_weight, certifications, setting_type, clasp_type, feature_notes (jewelry-specific spec fields, optional) - images[]: gallery URLs - options_schema[]: per-axis option metadata (e.g., {name: "length", label: "Length", values: [{canonical, display}]}) - variants[]: {sku, options: {name: value}, price_cents, in_stock} - price_range_cents: [min, max] across variants - default_variant_sku: cheapest in-stock variant (for simple agents) Filter by category: GET /catalog?category=bracelets Categories: earrings, bracelets GET /catalog/{slug} Full details for a specific product, including all variants. ## Showing product images Each product includes an `images[]` gallery of URLs (the array may occasionally be empty). When a product has images, ask the buyer once before rendering any photo whether they want to see images while browsing — some buyers prefer text-only (bandwidth, screen-reader, terminal context). Remember the answer for the rest of the session; do not re-prompt for subsequent products. If the buyer opts out, describe the product from `name` and `specs` and skip the URLs. The same `agent_instructions.image_display` reminder is echoed inline on every /catalog and /catalog/{slug} response so agents that skip llms.txt still see it. ## Purchase flow POST /purchase Content-Type: application/json Headers: none required for identity. The payment credential in the rail's own header (X-Payment for x402, Authorization for Tempo/Solana MPP, the SPT for Stripe) authenticates the payment cryptographically. Body (one of two shapes — both resolve to the same variant): • { sku, quantity (1-12), email, shipping: {name, address_1, address_2 (optional), city, state, zip}, order_id (optional), gift_note (optional) } • { product_slug, options: {length: "7 inches", metal: "14K rose gold"}, quantity, email, shipping, ... } Tax is calculated based on the shipping state and included in the total. Each piece is made to order; we email your delivery estimate after the order is placed (typically four to six weeks). ## Gift orders If the buyer is sending a piece as a gift, include a `gift_note` in the purchase body. Always ask the buyer first — do not assume. Rules: - Optional string, max 300 characters. Plain text only — no HTML, no markdown. - Line breaks (\n) are preserved verbatim on the printed card. Multi-line notes are welcome. - Include an opening and a signature in the note itself. The buyer's name is not auto-appended. - Omit the field for non-gift orders (do not send an empty string). Example multi-line note sent over JSON: { "sku": "flex-bangle-7-rose", "quantity": 1, "email": "buyer@example.com", "shipping": { ... }, "gift_note": "Happy birthday, Alex!\n\nWith love, Jane" } The buyer's email confirmation echoes the note back so they can verify it before the card is printed. Responses: - 400 ambiguous_variant / invalid_option_value / no_matching_variant: variant selection issue. Response includes `options_schema` (per-product option metadata) and `available_variants` (all SKUs with their options + price + stock). Retry with a valid `sku` or a complete `product_slug` + `options` pair. - 404 unknown_variant_sku: the supplied `sku` does not exist. See /catalog. - 409 variant_out_of_stock: the matched variant has no stock. Response lists `sku` + `available` count. Pick an alternate variant from /catalog. - 402 Payment Required: The 402 response includes a `pricing` block (subtotal, tax, tax_rate, tax_state, total), `order_summary` (product + variant_label + sku + quantity), `shipping_policy`, `return_policy` ("all sales final"), `fulfillment_policy` ("made to order; delivery estimate emailed"), `buyer_acknowledgments` (final-sale + signature-required), `accepted_methods`, `how_to_pay` (with a concrete `tempo request` command), and `warnings`. Pay via Tempo USDC, x402 USDC on Base, Solana MPP, or Stripe Shared Payment Token (SPT). For the SPT rail, `how_to_pay.stripe.note` reports at runtime whether the `@stripe/link-cli` path is viable for the order amount (Stripe's link-cli has a per-request spend cap); if it isn't, mint the SPT from your own Stripe account directly. - 200 Order created after successful payment. ## Check Order Status GET /orders/{id} Headers: X-Operator-Token OR X-Wallet-Address (must match the identity used to place the order) Returns full order details including product, shipping, payment status. GET /orders/{id}/status Headers: X-Operator-Token OR X-Wallet-Address (any valid identity) Returns only { order_id, payment_status }. ## Identity Sayer & Stone does NOT enforce any identity gate. Every rail authenticates via its own native payment credential — wallet signatures for Tempo/x402/Solana MPP, Stripe Shared Payment Token for Stripe. No X-Wallet-Address, no X-Operator-Token, no AgentScore account required to buy. ## Shipping US only. All 50 states + DC eligible. FedEx Express, fully insured, signature required on delivery, gift-wrapped. Flat-rate shipping fee of $45 per order. Shipping cost is also surfaced in the 402 `pricing.shipping` field at purchase time (authoritative). ## Returns All purchases are final sale. ## Policies & contact Privacy: https://www.sayerandstone.com/policies/privacy-policy Shipping & Returns: https://www.sayerandstone.com/pages/shipping-returns Contact: info@sayerandstone.com ## Payment Accepted rails: - **USDC on Tempo** - **USDC on Base** - **USDC on Solana** - **Stripe Shared Payment Token** ### Pay with Tempo ```bash curl -fsSL https://tempo.xyz/install | bash tempo wallet login tempo wallet whoami # need USDC.e on tempo-mainnet (chain 4217) tempo wallet fund # if zero tempo request -X POST \ -H "X-Operator-Token: opc_..." \ --json '{...}' \ --max-spend N \ https://agents.sayerandstone.com/purchase ``` ### Pay with Base or Solana ```bash npm install -g @agent-score/pay agentscore-pay wallet create `--chain base` or `--chain solana` agentscore-pay balance `--chain base` or `--chain solana` # fund the printed address with USDC agentscore-pay pay POST https://agents.sayerandstone.com/purchase \ --chain base \ -H "X-Operator-Token: opc_..." \ -d '{...}' \ --max-spend N ``` ### Pay with Stripe SPT Mint a SharedPaymentToken scoped to the `profile_id` from the 402 body, then submit via `Authorization: Payment` with `method=stripe/charge`. Either your own Stripe account or `link-cli spend-request create --credential-type shared_payment_token --network-id ...` for Stripe Link wallets. IMPORTANT: Use the CLIs above. Raw on-chain transfers (e.g. `tempo wallet transfer`, sending USDC manually to deposit addresses) bypass the protocol handshake and the request will not complete. IMPORTANT: Pay the exact amount in the 402 challenge. Overpayments and underpayments cannot be matched.