Fuelsoft APIbalcas.fuelsoft.co.uk ↗
Get live delivered wood-pellet prices, product listings, delivery options, and schedules for any UK postcode from Balcas Energy via two REST endpoints.
What is the Fuelsoft API?
The Balcas Fuelsoft API gives programmatic access to Balcas Energy's online ordering data through 2 endpoints. Call get_quote to retrieve the current delivered price for a specific product, postcode, and quantity — broken down by delivery schedule — and call list_products to enumerate every available product, its quantity constraints, delivery options, and date windows for a given UK postcode.
curl -X GET 'https://api.parse.bot/scraper/e9807280-5280-4631-983b-2e2b56cd55eb/get_quote?postcode=CA11+8HP&quantity=5&product_code=BAGG1x50' \ -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 balcas-fuelsoft-co-uk-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: Balcas Fuelsoft wood-pellet quote API."""
from parse_apis.balcas_fuelsoft_co_uk_api import (
BalcasFuelsoft, ProductType, InputNotFound,
)
client = BalcasFuelsoft()
# Discover what products and delivery schedules are available for a postcode.
catalog = client.product_catalogs.get(postcode="CA11 8HP")
print(f"Area {catalog.area_code} — currency {catalog.currency}")
for product in catalog.products:
print(f" {product.product_code}: {product.name} "
f"({product.min_quantity}–{product.max_quantity} {product.unit})")
for schedule in catalog.delivery_schedules:
print(f" {schedule.option}: {schedule.delivery_from} → {schedule.delivery_by}")
# Filter to bulk products only.
bulk_catalog = client.product_catalogs.get(postcode="CA11 8HP", product_type=ProductType.BULK)
print(f"Bulk products: {len(bulk_catalog.products)}")
# Get a delivered price quote for the first product at its minimum quantity.
product = catalog.products[0]
try:
price_quote = catalog.quote(
quantity=product.min_quantity,
product_code=product.product_code,
)
except InputNotFound:
print("Postcode or product not recognised by the site.")
else:
print(f"Quote for {price_quote.quantity} {product.unit} of {product.product_code} "
f"to {price_quote.postcode}:")
for line in price_quote.quotes:
print(f" {line.delivery_schedule.option}: "
f"goods £{line.goods} + VAT £{line.vat} + carriage £{line.carriage} "
f"= £{line.total}")
print("exercised: product_catalogs.get / catalog.quote")
Returns the site's current delivered price quote for one product at one UK postcode and quantity. Quantity is in the product's own unit: tonnes for the bulk pellet product (default product BULKG1, sold in 0.5 tonne steps between its min and max), or number of packs for bagged products. The result is an object with the resolved product (including the min/max quantity the site accepts), and a `quotes` array with one row per delivery schedule the site priced, each carrying unit price, goods, VAT, carriage and total in the response currency (GBP for UK postcodes). Prices are only valid at the time of the request. A quantity outside the product's range, an unknown product code, or a postcode the site does not deliver to returns a 422 with a message; `quotes` is empty only when the site itself declines to quote the address. Costs about six upstream round trips.
| Param | Type | Description |
|---|---|---|
| postcoderequired | string | UK postcode, e.g. CA11 8HP (space optional, case-insensitive). |
| quantityrequired | number | Order quantity in the product's unit (tonnes for BULKG1; packs for bagged products). Must fall within the product's min_quantity..max_quantity as reported by list_products. |
| product_code | string | Product to price, from list_products.products[*].product_code (case-insensitive). Omitted = the bulk 6mm pellet product. |
| delivery_option | string | Delivery option code from list_products.delivery_options[*].delivery_option. Omitted = the site's first (standard) option. |
{
"type": "object",
"fields": {
"quotes": "array of priced rows, one per delivery schedule: quote_id (nullable), product_code, product_name, quantity, unit, currency, price_per_unit, goods, goods_vat, carriage, carriage_vat, vat, total, delivery_option, delivery_schedule {schedule_code, option, days, delivery_from, delivery_by, excluded_products}",
"product": "object: product_code, name, details (nullable), product_type, unit, min_quantity, max_quantity, quantity_step, pack_size_tonnes",
"postcode": "normalised postcode that was priced",
"quantity": "number, quantity priced in the product unit",
"area_code": "site delivery-area code the postcode resolved to",
"delivery_option": "delivery option code used"
},
"sample": {
"data": {
"quotes": [
{
"vat": 86,
"unit": "TONNES",
"goods": 1720,
"total": 1806,
"carriage": 0,
"currency": "GBP",
"quantity": 5,
"quote_id": "b6ec7bb1-7d26-42be-ae71-9c0243fd9e22",
"goods_vat": 86,
"carriage_vat": 0,
"product_code": "BULKG1",
"product_name": "Bulk Wood Pellets 6mm <10% Moisture Unit: Tonnes",
"price_per_unit": 344,
"delivery_option": "Web_Normal_Tanker",
"delivery_schedule": {
"days": 7,
"option": "7 working days",
"delivery_by": "23-Sep-2026",
"delivery_from": "14-Sep-2026",
"schedule_code": "Web 7 Days",
"excluded_products": [
"BAGG1x50",
"BAGG1x75",
"BAGG1x96"
]
}
}
],
"product": {
"name": "Bulk Wood Pellets 6mm <10% Moisture Unit: Tonnes",
"unit": "TONNES",
"details": "6mm pellet - moisture < 10%",
"max_quantity": 8,
"min_quantity": 3,
"product_code": "BULKG1",
"product_type": "BULK",
"quantity_step": 0.5,
"pack_size_tonnes": 1
},
"postcode": "CA11 8HP",
"quantity": 5,
"area_code": "055",
"delivery_option": "Web_Normal_Tanker"
},
"status": "success"
}
}About the Fuelsoft API
What the API covers
Both endpoints are scoped to a UK postcode. list_products resolves the postcode to a Balcas delivery area_code and returns the full product catalogue available there: each product entry includes product_code, name, product_type (bulk or bagged), unit, min_quantity, max_quantity, quantity_step, and pack_size_tonnes. It also returns the available delivery_options (each with a code and display name) and the delivery_schedules for that area, including delivery_from/delivery_by date windows and any excluded_products per schedule. An optional product_type parameter narrows results to bulk or bagged pellets only.
Pricing with get_quote
get_quote prices a single product at a postcode and quantity. The required inputs are postcode and quantity (in the product's own unit — tonnes for the bulk 6mm pellet product BULKG1, or pack count for bagged products). The optional product_code parameter selects a non-default product from the codes returned by list_products; the optional delivery_option parameter selects a specific delivery tier. The response contains a quotes array with one row per eligible delivery schedule, each row carrying quote_id, product_code, product_name, quantity, unit, currency, and price fields. The response also echoes the normalised postcode, area_code, quantity, and the product object with its full constraint metadata.
Quantity rules and constraints
For the bulk pellet product, quantity is in tonnes and must fall within the product's min_quantity–max_quantity range in steps of quantity_step (0.5 tonne increments). For bagged products, quantity is the number of packs. Both sets of limits are returned by list_products before you call get_quote, so you can validate inputs client-side without an extra round-trip.
The Fuelsoft API is a managed, monitored endpoint for balcas.fuelsoft.co.uk — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when balcas.fuelsoft.co.uk 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 balcas.fuelsoft.co.uk 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?+
- Embed a live wood-pellet price checker on a heating installer's website using get_quote for any UK postcode and tonnage
- Build a bulk-buy optimisation tool that iterates over quantity steps from min_quantity to max_quantity to find the best per-tonne price
- Alert users when a delivery schedule's delivery_by date moves by polling list_products for schedule changes at their postcode
- Compare delivered prices across multiple UK postcodes to help haulage or agricultural businesses choose a delivery address
- Filter list_products by product_type to show only bagged pellet options and their pack-based quantity limits in a product catalogue
- Monitor area_code coverage for a postcode to determine whether Balcas delivers to a new depot location
- Integrate delivery_from and delivery_by windows into a procurement calendar for biomass heating projects
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.