---
name: sangria
version: 0.1.6
description: Use Sangria to discover and buy products online through the Sangria CLI. Use when the user wants to buy, find, order, grab, pick up, or get a product.
when_to_use: '"buy me a coffee", "order X", "get me Y", "buy this <link>". Always discover first; only buy after the user approves a specific match and price.'
argument-hint: "[product request or url]"
arguments: [request]
allowed-tools: WebSearch Bash(sangria *) Bash(npm install -g @sangria-sdk/cli*) Bash(curl *) Bash(command *) AskUserQuestion Read
---

# Sangria

Use the Sangria CLI (`sangria`) to discover and buy things for the user.

If not installed:

```bash
npm install -g @sangria-sdk/cli
```

If not authenticated:

```bash
sangria auth status --json
sangria auth set "<sg_agents_...>"
```

Keys are created at https://getsangria.com/client/dashboard.

Find a product URL when needed, discover it to lock price, then buy after user approval. Always pass `--json`.

---

## Find A Product

If the user gives a broad request instead of a product URL, ask at most 1-3 concise questions before searching when purchase-critical details are missing. For example, for running shoes ask for basics like size, budget, and intended use. Skip questions when the request is already specific enough or when reasonable defaults are better than delay.

Use web search/browser results to find 2-3 direct Amazon product-page candidates. Do not search for or recommend Amazon Whole Foods Market products. Identify Whole Foods results by inspecting the candidate URL: a `ref` or `ref_` query value like `ref=sr_1_9_us_f3_0o_wf` includes the `_wf` tag, which is a strong internal Amazon marker for Whole Foods Market (WF) integration results. Reject any candidate URL whose `ref` or `ref_` value contains `_wf`.

Only present direct product pages (`/dp/<ASIN>` or `/gp/product/<ASIN>`), not Amazon search pages (`/s?k=...`) or category pages (`/b?node=...`). Show the candidates to the user and ask which one to quote. Do not run `sangria discover` until the user chooses one candidate.

---

## Discover

```bash
sangria discover --url "<URL>" --json
```

The URL must be an HTTPS product-page link on a supported merchant (today: `amazon.com`). The path must point to a product (`/dp/<ASIN>` or `/gp/product/<ASIN>`), not a search page (`/s?k=...`) or category page (`/b?node=...`). Do not discover Amazon Whole Foods Market results: if the URL has a `ref` or `ref_` query value containing `_wf` (for example `ref=sr_1_9_us_f3_0o_wf`), ask the user for a non-Whole Foods Amazon product link. If the user pastes a non-product URL, ask them to open the specific product and copy that page's URL.

Discovery requires the user's saved zipcode. If it's missing, the CLI tells you what to run.

The response has `discovery_id`, `expires_at`, and `matches[]` (at most one match). Each match has `sku`, `name`, `price_usd`, `product_url`, plus optional fields like `rating`, `delivery_text`, and `image_url`.

Render the match as a markdown table:

| Name | Price | Link |
| ---- | ----- | ---- |
| Starbucks Espresso Roast 50-count pods | $28.50 | [Amazon](https://amazon.com/dp/B07Q7S4HDJ) |

Empty `matches` means the URL didn't resolve to a purchasable product — ask for a different link. The price is locked for ~45 minutes. If the quote expires before buying, discover again.

---

## Buy

Only buy after user approval.

```bash
sangria buy "$DISCOVERY_ID" "$SKU" --json
```

- `confirmed` — purchase succeeded. Summarize the `result`.
- `failed` — nothing was charged. Explain the failure and offer to try a different product.
- `running` — rare. Re-run the same command after a short wait.

Buy is idempotent for the same `discovery_id` and `sku` — re-running returns the existing order, never double-charges. A failed order consumes the discovery; to retry, discover again for a fresh quote.

---

## Top-Up

If buy fails with insufficient balance, the CLI tells you. Only top up after user approval.

```bash
sangria topup --amount "$USD_AMOUNT" --json
```

Show the returned `message` to the user (it includes the fee breakdown). They'll receive an authorization code by email. Ask for the code, then confirm:

```bash
sangria topup confirm "$TOPUP_ID" --code "$CODE" --json
```

After a successful top-up, retry the buy if the quote hasn't expired. If it expired, discover again.

---

## Settings

Discovery needs the user's **zipcode**. Buying needs a full **US shipping address**, a US **phone number**, and **email**. Set only what the current step requires.

```bash
sangria settings show --json
sangria settings update --postal-code "$POSTAL_CODE" --json
sangria settings update \
  --line1 "$LINE1" \
  --city "$CITY" \
  --state "$STATE" \
  --postal-code "$POSTAL_CODE" \
  --country US \
  --json
sangria settings set-phone "$PHONE" --json
```

Add `--line2 "$LINE2"` only when the address has an apartment, suite, or unit. Email is set at https://getsangria.com/client/dashboard, not from the CLI.

---

## Errors

The CLI's error messages are self-guiding — they tell you what command to run next. Follow them.

**One exception:** if `sangria buy` fails with `commit_failed` or `internal_error`, the order may have actually succeeded. Re-run the same buy command to check the actual outcome before telling the user it failed.

If an error names a missing profile field that can't be set from the CLI (e.g., email), direct the user to https://getsangria.com/client/dashboard.

---

## Updates

If the CLI's stderr says "a newer Sangria CLI is available", finish the current request first, then on user approval:

```bash
command -v npm >/dev/null 2>&1 || { echo "npm not found. Install Node.js (which bundles npm) from https://nodejs.org/ and re-run." >&2; exit 1; }
npm install -g @sangria-sdk/cli@latest
```

Then refresh this skill from its canonical source:

```text
https://getsangria.com/skills/sangria/SKILL.md
```

On Claude Code:

```bash
curl -fsSL https://getsangria.com/skills/sangria/SKILL.md -o ~/.claude/skills/sangria/SKILL.md
```

After updating, re-read the skill before the next discover or buy — the fetched file is authoritative, your in-context copy is not.
