Methodology
PaxExact estimate contract v1: public vocabulary
The closed vocabularies behind every PaxExact estimate — pricing, quantity, totals, and API states — defined in one place for reference and verification.
·
In short
PaxExact's estimate contract, version paxexact-estimate-v1, defines a small set of closed vocabularies used on every estimate: pricing_state, source_class and reason codes for line pricing; quantity_state and review_state for quantities; and completeness, tax_state, valuation_state and approval_state for totals. API keys carry an environment prefix (pxk_live_ or pxk_test_) and every authenticated response reports its rate-limit headroom.
- The contract version is the string paxexact-estimate-v1; it changes only for a breaking change to these vocabularies, never for an additive field.
- pricing_state is one of PRICED, UNPRICED, INSUFFICIENT_DATA, or STALE — never a bare number standing in for one of these.
- source_class is one of CATALOG, OWN_DATA, MANUAL, or UNVERIFIED, describing what kind of evidence produced an effective price.
- completeness is COMPLETE, INCOMPLETE_UNPRICED, or EMPTY, and governs whether a total is final, PARTIAL, or null.
- An API key's environment (live or sandbox) is encoded in its own prefix — pxk_live_ or pxk_test_ — so environment can never be mismatched between a key and the data it reaches.
- Every authenticated API response reports its own rate-limit headroom via X-RateLimit-* headers.
What this page is
This page lists the closed vocabularies that make up PaxExact's public estimate contract — the fixed sets of values a line item, a quantity, or a total can carry, and what each value means. It is a reference for verification, not a tutorial: anyone checking a specific PaxExact claim on this site, or reading a PaxExact API response, can use this list to confirm what a given field is allowed to say and what that value means in plain terms.
The contract has a version string, paxexact-estimate-v1, reported on every estimate response. It changes only when one of these vocabularies changes in a way that would break an existing integration — adding a new, additive field never bumps it. Treat the vocabularies below as the ones in force under that version.
An estimate is built from a small set of named scope records: a project (the estimate itself), rooms within it, and line items within each room. Each of these carries the pricing and quantity vocabularies described below wherever a price or a quantity applies, and the totals vocabulary rolls up at both the room and the project level.
Pricing vocabulary
Every priced or unpriced line item carries a pricing_state: PRICED (a price is in effect and current), UNPRICED (no usable price — never reported as zero), INSUFFICIENT_DATA (relevant evidence exists but falls short of PaxExact's own floor for reporting a number), or STALE (a price is in effect, but its basis — a catalog version or a set of observations — is no longer current).
When a price is in effect, source_class says what produced it: CATALOG (a managed price list), OWN_DATA (PaxExact's own accumulated observations, requiring at least two distinct projects), MANUAL (a person typed the figure), or UNVERIFIED (a legacy row of unrecorded origin that still counts but is flagged and never used as evidence).
When a line has no usable price, a reason_code explains why. The reason codes most relevant to a pricing check are UNKNOWN_PRICING_CODE (the code isn't in the catalog), INVALID_UNIT (the unit doesn't match the code), NO_UNIT (a coded line has no unit to price against), NO_GEOGRAPHY (no pricing region was set), INSUFFICIENT_SAMPLES (observations exist but from fewer than the required distinct projects), and CATALOG_MISS_NO_OBSERVATIONS (no catalog price and no observations at all).
Two rules of authority sit alongside these states rather than inside them: a human-entered (MANUAL) price always outranks an own-data suggestion, which stays visible but is never silently applied over it; and applying a pricing code always lets a catalog resolution override whatever number a client sent in the same request, reported back as source_class: CATALOG.
Quantity and review vocabulary
Every quantity carries a quantity_state — CURRENT, SUGGESTED, or STALE — describing whether the facts behind it are up to date, and a review_state — approved, suggested, or stale — describing what a human has done with it. A quantity also records who proposed it, a person or the system, so a reviewer can see at a glance which figures still need a human decision.
These two fields are reported separately rather than merged into one status because they answer different questions: quantity_state says whether the underlying facts have moved, and review_state says whether a person has acted on the quantity as it currently stands. A stale quantity blocks a silent edit outright; PaxExact's contract returns a 409 response rather than accepting a write against facts that are no longer current.
Totals vocabulary
An estimate's totals report completeness as COMPLETE, INCOMPLETE_UNPRICED, or EMPTY. The total itself is null when nothing priced counts, and reported as PARTIAL whenever completeness is anything other than COMPLETE.
Totals also report tax_state (APPLIED when the estimate carries a sales-tax rate the professional entered, NOT_APPLIED when it does not — there is no rate lookup or jurisdiction model), valuation_state (RCV_ONLY_NOT_DEPRECIATED today — every total is a replacement-cost figure; depreciation and actual cash value are not yet computed), and approval_state (ALL_REVIEWED or PENDING_REVIEW, describing whether every line has cleared human review). Alongside these, a total reports how many lines are counted, priced, and unpriced, so the vocabulary above can be checked against the actual line counts that produced it.
Environments and API keys
An organization's API key encodes its environment directly in its prefix: a live key begins pxk_live_ and can only see and create live estimates; a sandbox key begins pxk_test_ and is confined to sandbox estimates. The two environments never cross — sandbox data is never treated as evidence for pricing or reporting, and a key's environment cannot be reassigned by anything sent in a request.
Rate limits
Every authenticated response reports the calling key's current rate-limit headroom through a standard set of headers: X-RateLimit-Limit (the ceiling for the current window), X-RateLimit-Remaining (requests left in it), and X-RateLimit-Reset (when the window resets). These headers accompany both a successful response and a rate-limited one, so a client can see exactly where it stands without a separate lookup.
A request that exceeds the limit still counts against the window even though it is rejected, and the rate limit is checked before a key's validity is otherwise evaluated — so a request from a key that has separately been revoked or has expired can still come back rate-limited rather than unauthorized, if the window is already exhausted. Checking the key's own status directly is the reliable way to distinguish the two.
Sources
Where this comes from
Related