Public API · preview

Observed listings, ready to integrate.

Read the same confirmed Spirit Vale market snapshot used by ValeMarket. Public reads need no API key during preview.

market-api.spiritvalers.com
$ curl "https://market-api.spiritvalers.com/v2/markets/global/snapshot"

    
AccessNo key required
Snapshot15-minute edge cache
FormatJSON over HTTPS
CoverageObserved active listings

Quickstart

One URL. No setup.

Fetch the complete prebuilt global market snapshot in one request. It is generated every 15 minutes, so visitor traffic never waits for live database pagination.

const response = await fetch(
  "https://market-api.spiritvalers.com/v2/markets/global/snapshot"
);
if (!response.ok) throw new Error(`ValeMarket ${response.status}`);
const snapshot = await response.json();
Public preview. Read endpoints do not currently require an Authorization header. The contributor upload token is a separate credential and is not a developer API key.

Endpoints

Read the market.

GET/v2/markets/{marketId}/snapshotFast complete snapshot

Returns every current confirmed listing in one prebuilt response. Use global as the current market ID. This is the preferred route for complete market browsers and bulk integrations.

/v2/markets/global/snapshot
GET/v2/markets/{marketId}/stat-fingerprintsObserved stat price signals

Returns periodically regenerated matched asking-price lifts for sufficiently observed equipment stats. Values describe listing-price association, not completed sales, stat magnitude, or combat value. Artifact Rune, Jewel, Scroll, and Relic slots are modeled separately.

/v2/markets/global/stat-fingerprints
GET/v2/markets/{marketId}/listingsCurrent listings

Returns confirmed, fresh observations across the market. Use global as the current market ID.

  • minPriceMinimum unit price
  • maxPriceMaximum unit price
  • statStat name filter
  • sortprice-asc or price-desc
  • offset0–100,000
  • limit1–100; default 50
  • snapshotCurrent browser contract: 2
GET/v2/markets/{marketId}/items/{itemType}/{itemId}One item

Returns current observations for one numeric item type and item ID. It accepts the same filters and pagination parameters as the market listing route.

/v2/markets/global/items/1/Flax?limit=100
GET/v2/markets/{marketId}/items/{itemType}/{itemId}/historyObservation history

Returns up to 100 confirmed historical observations for one item. This endpoint does not accept query parameters.

/v2/markets/global/items/1/Flax/history
GET/v2/markets/{marketId}/items/{itemType}/{itemId}/price-historySeven-day prices

Returns hourly low, P25, median, P75, high, listing count, and unit count over the rolling seven-day observation window. Results are aggregated when requested and cached for 15 minutes. Late reports appear in their original observed hour; expired listings remain in historical buckets.

/v2/markets/global/items/1/Flax/price-history
GET/healthService health

Returns service status and the current observation protocol version. Use this for diagnostics, not frequent polling.

{"status":"ok","protocolVersion":2}

Response

Fields that matter.

Listing responses contain marketId, generatedAt, and a listings array. Item routes also echo itemType and itemId.

FieldTypeMeaning
generatedAtISO 8601When this cached API snapshot was generated.
listingKeystringStable public identity for the observed listing.
itemType / itemIdinteger / stringSpirit Vale item identifiers.
displayNamestring | nullObserved display name when available.
unitPrice / quantityintegerObserved unit price and quantity.
statsarrayPublic item roll fields: type, optional name/value, and percent flag.
enhancementsobject | omittedEquipment refine, potential, cards, gems, and artifact slot when observed.
firstSeenAt / lastSeenAtISO 8601Bounds of confirmed observation time.
expiresAtISO 8601 | nullKnown listing expiry. Filter rows where this time has passed.
Privacy boundary. Responses never contain seller, buyer, account, character, shop, installation-path, or raw-packet data.

Freshness

Share the snapshot.

The complete snapshot is generated once every 15 minutes and served as a prebuilt object. Short browser and edge caching absorbs repeat traffic while allowing clients to see each newly generated snapshot promptly.

  1. Honor Cache-Control and ETag. Do not add cache-busting query values or poll faster than the shared snapshot interval.
  2. Stay within the preview limits. Cloudflare's edge cache absorbs repeated identical reads before they execute API code. Uncached complete-snapshot requests allow 10 attempts per minute per network source; other uncached market reads share a 60-attempt-per-minute allowance. Limits are approximate per Cloudflare edge location. A limited request returns 429 with Retry-After: 60.
  3. Use generatedAt for snapshot age. Your local request time does not describe data freshness.
  4. Filter expiresAt locally. A listing can expire during the 15-minute cache window.
  5. Treat rows as observations, not sales. ValeMarket does not report completed transactions or guarantee that a listing remains available.

Errors

Handle status, then JSON.

StatusMeaningAction
304Not modifiedReuse the representation associated with your ETag.
400Invalid path or queryRead the JSON error and correct the request.
404Unknown routeCheck the endpoint and path identifiers.
429Traffic limitedBack off. Do not rotate addresses or add cache-busting parameters.
503Reads temporarily disabledHonor Retry-After when present.

Developer access

Building something public?

Tell us what you are integrating and the traffic you expect. Reads remain keyless during preview; access requests help shape managed keys, quotas, and change notifications before they become necessary.

Request developer access ↗