# Developer & agent documentation

The public read-only JSON API, the OpenAPI description, the MCP server, and the Markdown content-negotiation contract.

## Overview

Ezy Decking publishes three read-only, public, unauthenticated surfaces for agents and developers: a JSON API, Markdown content negotiation on every page, and an MCP server. None of them needs a key, an account or an email address.

Everything they expose is already visible on the public website. They exist so an agent can read it in a tenth of the tokens and act on it without scraping HTML.

## Public JSON API

Base URL: https://ezydecking.com.au/api/v1

| Endpoint | Returns |
| --- | --- |
| GET /api/v1 | Service index linking every endpoint |
| GET /api/v1/categories | The five shop categories and their subcategories |
| GET /api/v1/products | Products, filterable by category, sub, q and limit |
| GET /api/v1/products/{handle} | One product with variants, SKUs, prices and availability |
| GET /api/v1/ranges | Decking ranges with per-board prices, specs and colours |
| GET /api/v1/branches | Branch addresses, opening hours and phone numbers |
| GET /api/v1/delivery/zone?postcode= | Delivery zone, fulfilling branch, lead time, base freight |
| GET /api/v1/delivery/zones | The whole delivery-zone table |
| GET /api/v1/freight/quote?postcode=&weightKg=&volumeM3= | Vehicle class and freight price for a load |
| GET /api/v1/status | Live per-surface health — never cached |

```sh
# Compare decking ranges on price and spec
curl -s https://ezydecking.com.au/api/v1/ranges

# Search the catalogue
curl -s "https://ezydecking.com.au/api/v1/products?category=decking&limit=5"

# Will we deliver to this postcode, and how long?
curl -s "https://ezydecking.com.au/api/v1/delivery/zone?postcode=4211"
```

Prices are in AUD and include 10% GST. Every price returned is retail — trade pricing exists but is only visible to approved accounts signed in on the website.

- OpenAPI 3.1 description: https://ezydecking.com.au/openapi.json
- RFC 9727 API catalog: https://ezydecking.com.au/.well-known/api-catalog
- CORS is open (`Access-Control-Allow-Origin: *`) on every endpoint.

## Errors

Every error is an RFC 9457 `application/problem+json` document carrying a stable `code`, a human `detail`, and a `resolution` sentence describing what to do differently.

```json
{
  "type": "https://ezydecking.com.au/developers#errors",
  "title": "Postcode not in a served delivery zone",
  "status": 404,
  "detail": "Postcode 6000 is outside every Ezy Decking delivery zone.",
  "instance": "https://ezydecking.com.au/api/v1/delivery/zone?postcode=6000",
  "code": "unknown_postcode",
  "resolution": "We deliver to QLD, NSW, ACT, VIC and SA. Call 0424 341 353 to ask about a one-off freight quote elsewhere.",
  "documentation_url": "https://ezydecking.com.au/developers#errors"
}
```

| Status | When |
| --- | --- |
| 400 | A parameter is missing or malformed |
| 404 | No such product, or a postcode outside every served zone |
| 405 | A write verb — this API is read-only |
| 406 | The client rejected both `text/html` and `text/markdown` |
| 429 | Rate limit exceeded; `Retry-After` says how long to wait |
| 503 | The catalogue is temporarily unreachable |

## Rate limits

120 requests per client IP per 60 seconds. Every response carries the IETF `RateLimit-Policy` and `RateLimit` structured fields so you can pace requests instead of discovering the limit by hitting it.

```http
RateLimit-Policy: "public";q=120;w=60
RateLimit: "public";r=118;t=42
```

The limiter counts per compute instance rather than globally, so treat the published figure as a guaranteed floor rather than an exact budget. A `429` always includes `Retry-After`.

## Markdown content negotiation

Every public page serves a Markdown representation from the same URL, following the acceptmarkdown.com convention.

```sh
curl -s -H "Accept: text/markdown" https://ezydecking.com.au/delivery

# Or without a header — append .md to any path
curl -s https://ezydecking.com.au/delivery.md
```

