---
name: spark
description: Answer retail analytics questions about a merchant's connected stores (Shopify, WooCommerce, Odoo, Magento, Square, Clover) and run checkout audits with the MishiSpark `spark` CLI. Use when the user asks about store sales, orders, products, inventory or exports, asks "how did my store do", wants a checkout audit of a store URL, or wants to manage MishiSpark API keys, domain claims or credits.
---

# MishiSpark (`spark` CLI)

MishiSpark answers questions about a merchant's own store data and audits how well a store sells to AI shopping agents. Use the `spark` command line. Add `--json` to every command: stdout then holds one JSON document, also on errors.

## The Four Hard Rules

1. **Read-only by default.** Read, list and ask. Do not connect or disconnect stores, create or revoke keys, claim domains, cancel audits or buy credits unless the user asks for that exact action.
2. **Always state the connection, the period and the filters you used.** Every answer about numbers names the store (connection id and name), the date range and every filter. If you used a default (for example "the last 30 days"), say so.
3. **Never start a `standard` or `deep` audit without a confirmed budget.** Tell the user the price in credits (`GET /api/v1/pricing`: quick 300, standard 2,500, deep 15,000; 1 credit = USD 0.01). Start it only after the user confirms, and pass that budget as `--max-credits`.
4. **Never print the API key.** Do not echo `SPARK_API_KEY`, the config file or a key file. Refer to a key by its prefix (`spk_live_abcd…`) only.

## Sign in

Use one of these:

- `spark auth login --json`: the RFC 8628 device flow. Show the user the URL and the code from stderr. A person approves it in the browser. The CLI saves the key in `~/.config/spark/config.json` (mode 0600).
- `SPARK_API_KEY` environment variable: a key the merchant created in the web app (Settings, API Keys). It wins over the saved key.
- `spark auth agent-signup --tos-version <version> --operator-email <email> --json`: an agent account with an unfunded key and zero credits. The operator confirms the email for trial credits, or a person pays.

Check with `spark auth status --json`. Exit code 2 means: sign in again.

## Commands

| Task | Command |
|---|---|
| List stores | `spark connections list --json` |
| Ask a question (model, 10 credits) | `spark ask "<question>" --connection <id> --json` |
| Sales (tool `get_sales`) | `spark sales --connection <id> --from YYYY-MM-DD --to YYYY-MM-DD [--granularity day\|week\|month] --json` |
| Orders (tool `analyze_orders`) | `spark orders --connection <id> --from … --to … [--group-by hour\|day\|company\|warehouse\|product] --json` |
| Products (tool `search_products`) | `spark products --connection <id> [--query <text>] [--sort-by revenue_30d] [--limit 20] --json` |
| Inventory (tool `get_inventory_detail`) | `spark inventory --connection <id> [--status low_stock\|out_of_stock\|overstocked] --json` |
| Any tool (1 credit, no model) | `spark tools --json`, then `spark tool <name> --connection <id> --input '<json>' --json` |
| Export a preset to a file | `spark export --connection <id> --type weekly_revenue --from … --to … [--format csv\|excel] --json` |
| Checkout audit | `spark audit <url> --effort quick --accept-terms --json` |
| Audit status, report | `spark audit status <id> --json`, `spark audit report <id> --json` |
| Audit artefacts | `spark audit artefacts <id> --json`, `spark audit artefacts <id> --get <path> --out <file>` |
| Domain claim (owner tier) | `spark domains claim <host> --json`, publish the TXT record, then `spark domains verify <id> --json` |
| Credits | `spark credits balance --json` |

Prefer the direct tools (`sales`, `orders`, `products`, `inventory`, `tool`) over `ask` when the question maps to one tool: they cost 1 credit and return exact numbers. Use `ask` for open questions. Pass the user's dates; if the user gives none, say which default you used.

## Exit codes

| Code | Meaning | What to do |
|---|---|---|
| 0 | OK | Use the output. |
| 1 | Error (bad input, not found, server error) | Read `error.message`. Do not retry blindly. |
| 2 | Authentication (401, 403, no key) | Ask the user to sign in, or to add the missing scope. |
| 3 | Payment required (402) | Show the user the price, the amount and the `topup_url`. A person pays. Then run the same command again. |
| 4 | Rate limit or quota (429) | Wait `error.retry_after` seconds, then retry once. |

## Payment (402)

A charged call that the credits cannot cover exits 3 with `error.payment`: `challenge_id`, `price_credits`, `amount_credits`, `amount_cents`, `topup_url`. Tell the user. Do not buy credits on your own.

When the user approves a budget, run the command with `SPARK_PAY=auto`, `--max-credits <budget>` and `--wait`. The CLI then starts the payment of the challenge (only when the price is within the budget), prints the URL a person must complete, waits until it is paid and sends the request again with the same `Idempotency-Key`. Without `--wait` it exits 3 after it starts the payment.

## Audits

- `quick` needs no budget flag, but tell the user the price first.
- `standard` and `deep` need `--max-credits` (Rule 3). The CLI refuses without it.
- `--accept-terms` accepts the audit terms for the user. Ask the user first.
- `--wait` polls every 30 seconds until the audit is `complete`, `budget_exceeded`, `failed` or `cancelled`.
- The server can lower the effort for the public tier. Report the effort in the answer, not the one you asked for.
- The audit never places an order.

## More

- Agent docs: `https://api.spark.mishipay.com/llms.txt`.
- Prices: `https://api.spark.mishipay.com/api/v1/pricing`.
- OpenAPI: `https://api.spark.mishipay.com/openapi.json`.
