Expand description
Motor stock and prices from motor.fusionspace.co’s public API.
The motor finder lists every AeroTech, Cesaroni and Loki motor that a dozen U.S. vendors carry,
with each vendor’s stock and price. Its API is a handful of static JSON files, rebuilt
about hourly, with no key, no rate limit and no query parameters: a client fetches a whole file
and filters it itself. The files are Endpoint::Meta (when the data was built, and counts),
Endpoint::Motors (every motor some vendor lists, D class and up), Endpoint::InStock
(the same, only those in stock at one vendor or more), Endpoint::Vendors, and one motor’s
page (Endpoint::motor). Prices are whole cents; a listing’s unit price is its sticker
price over its pack size. The motor data itself (classes, impulses, delays) comes from
ThrustCurve.org, and designations are spelled as ThrustCurve spells them.
parse_meta, parse_motors, parse_in_stock, parse_vendors and parse_motor
read an answer, refusing one of another schema version, one whose count disagrees with its
list, and a motor or listing that breaks the API’s own rules (a pack of no motors, a unit price
over the sticker price, a cheapest offer on a motor out of stock). The fetch_ functions ask a
Client for the file, so the answer comes from the cache when it can, and offline from the
cache only; an answer that doesn’t parse is never cached. Stock moves by the hour, so a copy
stays fresh for TTL_S, an hour. Show ATTRIBUTION (it is on every Fetched) wherever
a price or stock is shown: the API’s data license, CC BY 4.0, asks for the credit “Motor stock
data from motor.fusionspace.co”, and its terms say to check stock and price on the vendor’s
own page before relying on them.
How far to trust it: a value is the answer’s, unchanged, bar a listing status the API adds
later (tests/motor_finder.rs reads every field of every recorded answer back). Whether a vendor really has a motor, at that price,
is the vendor’s to say: the finder reads their public listings, up to about an hour old when it
builds its files, and a fresh cached copy may be an hour older again. One value that breaks a
rule refuses the whole file, so the last good copy is kept; a cheapest offer with no price,
which the API allows, and a listing status it adds later (read as
ListingStatus::Unknown) are read.
use hpr_net::motor_finder;
// The in-stock list as recorded on 2026-10-01 at 07:07 UTC.
let body = include_bytes!("../tests/fixtures/replay/motor-finder-in-stock.json");
let list = motor_finder::parse_in_stock(body)?;
let l_class: Vec<_> = list.motors.iter().filter(|m| m.impulse_class == "L").collect();
assert_eq!((list.motors.len(), l_class.len()), (282, 20));Structs§
- Counts
Meta’s counts.- Listing
- One vendor’s listing of a motor.
- Meta
meta.json: when the data was built, and how much there is.- Motor
- A motor, with every vendor’s listing of it.
- Motor
List motors.jsonorin-stock.json.- Motor
Name - A motor’s manufacturer and designation, checked by
Endpoint::motorso its page’s URL stays in the API’smotors/folder. Its fields are private, so it can’t be changed past the checks. - Motor
Page - One motor’s page,
motors/{manufacturer}/{designation}.json. - Offer
- The cheapest in-stock offer of a motor: the in-stock listing with the lowest unit price. The API’s schema lets its prices be null; no recorded offer has them so.
- Vendor
- A vendor the finder reads.
- Vendor
List vendors.json.
Enums§
- Endpoint
- One of the API’s files.
- Hazmat
- Whether a motor ships as hazardous material (U.S. DOT), as the site labels it from the
propellant’s weight. Its API describes the labels as “required (>62.5g or H+), varies (F/G near
the limit — vendor-dependent), none (<=62.5g, A-E)”. On the 2026-10-01 recording, every D and
E motor is
NotRequiredand every H and upRequired; F and G motors areVaries(75) orRequired(29). - Listing
Status - A listing’s stock. A status the API adds later reads as
ListingStatus::Unknown, so one new word doesn’t refuse the whole list. - Motor
Finder Error - Why a motor finder request or answer was refused.
- Motor
Type - How a motor is built.
Constants§
- ATTRIBUTION
- The credit the API’s data license asks for, in its words (“Motor stock data from motor.fusionspace.co”), with the license, CC BY 4.0, and the API’s caution about stock and price.
- BASE_
URL - The API’s base URL, version 1.
- MANUFACTURERS
- The manufacturers the API lists: each one’s name as the API writes it, and the slug its motors’ pages sit under.
- SCHEMA_
VERSION - The schema version this module reads. A breaking change ships under a new path (
/api/v2/), so an answer of another version is refused. - TTL_S
- How long a cached answer counts as fresh, s: an hour, as often as the site rebuilds the files.
Functions§
- fetch_
in_ stock - Fetches
in-stock.jsonthroughclient, asfetch_metadoes. - fetch_
meta - Fetches
meta.jsonthroughclient. - fetch_
motor - Fetches one motor’s page through
client, asfetch_metadoes: the motor, and when its page was built. A page for another motor than the one asked for is refused, and never cached. - fetch_
motors - Fetches
motors.jsonthroughclient, asfetch_metadoes. - fetch_
vendors - Fetches
vendors.jsonthroughclient, asfetch_metadoes. - parse_
in_ stock - Reads
in-stock.json: asparse_motors, and every motor must be in stock. - parse_
meta - Reads
meta.json. - parse_
motor - Reads one motor’s page.
- parse_
motors - Reads
motors.json. - parse_
vendors - Reads
vendors.json. - unix_s
- Seconds since the Unix epoch of an ISO 8601 UTC time as the API writes it,
YYYY-MM-DDTHH:MM:SSfollowed byZor+00:00, with optional fractional seconds dropped;Nonefor anything else.