{"openapi":"3.1.0","info":{"title":"PToB content search","version":"1.0.0","description":"Full-text and typo-tolerant search over published English/German HTML, complete PDFs, diagrams and public downloads. Previews are extracted source text. Indexes are rebuilt with each site publication."},"servers":[{"url":"https://ptob.dev"}],"paths":{"/api/search":{"get":{"operationId":"searchContent","summary":"Find matching passages, with preview content included","parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":512},"description":"Up to 512 characters / 64 words, reduced to at most 8 meaningful terms. Exact/prefix matches first; bounded spelling correction only when no documents match. Reported partial matches retain device identifiers and negative qualifiers, and require two remaining terms when available. Device IDs and terms containing numbers are never corrected."},{"name":"context","in":"query","schema":{"type":"string","enum":["preview","full"],"default":"preview"},"description":"Previews are always included. full also includes the original indexed passage (approximately 1800 characters, not the entire PDF page). Use it to inspect nearby qualifications without downloading and parsing the source again."},{"name":"lang","in":"query","schema":{"type":"string","enum":["en","de"],"default":"en"}},{"name":"type","in":"query","schema":{"type":"string","enum":["all","page","article","research","pdf","data","diagram"],"default":"all"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":20,"default":10}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":200,"default":0}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}},"description":"Ranked documents. Each result includes title, type, language, original date when available, heading, canonical url (with #page for PDF), website reader href, plain preview, markedPreview (U+0001/U+0002 delimit matching words), description, image and relevance score. Top passage per document. total is exact; facets count matching documents by content type before the type filter. correction is null or the corrected query. durationMs measures worker search time; indexVersion identifies the exact content snapshot. Empty q returns coverage counts."},"400":{"description":"Invalid query, filter or pagination; JSON error."},"503":{"description":"Bounded queue full, timeout or unavailable index; JSON error. Retry later."}}}}},"components":{"schemas":{"SearchResult":{"type":"object","required":["title","type","language","url","canonicalUrl","href","preview","markedPreview","citation","provenance","contentUsage","excerptKind"],"properties":{"title":{"type":"string"},"type":{"type":"string","enum":["page","article","research","pdf","data","diagram"]},"language":{"type":"string","enum":["en","de"]},"url":{"type":"string","description":"Canonical source path with section anchor or PDF page."},"canonicalUrl":{"type":"string","format":"uri"},"href":{"type":"string","description":"Website destination, including the built-in PDF reader."},"heading":{"type":"string"},"page":{"type":["integer","null"],"minimum":1},"date":{"type":"string","description":"Original source date when available; empty when absent."},"description":{"type":"string"},"image":{"type":"string"},"citation":{"$ref":"#/components/schemas/Citation"},"provenance":{"$ref":"#/components/schemas/Provenance"},"contentUsage":{"$ref":"#/components/schemas/ContentUsage"},"passage":{"type":"string","description":"Original indexed passage, present only for context=full."},"excerptKind":{"type":"string","enum":["pdf-text","source-text"]},"preview":{"type":"string","description":"Plain source excerpt, included immediately."},"markedPreview":{"type":"string","description":"Same excerpt with U+0001 and U+0002 around matching words; escape before rendering as HTML."},"score":{"type":"number"}}},"Citation":{"type":"object","properties":{"title":{"type":"string"},"authors":{"type":"array","items":{"type":"string"}},"publisher":{"type":"string"},"publishedAt":{"type":["string","null"],"format":"date"},"modifiedAt":{"type":["string","null"],"format":"date"},"url":{"type":"string","format":"uri"},"locator":{"type":"object","properties":{"type":{"enum":["page","section"]},"value":{"type":["integer","string"]},"anchor":{"type":["string","null"]}}}}},"Provenance":{"type":"object","properties":{"sourceUrl":{"type":"string","format":"uri"},"sourceSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"rightsUrl":{"type":"string","format":"uri"},"license":{"type":["object","null"],"properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"}}}}},"ContentUsage":{"type":"object","description":"Publisher preferences for the original source; separate from its copyright license. Mixed search responses decline training regardless of individual source preferences. No extra citation requirement is imposed.","properties":{"aiTrain":{"type":"boolean"},"search":{"type":"boolean"},"aiInput":{"type":"boolean"},"reason":{"type":"string"}}},"SearchResponse":{"type":"object","required":["query","language","results","total","indexVersion","durationMs"],"properties":{"query":{"type":"string"},"language":{"type":"string","enum":["en","de"]},"type":{"type":"string"},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"correction":{"type":["string","null"]},"searchTerms":{"type":"array","maxItems":8,"items":{"type":"string"}},"queryReduced":{"type":"boolean"},"matchMode":{"type":"string","enum":["all-terms","partial"]},"durationMs":{"type":"number"},"indexVersion":{"type":"string","description":"SHA256 fingerprint of the indexed content snapshot."},"cached":{"type":"boolean"},"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}},"facets":{"type":"object","additionalProperties":{"type":"integer"}},"coverage":{"type":"object","properties":{"documents":{"type":"integer"},"pdfPages":{"type":"integer"}}}}}}},"x-examples":["/api/search?q=holdover&lang=en","/api/search?q=chrony&type=pdf&context=full","/api/search?q=Zeitübertragung&lang=de"],"x-retrieval":"Follow result.url with Accept: text/markdown for source HTML pages. PDF URLs identify the matching page; result.href opens the website reader at that page. Source excerpts retain the paper edition and known original dates. citation provides author, title, canonical locator and known dates; provenance binds the exact source SHA256 and its existing rights notice. A null license means no license was inferred. Credit follows existing source terms; there is no special attribution, ranking or citation quota for search results. Fuzzy search corrects spelling, not meaning; Every request returns one language only: en (default) or de. English PDF originals appear only in English results.","x-limits":"At most 20 results, 512 input characters / 64 words, and 8 meaningful search terms per request. Public endpoint; no credentials. No search history is persisted. Responses are no-store. Local search does not change external crawler policy."}