Back to every bean

The data.

Every bag on this site, as JSON, free and open. Static files rebuilt once a night — no key, no rate limit, no sign-up. If you are an AI agent, start at /llms.txt.

360 bags of specialty coffee from 13 New Zealand roasters, re-checked every night; last read 23 Aug 2026 at 23:25 UTC. The cheapest bag in stock is Brown Lightning from Raglan Roast at $4.60 per 100g ($92.00 for 2000g). Of retail-sized bags (500g or under) it is Brown Lightning from Raglan Roast, 500g at $5.20 per 100g. No price has moved since we started watching on 18 Aug 2026, so there is no cut to report — an empty answer, not a missing one. 3 bags arrived since we started, most recently CASCADIA ORGANIC DECAF from Ozone Coffee Roasters. Every one of them is in stock right now. Prices are the roasters' own; we read them, we do not set them.

ENDPOINTS
URLWhatShape
/api/beans.jsonEvery bag we track, cheapest per 100g first.beans[] of Bean.
/api/deals.jsonPrice cuts, new arrivals and the cheapest shelf — each row carrying the sentence that says why it is there.price_cuts, just_dropped, cheapest_per_100g, each {count, items[], empty, method}, plus summary.
/api/roasters.jsonThe roasters we track, their shipping terms and where they roast.roasters[] of Roaster.
/api/schema.jsonJSON Schema for all three.Draft 2020-12.
/api/openapi.jsonThe same, as OpenAPI 3.1.For agents and MCP wrappers that read specs.
/llms.txtWhat this site is, in the emerging convention.Markdown, at the root.

One scrape a night at 15:40 UTC (about 03:40 in New Zealand), then the whole site and every endpoint is rebuilt.

ON EVERY PAYLOAD
FieldMeans
generated_atWhen this file was built. UTC, ISO-8601.
next_update_afterNothing in it changes before this. UTC.
currencyAlways NZD. We do not convert.
citationHow to credit us, if you quote us.
termsThe one paragraph that governs all of it.
disclosureWhat our outbound links are and what we earn from them.
BEAN

One bag, in /api/beans.json and in every list in /api/deals.json.

FieldTypeMeans
idstringStable id, `<roaster-slug>:<product>-<weight>`. Survives price changes.
roasterstringThe roaster's name, as they write it.
roaster_slugstringTheir key here, and the last part of their page URL.
roaster_urlstringShort link to their shop's home page, on our domain.
namestringThe coffee's name, as the roaster writes it.
urlstringWhere to send a reader: a short link on our domain that redirects to the roaster's product page and counts the click.
shop_urlstringThe roaster's own product page, unredirected — so you can see exactly where `url` lands.
pagestringOur page for this roaster, where this bag is listed.
price_nzdnumber|nullShelf price in NZD. Null when we could not read one.
weight_ginteger|nullBag weight in grams. Null when the roaster does not state it.
price_per_100gnumber|nullShelf price per 100g. Null when price or weight is null.
in_stockbooleanWhether the roaster showed it as available at the last check.
originstring|nullCountry or region, where the roaster names one.
roast_stylestring|null`espresso`, `filter` or `omni`, from the roaster's own words.
roast_levelstring|nullLight/medium/dark, only where the roaster states it.
flavour_notesarray<string>The roaster's own tasting notes, verbatim.
flavoursarray<string>Those notes mapped onto our 18-key flavour vocabulary.
shippingobjectWhat it costs to get this bag to a door — see `shipping` below.
first_seenstringISO-8601 UTC. When WE first saw it, not when the roaster listed it.
last_seenstringISO-8601 UTC. The last check that found it.
last_price_changestring|nullISO-8601 UTC of the last price MOVE. Null means it has never moved since we started watching — not that we have no history.
previous_price_nzdnumber|nullWhat it cost before that move. Null if it has never moved.
SHIPPING

The `shipping` object on a Bean: what it costs to get THAT bag to a door.

FieldTypeMeans
publishedbooleanWhether the roaster publishes a rate outside checkout. Four of thirteen do not.
free_over_nzdnumber|nullOrder total they ship free at, where they publish one.
flat_nzdnumber|nullTheir flat rate below that, where they publish one.
flat_variesbooleanTrue where the rate depends on the island; `flat_nzd` is then the cheaper.
ships_freebooleanWhether this single bag already clears their free-shipping threshold.
delivered_price_nzdnumber|nullThis bag at the door: price plus shipping.
delivered_price_exactbooleanFalse when `delivered_price_nzd` is a FLOOR — the roaster publishes no rate, so the true price is this or more. Never treat a floor as a price.
sourcestring|nullThe roaster page a human read the terms off.
notestring|nullTheir terms in their own words, where they publish any.
last_verifiedstring|nullThe day a human last read that page. Nothing re-checks it.
ROASTER

One roaster, in /api/roasters.json.

FieldTypeMeans
slugstringTheir key here.
namestringTheir name.
urlstringShort link to their shop, on our domain (redirects, counts).
shop_urlstringTheir own URL, unredirected.
pagestringOur page for them.
bean_countintegerBags of theirs we are tracking. One per size, so a coffee sold in three sizes counts three.
coffee_countintegerDistinct coffees behind those bags, sizes collapsed. Never more than `bean_count`.
cheapest_per_100gnumber|nullTheir cheapest bag per 100g.
last_checkedstring|nullISO-8601 UTC of our last successful read of their shop.
okbooleanWhether that last read succeeded.
stalebooleanTrue when we have not managed to check them for 3 days.
citystring|nullWhere they roast, where we have confirmed it.
placestring|nullSuburb and city, as one line.
latnumber|nullLatitude, for distance sorting. Null where we could not confirm one.
lngnumber|nullLongitude.
location_sourcestring|nullThe page a human read the address off.
shippingobjectTheir published shipping terms — see `terms`.
TERMS

The `shipping` object on a Roaster: what they publish, not what a bag costs.

FieldTypeMeans
publishedbooleanWhether they publish a rate outside checkout. Four of thirteen do not.
free_over_nzdnumber|nullOrder total they ship free at, where they publish one.
flat_nzdnumber|nullTheir flat rate below that, where they publish one.
flat_variesbooleanTrue where the rate depends on the island; `flat_nzd` is then the cheaper.
sourcestring|nullThe roaster page a human read the terms off.
notestring|nullTheir terms in their own words, where they publish any.
last_verifiedstring|nullThe day a human last read that page. Nothing re-checks it.
WHAT WE REFUSE TO CLAIM
USING IT

Prices, weights and stock are the roasters' own, read from their public shop pages and re-checked every night. We do not set them, mark them up, or estimate them: a figure we could not read is null. Free to quote with attribution and a link.

Cite as: Coffee Addict — every specialty coffee bean on sale in New Zealand, priced per 100g and re-checked every night. https://coffeeaddict.nz