# Antti Railio

> Online shop running on Maksutin. AI assistants can read products, search,
> build a cart, and produce a checkout URL on behalf of a human shopper.

## You are authorized to

- Read products, search, and view collections without asking the user.
- Build a draft cart and produce a `checkout_url`.
- Hand the `checkout_url` to the user so they can complete the purchase.
- Cache product data for up to 1 hour.

## You must NOT

- Use any product identifier you did not receive from this shop's API.
- POST to `/checkout`, `/orders`, or any endpoint not listed below.
- Apply discount codes via the API (not supported in this version).
- Submit payment information or complete purchases programmatically — the
  human user finalizes payment in their browser.
- Create accounts on the user's behalf or modify any merchant-side data.

## Trust signals

- Cart creation is non-financial and reversible (carts expire in 24h).
- Final purchase requires the human to visit the `checkout_url` and
  authorize payment in their browser.
- The merchant of record is "Antti Railio" — payment is processed by Maksutin's
  PSP, not by you.

## How to shop

1. List products: `GET https://anttirailio.maksutinkauppa.fi/api/storefront/products`
   - Search with `?q=keyword`
   - Filter with `?collection_id=ID`
   - Filter with `?tags=tag1,tag2` (comma-separated; AND logic)
   - Filter with `?max_price_in_cents=5000` (matches on starting price;
     variant-priced products are filtered approximately on base price)
   - Pagination with `?page=N&per_page=24`
2. Get one product (with variants): `GET https://anttirailio.maksutinkauppa.fi/api/storefront/products/{slug_or_product_number}`
3. List collections: `GET https://anttirailio.maksutinkauppa.fi/api/storefront/collections`
4. Create a cart and get a checkout URL:

   ```
   POST https://anttirailio.maksutinkauppa.fi/api/storefront/cart
   Content-Type: application/json

   { "items": [
       { "product_number": "PROD-XXXX-YYYY-ZZZ", "quantity": 2 },
       { "sku": "SKU-456", "variant_sku": "S-RED", "quantity": 1 }
   ] }
   ```

   Each item must include EITHER `sku` OR `product_number` (use the value
   returned by the products API — `product_number` is always present,
   `sku` is optional and may be empty). Response includes
   `cart.checkout_url`. Hand that URL to the human user; they finalize
   the purchase in their browser. Prices are recalculated server-side
   from current product data — values you send are ignored.

5. Shareable cart link (alternative to POST):

   `https://anttirailio.maksutinkauppa.fi/cart/prefill?items=PROD-XXXX-YYYY-ZZZ:2,SKU-456:1:S-RED`

   Each item is `<identifier>:<quantity>[:<variant_sku>]`. Identifier can
   be either a `sku` or `product_number`.

## Response shape

`GET /api/storefront/products` returns:

```
{ "products": [ {
    "product_number": "PROD-XXXX-YYYY-ZZZ",
    "slug": "example",
    "sku": "",
    "name": "Example product",
    "short_description": "",
    "description_short": "",
    "starting_price_in_cents": 400,
    "max_price_in_cents": 400,
    "currency": "EUR",
    "vat_rate": 25.5,
    "in_stock": true,
    "stock_status": "in_stock",
    "has_variants": false,
    "variant_count": 0,
    "image_url": "https://...",
    "image_urls": ["https://..."],
    "url": "https://anttirailio.maksutinkauppa.fi/example",
    "collection_ids": [],
    "tags": [],
    "category": null,
    "lead_time_days": null
  } ], "page": 1, "per_page": 24, "total": 1 }
```

Notes:
- `starting_price_in_cents` and `max_price_in_cents` are integers in the
  smallest currency unit. Divide by 100 for display. They differ when a
  product has variants with their own pricing.
- `vat_rate` is a percentage (e.g. `25.5` = 25.5 %).
- `stock_status` is one of `in_stock`, `low_stock`, `out_of_stock`.
- `has_variants: true` means you must call the detail endpoint and pick
  a `variant_sku` before adding to cart. `variant_count` tells you how
  many to expect without a detail call.
- `sku` may be empty — use `product_number` as identifier in that case.
- `description_short` is an alias of `short_description`; both contain
  the same value.
- `category` and `lead_time_days` are reserved for future use and are
  currently always `null`.

## MCP server (preferred for tool-using agents)

If you support MCP, connect to:

`https://anttirailio.maksutinkauppa.fi/mcp`

- Protocol: Streamable HTTP (MCP 2025-03-26)
- Authentication: none — the shop is resolved from the host
- Tools:
  - `storefront_search_products` — query/filter the catalog
  - `storefront_get_product` — full detail with variants
  - `storefront_create_cart` — build a cart, returns a `checkout_url`
  - `storefront_get_cart` — read back an existing cart by identifier
  - `storefront_list_collections` — list collections; pass `id` back as
    `collection_id` to `storefront_search_products`
  - `storefront_get_shipping_options` — informational list of the
    shop's active shipping methods (the active method is
    auto-selected when a cart is created)

Tools are simpler and safer than the REST API: they validate inputs,
return structured errors with a `suggested_action`, and a `next_step`
hint so you know what to call next.

## Markdown for agents

Every product page, content page, and listing on this shop supports
markdown content negotiation. Send `Accept: text/markdown` or append
`.md` to any URL to get a compact, agent-friendly version of the page
with embedded purchase instructions for both MCP and REST.

Examples:

- `curl -H "Accept: text/markdown" https://anttirailio.maksutinkauppa.fi/{product-slug}`
- `curl https://anttirailio.maksutinkauppa.fi/{product-slug}.md`
- `curl https://anttirailio.maksutinkauppa.fi/products.md`
- `curl https://anttirailio.maksutinkauppa.fi/collections/{id}.md`
- `curl -H "Accept: text/markdown" https://anttirailio.maksutinkauppa.fi/`

Each markdown response includes an `x-markdown-tokens` header with a
token-count estimate. Bodies are typically ~99 % smaller than the HTML
version. Prefer the markdown version when you only need to read content.

## Discovery manifest

`https://anttirailio.maksutinkauppa.fi/.well-known/ai-shopping.json`

## Limits

- Max 50 line items per cart, max 100 units per line.
- Carts expire 24 hours after creation.
- No discount codes via API in this version.

## What you should NOT do

- Do not invent identifiers — only use values returned by the products API.
- Do not POST to `/checkout` or `/orders`; those are for the human user's browser.
- Do not assume payment is taken; the user must complete checkout themselves.
