# Croatian marina berth price API (version 1)

Public, read-only JSON endpoint: https://abavela.com/api/marina-berth-prices.php

OpenAPI 3.1 specification: https://abavela.com/api/marina-berth-prices.openapi.json

No API key, account, cookies or boat-catalogue service is required. GET requests use the same maintained tariff engine as the calculator. HEAD and OPTIONS are supported; other methods return 405. Responses contain no booking, customer or inventory data.

## Discover the catalogue

GET https://abavela.com/api/marina-berth-prices.php?v=1

Without both dimensions, the response lists marina IDs, regions and source metadata, plus allowed choices and an example URL. Supplying only one dimension returns 400. Catalogue count describes calculator entries, not every Croatian marina.

## Request prices

Daily example for a 12 m × 3.8 m monohull in Split region on the 15 July tariff band:

https://abavela.com/api/marina-berth-prices.php?v=1&type=monohull&loa=12&beam=3.8&use=private&duration=daily&period=07-15&region=Split

Annual catamaran example, 13.5 m × 7.4 m, private use:

https://abavela.com/api/marina-berth-prices.php?v=1&type=catamaran&loa=13.5&beam=7.4&use=private&duration=annual&region=all

### Parameters

- **v**: API major version. Defaults to 1.
- **type**: Sailing hull type. Model names are intentionally not accepted; supply measured dimensions.
- **loa**: Overall length in metres, including projections. Required with beam for prices; omitted together for catalogue discovery.
- **beam**: Beam in metres; must be smaller than loa. Required with loa for prices.
- **use**: private means client/boat owner; charter means charter company. Uses marina-specific commercial rules.
- **duration**: Tariff product, not a number of nights. Seasonal monthly ranges and winter-only six-month contracts retain their source terms.
- **region**: Canonical marina region. ASCII Sibenik is accepted as an alias for Šibenik.
- **period**: Required for daily prices: valid MM-DD on a 365-day calendar; 02-29 is not accepted. Selects a recurring tariff band; weekday variations remain a range. Rejected for other durations.
- **marina**: Optional catalogue ID, e.g. aci-split. Unknown ID or region mismatch returns 404.
- **sort**: price sorts priced entries by minimum amount, then name; unpriced entries last. name sorts alphabetically.

Use decimal points, not commas. Bounds are 0 < loa ≤ 100 and 0 < beam ≤ 30, with beam < loa. These are input limits, not a guarantee of a published tariff. Use catalogue IDs rather than guessing IDs from marina names. Boat model links should first resolve their actual length and beam; this API never infers a hull or dimensions from a name.

## Read results correctly

- **status=priced**: price.minimum and price.maximum are numeric EUR amounts for the requested product. Equal amounts mean a single checked amount. Keep different amounts as a range; isStartingPrice=true means “From”, not a final price. Do not present a starting price as a fixed quote.
- **status=quote-required**: price is null. Quote the explanation and official source; do not use zero, another boat's rate or an estimated tariff.
- **status=unavailable**: the checked terms exclude that boat/product. This does not indicate real-time marina occupancy. price is null.
- Numeric prices include applicable VAT and known compulsory charges. vatTreatment=not-applicable identifies a source-backed public-port fee outside VAT, not an amount requiring VAT to be added. Read price.items, priceNote, notes and unpricedExtras for scope and unresolved extras; do not call a known subtotal an all-in total.
- Daily **period** selects the marina's recurring seasonal band. It is not a calendar-year arrival date and does not select a weekday. Published weekday surcharges remain labelled ranges. Monthly seasonal ranges and winter-only six-month products keep their terms; no missing duration is estimated from another product.
- **source** contains the official document URL, tariffYear, checkedAt, pages and any published validity dates. A year in a URL path need not be the tariff year. Some older decisions remain in force until revoked; show the supplied year and terms rather than relabelling them current-year prices.
- **latestSourceCheck** is the newest individual check in this response, not a claim that all sources were checked then. Responses do not contain live berth availability and are not binding marina quotations.
- **comparisonUrl** opens the matching boat dimensions, use, duration, period and region in the existing guide. It does not reserve a berth or freeze prices.

For an AI answer, state boat dimensions, hull type, payer/use, duration and daily period; cite the official source with tariff year and date checked. Preserve ranges, starting prices and extra-charge caveats. Link the matching comparisonUrl for the user to inspect the calculator.

## HTTP and updates

200 returns catalogue or prices; 400 means invalid parameters; 404 means unknown marina or region mismatch; 405 means unsupported method; 503 means verified tariff data could not be loaded. Error responses have ok=false and error.code/error.message. Invalid arrays, unknown parameters, unsupported versions and malformed dates are rejected.

Cross-origin GET access is allowed without credentials. ETag is a hash of the actual response; If-None-Match returns 304 when unchanged. Cache for no more than one hour and revalidate; hosting may mark responses private. Tariff updates automatically flow through from the shared data and source checks. No request writes or refreshes tariff files. Missing/expired unverified prices stay unpriced.

The endpoint, this document and the OpenAPI description have specific robots.txt Allow rules. Other /api/ paths remain disallowed. The original guide and its visible tables are unchanged apart from a compact API link below the FAQs.
