Pricing Methodology
This page describes how the pricing numbers in the Pet Cremation Place directory are sourced, refreshed, and displayed. The refresh cadence, last-run timestamp, and counts below are pulled live from our database — nothing on this page is hand-maintained. If the cron hasn't run, or it ran but recorded an error, you can see that directly here.
What this page covers
It explains how our scraped_pricing, pricing_tiers, and normalized_pricing columns get populated, how often they're refreshed, what it means for a provider to be "claimed" versus "unclaimed" in this context, and what to do if a price you see on a provider page looks stale.
Where the pricing numbers come from
Three sources write to the pricing columns on a provider listing:
- Periodic scrape of provider websites. The pricing-refresh cron shells out to
scripts/scrape-pricing-firecrawl.js, which extracts structured pricing from public provider pages via Firecrawl and writes it toproviders.scraped_pricing,providers.pricing_source,providers.pricing_source_url, andproviders.pricing_scraped_at. - Provider-claimed self-edit. When a provider claims their listing, they can edit pricing fields through the claim portal. Self-edits run on demand rather than waiting for the monthly cron, so a claimed provider's prices may be more current than the cron cadence alone would imply.
- Future structured feeds. Third-party structured data feeds may be added later. Today, only the two sources above write to these columns.
Once a refresh tick lands, the orchestrator stamps providers.pricing_last_refreshed_at for every provider in that run's cohort — including the rows whose individual scraper requests failed. That stamp is what the next cron tick uses to decide who is in scope.
What "unclaimed" vs "claimed" means here
An unclaimed listing's pricing is sourced only from the periodic scrape plus the monthly cron. There is no second path; what you see is what the scraper saw, refreshed no more than once a month.
A claimed listing can have its pricing edited through the claim portal in addition to whatever the scraper wrote. That means a claimed provider's prices can move faster than the 30-day refresh window — but it also means an unclaimed listing is not guaranteed to be as current as a claimed one. We do not promise equal freshness across both groups.
How often we refresh
The pricing-refresh cron runs on the 1st of each month at 08:00 UTC, configured in polsia.toml. The script entrypoint is scripts/pricing-refresh-cron.js; the orchestrator that decides who is in scope lives in lib/pricing-refresh.js.
Pricing data is considered current if it was refreshed within the last 30 days. The next run pulls any provider whose pricing was never refreshed, or whose last refresh is older than 30 days — currently 0 providers are in scope.
Live stats from the database
Last completed run: 2026-08-01 20:07:06 UTC (cron)
Providers updated in that run: 0 out of 5,497 in scope
Providers currently in the next refresh scope: 0
Coverage: 5,497 of 5,497 providers with a website have at least one recorded refresh (oldest 2026-08-01, newest 2026-08-01).
Last cron-run receipt: 2026-08-01 20:07:06 UTC (1 cron runs total).
What the columns store
Each pricing field has a distinct role. None of them are estimates or imputed — if a column is empty for a provider, the page that surfaces it should render nothing rather than guessing:
scraped_pricing(JSONB) — the structured payload returned by the Firecrawl scrape. Contains per-servicestarting_at,tiers, andprice_rangevalues where the scraper could find them.pricing_tiers(JSONB) — legacy structured tier data written by earlier enrichment passes; the pricing widget still reads it for backwards compatibility.normalized_pricing(JSONB) — the computedmin/maxvalues the pricing widget surfaces on state and city pages.pricing_source(VARCHAR) — a short label describing what the scraper found:fetch_failed,no_pricing,live_page, etc. The pricing pill on a provider card hides itself when this isfetch_failedorno_pricing.pricing_scraped_at(TIMESTAMPTZ) — per-row timestamp of the last successful scrape for that provider's page.pricing_last_refreshed_at(TIMESTAMPTZ) — cohort anchor stamped by the orchestrator after each run. This is what the next cron tick reads to decide who is in scope.
What the pricing widget does
On state and city pages, a pricing widget aggregates normalized_pricing and pricing_tiers across the providers in view and renders service-level cost ranges. It deliberately suppresses itself on thin coverage — fewer than three providers in scope, or fewer than three with pricing data, and the widget renders nothing rather than implying a range from a tiny sample. That suppression is why some states and cities do not show a cost card.
What to do if a price looks stale
Prices are a snapshot at refresh time, not a personalized quote. If the number on a provider page is older than you'd like, you have three concrete options:
- Flag it via Suggest an edit on the provider page — the link is on every listing.
- Call the provider directly to confirm their current pricing and what's included. Their phone number is on the listing.
- Email hello@petcremationplace.com and we'll pull that provider into the next refresh scope or run a manual one.
Limitations and caveats
The numbers on this page and on individual provider listings are ranges from a sample of providers, not personalized quotes. Your individual price depends on your pet, your region, and what is included.
The cron's coverage is best-effort. Rows whose scraper requests fail are not re-scraped until the next monthly tick unless a manual run is triggered. A successful run still stamps pricing_last_refreshed_at for the whole cohort, so a partially-failed run keeps those providers out of the next tick by design — we'd rather show a slightly older number than hammer the same failing URL every day.
We do not guarantee that any single price reflects the provider's current site. A provider may have updated prices between scrapes, or between visits by our staff. Treat the number as a directional range, then call for a written quote.
For the top-line directory numbers behind all of this — total providers, claimed vs unclaimed, pricing coverage per service — see our transparency page. For how search results are ordered, read how we rank providers.