{"openapi":"3.1.0","info":{"title":"PulseGate documented API","version":"2026-10-07","summary":"The endpoints documented at /developers, described for programs.","description":"Describes the endpoints documented at https://www.pulsegate.ai/developers, as they answer today. That page, not this file, is what section 7.1 of the Terms refers to: the permission covers the endpoints named there, within the limits published there, and where this file and the page differ, the page applies.\n\nFields named on that page will not be removed without notice. This file describes every field the responses carry; a field described here and not named there carries no such promise.\n\nKeyless: no registration, no API key, no account.\n\nLimits, per IP; an IPv6 address counts by its /64. Per minute, the default count covers the catalogue paths below, and each request is checked against its own path's ceiling: 80 for /api/apps, /api/apps/facets and /api/search; 60 for /api/categories, /api/stats/public and /api/mcp. Sixty requests to /api/apps in a minute therefore leave none for /api/stats/public in that minute. Per day there is one more count per IP, and each request is checked against its own path's ceiling: 20,000 for /api/apps and the paths beneath it, 5,000 for /api/search. Every /api/search request adds to it; a request to /api/apps or beneath it adds only once the IP has gone over roughly 30 requests in its current minute, on any path, and so do record pages and some other requests to this site, under the same rule. Every search therefore counts toward the 20,000, and a burst on /api/apps spends the 5,000 of /api/search too. /api/mcp keeps a daily count of its own: 2,000 calls, from the first call. Access within the published limits is permitted; access that exceeds or circumvents them is not.\n\nBounded search, individual records, Wire lists, MCP and discovery admit declared headless clients through the same guards. Other paths may refuse declared automation with HTTP 403 plain text. Protected data uses one shared network allowance (anonymous: at most 500,000 units per UTC day, subject to shared/global ceilings). Search and each MCP POST reserve 80, API detail 16, HTML detail 136. Wire reserves 16 per requested list item (JSON default 320, maximum 800; HTML 384 unfiltered or 320 filtered). HEAD on these search/individual-record/Wire paths reserves the same GET weight. Wire retains its separate 600/minute tier; catalogue images have their own 60/minute counter without changing daily or shared allowances. No refunds or new quota by format/tool. Admission precedes internal cache reads; protected responses are no-store. Distributed-budget failure falls back to 5,000 units per hour per instance, not a distributed guarantee.\n\ninfo.version identifies the publication date of this revision, matching the effective date on /developers and the corresponding Terms revision.","termsOfService":"https://www.pulsegate.ai/terms","contact":{"name":"PulseGate","url":"https://www.pulsegate.ai/contact"}},"externalDocs":{"description":"The documented interface — the page this file describes.","url":"https://www.pulsegate.ai/developers"},"servers":[{"url":"https://www.pulsegate.ai"}],"tags":[{"name":"agent-facing","description":"Open in robots.txt to the crawlers of OpenAI, Anthropic and Perplexity."},{"name":"client-facing","description":"Excluded from crawling in robots.txt. Documented for programs that call it directly; it is uncached and costs a database read per request, so a crawler should read the record page instead."},{"name":"agent-protocol","description":"Model Context Protocol, POST only. Serves agents acting on a request and is never crawled."}],"paths":{"/api/search":{"get":{"tags":["agent-facing"],"operationId":"search","summary":"Ask a question","description":"Some apps, recent changes or details about what an app can do may be missing from the index. No matches in the indexed data does not mean no suitable service exists. Check HTTP status first. Successful empty results differ from 400 input errors, 403 refused depth and 503 unavailable source; error envelopes have no usable count or candidates. JSON and text share a 32 KiB representation ceiling and ten candidate identities. scope.matched says how many rows matched; scope.available how many paging can reach. Not cached. Limit: 80 a minute and 5,000 a day, per IP, each checked on a count shared with other paths (info.description).","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["json","text"]},"description":"Explicit format wins over Accept; absent format negotiates application/json and text/plain, default JSON. Unsupported/conflicting format: 400; unsupported Accept: 406. No format=agent."},{"name":"require","in":"query","schema":{"type":"string","maxLength":256},"description":"Up to three unique api/mcp/cli/selfHosted:true|false, pricing:<value>, license:<family> requirements, comma-separated. At most five requirements plus recorded filters. Unsupported conditions and alternatives with requirements return 400."},{"name":"unknown","in":"query","schema":{"type":"string","enum":["include","exclude"],"default":"include"},"description":"Include candidates needing verification, or require attributed evidence. Current B2 records cannot establish strict capability matches."},{"name":"q","in":"query","schema":{"type":"string"},"description":"The query. At most 120 Unicode codepoints, 512 UTF-8 bytes and 12 words; excess is HTTP 400."},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":1},"description":"Page of the answer. Above 50 the answer is 403 with refused: depth. A value below 1 or not a number reads as 1, and a fraction as its whole part."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1},"description":"Rows per page — of results, with lead counted among them, or of nearest when only the meaning channel found anything — at most 10, which is also the page size when limit is absent: a larger value is accepted, served as 10, and not echoed back — do not infer the page size from your request. Below 1 reads as 1, above 10 as 10, and a fraction as its whole part."},{"name":"platform","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by platform; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is platform, and filters describe recorded classifications, never proof of a capability."},{"name":"license","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by license; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is license, and filters describe recorded classifications, never proof of a capability."},{"name":"pricing","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by pricing; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is pricing, and filters describe recorded classifications, never proof of a capability."},{"name":"category","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by category; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is category, and filters describe recorded classifications, never proof of a capability."}],"responses":{"200":{"description":"The answer. A query that resolves to nothing is answered here too, with the empty shape.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}},"400":{"description":"Invalid, duplicate conflicting, overlong or unsupported search conditions; empty envelope with error.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SearchResponse"},{"$ref":"#/components/schemas/ErrorOnly"}]}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}},"403":{"description":"page above 50: refused depth; no usable candidates.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRefused"}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}},"406":{"description":"Unsupported or conflicting representation.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOnly"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"503":{"description":"Unavailable or deadline: empty envelope with failed: true, never cached records.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SearchFailed"},{"$ref":"#/components/schemas/ErrorOnly"}]}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}}}},"head":{"operationId":"searchHead","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["json","text"]},"description":"Explicit format wins over Accept; absent format negotiates application/json and text/plain, default JSON. Unsupported/conflicting format: 400; unsupported Accept: 406. No format=agent."},{"name":"require","in":"query","schema":{"type":"string","maxLength":256},"description":"Up to three unique api/mcp/cli/selfHosted:true|false, pricing:<value>, license:<family> requirements, comma-separated. At most five requirements plus recorded filters. Unsupported conditions and alternatives with requirements return 400."},{"name":"unknown","in":"query","schema":{"type":"string","enum":["include","exclude"],"default":"include"},"description":"Include candidates needing verification, or require attributed evidence. Current B2 records cannot establish strict capability matches."},{"name":"q","in":"query","schema":{"type":"string"},"description":"The query. At most 120 Unicode codepoints, 512 UTF-8 bytes and 12 words; excess is HTTP 400."},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":1},"description":"Page of the answer. Above 50 the answer is 403 with refused: depth. A value below 1 or not a number reads as 1, and a fraction as its whole part."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1},"description":"Rows per page — of results, with lead counted among them, or of nearest when only the meaning channel found anything — at most 10, which is also the page size when limit is absent: a larger value is accepted, served as 10, and not echoed back — do not infer the page size from your request. Below 1 reads as 1, above 10 as 10, and a fraction as its whole part."},{"name":"platform","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by platform; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is platform, and filters describe recorded classifications, never proof of a capability."},{"name":"license","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by license; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is license, and filters describe recorded classifications, never proof of a capability."},{"name":"pricing","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by pricing; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is pricing, and filters describe recorded classifications, never proof of a capability."},{"name":"category","in":"query","schema":{"type":"string","maxLength":64},"description":"Narrows the answer by category; unknown or overlong values return HTTP 400. axes[].values[].value offers values for the axis whose param is category, and filters describe recorded classifications, never proof of a capability."}],"summary":"GET status and headers without the body","description":"Automatic HEAD uses GET handling and may perform its database work. The corresponding GET weight is reserved once: search 80, API detail 16, Wire 16 per requested item.","responses":{"200":{"description":"The answer. A query that resolves to nothing is answered here too, with the empty shape.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"400":{"description":"Invalid, duplicate conflicting, overlong or unsupported search conditions; empty envelope with error.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"403":{"description":"page above 50: refused depth; no usable candidates.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"406":{"description":"Unsupported or conflicting representation.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"429":{"description":"A published limit was reached. The per-minute answer carries X-RateLimit-Limit, X-RateLimit-Remaining and usually X-RateLimit-Reset; a daily ceiling carries X-RateLimit-Scope instead. A client that asked for text/html when the daily ceiling was reached gets a page saying so instead of the JSON.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-RateLimit-Scope":{"$ref":"#/components/headers/XRateLimitScope"}}},"503":{"description":"Unavailable or deadline: empty envelope with failed: true, never cached records.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}}}}}},"/api/apps":{"get":{"tags":["agent-facing"],"operationId":"listApps","summary":"Page the catalogue","description":"Filters are documented in responses rather than here: /api/apps/facets returns every facet and its counts, /api/categories the category tree. An unknown parameter is ignored silently: a typo does not produce an error, it produces different data. Applying any filter changes the default ordering from balanced to firstSeen; read meta.order, do not assume it. items and apps are the same array; read items. Limit: 80 requests per minute per IP, and the daily ceiling in info.description.","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":1},"description":"Page of the list: at most 50, and the offset at most 5,000, whichever binds first — beyond that the answer is 403 with error pagination_limit. Not an integer of at least 1: 400 with error bad_request."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"default":50},"description":"Rows per page, clamped to 100. Not an integer of at least 1: 400 with error bad_request."}],"responses":{"200":{"description":"A page of the catalogue. The second shape answers only when the server has no database configured at all, a state production does not run in.","headers":{"Cache-Control":{"description":"Current public visibility is checked before cached items are released; aggregate counts can describe the cached snapshot. Private and no-store.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/AppsPage"},{"$ref":"#/components/schemas/AppsUnavailable"}]}}}},"400":{"description":"Invalid page or limit: error is bad_request.","headers":{"Cache-Control":{"description":"Always no-store.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0","no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorWithMessage"}}}},"403":{"description":"Deeper than the published paging depth: error is pagination_limit, as JSON. Or, as text, a declared automation User-Agent, refused before anything is counted, when the request reaches our servers. New list responses are no-store.","headers":{"Cache-Control":{"description":"Always no-store.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0","no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Blocked-UA":{"description":"On the refusal of a declared automation User-Agent only: the declared token that matched, or declared-automation.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorWithMessage"}},"text/plain":{"schema":{"type":"string","examples":["Automated access is not permitted.\n"]}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Internal failure: error is Internal Server Error.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Cache-Control":{"description":"Private and no-store.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorWithMessage"}}}}}}},"/api/apps/facets":{"get":{"tags":["agent-facing"],"operationId":"facetCounts","summary":"Facet counts","description":"How many records sit behind each value of each facet, counted over the visible catalogue in the scope of cat and sub. Every other parameter is left unapplied and named in ignored. Limit: 80 requests per minute per IP, and the daily ceiling in info.description.","parameters":[{"name":"cat","in":"query","schema":{"type":"string"},"description":"Top category slug (from /api/categories) to count within."},{"name":"sub","in":"query","schema":{"type":"string"},"description":"Subcategory slug to count within. Equal to cat, it addresses the records filed at cat itself rather than in its children."}],"responses":{"200":{"description":"The counts. When they cannot be read the answer is empty counts and pool 0 — no numbers rather than wrong ones.","headers":{"Cache-Control":{"description":"public, s-maxage=3600, stale-while-revalidate=86400","required":true,"schema":{"type":"string","examples":["public, s-maxage=3600, stale-while-revalidate=86400"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FacetCounts"}}}},"403":{"$ref":"#/components/responses/AutomationRefused"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/api/categories":{"get":{"tags":["agent-facing"],"operationId":"categories","summary":"The category tree","description":"Without parameters: every current category as slug and name. With level=top and withSubCounts=1: the top categories with their record counts and their subcategories. Limit: 60 requests per minute per IP.","parameters":[{"name":"level","in":"query","schema":{"type":"string","enum":["top"]},"description":"top: top-level categories only."},{"name":"withSubCounts","in":"query","schema":{"type":"string","enum":["1"]},"description":"1, together with level=top: add each category's record count and its subcategories."},{"name":"includeLegacy","in":"query","schema":{"type":"string","enum":["1"]},"description":"1: include retired categories."}],"responses":{"200":{"description":"The categories.","headers":{"Cache-Control":{"description":"public, s-maxage=300, stale-while-revalidate=600","required":true,"schema":{"type":"string","examples":["public, s-maxage=300, stale-while-revalidate=600"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoriesResponse"}}}},"403":{"$ref":"#/components/responses/AutomationRefused"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Internal failure: no items, meta.degraded true, and an error string.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoriesFailed"}}}}}}},"/api/stats/public":{"get":{"tags":["agent-facing"],"operationId":"publicStats","summary":"The published figures","description":"Index size, recent indexing volume, and a seven-day daily series. Every figure carries the window it covers. Limit: 60 requests per minute per IP.","responses":{"200":{"description":"The figures. When the database cannot be reached the same shape answers with zeros, deltaPct null and insufficientHistory true, under a shorter cache window.","headers":{"Cache-Control":{"description":"public, max-age=0, s-maxage=60, stale-while-revalidate=300; the zeroed answer uses 15 and 75.","required":true,"schema":{"type":"string","examples":["public, max-age=0, s-maxage=60, stale-while-revalidate=300","public, max-age=0, s-maxage=15, stale-while-revalidate=75"]}},"Access-Control-Allow-Origin":{"description":"A fixed origin, never reflected from the request.","schema":{"type":"string","examples":["https://www.dimaxia.com"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicStats"}}}},"403":{"$ref":"#/components/responses/AutomationRefused"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Internal failure.","headers":{"Access-Control-Allow-Origin":{"description":"A fixed origin, never reflected from the request.","schema":{"type":"string","examples":["https://www.dimaxia.com"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOnly"}}}}}}},"/api/apps/{slug}":{"get":{"tags":["client-facing"],"operationId":"getApp","summary":"One record","description":"The public fields of a single record. A record outside the catalogue — deleted, taken down by an administrator, unlisted, not eligible, excluded by curation, or folded into another record as a duplicate — answers 404, the same as a slug this index does not hold. A record confirmed gone is still in the catalogue and still answers. JSON or text/plain of the same public profile; at most 32 KiB per representation, the profile at most 16 KiB. Private and no-store, including errors. Limit: 80 requests per minute per IP, and the daily ceiling in info.description.","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["json","text"]},"description":"Explicit format wins over Accept; absent format negotiates application/json and text/plain, default JSON. Unsupported/conflicting format: 400; unsupported Accept: 406. No format=agent."},{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The record's slug, current or former."}],"responses":{"200":{"description":"The record.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppRecordResponse"}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}},"308":{"description":"A former slug of a renamed record. A slug held today by a record in the catalogue answers for that record, never with a redirect.","headers":{"Location":{"description":"The endpoint at the current slug, as a path: /api/apps/{current}, preserving an explicit format.","schema":{"type":"string"}},"Cache-Control":{"description":"Always no-store.","required":true,"schema":{"type":"string","examples":["no-store"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"400":{"description":"Unsupported or conflicting representation.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOnly"}}}},"404":{"description":"No record in the catalogue answers to this slug.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOnly"}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}},"406":{"description":"Unsupported or conflicting representation.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOnly"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"503":{"description":"Record source or representation unavailable, not missing.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOnly"}},"text/plain":{"schema":{"type":"string","description":"Same bounded public data as JSON, preserving uncertainty and explicit errors; not Markdown."}}}}}},"head":{"operationId":"getAppHead","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["json","text"]},"description":"Explicit format wins over Accept; absent format negotiates application/json and text/plain, default JSON. Unsupported/conflicting format: 400; unsupported Accept: 406. No format=agent."},{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The record's slug, current or former."}],"summary":"GET status and headers without the body","description":"Automatic HEAD uses GET handling and may perform its database work. The corresponding GET weight is reserved once: search 80, API detail 16, Wire 16 per requested item.","responses":{"200":{"description":"The record.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"308":{"description":"A former slug of a renamed record. A slug held today by a record in the catalogue answers for that record, never with a redirect.","headers":{"Location":{"description":"The endpoint at the current slug, as a path: /api/apps/{current}, preserving an explicit format.","schema":{"type":"string"}},"Cache-Control":{"description":"Always no-store.","required":true,"schema":{"type":"string","examples":["no-store"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"400":{"description":"Unsupported or conflicting representation.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"404":{"description":"No record in the catalogue answers to this slug.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"406":{"description":"Unsupported or conflicting representation.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"429":{"description":"A published limit was reached. The per-minute answer carries X-RateLimit-Limit, X-RateLimit-Remaining and usually X-RateLimit-Reset; a daily ceiling carries X-RateLimit-Scope instead. A client that asked for text/html when the daily ceiling was reached gets a page saying so instead of the JSON.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-RateLimit-Scope":{"$ref":"#/components/headers/XRateLimitScope"}}},"503":{"description":"Record source or representation unavailable, not missing.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}}}}}},"/api/mcp":{"post":{"tags":["agent-protocol"],"operationId":"mcp","summary":"Model Context Protocol endpoint","description":"Stateless JSON-RPC 2.0 over one POST, for clients of the Streamable HTTP transport: initialize, then tools/list and tools/call with search_catalog, lookup_project or list_identifier_platforms. One request object per POST; there are no batches and no sessions. A tool that cannot answer replies with result.isError true over HTTP 200 application/json, distinct from transport failures. search_catalog also returns structuredContent.error with logical status 400/403/503; 503 has retryAfterSeconds: 5. Its success uses the same SearchResponse plus text, not a second search. Full profiles are not an MCP tool; read the record endpoint/page. Unparsable JSON is answered -32700, a body that is not one request object -32600, an unknown method -32601 — each with HTTP 200. The jsonrpc member is not checked. A GET answers 405 with Allow: POST, because there is no event stream to open. It says nothing about whether software is alive or maintained; every provenance tool answer carries what_this_answer_does_not_say. Limit: 60 requests per minute on the count shared by every path, and 2,000 calls per day, per IP, on a count of its own, from the first call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpRequest"}}}},"responses":{"200":{"description":"A JSON-RPC response: a result, or an error.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpResponse"}}}},"202":{"description":"A notification (a method under notifications/ and no id) was accepted. No body.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"400":{"description":"The request body could not be read.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"text/plain":{"schema":{"type":"string","description":"Could not read the request body."}}}},"403":{"description":"Sent by a page on another site (Sec-Fetch-Site cross-site or same-site; MCP clients send no such header), refused by the protocol handler. Declared automation is admitted through the same middleware guards.","headers":{"Cache-Control":{"description":"The production catalogue guard sets private/no-store before this refusal; a direct handler call without middleware omits it.","schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Blocked-UA":{"description":"On the refusal of a declared automation User-Agent only: the declared token that matched, or declared-automation.","schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string","examples":["Cross-site requests are refused."]}}}},"413":{"description":"The body is longer than 64,000 bytes.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"text/plain":{"schema":{"type":"string","description":"Request too large."}}}},"415":{"description":"The Content-Type is not application/json.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"text/plain":{"schema":{"type":"string","description":"This endpoint takes JSON-RPC as application/json."}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/api/industry-updates":{"get":{"tags":["agent-facing"],"operationId":"wireList","summary":"Read a bounded Wire list","description":"GET and HEAD on this exact path and /wire HTML only. Default today/7d. No event, saved view, cursor, offset, custom range, story detail, widget or subpath is granted. Unknown/conflicting API parameters return 400. Refused taxonomy/window filters return an explicit empty scope, never a wider list. Cache revalidates after 60 seconds and may serve a successful snapshot for at most 180 seconds from acquisition. A valid cache need not reveal a source outage. Cache hits or failed refreshes never renew the acquisition clock. Without a valid snapshot, source/size failure returns API 503 with Retry-After: 5; HTML shows an error and may stream HTTP 200. External no-store. Same projection as HTML (24 unfiltered or 20 filtered items), not a bound on the whole HTML document. Existing Wire tier 600/minute; reserve 16 shared units per requested item (default 320, maximum 800), HEAD same. Pause polling while hidden and respect Retry-After on 429/503. Permission covers metadata, bounded summaries and source URLs, not bulk crawling, archiving, export, redistribution, model training or third-party rights.","parameters":[{"name":"view","in":"query","schema":{"type":"string","enum":["today","front","week","ranked","river"],"default":"today"}},{"name":"timeframe","in":"query","schema":{"type":"string","enum":["24h","7d","30d"],"default":"7d"}},{"name":"cat","in":"query","schema":{"type":"string"}},{"name":"sub","in":"query","schema":{"type":"string"}},{"name":"leaf","in":"query","schema":{"type":"string"}},{"name":"kind","in":"query","schema":{"type":"string"}},{"name":"provider","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"description":"Agent workflow accepts integers 1–50 only. Existing direct handler clamps other numeric values and defaults non-numeric values to 20."}],"responses":{"200":{"description":"A bounded list or explicitly refused empty filter scope.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","required":["items","nextCursor","hasMore","live","meta"],"description":"Whole-item prefix, each serialized item at most 3276 UTF-8 bytes; entire JSON at most floor(32768 × requested limit / 10) bytes. Operational ceilings, not measured Wire quantiles. No full story or sources payload.","properties":{"items":{"type":"array","maxItems":50,"items":{"type":"object","required":["id","vendor","publishedAt","firstSeenAt","titleShort","statusLine","whyItMatters","category","confidence","impactScore","thumbnailUrl","entities","keyPoints","sourcesCount","primarySourceUrl","isBreaking","isResolved","isMonitoring","eventStartedAt","reportsNothing","isScheduled","timeIsOurs","taxTopSlugs","taxSubSlugs","relevanceScore","heat","kind","evidence","vendorHost"],"properties":{"id":{"type":"string","description":"News item identifier."},"vendor":{"type":["string","null"],"description":"Recorded vendor."},"publishedAt":{"type":"string","format":"date-time","description":"Publisher time, or detection time when timeIsOurs is true."},"firstSeenAt":{"type":"string","format":"date-time","description":"Time recorded by the list mapper."},"titleShort":{"type":"string","description":"Display headline."},"displayTitle":{"type":"string","description":"Display headline."},"statusLine":{"type":"string","description":"Display status line."},"whyItMatters":{"type":["string","null"],"description":"Bounded summary, when present."},"category":{"type":"string","description":"Public category label."},"confidence":{"type":"string","description":"Recorded evidence label, not independent verification."},"impactScore":{"type":"number"},"thumbnailUrl":{"type":["string","null"],"description":"Image reference, if available."},"entities":{"type":"array","items":{"type":"string"},"description":"Named entities."},"keyPoints":{"type":"array","maxItems":0,"items":{"type":"string"}},"sourcesCount":{"type":"integer","description":"Recorded source count."},"primarySourceUrl":{"type":["string","null"],"description":"Source URL; never truncated to meet the response bound."},"isBreaking":{"type":"boolean"},"isResolved":{"type":"boolean"},"isMonitoring":{"type":"boolean"},"eventStartedAt":{"type":["string","null"],"format":"date-time","description":"Publisher's incident start, when known."},"reportsNothing":{"type":"boolean"},"isScheduled":{"type":"boolean"},"timeIsOurs":{"type":"boolean","description":"True means publishedAt is detection time, not the publisher timestamp."},"taxTopSlugs":{"type":"array","items":{"type":"string"},"description":"Recorded top taxonomy."},"taxSubSlugs":{"type":"array","items":{"type":"string"},"description":"Recorded sub taxonomy."},"relevanceScore":{"type":"number"},"heat":{"oneOf":[{"type":"null"},{"type":"object","required":["points","source","threadUrl"],"properties":{"points":{"type":"number"},"source":{"const":"hn"},"threadUrl":{"type":"string","description":"Recorded discussion URL."}}}]},"kind":{"type":["string","null"],"description":"Recorded story kind."},"evidence":{"type":"string","enum":["page","feed"]},"vendorHost":{"type":["string","null"],"description":"Publisher host."}}}},"nextCursor":{"type":"null"},"hasMore":{"type":"boolean","description":"More items exist or the bounded prefix stopped; no cursor access is offered."},"live":{"type":"object","required":["lastSuccessfulRunAt","ageMinutes"],"properties":{"lastSuccessfulRunAt":{"type":["string","null"],"format":"date-time","description":"Last publication time, not a freshness or delivery SLA."},"ageMinutes":{"type":"null"}}},"meta":{"type":"object","required":["source","timeframe","filterRefused","kind","provider","providerBasis","providerCoverage","byteLimited"],"properties":{"source":{"type":"string","enum":["news_v2","error"]},"timeframe":{"type":"string","description":"Applied window, or none on refusal/failure."},"filterRefused":{"type":["string","null"],"description":"Explicit reason for a refused scope; no widening."},"kind":{"type":["string","null"],"description":"Applied kind filter."},"provider":{"type":["string","null"],"description":"Applied provider filter."},"providerBasis":{"type":["string","null"],"description":"Evidence used for provider matching."},"providerCoverage":{"type":"array","items":{"type":"object","required":["slug","statusPages"],"properties":{"slug":{"type":"string"},"statusPages":{"type":"integer"}}}},"byteLimited":{"type":"boolean","description":"A whole-item prefix stopped at the byte bound."}}}}}}}},"400":{"description":"Unsupported or conflicting API list parameters.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","required":["items","nextCursor","hasMore","live","meta"],"description":"Whole-item prefix, each serialized item at most 3276 UTF-8 bytes; entire JSON at most floor(32768 × requested limit / 10) bytes. Operational ceilings, not measured Wire quantiles. No full story or sources payload.","properties":{"items":{"type":"array","maxItems":50,"items":{"type":"object","required":["id","vendor","publishedAt","firstSeenAt","titleShort","statusLine","whyItMatters","category","confidence","impactScore","thumbnailUrl","entities","keyPoints","sourcesCount","primarySourceUrl","isBreaking","isResolved","isMonitoring","eventStartedAt","reportsNothing","isScheduled","timeIsOurs","taxTopSlugs","taxSubSlugs","relevanceScore","heat","kind","evidence","vendorHost"],"properties":{"id":{"type":"string","description":"News item identifier."},"vendor":{"type":["string","null"],"description":"Recorded vendor."},"publishedAt":{"type":"string","format":"date-time","description":"Publisher time, or detection time when timeIsOurs is true."},"firstSeenAt":{"type":"string","format":"date-time","description":"Time recorded by the list mapper."},"titleShort":{"type":"string","description":"Display headline."},"displayTitle":{"type":"string","description":"Display headline."},"statusLine":{"type":"string","description":"Display status line."},"whyItMatters":{"type":["string","null"],"description":"Bounded summary, when present."},"category":{"type":"string","description":"Public category label."},"confidence":{"type":"string","description":"Recorded evidence label, not independent verification."},"impactScore":{"type":"number"},"thumbnailUrl":{"type":["string","null"],"description":"Image reference, if available."},"entities":{"type":"array","items":{"type":"string"},"description":"Named entities."},"keyPoints":{"type":"array","maxItems":0,"items":{"type":"string"}},"sourcesCount":{"type":"integer","description":"Recorded source count."},"primarySourceUrl":{"type":["string","null"],"description":"Source URL; never truncated to meet the response bound."},"isBreaking":{"type":"boolean"},"isResolved":{"type":"boolean"},"isMonitoring":{"type":"boolean"},"eventStartedAt":{"type":["string","null"],"format":"date-time","description":"Publisher's incident start, when known."},"reportsNothing":{"type":"boolean"},"isScheduled":{"type":"boolean"},"timeIsOurs":{"type":"boolean","description":"True means publishedAt is detection time, not the publisher timestamp."},"taxTopSlugs":{"type":"array","items":{"type":"string"},"description":"Recorded top taxonomy."},"taxSubSlugs":{"type":"array","items":{"type":"string"},"description":"Recorded sub taxonomy."},"relevanceScore":{"type":"number"},"heat":{"oneOf":[{"type":"null"},{"type":"object","required":["points","source","threadUrl"],"properties":{"points":{"type":"number"},"source":{"const":"hn"},"threadUrl":{"type":"string","description":"Recorded discussion URL."}}}]},"kind":{"type":["string","null"],"description":"Recorded story kind."},"evidence":{"type":"string","enum":["page","feed"]},"vendorHost":{"type":["string","null"],"description":"Publisher host."}}}},"nextCursor":{"type":"null"},"hasMore":{"type":"boolean","description":"More items exist or the bounded prefix stopped; no cursor access is offered."},"live":{"type":"object","required":["lastSuccessfulRunAt","ageMinutes"],"properties":{"lastSuccessfulRunAt":{"type":["string","null"],"format":"date-time","description":"Last publication time, not a freshness or delivery SLA."},"ageMinutes":{"type":"null"}}},"meta":{"type":"object","required":["source","timeframe","filterRefused","kind","provider","providerBasis","providerCoverage","byteLimited"],"properties":{"source":{"type":"string","enum":["news_v2","error"]},"timeframe":{"type":"string","description":"Applied window, or none on refusal/failure."},"filterRefused":{"type":["string","null"],"description":"Explicit reason for a refused scope; no widening."},"kind":{"type":["string","null"],"description":"Applied kind filter."},"provider":{"type":["string","null"],"description":"Applied provider filter."},"providerBasis":{"type":["string","null"],"description":"Evidence used for provider matching."},"providerCoverage":{"type":"array","items":{"type":"object","required":["slug","statusPages"],"properties":{"slug":{"type":"string"},"statusPages":{"type":"integer"}}}},"byteLimited":{"type":"boolean","description":"A whole-item prefix stopped at the byte bound."}}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"503":{"description":"No valid snapshot: expired/invalid acquisition time, source unavailable or first item/metadata cannot fit. Empty items. A valid cache up to 180s may mask a current source outage.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Retry-After":{"schema":{"const":"5"}}},"content":{"application/json":{"schema":{"type":"object","required":["items","nextCursor","hasMore","live","meta"],"description":"Whole-item prefix, each serialized item at most 3276 UTF-8 bytes; entire JSON at most floor(32768 × requested limit / 10) bytes. Operational ceilings, not measured Wire quantiles. No full story or sources payload.","properties":{"items":{"type":"array","maxItems":50,"items":{"type":"object","required":["id","vendor","publishedAt","firstSeenAt","titleShort","statusLine","whyItMatters","category","confidence","impactScore","thumbnailUrl","entities","keyPoints","sourcesCount","primarySourceUrl","isBreaking","isResolved","isMonitoring","eventStartedAt","reportsNothing","isScheduled","timeIsOurs","taxTopSlugs","taxSubSlugs","relevanceScore","heat","kind","evidence","vendorHost"],"properties":{"id":{"type":"string","description":"News item identifier."},"vendor":{"type":["string","null"],"description":"Recorded vendor."},"publishedAt":{"type":"string","format":"date-time","description":"Publisher time, or detection time when timeIsOurs is true."},"firstSeenAt":{"type":"string","format":"date-time","description":"Time recorded by the list mapper."},"titleShort":{"type":"string","description":"Display headline."},"displayTitle":{"type":"string","description":"Display headline."},"statusLine":{"type":"string","description":"Display status line."},"whyItMatters":{"type":["string","null"],"description":"Bounded summary, when present."},"category":{"type":"string","description":"Public category label."},"confidence":{"type":"string","description":"Recorded evidence label, not independent verification."},"impactScore":{"type":"number"},"thumbnailUrl":{"type":["string","null"],"description":"Image reference, if available."},"entities":{"type":"array","items":{"type":"string"},"description":"Named entities."},"keyPoints":{"type":"array","maxItems":0,"items":{"type":"string"}},"sourcesCount":{"type":"integer","description":"Recorded source count."},"primarySourceUrl":{"type":["string","null"],"description":"Source URL; never truncated to meet the response bound."},"isBreaking":{"type":"boolean"},"isResolved":{"type":"boolean"},"isMonitoring":{"type":"boolean"},"eventStartedAt":{"type":["string","null"],"format":"date-time","description":"Publisher's incident start, when known."},"reportsNothing":{"type":"boolean"},"isScheduled":{"type":"boolean"},"timeIsOurs":{"type":"boolean","description":"True means publishedAt is detection time, not the publisher timestamp."},"taxTopSlugs":{"type":"array","items":{"type":"string"},"description":"Recorded top taxonomy."},"taxSubSlugs":{"type":"array","items":{"type":"string"},"description":"Recorded sub taxonomy."},"relevanceScore":{"type":"number"},"heat":{"oneOf":[{"type":"null"},{"type":"object","required":["points","source","threadUrl"],"properties":{"points":{"type":"number"},"source":{"const":"hn"},"threadUrl":{"type":"string","description":"Recorded discussion URL."}}}]},"kind":{"type":["string","null"],"description":"Recorded story kind."},"evidence":{"type":"string","enum":["page","feed"]},"vendorHost":{"type":["string","null"],"description":"Publisher host."}}}},"nextCursor":{"type":"null"},"hasMore":{"type":"boolean","description":"More items exist or the bounded prefix stopped; no cursor access is offered."},"live":{"type":"object","required":["lastSuccessfulRunAt","ageMinutes"],"properties":{"lastSuccessfulRunAt":{"type":["string","null"],"format":"date-time","description":"Last publication time, not a freshness or delivery SLA."},"ageMinutes":{"type":"null"}}},"meta":{"type":"object","required":["source","timeframe","filterRefused","kind","provider","providerBasis","providerCoverage","byteLimited"],"properties":{"source":{"type":"string","enum":["news_v2","error"]},"timeframe":{"type":"string","description":"Applied window, or none on refusal/failure."},"filterRefused":{"type":["string","null"],"description":"Explicit reason for a refused scope; no widening."},"kind":{"type":["string","null"],"description":"Applied kind filter."},"provider":{"type":["string","null"],"description":"Applied provider filter."},"providerBasis":{"type":["string","null"],"description":"Evidence used for provider matching."},"providerCoverage":{"type":"array","items":{"type":"object","required":["slug","statusPages"],"properties":{"slug":{"type":"string"},"statusPages":{"type":"integer"}}}},"byteLimited":{"type":"boolean","description":"A whole-item prefix stopped at the byte bound."}}}}}}}}}},"head":{"operationId":"wireListHead","parameters":[{"name":"view","in":"query","schema":{"type":"string","enum":["today","front","week","ranked","river"],"default":"today"}},{"name":"timeframe","in":"query","schema":{"type":"string","enum":["24h","7d","30d"],"default":"7d"}},{"name":"cat","in":"query","schema":{"type":"string"}},{"name":"sub","in":"query","schema":{"type":"string"}},{"name":"leaf","in":"query","schema":{"type":"string"}},{"name":"kind","in":"query","schema":{"type":"string"}},{"name":"provider","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"description":"Agent workflow accepts integers 1–50 only. Existing direct handler clamps other numeric values and defaults non-numeric values to 20."}],"summary":"GET status and headers without the body","description":"Automatic HEAD uses GET handling and may perform its database work. The corresponding GET weight is reserved once: search 80, API detail 16, Wire 16 per requested item.","responses":{"200":{"description":"A bounded list or explicitly refused empty filter scope.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"400":{"description":"Unsupported or conflicting API list parameters.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"}}},"429":{"description":"A published limit was reached. The per-minute answer carries X-RateLimit-Limit, X-RateLimit-Remaining and usually X-RateLimit-Reset; a daily ceiling carries X-RateLimit-Scope instead. A client that asked for text/html when the daily ceiling was reached gets a page saying so instead of the JSON.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-RateLimit-Scope":{"$ref":"#/components/headers/XRateLimitScope"}}},"503":{"description":"No valid snapshot: expired/invalid acquisition time, source unavailable or first item/metadata cannot fit. Empty items. A valid cache up to 180s may mask a current source outage.","headers":{"Cache-Control":{"description":"Private and no-store, including errors.","required":true,"schema":{"type":"string","examples":["private, no-store, max-age=0"]}},"Vary":{"schema":{"type":"string","examples":["Accept"]}},"X-Content-Type-Options":{"schema":{"type":"string","examples":["nosniff"]}},"CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"Cloudflare-CDN-Cache-Control":{"schema":{"type":"string","examples":["no-store"]}},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"Retry-After":{"schema":{"const":"5"}}}}}}}},"components":{"headers":{"XRateLimitLimit":{"description":"The per-minute ceiling of the path this request went to. The count it is checked against is one per IP and covers every path. On a response served from a cache it describes the request that filled the cache, not yours.","schema":{"type":"integer"}},"XRateLimitRemaining":{"description":"This path's ceiling minus every request this IP has made in the current minute, on any path; 0 when refused.","schema":{"type":"integer"}},"XRateLimitReset":{"description":"When the current minute's count resets, in Unix seconds.","schema":{"type":"integer"}},"RetryAfter":{"description":"Seconds to wait before asking again.","required":true,"schema":{"type":"integer"}},"XRateLimitScope":{"description":"Which ceiling was reached when it is not the per-minute one: daily (the per-IP daily ceiling) or ai-family-daily (a crawler family's daily budget).","schema":{"type":"string","enum":["daily","ai-family-daily"]}}},"responses":{"AutomationRefused":{"description":"A User-Agent that declares a headless browser or a scraping framework, refused before any limit counts it. Text, not JSON, and no rate-limit headers. The refusal happens on our servers: a response the edge cache already holds is served to any client without reaching them — as a 200, with the rate-limit headers of the request that filled the cache.","headers":{"Cache-Control":{"description":"Always no-store.","required":true,"schema":{"type":"string","examples":["no-store"]}},"X-Blocked-UA":{"description":"On the refusal of a declared automation User-Agent only: the declared token that matched, or declared-automation.","schema":{"type":"string"}}},"content":{"text/plain":{"schema":{"type":"string","examples":["Automated access is not permitted.\n"]}}}},"TooManyRequests":{"description":"A published limit was reached. The per-minute answer carries X-RateLimit-Limit, X-RateLimit-Remaining and usually X-RateLimit-Reset; a daily ceiling carries X-RateLimit-Scope instead. A client that asked for text/html when the daily ceiling was reached gets a page saying so instead of the JSON.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-RateLimit-Scope":{"$ref":"#/components/headers/XRateLimitScope"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}},"text/html":{"schema":{"type":"string","description":"The daily-ceiling page."}}}}},"schemas":{"AppListItem":{"type":"object","description":"One record, as /api/apps lists it.","required":["id","slug","recordUrl","name","rawName","canonicalUrl","canonicalDomain","category","categorySlug","categoryKey","entityType","languages","platforms","faviconUrl","deltaWeekly","sourceCount","outboundUrl","displayUrl","tagline","developerName","firstSeenAt","firstSeenBasis","firstShippedAt","stackPrimary","authorship","indexedAt","lastCheckedAt","deadConfirmedAt","aliveStatus"],"properties":{"id":{"type":"string","description":"This index's identifier for the record."},"slug":{"type":"string","description":"The record's current slug."},"recordUrl":{"type":"string","format":"uri","description":"The permanent address of our record of it — the page to cite: https://www.pulsegate.ai/apps/{slug}. It is not the software's address; canonicalUrl and outboundUrl point at the software."},"name":{"type":"string","description":"Display name. When two rows on one page would show the same name, a distinguishing suffix follows it."},"rawName":{"type":"string","description":"The name as discovered."},"canonicalUrl":{"type":"string","description":"The software's address as this index holds it — on many rows a store, marketplace or registry page rather than the maker's own site."},"canonicalDomain":{"type":"string","description":"The domain of canonicalUrl as this index holds it."},"category":{"type":["string","null"],"description":"Name of the record's category."},"categorySlug":{"type":["string","null"],"description":"Slug of the record's category, as /api/categories lists it."},"categoryKey":{"type":"string","description":"categorySlug when there is one; otherwise an older category key, or uncategorized."},"entityType":{"type":"string","enum":["PRODUCT","INFRASTRUCTURE"],"description":"PRODUCT: something people use. INFRASTRUCTURE: something builders build on."},"languages":{"type":"array","items":{"type":"string"},"description":"Languages detected on the software's site, as codes. May be empty."},"platforms":{"type":"array","items":{"type":"string"},"description":"Platforms detected, such as WEB, MOBILE, DESKTOP, API or CLI; WEB when none was detected."},"faviconUrl":{"type":["string","null"],"description":"The icon this index holds for the software."},"deltaWeekly":{"type":"null","description":"Always null: no weekly change is computed."},"sourceCount":{"type":"integer","description":"How many identifier and watched links back the record, counting at most six of each."},"outboundUrl":{"type":"string","description":"The most specific link to the software this index holds: its store or listing page where one exists, else canonicalUrl."},"displayUrl":{"type":"string","description":"outboundUrl shortened for display, or canonicalDomain."},"tagline":{"type":["string","null"],"description":"One line on what it does; null when there is no description."},"developerName":{"type":["string","null"],"description":"Who makes it, when known."},"firstSeenAt":{"type":["string","null"],"format":"date-time","description":"When this index first saw the record — not when the software was released. For records indexed before October 1, 2026 it is often an estimate written by a historical backfill: read firstSeenBasis, and treat a backfilled value as at best a lower bound on the project's age, not an observation."},"firstSeenBasis":{"type":["string","null"],"enum":["observed","backfilled","unknown",null],"description":"How firstSeenAt was set. observed: this index saw the record at that time. backfilled: a backfill's own record shows it wrote the date, or the date is older than this index, so firstSeenAt is not an observation — read it as at best a lower bound on the project's age. unknown: we hold a date and could not establish which of the two it is — read it as backfilled. null: there is no first-seen date. It describes our date, not when the software was released."},"firstShippedAt":{"type":["string","null"],"format":"date-time","description":"The software's release date where it is documented; null otherwise. A model's guess is never published here."},"stackPrimary":{"oneOf":[{"$ref":"#/components/schemas/StackPrimary"},{"type":"null"}],"description":"Null when no stack axis has exactly one detection."},"authorship":{"type":["string","null"],"description":"Who builds it: solo, small_team, team, company or community; null when not established."},"indexedAt":{"type":"string","format":"date-time","description":"When the record entered this index — always an observation."},"lastCheckedAt":{"type":["string","null"],"format":"date-time","description":"Time of the liveness check. Null if no check has run; never filled in from another date."},"deadConfirmedAt":{"type":["string","null"],"format":"date-time","description":"When the record was confirmed gone; null unless aliveStatus is gone."},"aliveStatus":{"type":"string","enum":["alive","gone","unverified"],"description":"alive: a liveness check ran and found it there. gone: a liveness check ran and found it gone. unverified: we have not established it — not \"probably alive\". A record fetched successfully but never assessed is unverified."}}},"StackPrimary":{"type":"object","description":"One detection per stack axis, or null on an axis where the detections disagree or there are none.","required":["framework","hosting","ai"],"properties":{"framework":{"type":["string","null"],"description":"Web framework."},"hosting":{"type":["string","null"],"description":"Hosting."},"ai":{"type":["string","null"],"description":"AI provider."}}},"ActivitySnapshot":{"type":"object","description":"Indexing volume by first-seen date.","required":["indexed24h","indexed7d","indexedLastHour","dailyCounts7d","avg30d","avg7d","deltaPct","insufficientHistory"],"properties":{"indexed24h":{"type":"integer","description":"First seen in the last 24 hours."},"indexed7d":{"type":"integer","description":"First seen in the last 7 days."},"indexedLastHour":{"type":"integer","description":"First seen in the last hour."},"dailyCounts7d":{"type":"array","items":{"$ref":"#/components/schemas/DailyCount"},"description":"Seven UTC days, oldest first."},"avg30d":{"type":"number","description":"Daily average over 30 days."},"avg7d":{"type":"number","description":"Daily average over 7 days."},"deltaPct":{"type":["integer","null"],"description":"indexed24h against avg30d, in per cent; null when there is no average."},"insufficientHistory":{"type":"boolean","description":"True when the index holds less than 30 days of history for this scope."}}},"DailyCount":{"type":"object","required":["ts","value"],"properties":{"ts":{"type":"string","format":"date","description":"The UTC day, as YYYY-MM-DD."},"value":{"type":"integer","description":"Records first seen that day."}}},"AppsPage":{"type":"object","required":["meta","items","apps"],"properties":{"meta":{"$ref":"#/components/schemas/AppsMeta"},"items":{"type":"array","items":{"$ref":"#/components/schemas/AppListItem"},"description":"The page."},"apps":{"type":"array","items":{"$ref":"#/components/schemas/AppListItem"},"deprecated":true,"description":"The same array as items. Legacy, and may go: read items."}}},"AppsMeta":{"type":"object","required":["generatedAt","methods","filteredCount","totalFilteredCount","totalScopeCount","totalIndexedCount","totalAllCount","activeCount","deadCount","indexed24h","activity","page","limit","window","market","segment","isExploreMode","leaderboardMax","directQueryUsed","metaPartial","order","balancedAvailable","unsatisfiable"],"properties":{"generatedAt":{"type":"string","format":"date-time","description":"When this payload was assembled — the time the list was computed. It is not a date for the rows in it: each row carries its own (lastCheckedAt, firstSeenAt, indexedAt)."},"methods":{"type":"array","items":{"$ref":"#/components/schemas/MethodStamp"},"description":"The methods that decided fields of the items in this response, each with the version that decided them: only methods behind a field the items carry, never the whole list. Empty when there are no items. Each method's definition and changelog are on /methodology."},"filteredCount":{"type":"integer","description":"Rows matching the request, as the board displays them (capped at leaderboardMax outside explore mode)."},"totalFilteredCount":{"type":"integer","description":"Rows matching the request."},"totalScopeCount":{"type":"integer","description":"Rows matching the request without its time window; the index's size when the request is the whole catalogue."},"totalIndexedCount":{"type":"integer","description":"Records in the index."},"totalAllCount":{"type":"integer","description":"Records in the index."},"activeCount":{"type":"integer","description":"Records in the index not confirmed gone."},"deadCount":{"type":"integer","description":"Records confirmed gone."},"indexed24h":{"type":"integer","description":"Records first seen in the last 24 hours, within the request's scope; 0 when activity is null."},"activity":{"oneOf":[{"$ref":"#/components/schemas/ActivitySnapshot"},{"type":"null"}],"description":"Recent indexing volume in the request's scope; null when not computed."},"page":{"type":"integer","description":"The page served."},"limit":{"type":"integer","description":"The limit applied: the requested value, clamped to 100."},"window":{"type":"string","enum":["7d","30d","all"],"description":"The time window applied."},"market":{"const":"global","description":"Always global."},"segment":{"type":"string","description":"The segment requested; top unless the request named another."},"isExploreMode":{"type":"boolean","description":"True when the request narrows the catalogue, and the board's cap does not apply."},"leaderboardMax":{"type":"integer","description":"The cap on filteredCount outside explore mode."},"directQueryUsed":{"type":"boolean","description":"Legacy: true on every answer that read rows, false on the unavailable one."},"metaPartial":{"type":"boolean","description":"True when the counts in this meta describe only the rows served, not the whole result."},"order":{"type":"string","enum":["balanced","firstSeen","name","lastUpdated","relevance"],"description":"The order the rows are actually in. Any filter changes the default from balanced to firstSeen. Read it; do not assume it."},"balancedAvailable":{"type":"boolean","description":"Whether the balanced order could serve this request."},"unsatisfiable":{"type":"array","items":{"type":"string"},"description":"Parameters that were asked for and could not narrow anything. When non-empty, the result is empty."}}},"MethodStamp":{"type":"object","required":["id","version"],"properties":{"id":{"type":"string","description":"The method's id, as /methodology lists it."},"version":{"type":"string","description":"The version of that method this response was computed with."}}},"AppsUnavailable":{"type":"object","description":"Answered with HTTP 200 and no-store when the server has no database configured.","required":["meta","items","apps","error"],"properties":{"meta":{"$ref":"#/components/schemas/AppsUnavailableMeta"},"items":{"type":"array","maxItems":0,"items":{"$ref":"#/components/schemas/AppListItem"}},"apps":{"type":"array","maxItems":0,"items":{"$ref":"#/components/schemas/AppListItem"},"deprecated":true},"error":{"const":"Database unavailable"}}},"AppsUnavailableMeta":{"type":"object","required":["generatedAt","methods","filteredCount","totalFilteredCount","totalScopeCount","totalIndexedCount","totalAllCount","activeCount","deadCount","indexed24h","activity","page","limit","window","market","segment","isExploreMode","leaderboardMax","directQueryUsed","metaPartial","degraded"],"properties":{"generatedAt":{"type":"string","format":"date-time","description":"When this payload was assembled — the time the list was computed. It is not a date for the rows in it: each row carries its own (lastCheckedAt, firstSeenAt, indexedAt)."},"methods":{"type":"array","items":{"$ref":"#/components/schemas/MethodStamp"},"description":"The methods that decided fields of the items in this response, each with the version that decided them: only methods behind a field the items carry, never the whole list. Empty when there are no items. Each method's definition and changelog are on /methodology."},"filteredCount":{"type":"integer","description":"Rows matching the request, as the board displays them (capped at leaderboardMax outside explore mode)."},"totalFilteredCount":{"type":"integer","description":"Rows matching the request."},"totalScopeCount":{"type":"integer","description":"Rows matching the request without its time window; the index's size when the request is the whole catalogue."},"totalIndexedCount":{"type":"integer","description":"Records in the index."},"totalAllCount":{"type":"integer","description":"Records in the index."},"activeCount":{"type":"integer","description":"Records in the index not confirmed gone."},"deadCount":{"type":"integer","description":"Records confirmed gone."},"indexed24h":{"type":"integer","description":"Records first seen in the last 24 hours, within the request's scope; 0 when activity is null."},"activity":{"oneOf":[{"$ref":"#/components/schemas/ActivitySnapshot"},{"type":"null"}],"description":"Recent indexing volume in the request's scope; null when not computed."},"page":{"type":"integer","description":"The page served."},"limit":{"type":"integer","description":"The limit applied: the requested value, clamped to 100."},"window":{"type":"string","enum":["7d","30d","all"],"description":"The time window applied."},"market":{"const":"global","description":"Always global."},"segment":{"type":"string","description":"The segment requested; top unless the request named another."},"isExploreMode":{"type":"boolean","description":"True when the request narrows the catalogue, and the board's cap does not apply."},"leaderboardMax":{"type":"integer","description":"The cap on filteredCount outside explore mode."},"directQueryUsed":{"type":"boolean","description":"Legacy: true on every answer that read rows, false on the unavailable one."},"metaPartial":{"type":"boolean","description":"True when the counts in this meta describe only the rows served, not the whole result."},"degraded":{"const":true}}},"ErrorWithMessage":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string","description":"A short code or phrase."},"message":{"type":"string","description":"What happened, in a sentence."}}},"ErrorOnly":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"A short code or phrase: not_found on /api/apps/{slug}."}}},"AppRecordResponse":{"type":"object","required":["app"],"properties":{"app":{"$ref":"#/components/schemas/AppRecord"}}},"PublicPurposeProfileV1":{"type":"object","description":"Versioned compact purpose profile, at most 16 KiB including JSON escaping. Null means unknown. Current enrichment supplies inferred/unknown claims, never functional tests. Collection evidence covers every retained member. Record links do not certify claims. The same fixed slice supplies the human detail.","required":["version","summary","purpose","audience","tasks","topics","functions","constraints","sources","recordChangedAt"],"properties":{"version":{"const":1},"summary":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["string","null"],"maxLength":480},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"purpose":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["string","null"],"maxLength":320},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"audience":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["string","null"],"maxLength":160},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"tasks":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["array","null"],"maxItems":6,"items":{"type":"string","maxLength":80}},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"topics":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["array","null"],"maxItems":5,"items":{"type":"string","maxLength":48}},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"functions":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["array","null"],"maxItems":15,"items":{"type":"string","maxLength":48}},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"constraints":{"type":"object","required":["pricing","license","platforms","deployment","api","mcp","cli","selfHosted"],"properties":{"pricing":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["string","null"],"maxLength":64},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"license":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["string","null"],"maxLength":96},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"platforms":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["array","null"],"maxItems":5,"items":{"type":"string","maxLength":16}},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"deployment":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["array","null"],"maxItems":11,"items":{"type":"string","maxLength":48}},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"api":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["boolean","null"]},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"mcp":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["boolean","null"]},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"cli":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["boolean","null"]},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}},"selfHosted":{"type":"object","required":["value","basis","sourceRefs","observedAt"],"properties":{"value":{"type":["boolean","null"]},"basis":{"type":"string","enum":["inferred","publisher_claim","technical_observation","functional_test","unknown"]},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Only sources supporting this exact claim; empty for record-only links."},"observedAt":{"type":["string","null"],"format":"date-time","description":"Date of this exact claim observation, otherwise null; not the record update date."}}}}},"sources":{"type":"array","maxItems":3,"items":{"type":"object","required":["id","url","kind","scope"],"properties":{"id":{"type":"string","description":"Reference identifier within this profile."},"url":{"type":"string","format":"uri","maxLength":1024},"kind":{"type":"string","enum":["publisher","store","registry","repository"]},"scope":{"type":"string","enum":["record","claim"]}}}},"recordChangedAt":{"type":["string","null"],"format":"date-time","description":"When this record's detail content changed, never when every claim was checked."}}},"AppRecord":{"type":"object","description":"One record, as /api/apps/{slug} answers for it.","required":["id","slug","name","canonicalUrl","canonicalDomain","category","platformType","isListed","isExcludedDefault","recordUrl","firstSeenAt","firstSeenBasis"],"properties":{"profile":{"$ref":"#/components/schemas/PublicPurposeProfileV1"},"id":{"type":"string","description":"This index's identifier for the record."},"slug":{"type":"string","description":"The record's current slug."},"name":{"type":"string","description":"The name as discovered — the value /api/apps calls rawName."},"canonicalUrl":{"type":"string","description":"The software's address as this index holds it."},"canonicalDomain":{"type":"string","description":"The domain of canonicalUrl as this index holds it."},"category":{"type":["string","null"],"description":"The record's older category key; /api/apps carries the current category."},"platformType":{"type":"string","enum":["web","mobile","desktop","extension","plugin","api","other"],"description":"The kind of software."},"isListed":{"const":true,"description":"Always true: an unlisted record answers 404."},"isExcludedDefault":{"const":false,"description":"Always false: a record excluded by curation answers 404."},"recordUrl":{"type":"string","format":"uri","description":"The permanent address of our record of it — the page to cite: https://www.pulsegate.ai/apps/{slug}. canonicalUrl points at the software."},"firstSeenAt":{"type":["string","null"],"format":"date-time","description":"As on /api/apps items."},"firstSeenBasis":{"type":["string","null"],"enum":["observed","backfilled","unknown",null],"description":"As on /api/apps items: how firstSeenAt was set; backfilled makes it at best a lower bound on the project's age, not an observation."}}},"SearchResponse":{"type":"object","required":["shape","evidenceLimited","overview","query","lead","results","nearest","relaxedBy","axes","scope","tookMs"],"properties":{"shape":{"type":"string","enum":["answer","list","empty"],"description":"answer: lead is the row the query was about. list: no single row was. empty: nothing matched, and nearest holds the closest rows."},"failed":{"type":"boolean","description":"True only when search failed; no cached candidates are returned."},"error":{"type":"string","description":"Input error or temporary unavailability explanation."},"evidenceLimited":{"type":"boolean","description":"Requirements cannot currently be established from attributed evidence."},"overview":{"type":["object","null"],"description":"Optional fixed-scope observation: 14 closed UTC days of currently visible indexed additions, two seven-day totals and delta, tracking/observation dates; up to three currently published news items from the existing seven-day feed with Seen/Published and known effective date. Never market growth."},"query":{"$ref":"#/components/schemas/SearchQuery"},"lead":{"oneOf":[{"$ref":"#/components/schemas/SearchRow"},{"type":"null"}],"description":"Only on the answer shape. When present it is the first result, not an extra one."},"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchRow"},"description":"The rows of this page after lead: at most 10 rows with lead counted among them."},"nearest":{"type":"array","items":{"$ref":"#/components/schemas/SearchRow"},"description":"Only on the empty shape: the closest rows. When only the meaning channel found anything, they are that answer, paged as results are: at most 10 rows a page (limit, when smaller), with scope.pages and scope.available counting them. Otherwise they were found by dropping the constraint relaxedBy names: at most 5, on page 1 only — a later page holding no rows is the end of the answer, and its nearest is empty."},"relaxedBy":{"type":["string","null"],"enum":["predicates","meaning",null],"description":"Which constraint was dropped to reach nearest. Null when nothing was dropped."},"axes":{"type":"array","items":{"$ref":"#/components/schemas/SearchAxis"},"description":"Ways to narrow this answer, counted over the matched set. Empty when there is no matched set to count."},"scope":{"$ref":"#/components/schemas/SearchScope"},"tookMs":{"type":"integer","description":"Milliseconds spent answering."}}},"SearchRefused":{"type":"object","required":["shape","evidenceLimited","overview","query","lead","results","nearest","relaxedBy","axes","scope","tookMs","refused"],"properties":{"shape":{"type":"string","enum":["answer","list","empty"],"description":"answer: lead is the row the query was about. list: no single row was. empty: nothing matched, and nearest holds the closest rows."},"failed":{"type":"boolean","description":"True only when search failed; no cached candidates are returned."},"error":{"type":"string","description":"Input error or temporary unavailability explanation."},"evidenceLimited":{"type":"boolean","description":"Requirements cannot currently be established from attributed evidence."},"overview":{"type":["object","null"],"description":"Optional fixed-scope observation: 14 closed UTC days of currently visible indexed additions, two seven-day totals and delta, tracking/observation dates; up to three currently published news items from the existing seven-day feed with Seen/Published and known effective date. Never market growth."},"query":{"$ref":"#/components/schemas/SearchQuery"},"lead":{"oneOf":[{"$ref":"#/components/schemas/SearchRow"},{"type":"null"}],"description":"Only on the answer shape. When present it is the first result, not an extra one."},"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchRow"},"description":"The rows of this page after lead: at most 10 rows with lead counted among them."},"nearest":{"type":"array","items":{"$ref":"#/components/schemas/SearchRow"},"description":"Only on the empty shape: the closest rows. When only the meaning channel found anything, they are that answer, paged as results are: at most 10 rows a page (limit, when smaller), with scope.pages and scope.available counting them. Otherwise they were found by dropping the constraint relaxedBy names: at most 5, on page 1 only — a later page holding no rows is the end of the answer, and its nearest is empty."},"relaxedBy":{"type":["string","null"],"enum":["predicates","meaning",null],"description":"Which constraint was dropped to reach nearest. Null when nothing was dropped."},"axes":{"type":"array","items":{"$ref":"#/components/schemas/SearchAxis"},"description":"Ways to narrow this answer, counted over the matched set. Empty when there is no matched set to count."},"scope":{"$ref":"#/components/schemas/SearchScope"},"tookMs":{"type":"integer","description":"Milliseconds spent answering."},"refused":{"const":"depth","description":"page was above 50."}}},"SearchFailed":{"type":"object","required":["shape","evidenceLimited","overview","query","lead","results","nearest","relaxedBy","axes","scope","tookMs","failed"],"properties":{"shape":{"type":"string","enum":["answer","list","empty"],"description":"answer: lead is the row the query was about. list: no single row was. empty: nothing matched, and nearest holds the closest rows."},"failed":{"const":true},"error":{"type":"string","description":"Input error or temporary unavailability explanation."},"evidenceLimited":{"type":"boolean","description":"Requirements cannot currently be established from attributed evidence."},"overview":{"type":["object","null"],"description":"Optional fixed-scope observation: 14 closed UTC days of currently visible indexed additions, two seven-day totals and delta, tracking/observation dates; up to three currently published news items from the existing seven-day feed with Seen/Published and known effective date. Never market growth."},"query":{"$ref":"#/components/schemas/SearchQuery"},"lead":{"oneOf":[{"$ref":"#/components/schemas/SearchRow"},{"type":"null"}],"description":"Only on the answer shape. When present it is the first result, not an extra one."},"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchRow"},"description":"The rows of this page after lead: at most 10 rows with lead counted among them."},"nearest":{"type":"array","items":{"$ref":"#/components/schemas/SearchRow"},"description":"Only on the empty shape: the closest rows. When only the meaning channel found anything, they are that answer, paged as results are: at most 10 rows a page (limit, when smaller), with scope.pages and scope.available counting them. Otherwise they were found by dropping the constraint relaxedBy names: at most 5, on page 1 only — a later page holding no rows is the end of the answer, and its nearest is empty."},"relaxedBy":{"type":["string","null"],"enum":["predicates","meaning",null],"description":"Which constraint was dropped to reach nearest. Null when nothing was dropped."},"axes":{"type":"array","items":{"$ref":"#/components/schemas/SearchAxis"},"description":"Ways to narrow this answer, counted over the matched set. Empty when there is no matched set to count."},"scope":{"$ref":"#/components/schemas/SearchScope"},"tookMs":{"type":"integer","description":"Milliseconds spent answering."}}},"SearchQuery":{"type":"object","required":["raw","resolved","intent","filters","unapplied"],"properties":{"raw":{"type":"string","description":"The query as received, bounded for public echo."},"warnings":{"type":"array","items":{"type":"string"},"description":"Conditions searched as text or missing evidence."},"requirements":{"type":"array","maxItems":3,"items":{"type":"object","properties":{"key":{"type":"string","description":"Supported requirement key"},"value":{"type":["string","boolean"]}}}},"unknown":{"type":"string","enum":["include","exclude"]},"resolved":{"type":"string","description":"The text that was searched for."},"intent":{"type":"string","enum":["known_item","constrained","need","anchor","explore"],"description":"How the query was read: a name, a need with a constraint, a need, an alternative to something, or a scope."},"filters":{"type":"array","items":{"type":"string"},"description":"The narrowings asked for, as labels."},"unapplied":{"type":"array","items":{"type":"string"},"description":"Narrowings that were asked for and could not be honoured."}}},"SearchRow":{"type":"object","required":["id","slug","recordUrl","name","domain","category","developerName","faviconUrl","tagline","platforms","licence","pricing","why","matchedBy","sources","sameName"],"properties":{"id":{"type":"string","description":"This index's identifier for the record."},"slug":{"type":"string","description":"The record's current slug."},"recordUrl":{"type":"string","format":"uri","description":"The permanent address of our record of it — the link to cite: https://www.pulsegate.ai/apps/{slug}. domain is the software's, not ours."},"name":{"type":"string","description":"Display name."},"domain":{"type":["string","null"],"description":"The software's domain."},"category":{"type":["string","null"],"description":"Name of the record's category."},"developerName":{"type":["string","null"],"description":"Who makes it, when known."},"faviconUrl":{"type":["string","null"],"description":"The icon this index holds for the software."},"tagline":{"type":["string","null"],"description":"One line on what it does; null when there is no description."},"platforms":{"type":"array","items":{"type":"string"},"description":"Identifier platforms the record is held on, such as github_repo or apple_app_id."},"licence":{"type":["string","null"],"description":"Licence."},"pricing":{"type":["string","null"],"description":"Price posture."},"why":{"type":"array","items":{"type":"string"},"description":"Up to two short reasons, each at most 80 codepoints."},"constraints":{"type":"array","maxItems":3,"items":{"type":"object","properties":{"key":{"type":"string","description":"Asked requirement"},"value":{"type":["string","boolean"]},"status":{"type":"string","enum":["met","unmet","unknown"]},"basis":{"type":"string","description":"Evidence basis; inferred is not supported"},"recordedMatch":{"type":["boolean","null"]},"reason":{"type":"string","description":"Bounded explanation"},"sourceRefs":{"type":"array","items":{"type":"string"},"description":"Attributed claim references only; no record-link evidence"},"observedAt":{"type":["string","null"],"description":"Actual claim observation date, never record update time"}}}},"requirementStatus":{"type":["string","null"],"enum":["met","unmet","unknown",null]},"recordSources":{"type":"array","maxItems":0,"items":{"type":"object"},"description":"Richer sources remain in the protected detail while output equivalence is uncalibrated."},"matchedBy":{"type":"array","items":{"type":"string"},"description":"Which retrieval channels found the row: name, terms, meaning."},"sources":{"type":"integer","description":"How many identifier platforms the record is held on."},"sameName":{"type":"integer","description":"How many rows of this answer carry the same name, this one included."}}},"SearchAxis":{"type":"object","required":["key","param","label","values"],"properties":{"key":{"type":"string","enum":["category","platform","license"]},"param":{"type":"string","enum":["category","platform","license"],"description":"The query parameter that narrows by this axis."},"label":{"type":"string","description":"Label for the axis."},"values":{"type":"array","items":{"$ref":"#/components/schemas/SearchAxisValue"},"description":"At most four values."}}},"SearchAxisValue":{"type":"object","required":["value","label","count"],"properties":{"value":{"type":"string","description":"The value to send in param."},"label":{"type":"string","description":"Label for the value."},"count":{"type":"integer","description":"Matched rows with this value."}}},"SearchScope":{"type":"object","required":["matched","matchedIsFloor","searched","page","pages","available"],"properties":{"matched":{"type":"integer","description":"How many rows matched."},"matchedIsFloor":{"type":"boolean","description":"True when matched stopped counting at a ceiling, so the true number is at least this."},"searched":{"type":"integer","description":"How many records the query looked through; may be an estimate."},"searchedIsEstimate":{"type":"boolean","description":"True when searched is a planner estimate, not an exact census."},"page":{"type":"integer","description":"The page served."},"pages":{"type":"integer","description":"How many pages paging can reach, at most 50."},"available":{"type":"integer","description":"How many rows paging can reach."}}},"FacetCounts":{"type":"object","required":["counts","pool","appliedTo","ignored"],"properties":{"counts":{"type":"object","description":"Facet → value → number of records. Keys are the facets' own names (license, pricing, deployment, …), not query parameter names.","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"pool":{"type":"integer","description":"Records the counts are shares of."},"appliedTo":{"$ref":"#/components/schemas/FacetScope"},"ignored":{"type":"array","items":{"type":"string"},"description":"Parameters sent with the request that the counts do not take into account, sorted."}}},"FacetScope":{"type":"object","required":["cat","sub"],"properties":{"cat":{"type":["string","null"],"description":"The cat the counts are scoped to."},"sub":{"type":["string","null"],"description":"The sub the counts are scoped to."}}},"CategoriesResponse":{"type":"object","required":["meta","items"],"properties":{"meta":{"$ref":"#/components/schemas/CategoriesMeta"},"items":{"type":"array","items":{"$ref":"#/components/schemas/CategoryItem"}}}},"CategoriesFailed":{"type":"object","required":["meta","items","error"],"properties":{"meta":{"$ref":"#/components/schemas/CategoriesMeta"},"items":{"type":"array","maxItems":0,"items":{"$ref":"#/components/schemas/CategoryItem"}},"error":{"const":"Failed to fetch categories"}}},"CategoriesMeta":{"type":"object","required":["source","migrationPending","legacyFallbackUsed","degraded"],"properties":{"source":{"type":"string","enum":["category-table-hierarchy","category-table","appEntity-fallback","error"],"description":"Where the list came from: the tree with counts, the flat table, a fallback to category names held on records, or a failure."},"migrationPending":{"type":"boolean","description":"True on the tree with counts."},"legacyFallbackUsed":{"type":"boolean","description":"True when the list came from category names held on records."},"degraded":{"type":"boolean","description":"True on a failure."}}},"CategoryItem":{"type":"object","required":["slug","name"],"description":"sortOrder, count and subs are present with level=top and withSubCounts=1.","properties":{"slug":{"type":"string","description":"Category slug — a value /api/apps/facets takes as cat or sub."},"name":{"type":"string","description":"Category name."},"sortOrder":{"type":"integer","description":"Position in the tree."},"count":{"type":"integer","description":"Visible records in the category and beneath it."},"subs":{"type":"array","items":{"$ref":"#/components/schemas/SubcategoryItem"}}}},"SubcategoryItem":{"type":"object","required":["slug","name","sortOrder","count"],"properties":{"slug":{"type":"string","description":"Subcategory slug."},"name":{"type":"string","description":"Subcategory name."},"sortOrder":{"type":"integer","description":"Position under its parent."},"count":{"type":"integer","description":"Visible records in the subcategory and beneath it."}}},"PublicStats":{"type":"object","required":["market_size","avg_daily_7d","indexed24h","indexed7d","indexedLastHour","dailyCounts7d","avg30d","avg7d","deltaPct","insufficientHistory","timestamp"],"properties":{"market_size":{"type":"integer","description":"Records in the index."},"avg_daily_7d":{"type":"integer","description":"Records first seen per day, averaged over the last 7 days and rounded."},"indexed24h":{"type":"integer","description":"Records first seen in the last 24 hours."},"indexed7d":{"type":"integer","description":"Records first seen in the last 7 days."},"indexedLastHour":{"type":"integer","description":"Records first seen in the last hour."},"dailyCounts7d":{"type":"array","items":{"$ref":"#/components/schemas/DailyCount"},"description":"Seven UTC days, oldest first."},"avg30d":{"type":"number","description":"Records first seen per day, averaged over 30 days."},"avg7d":{"type":"number","description":"Records first seen per day, averaged over 7 days."},"deltaPct":{"type":["integer","null"],"description":"indexed24h against avg30d, in per cent; null when there is no average."},"insufficientHistory":{"type":"boolean","description":"True when the index holds less than 30 days of history."},"timestamp":{"type":"string","format":"date-time","description":"When the windowed figures were computed. market_size is read separately and can be newer."}}},"RateLimited":{"type":"object","required":["error","message","retryAfter"],"properties":{"error":{"type":"string","enum":["Too Many Requests","Daily limit reached","Daily crawl budget reached"]},"message":{"type":"string","description":"What happened, in a sentence."},"retryAfter":{"type":"integer","description":"Seconds to wait — the same value as Retry-After."}}},"McpRequest":{"description":"One JSON-RPC 2.0 request object.","oneOf":[{"$ref":"#/components/schemas/McpInitializeRequest"},{"$ref":"#/components/schemas/McpToolsListRequest"},{"$ref":"#/components/schemas/McpToolsCallRequest"},{"$ref":"#/components/schemas/McpNotification"}]},"McpInitializeRequest":{"type":"object","required":["jsonrpc","id","method"],"properties":{"jsonrpc":{"const":"2.0","description":"Send 2.0; the server does not check it."},"id":{"type":["string","number"],"description":"Echoed in the response."},"method":{"const":"initialize"},"params":{"type":"object","description":"The client's protocol version, capabilities and identity. The server answers the same either way."}}},"McpToolsListRequest":{"type":"object","required":["jsonrpc","id","method"],"properties":{"jsonrpc":{"const":"2.0","description":"Send 2.0; the server does not check it."},"id":{"type":["string","number"],"description":"Echoed in the response."},"method":{"const":"tools/list"}}},"McpToolsCallRequest":{"type":"object","required":["jsonrpc","id","method","params"],"properties":{"jsonrpc":{"const":"2.0","description":"Send 2.0; the server does not check it."},"id":{"type":["string","number"],"description":"Echoed in the response."},"method":{"const":"tools/call"},"params":{"oneOf":[{"$ref":"#/components/schemas/McpSearchCall"},{"$ref":"#/components/schemas/McpLookupProjectCall"},{"$ref":"#/components/schemas/McpListPlatformsCall"}]}}},"McpSearchCall":{"type":"object","required":["name"],"properties":{"name":{"const":"search_catalog"},"arguments":{"$ref":"#/components/schemas/SearchCatalogArguments"}}},"SearchCatalogArguments":{"type":"object","additionalProperties":false,"properties":{"q":{"type":"string","maxLength":120,"description":"Name or task; at most 512 UTF-8 bytes and 12 words. No model or translation is called."},"platform":{"type":"string","description":"Recorded platform filter, using the HTTP search vocabulary."},"category":{"type":"string","description":"Recorded category slug, including its descendants."},"pricing":{"type":"string","description":"Recorded pricing classification, not proof of a price."},"license":{"type":"string","description":"Recorded license family, not a verified legal conclusion."},"require":{"type":"string","maxLength":256,"description":"Up to three requirements, e.g. api:true,mcp:true. Missing or inferred evidence stays unknown."},"unknown":{"type":"string","enum":["include","exclude"],"description":"Defaults to include candidates needing verification."},"page":{"type":"integer","description":"Same normalization as HTTP search; depth beyond 50 is refused."},"limit":{"type":"integer","description":"Same normalization as HTTP search; at most ten combined identities."}}},"SearchToolError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","status","message"],"properties":{"code":{"type":"string","enum":["invalid_input","pagination_limit","search_unavailable"]},"status":{"type":"integer","enum":[400,403,503]},"message":{"type":"string","description":"Reason; no candidates or count."},"retryAfterSeconds":{"type":"integer","const":5}}}}},"McpLookupProjectCall":{"type":"object","required":["name","arguments"],"properties":{"name":{"const":"lookup_project"},"arguments":{"$ref":"#/components/schemas/LookupProjectArguments"}}},"LookupProjectArguments":{"type":"object","description":"Either slug, or both platform and value.","properties":{"slug":{"type":"string","maxLength":512,"description":"The record's slug, current or former."},"platform":{"type":"string","maxLength":64,"description":"Identifier platform to look up by, e.g. github_repo or npm_package; list_identifier_platforms lists them. Use with value."},"value":{"type":"string","maxLength":512,"description":"The identifier on that platform, e.g. owner/name for github_repo."}}},"McpListPlatformsCall":{"type":"object","required":["name"],"properties":{"name":{"const":"list_identifier_platforms"},"arguments":{"type":"object","maxProperties":0,"description":"Takes no arguments."}}},"McpNotification":{"type":"object","required":["jsonrpc","method"],"description":"No id. Answered 202 with no body.","properties":{"jsonrpc":{"const":"2.0","description":"Send 2.0; the server does not check it."},"method":{"type":"string","pattern":"^notifications/"}}},"McpResponse":{"oneOf":[{"$ref":"#/components/schemas/McpInitializeResponse"},{"$ref":"#/components/schemas/McpToolsListResponse"},{"$ref":"#/components/schemas/McpToolCallResponse"},{"$ref":"#/components/schemas/McpErrorResponse"}]},"McpInitializeResponse":{"type":"object","required":["jsonrpc","id","result"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","number","null"],"description":"The request's id; null when the request carried none."},"result":{"$ref":"#/components/schemas/McpInitializeResult"}}},"McpInitializeResult":{"type":"object","required":["protocolVersion","capabilities","serverInfo","instructions"],"properties":{"protocolVersion":{"const":"2025-06-18"},"capabilities":{"$ref":"#/components/schemas/McpCapabilities"},"serverInfo":{"$ref":"#/components/schemas/McpServerInfo"},"instructions":{"type":"string","description":"What the server answers, and what it does not."}}},"McpCapabilities":{"type":"object","required":["tools"],"properties":{"tools":{"type":"object","description":"Empty: the three tools do not change during a session."}}},"McpServerInfo":{"type":"object","required":["name","version"],"properties":{"name":{"const":"pulsegate-provenance"},"version":{"type":"string","description":"The server's version."}}},"McpToolsListResponse":{"type":"object","required":["jsonrpc","id","result"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","number","null"],"description":"The request's id; null when the request carried none."},"result":{"$ref":"#/components/schemas/McpToolsListResult"}}},"McpToolsListResult":{"type":"object","required":["tools"],"properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/McpToolDefinition"},"description":"search_catalog, lookup_project and list_identifier_platforms."}}},"McpToolDefinition":{"type":"object","required":["name","title","description","inputSchema","annotations"],"properties":{"name":{"type":"string","enum":["search_catalog","lookup_project","list_identifier_platforms"]},"title":{"type":"string","description":"Human-readable tool title."},"description":{"type":"string","description":"What the tool returns."},"annotations":{"type":"object","required":["title","readOnlyHint","destructiveHint","idempotentHint","openWorldHint"],"properties":{"title":{"type":"string","description":"Human-readable title for clients reading ToolAnnotations."},"readOnlyHint":{"const":true},"destructiveHint":{"const":false},"idempotentHint":{"const":true},"openWorldHint":{"const":false}}},"inputSchema":{"type":"object","description":"JSON Schema of the arguments — LookupProjectArguments, or none."}}},"McpToolCallResponse":{"type":"object","required":["jsonrpc","id","result"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","number","null"],"description":"The request's id; null when the request carried none."},"result":{"$ref":"#/components/schemas/McpToolCallResult"}}},"McpToolCallResult":{"type":"object","required":["content","isError"],"properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/McpTextContent"},"description":"One text item: the answer as JSON, or why there is none."},"structuredContent":{"oneOf":[{"$ref":"#/components/schemas/SearchResponse"},{"$ref":"#/components/schemas/SearchToolError"},{"$ref":"#/components/schemas/LookupProjectResult"},{"$ref":"#/components/schemas/IdentifierPlatformsResult"}],"description":"The answer as an object. Search tool errors carry SearchToolError; legacy provenance errors omit structuredContent."},"isError":{"type":"boolean","description":"True when the tool could not answer; the reason is the text content."}}},"McpTextContent":{"type":"object","required":["type","text"],"properties":{"type":{"const":"text"},"text":{"type":"string","description":"The answer as indented JSON, or the reason there is none."}}},"LookupProjectResult":{"type":"object","required":["slug","name","url","record_url","identifiers","identifiers_returned","identifiers_truncated","what_this_answer_does_not_say"],"properties":{"slug":{"type":"string","description":"The record's current slug."},"renamed_from":{"type":"string","description":"Present when the record was asked for by a former slug: the slug asked by. slug is the current one."},"name":{"type":"string","description":"Display name."},"url":{"type":"string","description":"The software's own address."},"record_url":{"type":"string","format":"uri","description":"The permanent address of our record of it — the page to cite: https://www.pulsegate.ai/apps/{slug}."},"identifiers":{"type":"array","items":{"$ref":"#/components/schemas/PublishedIdentifier"},"description":"At most 50."},"identifiers_returned":{"type":"integer","description":"How many identifiers are in this answer."},"identifiers_truncated":{"type":"boolean","description":"True when the record holds more identifiers than this answer carries."},"platforms_withheld":{"type":"array","items":{"type":"string"},"description":"Present when the record holds more than 25 identifiers on a platform — a known identity-collapse defect in our data: the platforms left out of identifiers."},"platforms_withheld_because":{"type":"string","description":"Present with platforms_withheld: why they are left out."},"what_this_answer_does_not_say":{"type":"array","items":{"type":"string"},"description":"What this answer does not claim. Keep it with anything you quote from it."}}},"PublishedIdentifier":{"type":"object","required":["platform","value","url","arrival","identity_check","attached_by_dedup"],"properties":{"platform":{"type":"string","description":"The identifier's platform."},"value":{"type":"string","description":"The identifier on that platform."},"url":{"type":["string","null"],"description":"Where the identifier points, when held."},"arrival":{"type":"string","enum":["registry_metadata","outlink_scrape","found_store_ids","source_declared","url_derived","recorded_before_provenance_was_kept","recorded_but_not_described_here"],"description":"How the identifier first arrived. url_derived: parsed out of the store address of the record it was first written to, so it restates that address rather than corroborating it. recorded_before_provenance_was_kept: written before arrival began being recorded, on 2026-08-20. recorded_but_not_described_here: an arrival was recorded in a form this server does not describe."},"identity_check":{"type":"string","enum":["checked_and_belongs","checked_and_does_not_belong","checked_and_undecided","nobody_has_checked"],"description":"Whether anyone has checked that the identifier belongs to this record. Four kinds of statement, not a scale."},"attached_by_dedup":{"type":["string","null"],"description":"A recognized public rule by which we joined it to this record; describes the first attachment only. Unknown reason codes are withheld as null; absence makes no claim."}}},"IdentifierPlatformsResult":{"type":"object","required":["platforms","what_this_answer_does_not_say"],"properties":{"platforms":{"type":"array","items":{"$ref":"#/components/schemas/IdentifierPlatform"}},"what_this_answer_does_not_say":{"type":"array","items":{"type":"string"},"description":"What this answer does not claim. Keep it with anything you quote from it."}}},"IdentifierPlatform":{"type":"object","required":["platform","identifiers_held"],"properties":{"platform":{"type":"string","description":"A value lookup_project accepts as platform."},"identifiers_held":{"type":"integer","description":"Identifiers held on it, over the records lookup_project answers for."}}},"McpErrorResponse":{"type":"object","required":["jsonrpc","id","error"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","number","null"],"description":"The request's id; null when it could not be read or there was none."},"error":{"$ref":"#/components/schemas/McpError"}}},"McpError":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer","enum":[-32700,-32600,-32601,-32603],"description":"-32700 parse error · -32600 not a single request object · -32601 unknown method · -32603 internal error."},"message":{"type":"string","description":"What happened."}}}}}}