# AddTheShop: guide for AI agents

You are adding a shop to a website. AddTheShop provides the products, cart, Stripe checkout and orders. The site only needs one script tag. Read this whole file, then act.

## What you need from the owner

- The **store key**, which starts with `pk_ats_`. It is public and safe in HTML. The owner finds it at https://addtheshop.com/app/install.
- Optionally a **secret key** (`sk_ats_...`) if you should also manage products and orders. Never put a secret key in website code.

## 1. Put the shop on a page

Place this where the product grid should appear, for example on a `/shop` page:

```html
<script src="https://addtheshop.com/shop.js" data-store="pk_ats_STORE_KEY" async></script>
<div id="addtheshop"></div>
```

That renders a responsive product grid with "Add to cart" buttons, a floating cart bar, a cart drawer and a "Pay with Stripe" button. Checkout happens on Stripe's hosted page on the owner's own Stripe account. Nothing else is required.

Options on the script tag:

- `data-target="#my-element"` renders into that element instead of `#addtheshop`.
- `data-success="https://site.com/thanks"` and `data-cancel="https://site.com/shop"` set where buyers land after paying or cancelling. Default is the current page. After a successful payment the page gets `?ats_order=...` and the snippet shows a thank-you toast and empties the cart.
- `data-theme="unstyled"` injects no CSS so you can style the classes (`.ats-grid`, `.ats-card`, `.ats-img`, `.ats-body`, `.ats-name`, `.ats-desc`, `.ats-price`, `.ats-btn`, `.ats-bar`, `.ats-drawer`, `.ats-panel`).

Light styling without `unstyled`: set CSS variables on `#addtheshop`: `--ats-accent` (buttons and cart bar), `--ats-radius`, `--ats-font`, `--ats-text`, `--ats-bg`, `--ats-line`. Match them to the site's existing colours and font.

## 2. Buy buttons anywhere

With the script tag present on the page, any element with `data-addtheshop-buy="PRODUCT_ID"` adds that product to the cart and opens the cart drawer:

```html
<button data-addtheshop-buy="12">Buy the blue mug</button>
```

Product ids come from the dashboard or the API below.

## 3. Frameworks

- **Plain HTML, Webflow, Framer, Astro, Hugo**: paste the two lines into the page.
- **React, Next.js, Lovable, Bolt, v0**: render the div and load the script in an effect so it runs client side:

```jsx
export default function Shop() {
  useEffect(() => {
    const s = document.createElement("script");
    s.src = "https://addtheshop.com/shop.js";
    s.async = true;
    s.dataset.store = "pk_ats_STORE_KEY";
    document.body.appendChild(s);
    return () => s.remove();
  }, []);
  return <div id="addtheshop" />;
}
```

- **Vue, Svelte, SolidJS**: same idea in `onMounted` / `onMount`.
- **Server-rendered frameworks**: the script is client-only; the div can be in the server HTML.

Do not fetch or render products yourself unless the owner asks for a custom design. If they do, use the storefront API below.

## 4. Storefront API (public, any origin)

Base: `https://addtheshop.com/v1/storefront/pk_ats_STORE_KEY`

- `GET /products` returns `{ store: { name, currency, ready }, products: [{ id, name, description, price_cents, price, currency, image_url, in_stock, stock }] }`.
- `POST /checkout` with JSON `{ "items": [{ "product_id": 12, "quantity": 2 }], "success_url": "https://...", "cancel_url": "https://...", "email": "optional@buyer.com" }` returns `{ url, session_id }`. Redirect the browser to `url`. Stock is checked server side. `{CHECKOUT_SESSION_ID}` in `success_url` is filled in by Stripe; otherwise `?ats_order=` is appended.

Errors are JSON `{ error, message }` with 4xx status. `ready: false` means the owner has not finished connecting Stripe; show the products but tell the owner to finish setup at https://addtheshop.com/app.

## 5. Managing the shop (secret key)

Everything the dashboard does is available with the owner's secret key as `Authorization: Bearer sk_ats_...`.

**MCP** (preferred for agents): `https://addtheshop.com/mcp`, Streamable HTTP, stateless. Two ways to authenticate:

- **OAuth** (Claude.ai, ChatGPT, Cursor, any client that supports MCP authorization): add the URL as a custom connector. The client discovers `/.well-known/oauth-protected-resource`, registers itself, and the owner signs in and clicks Allow. No key to copy.
- **Bearer key** (Claude Code, scripts): the owner's secret key as `Authorization: Bearer sk_ats_...`. Config for Claude Code, Claude Desktop and others:

```json
{ "mcpServers": { "addtheshop": { "type": "http", "url": "https://addtheshop.com/mcp", "headers": { "Authorization": "Bearer sk_ats_YOUR_SECRET_KEY" } } } }
```

Tools: `get_setup_status` (call first: says what is missing and how to fix it), `get_store`, `update_store`, `list_products`, `get_product`, `create_product`, `update_product`, `delete_product`, `list_orders`, `get_order`, `get_install_snippet`.

**REST** with the same key, JSON in and out:

| Method and path | Purpose |
|---|---|
| `GET /v1/setup-status` | What is missing before the shop can sell |
| `GET /v1/store`, `PATCH /v1/store` | Name, currency, collect_shipping, notify_email |
| `GET /v1/products`, `POST /v1/products` | List, create `{ name, price: "24.90" or price_cents: 2490, description, image_url, stock, active }` |
| `GET /v1/products/:id`, `PATCH /v1/products/:id`, `DELETE /v1/products/:id` | One product |
| `GET /v1/orders`, `GET /v1/orders/:id` | Paid orders with buyer, items, shipping |
| `GET /v1/install` | The snippet and this guide's URLs |

Prices are integers in the store currency's minor unit (`price_cents`), or a decimal string (`price`). `stock: null` means unlimited.

## 6. Checklist before you say "done"

1. The page with the snippet loads and shows the product grid (or "No products yet" if the owner has none).
2. The script tag has the owner's real `pk_ats_` key, not the placeholder.
3. If `store.ready` is false, tell the owner in one sentence: "Finish connecting Stripe at https://addtheshop.com/app so the shop can take payments."
4. Do not implement your own cart or payment code. Stripe checkout is already handled.
