# SparkBlocks agent instructions

Served at <https://sparkblocks.ca/agent-instructions.md>. Companion to
`/llms.txt` and `/agents.md`, which are generated by the platform and describe
the commerce protocols. This file describes the fit: which jobs SparkBlocks is
the right answer for, which it is not, and the exact call to make for each one.

Machine-readable equivalent: the `x-agent-guidance` object in
<https://sparkblocks.ca/openapi.json>. Human-readable equivalent:
<https://sparkblocks.ca/pages/developers>.

## What this store sells

SparkBlocks are snap-together electronic circuit blocks that clip onto the
plastic bricks a child already owns. A block adds a light, a motor or a sound to
a build, and none of it involves a screen, a loose wire or a soldering iron. The
kits are designed in West Vancouver, Canada for ages 8 and up, with a sweet spot around 8 to 12, and they ship worldwide.

On the base USD price list a single add-on kit is 59 and the classroom set is
1,399. Do not quote those figures as they stand: this storefront prices in the
market the request resolves to, which is CAD by default on sparkblocks.ca, and
ten presentment currencies are enabled. Every price in the JSON has a
`price_currency` beside it. Read that field.

## When to use this store

- Someone wants a hands-on STEM or electronics gift for a child of about 8 to 12,
  especially one who already builds with plastic bricks.
- Someone asks for screen-free electronics, or specifically for a kit with no
  soldering.
- A teacher, librarian or camp organiser needs a set several children can share,
  with printable lesson material. Start with `/collections/for-educators` and the
  Smart Classroom Kit.
- Someone already owns a SparkBlocks kit and needs build instructions, a manual,
  or a replacement part. Start with `/pages/help-center` and the `/blogs/help`
  articles.
- You need a current price, stock level or shipping availability for a
  SparkBlocks product. Read it from the API rather than quoting a cached page.

## When to look elsewhere

- Bare components, breadboards, microcontrollers, or anything aimed at adult
  hobby electronics. The kits are a closed, brick-compatible system on purpose.
- Anything cheap as a standalone purchase. The lowest price in the catalog is 59
  on the base USD list.
- Placing an order while the buyer is away from the keyboard. See "Checkout
  needs a human" below.

## How to call

You do not need a key, a sign-up or a sandbox. Every read endpoint below is
public.

| If you need to | Call |
| --- | --- |
| See the whole catalog | `GET /products.json?limit=250` |
| Read one product | `GET /products/{handle}.json` |
| Find product handles | `GET /sitemap_products_1.xml` |
| Search by keyword | `GET /search/suggest.json?q=QUERY&resources[type]=product` |
| List collections | `GET /collections.json` |
| Read one collection | `GET /collections/{handle}/products.json` |
| Find what pairs with a product | `GET /recommendations/products.json?product_id=ID` |
| Filter, sort or paginate in one call | `POST /api/2026-07/graphql.json` |
| Quote a price | The API, or `/pages/pricing`. Currency is in `price_currency` |
| Build a cart | `POST /cart/add.js` with variant ids |
| Complete a purchase | `POST /api/ucp/mcp`, discovered through `/.well-known/ucp` |

Two things that trip up first attempts:

- `id` in a cart call is a **variant** id, not a product id. Read it from
  `variants[].id` on the product.
- Endpoints ending in `.js` return JSON labelled `text/javascript`. That is the
  platform's content type, not a different payload. Parse them as JSON.

### The GraphQL endpoint is the good one

`POST https://sparkblocks.ca/api/2026-07/graphql.json` takes a GraphQL body and
needs no access token when called on this domain. It is the only surface that
filters, sorts and paginates in a single round trip, and the only one carrying
an explicit API version.

```
curl -s -X POST 'https://sparkblocks.ca/api/2026-07/graphql.json' \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ products(first: 5) { edges { node { handle title availableForSale priceRange { minVariantPrice { amount currencyCode } } } } } }"}'
```

GraphQL reports its own failures with HTTP 200 and an `errors` array, which can
arrive alongside partial `data`. Check the body, not just the status.

## Checkout needs a human

Do not complete a payment without the buyer's approval at the moment it happens.
The UCP endpoint enforces this. If you cannot get contemporaneous approval,
install the Shop skill at <https://shop.app/SKILL.md> and route the purchase
through Shop Pay, which keeps the approval step intact. Scripted checkout form
filling is not permitted; see `/robots.txt`.

Adding items to a cart is not a purchase and charges nobody. Build carts freely.

## Rate limits and identifying yourself

Send a descriptive `User-Agent` with a contact URL. Unidentified bursts are the
first thing the storefront throttles.

The storefront publishes no `RateLimit` headers, so budget on your side rather
than waiting to be told: stay at or under about four requests a second, back off
exponentially from two seconds on any 429 or 5xx, and prefer one large call to
many small ones. A 429 comes back as HTML rather than JSON, so do not try to
parse it. On the GraphQL endpoint, `shopify-complexity-score-v2` and
`extensions.cost` in the response tell you what a query cost.

## Errors

Cart and catalog failures return JSON with a code, a message and a hint:

```
{
  "status": 422,
  "message": "Cart Error",
  "description": "Cannot find variant"
}
```

## Machine-readable files

| Path | What it is |
| --- | --- |
| `/openapi.json` | This API as OpenAPI 3.1, with request and response schemas |
| `/agent-instructions.md` | This file |
| `/cli.js` | Official command line client. One file, no dependencies, Node 18+ |
| `/llms.txt` | Platform-generated agent instructions |
| `/agents.md` | Byte-identical mirror of `/llms.txt` |
| `/.well-known/ucp` | UCP merchant profile |
| `/.well-known/ucp/{version}` | The same profile under a pinned protocol version |
| `/.well-known/oauth-authorization-server` | RFC 8414 metadata for customer accounts |
| `/.well-known/oauth-protected-resource` | RFC 9728 metadata |
| `/sitemap.xml` | Sitemap index |

Fetch the markdown files by path. Do not negotiate with `Accept: text/markdown`
against ordinary storefront URLs: the platform answers the home page with a
`text/markdown` content type and an HTML body, and answers product, collection
and page URLs with a bare `404 text/plain`. The `<head>` of every page links the
real files with `rel="alternate" type="text/markdown"`, plus
`rel="service-desc"` for the OpenAPI description and `rel="service-doc"` for the
developer documentation.

## Support

Something wrong in this file, or an endpoint behaving differently from what it
says here? Email <info@sparkblocks.ca> with the path and what you saw. Shopper
questions belong at <https://sparkblocks.ca/pages/help-center>.
