v3.0.0 — capabilitySearch replaces searchAPIs
Breaking
searchAPIs()is gone. Replaced bycapabilitySearch(). The legacy substring ranker at/api/facilitator/marketplace/resourceswas retired — discovery now goes through the semantic capability search pipeline at/api/x402gle/capability(vector search + similarity floor + tiering + cross-encoder LLM rerank).DiscoveredAPItype removed. Replaced byCapabilityAPI. The new shape carriestier: 'strong' | 'related', a rawsimilarityscore (0–1), awhystring explaining the ranking factors, and a final combinedscore. It also nests gaming-flag signals (gamingFlags,gamingSuspicious) and dropssellerReputation,totalVolume(formatted),lastActive, andauthRequired.- Hard-filter params are gone.
category,network,maxPrice,verifiedOnly, andsortwere removed from the search options. They were the source of silent false-empties (e.g.{ query: 'ETH price', network: 'ethereum' }returned zero results because every ETH-price resource accepts payment on Base). The ranker handles these semantically; payment rail is a checkout-time concern the caller handles separately. The new options are:query(required),limit,unverified,testnets,rerank, andendpoint. - Response is tiered.
capabilitySearch()returns{ strongResults, relatedResults, strongCount, relatedCount, topSimilarity, noMatchReason, rerank, intent, durationMs }instead of a flat array.strongResultsare high-confidence matches that cleared the strong similarity threshold;relatedResultsare adjacent candidates that cleared the floor but not the strong threshold.
Added
capabilitySearch(options: CapabilitySearchOptions): Promise<CapabilitySearchResult>— semantic search with synonym expansion at the intent parse layer, similarity floor filtering, strong/related tiering, and cross-encoder LLM rerank on the top strong results.NoMatchReasontype —'below_similarity_threshold' | 'below_strong_threshold' | null. Callers can distinguish "corpus has zero candidates" from "candidates exist but none are high-confidence".- Intent telemetry on every response —
result.intentexposes the parsedcapabilityTextand the synonym-expandedexpandedCapabilityTextthat was actually embedded for the vector search. Useful for debugging why a query ranked a particular way. - Rerank telemetry on every response —
result.rerank.appliedtells you whether the LLM cross-encoder actually reordered the top strong results, andresult.rerank.reasonexplains any skip.
Migration
Replace the search call:
// Before (2.x)
const results = await searchAPIs({ query: 'ETH price', category: 'data', maxPrice: 0.10 });
for (const api of results) { console.log(api.name, api.price); }
// After (3.0)
const result = await capabilitySearch({ query: 'ETH price' });
for (const api of result.strongResults) { console.log(api.name, api.price, api.why); }
if (result.strongCount === 0 && result.relatedCount > 0) {
// Fall back to related matches when nothing cleared the strong threshold
for (const api of result.relatedResults) { console.log('related:', api.name); }
}Filter semantically via the query text, not parameters:
searchAPIs({ category: 'defi' })→capabilitySearch({ query: 'DeFi tools' })searchAPIs({ network: 'solana' })→capabilitySearch({ query: 'on Solana' })(or filter client-side viapricing.network)searchAPIs({ maxPrice: 0.10 })→ filter the result array:result.strongResults.filter(r => r.priceUsdc != null && r.priceUsdc <= 0.10)