- Markdown responses set `Content-Type: text/markdown; charset=utf-8` and `Vary: Accept`.
- Quality values are honoured, and a more specific media range beats a wildcard regardless of q (RFC 9110 §12.5.1).
- A client that rejects both `text/html` and `text/markdown` gets `406 Not Acceptable`, not a guess.
- The whole site as one document: https://ezydecking.com.au/llms-full.txt
- The site index with when-to-use guidance: https://ezydecking.com.au/llms.txt

## MCP server

Connect a Streamable HTTP MCP client to https://ezydecking.com.au/mcp. No authentication, no session setup.

| Tool | What it does |
| --- | --- |
| ezy_decking_search_products | Search Ezy Decking's live product catalogue by free text, category or subcategory. |
| ezy_decking_get_product | Fetch one product by its handle, with every variant — colour, board length, SKU, price in AUD (GST-inclusive) and whether it is available. |
| ezy_decking_decking_ranges | List every composite/PVC decking range with its price per board by length, board and joist-spacing spec, and available colours. |
| ezy_decking_check_delivery | Resolve a four-digit Australian postcode to its Ezy Decking delivery zone, the branch that fulfils it, the delivery lead time in business days and the base freight price. |
| ezy_decking_quote_freight | Given a destination postcode and a load's total weight (kg) and volume (m³), return the vehicle class required (van, 4t truck or 6t truck) and the indicative freight price in AUD. |
| ezy_decking_branches | Return every Ezy Decking location with its address, opening hours and phone number — Gold Coast, Brisbane display, Sydney and Adelaide. |
| ezy_decking_categories | Return the five top-level shop categories and their subcategories with the URL for each. |

```sh
curl -s -X POST https://ezydecking.com.au/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

- Every tool is read-only and idempotent. None places an order or writes anything.
- Server card: https://ezydecking.com.au/.well-known/mcp/server-card.json
- Registry manifest: https://ezydecking.com.au/server.json
- AI catalog: https://ezydecking.com.au/.well-known/ai-catalog.json
- Installable agent skill: https://ezydecking.com.au/.well-known/agent-skills/index.json

## Authentication, writes and webhooks

There are none, deliberately. These surfaces are public and read-only, so API keys, OAuth scopes, pagination cursors, `Idempotency-Key`, asynchronous jobs, webhooks and event subscriptions do not apply.

Orders, sample requests, trade applications and warranty registrations are completed by a person on the website. If a user wants one of those, hand them the link rather than attempting the form — the flows need a human, and the API will not accept them.

## Versioning and deprecation policy

Stable operations live under `/api/v1`. A breaking change gets a new major path; `v1` is never mutated in place. Adding a field is not a breaking change, so parse defensively and ignore what you do not recognise.

When an operation is going away it is announced in the response itself, not only in prose here, so a running client finds out without anyone reading a changelog:

- **`Deprecation`** (RFC 9745) appears on every response from a deprecated operation, carrying the date the deprecation took effect.
- **`Sunset`** (RFC 8594) carries the date the operation stops responding. There is at least **6 months** between the two.
- **`Link: rel="deprecation"`** points at the section of this page explaining what to use instead.
- Nothing is currently deprecated, so no `Deprecation` or `Sunset` header is being sent today.

```http
HTTP/1.1 200 OK
Deprecation: @1780272000
Sunset: Wed, 01 Jul 2026 00:00:00 GMT
Link: <https://ezydecking.com.au/developers#versioning-and-deprecation>; rel="deprecation"
```

A removed major version answers `410 Gone` with a problem document whose `resolution` names its replacement — never a silent `404`.

Questions, or something wrong in the data? Email sales@ezydecking.com.au or call 0424 341 353.

---

Source: [Ezy Decking](https://ezydecking.com.au/developers) · Machine-readable index: [/llms.txt](https://ezydecking.com.au/llms.txt) · Public API: [/api/v1](https://ezydecking.com.au/api/v1) · Sitemap: [/sitemap.xml](https://ezydecking.com.au/sitemap.xml)
Prices in AUD and GST-inclusive. Phone 0424 341 353 · sales@ezydecking.com.au