Sheds and portable buildings (configure and price)
Price a portable building the way its maker's own 3D configurator does — give a size in feet and a zip and get the real regional price for every style…
Price a portable building the way its maker's own 3D configurator does — give a size in feet and a zip and get the real regional price for every style that builds it, the exact siding surcharge rather than a guessed range, a real product image and spec for each one, and the link to go order it. Plus the maker's real dealer locations by state.
Also known as: shed, portable building, storage building, barn, lofted barn, cabin, garage, carport, outbuilding, backyard building
Call it
bowmark.sheds.quote(request: ShedQuoteRequest, options?: CallOptions): Promise<ShedQuoteResult>
bowmark.sheds.listStyles(options?: CallOptions): Promise<ShedStylesResult>
bowmark.sheds.findDealers(state: string, options?: CallOptions): Promise<ShedDealerResult>Functions
| Function | What it does |
|---|---|
quote | Prices a building at a real size for a real zip, exactly the way the maker's own configurator does — the regional base price plus the EXACT siding surcharge its rules apply at that width… |
listStyles | Lists every building style each maker actually offers — its customer-facing name, the siding it can be built in, every real buildable size in FEET, and what the building IS (a real product… |
findDealers | Looks up the real places that sell a maker's buildings in one US state or Canadian province — full name ("Tennessee") or abbreviation ("TN") — with name, city, phone and the dealer's own… |
Types
type ShedSize = {
sizeKey: string // the maker's own key; opaque, meaningful only to source
widthFt: number // FEET, always — the maker's own units are converted away
lengthFt: number
}
type ShedStyle = {
source: string // which maker — a provider id
brand: string // the maker's brand name, for an answer that names who builds it
key: string // the maker's own style key
label: string // the style as a customer sees it ("Lofted Barn")
sidingOptions: string[] // siding keys; the first is the maker's standard
sizes: ShedSize[]
imageUrl: string | null // a real product image from the maker's own catalogue
roofStyle: string | null // "gable", "gambrel", ...
roofing: string | null // "metal", ...
wallHeight: string | null // the maker's own spec, verbatim, e.g. "left-78-right-78-eave-72"
}
type ShedStylesResult = {
styles: ShedStyle[]
warnings: string[] // always present; a maker named here returned NOTHING
}
type ShedQuoteRequest = {
widthFt: number // in feet, as a person says it — "a 12 by 20"
lengthFt: number
zip: string // required; every maker prices regionally
style?: string // style key OR its customer-facing name, matched loosely.
// Omit to price EVERY style that builds the size
siding?: string // omit for the maker's standard siding
}
type ShedQuote = {
source: string
brand: string
styleKey: string
style: string // "Lofted Barn"
model: string | null // the maker's model name, where it has one
widthFt: number
lengthFt: number
siding: string // the siding key this was priced in
zip: string
region: string // the maker's own pricing region that zip fell under
basePrice: number
sidingSurcharge: number // what the siding added, by the maker's rules; 0 for standard
total: number // basePrice + sidingSurcharge, the maker's own arithmetic
currency: string
imageUrl: string | null // what the building looks like, from the maker's catalogue
roofStyle: string | null // "gable", "gambrel", ...
roofing: string | null // "metal", ...
wallHeight: string | null // the maker's own spec, verbatim
orderUrl: string // where to go order THIS build, always present
}
type ShedQuoteResult = {
quotes: ShedQuote[] // cheapest first, across every maker that builds the size
warnings: string[] // always present; names a dropped maker, a style that does
// not build the size, and a capped fan
}
type ShedDealer = {
source: string
brand: string
name: string
city: string
state: string
zip: string
phone: string | null // null when the directory lists none (never "")
url: string
}
type ShedDealerResult = {
dealers: ShedDealer[]
warnings: string[]
}
type CallOptions = {
timeoutMs?: number // per-provider budget in ms, default 30000, clamped to 1000-55000.
// A provider slower than this is DROPPED from the results and
// NAMED in warnings — never silently absent
}Examples
// The question a person actually asks: what does a 12x20 shed cost near me.
// No style key, no maker's units — a size in feet and a zip.
const { quotes, warnings } = await bowmark.sheds.quote({ widthFt: 12, lengthFt: 20, zip: "38257" });
for (const w of warnings) log(w);
const cheapest = quotes[0];
if (!cheapest) return { priced: false, warnings };
log(`${quotes.length} builds priced, from $${cheapest.total} (${cheapest.brand})`);
return {
from: cheapest.total,
style: cheapest.style,
region: cheapest.region,
orderAt: cheapest.orderUrl,
all: quotes.map(q => ({ style: q.style, brand: q.brand, total: q.total })),
};// What the siding upgrade actually costs, which is the number a price sheet
// never carries: price the same building twice and subtract.
const base = await bowmark.sheds.quote({ widthFt: 12, lengthFt: 24, zip: "38257", style: "lofted barn" });
const metal = await bowmark.sheds.quote({ widthFt: 12, lengthFt: 24, zip: "38257", style: "lofted barn", siding: "metal" });
const a = base.quotes[0], b = metal.quotes[0];
if (!a || !b) return { comparable: false, warnings: [...base.warnings, ...metal.warnings] };
return { standard: a.total, metal: b.total, upgrade: b.total - a.total, region: a.region };Providers behind it
| Provider | |
|---|---|
premierbuildings | Premier Portable Buildings |