Cannondale APIcannondale.com ↗
Access Cannondale's full bike catalog, detailed specs, geometry tables, variant pricing, and local dealer locations via a structured JSON API.
What is the Cannondale API?
The Cannondale API covers 6 endpoints that expose the full Cannondale product catalog — bikes, electric bikes, and gear — along with detailed specs, geometry by frame size, variant-level pricing and UPC codes, and nearby dealer locations. The get_bike_detail endpoint returns spec groups including Drivetrain, Frameset, Brakes, WheelsAndTires, and Electronics, plus a geometry object keyed by size and a variants array with SKU, color, price, sale price, and inventory status.
curl -X GET 'https://api.parse.bot/scraper/a3515044-41d4-44cf-a889-e3c49ca05dda/list_bikes?limit=5&offset=0' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace cannondale-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Cannondale SDK — browse bikes, drill into specs, find dealers."""
from parse_apis.cannondale_product_dealer_api import Cannondale, BikeNotFound
client = Cannondale()
# List electric bikes — limit= caps total items fetched.
for bike in client.bikes.list_electric(limit=3):
print(bike.name, bike.platform, bike.category)
# Search for a specific platform, take one result and drill into detail.
bike = client.bikes.search(query="SuperSix", limit=1).first()
if bike:
try:
detail = bike.details()
print(detail.name, detail.platform, detail.category)
for v in detail.variants[:2]:
print(v.sku, v.size, v.color, v.upc)
except BikeNotFound as exc:
print(f"Bike page gone: {exc}")
# Browse gear products.
for product in client.gearproducts.list(limit=3):
print(product.name, product.sub_category, product.salsify_id)
# Find nearby dealers.
for dealer in client.dealers.nearby(latitude="40.7128", longitude="-74.0060", limit=3):
print(dealer.name, dealer.city, dealer.address)
print("exercised: bikes.list_electric / bikes.search / bike.details / gearproducts.list / dealers.nearby")
List all bikes from the Cannondale catalog with pagination. Returns bikes across all categories (road, mountain, electric, etc.) with variant and tag information. Each bike includes a URL that can be passed to get_bike_detail for full specifications.
| Param | Type | Description |
|---|---|---|
| limit | integer | Number of results per page (max 250). |
| offset | integer | Starting index for results. Pagination is calculated as page = (offset / limit) + 1. |
{
"type": "object",
"fields": {
"bikes": "array of bike objects with name, platform, category, sub_category, salsify_id, url, description, model_year, is_electric, tags, badges, and variants",
"count": "integer number of bikes returned in this response",
"total": "integer total number of bikes in the catalog"
}
}About the Cannondale API
Catalog Endpoints
list_bikes returns the full Cannondale bicycle catalog with pagination — up to 250 results per call using limit and offset. Each bike object includes name, platform, category, sub_category, model_year, is_electric, tags, and a url field you pass directly into get_bike_detail. list_electric_bikes mirrors this structure but filters to the electric category only, useful when you need to isolate e-bike inventory. list_gear covers non-bike products — components, accessories, apparel, and lights — with the same paginated structure.
Search and Detail
search_products accepts a required query string and searches across model names, platforms, categories, and descriptions. It returns the same product shape as the catalog endpoints, so a result from a 'gravel' or 'SuperSix' query can feed directly into get_bike_detail. The detail endpoint returns structured specs broken into groups (Brakes, Components, Drivetrain, Frameset, WheelsAndTires, Electronics, GeneralInfo), a geometry object mapping each size to its measurements, and a variants array containing sku, size, color, upc, price, sale_price, and inventory.
Dealer Locator
get_dealers finds authorized Cannondale dealers near a latitude/longitude pair. It defaults to San Francisco (37.7749, -122.4194) but accepts any coordinates. An optional upc parameter — retrievable from a bike's variant data — filters results to dealers that stock that specific bike variant. Each dealer object includes id, name, address, city, lat, and lng. The radius parameter controls the approximate search area in km.
The Cannondale API is a managed, monitored endpoint for cannondale.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when cannondale.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official cannondale.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a bike comparison tool using
get_bike_detailgeometry and spec data across multiple models and sizes. - Power an e-bike finder by querying
list_electric_bikesand filtering bymodel_yearorsub_category. - Display in-stock local dealers for a specific bike variant by pairing a variant's
upcwithget_dealerscoordinates. - Index the full Cannondale catalog for a price-tracking tool using
variants.priceandvariants.sale_pricefromget_bike_detail. - Expose a gear and accessories search using
list_gearwith keyword filtering viasearch_products. - Generate size guides by extracting the
geometryobject fromget_bike_detailfor each frame size across a platform. - Sync SKU and UPC data from
variantsinto a POS or inventory management system.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Cannondale offer an official public developer API?+
What does `get_bike_detail` return that the list endpoints don't?+
get_bike_detail returns the full spec breakdown across groups (Brakes, Components, Drivetrain, Frameset, WheelsAndTires, Electronics, GeneralInfo), a geometry table keyed by frame size, and the complete variants array with per-variant SKU, UPC, price, sale_price, and inventory status. The list endpoints return summary fields only — name, category, platform, model_year, tags, and a URL — without specs or geometry.Can I filter `list_bikes` by category, platform, or model year?+
list_bikes returns all bikes with limit and offset pagination only; category-level filtering requires using list_electric_bikes for the electric segment or search_products with a keyword. You can fork this API on Parse and revise it to add category or model-year filter parameters.Does the API return user reviews or ratings for bikes?+
How does pagination work across the catalog endpoints?+
limit (max 250) and offset integer parameters. The effective page number is calculated as (offset / limit) + 1. Each response returns count (items in this response) and total (full catalog size), so you can determine how many additional calls are needed to paginate through all results.