Developers and agents
Everything here is public and needs no account or API key. This page explains which host does what, how to search the catalogue, where current prices live, and how a shopping agent hands a buyer to a supported checkout.
Two hosts
Browsing happens on this host. Carts, checkout and orders happen on the Shopify-run checkout host. Paths from one do not exist on the other.
| Task | URL | Host |
|---|---|---|
| Read a page in English or Dutch | https://www.saltoftheearthnatural.com/en/...https://www.saltoftheearthnatural.com/nl/... | Storefront |
| Read the same page as markdown Send Accept: text/markdown to the page URL, or fetch its /api/md twin directly. | https://www.saltoftheearthnatural.com/api/md/en/... | Storefront |
| Every current price in one table | https://www.saltoftheearthnatural.com/en/pricing https://www.saltoftheearthnatural.com/nl/pricing https://www.saltoftheearthnatural.com/pricing.md | Storefront |
| Search the catalogue | GET https://www.saltoftheearthnatural.com/api/search?q=... | Storefront |
| Buy on a customer's behalf (UCP) | https://checkout.saltoftheearthnatural.com/.well-known/ucpPOST https://checkout.saltoftheearthnatural.com/api/ucp/mcp | Checkout (Shopify) |
| Shopify's own product JSON Exists only on the checkout host. On this host, the product page carries the same facts as Product/Offer JSON-LD and as markdown. | https://checkout.saltoftheearthnatural.com/products/{handle}.json | Checkout (Shopify) |
Product search API
A single read-only endpoint returns the products that best match a phrase: names, fragrances, formats and notes, combining keyword and semantic matching. It does not return prices or stock; take those from the product page or the price list.
Endpoint
GET https://www.saltoftheearthnatural.com/api/search?q=<phrase>&limit=<1..50>Parameters
- q (required): the search phrase. Whitespace is trimmed, the value is cut to 200 characters, and fewer than 2 remaining characters is an error.
- limit (optional): how many results to return, default 20, clamped to between 1 and 50. Values outside the range are clamped, not rejected.
Response
A JSON object with the normalised query, a count, the results in rank order, and the source of the results. Each result carries the product handle, its absolute product page URL, the product name and descriptive attributes. Ranking scores are relative to the one response and are not stable between requests.
curl -sS "https://www.saltoftheearthnatural.com/api/search?q=lavender%20refill&limit=2"{
"query": "lavender refill",
"count": 2,
"source": "supabase",
"results": [
{
"product_code_uk": "CRYS300LV-C",
"shopify_handle": "lavender-vanilla-spray-refill-pouch",
"url": "https://www.saltoftheearthnatural.com/en/product/lavender-vanilla-spray-refill-pouch",
"product_name": "Lavender & Vanilla Spray Refill Deodorant",
"format": "spray",
"is_refill": true,
"is_refillable": false,
"parent_product_code": "CRYS38-C",
"fragrance_name": "Lavender & Vanilla",
"top_notes": "Cardamom & Lemon",
"awards": null,
"award_count": 0,
"review_summary": null,
"average_rating": 5,
"fts_rank": 0,
"semantic_rank": 0.48,
"combined_score": 0.0246
}
]
}source is "supabase" normally and "shopify" when the primary index was unavailable and the Shopify catalogue answered instead; the X-Search-Source header says the same. X-Search-Degraded: 1 marks a response produced while one provider was failing.
Errors
Every error is JSON with a stable code, a human message and a hint for recovery. There are no HTML error pages on this endpoint.
- 400 invalid_query: q is missing or shorter than 2 characters after trimming.
- 405 method_not_allowed: only GET is supported; the Allow header lists the accepted methods.
- 503 search_unavailable: both search providers failed. Honour Retry-After and try again.
- 429: the edge rate limit. This is applied by the hosting platform under abusive traffic; there is no per-key quota and no quota headers. Back off and retry later.
curl -sS "https://www.saltoftheearthnatural.com/api/search?q=x"
{
"error": "Query must be at least 2 characters",
"code": "invalid_query",
"hint": "Pass a \"q\" query parameter of 2 to 200 characters, e.g. ?q=lavender%20refill",
"results": []
}Limits and caching
Results are the top matches only; there is no cursor or page parameter. Successful responses are cacheable at the CDN for up to 30 minutes, so repeated identical queries are cheap. Empty results are cached briefly and degraded responses are not cached at all.
The machine-readable description of this endpoint is the OpenAPI document at https://www.saltoftheearthnatural.com/openapi.json.
Prices and availability
Every product page publishes schema.org Product and Offer JSON-LD with the current price, currency and availability for the storefront's default market. The price list shows every product in one table, in GBP on the English storefront and EUR on the Dutch one, and the same table is available as markdown. The delivery country chosen at checkout decides the final currency and total.
curl -sS -H "Accept: text/markdown" "https://www.saltoftheearthnatural.com/en/product/crystal-deodorant-classic"Buying on a customer's behalf
Do not script the storefront's cart. Shopify runs a Universal Commerce Protocol (UCP) surface for this store on the checkout host:
- https://checkout.saltoftheearthnatural.com/.well-known/ucp Discovery profile: supported versions, endpoints, capabilities and payment handlers.
POST https://checkout.saltoftheearthnatural.com/api/ucp/mcpMCP endpoint (Streamable HTTP, JSON-RPC). Call tools/list first; it lists catalogue search and lookup, product detail, cart, checkout and order tools with their input schemas.- Tool calls require an agent profile in meta.ucp-agent.profile. Without one the endpoint answers a structured JSON-RPC error rather than a result.
- Payment always needs the buyer's explicit, contemporaneous approval. Never complete a checkout without it.
- Use the identifiers the UCP tools return. A storefront handle or SKU is not a checkout identifier.
curl -sS -X POST "https://checkout.saltoftheearthnatural.com/api/ucp/mcp" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'The full agent instructions, including Shopify's managed document, are at https://www.saltoftheearthnatural.com/agents.md.
Authentication
Reading this host needs no credentials: pages, markdown, the price list, the search API and every discovery file are anonymous.
On the checkout host, UCP discovery and tools/list are anonymous too. Operations that act on a customer's account are governed by Shopify. The checkout host publishes RFC 9728 protected-resource metadata naming its authorization server, and that server's RFC 8414 metadata declares the supported scopes and PKCE methods:
- Protected-resource metadata: https://checkout.saltoftheearthnatural.com/.well-known/oauth-protected-resource
- Authorization-server metadata: https://checkout.saltoftheearthnatural.com/.well-known/oauth-authorization-server
- Shopify's guide to agent authentication and rate limits
This storefront host is not an authorization server and never issues or accepts tokens. Do not send credentials to it.
Rate limits and fair use
- There are no API keys, quotas or quota headers on this host. Traffic is protected at the edge and abusive patterns receive 429 or 403 responses.
- Cache what you fetch: search responses and discovery files carry Cache-Control headers that say how long they stay valid.
- Identify your agent with a descriptive User-Agent and respect robots.txt.
- The UCP MCP endpoint is rate limited per IP by Shopify; back off on 429.
Machine-readable files
- https://www.saltoftheearthnatural.com/openapi.json OpenAPI description of the search API
- https://www.saltoftheearthnatural.com/llms.txt Site overview for language models
- https://www.saltoftheearthnatural.com/agents.md Agent instructions (storefront and Shopify)
- https://www.saltoftheearthnatural.com/pricing.md Price list as markdown
- https://www.saltoftheearthnatural.com/.well-known/ard.json Agentic Resource Discovery catalog
- https://www.saltoftheearthnatural.com/.well-known/mcp/server-card.json MCP server card for the UCP endpoint
- https://www.saltoftheearthnatural.com/sitemap.xml Every indexable URL