{"openapi":"3.0.1","info":{"title":"Vi\u1ec7t \u0110i\u1ec3n API","description":"Read-only API over the Digitizing Vietnam H\u00e1n-N\u00f4m OCR corpus: browse texts, read per-page OCR, and search.","version":"1.0.0"},"servers":[{"url":"https://www.viet-dien.com"}],"paths":{"/api/v1/stats":{"get":{"operationId":"getStats","summary":"Corpus totals","responses":{"200":{"description":"Counts of texts and pages"}}}},"/api/v1/texts":{"get":{"operationId":"listTexts","summary":"List or filter texts","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Filter by romanized or Sinitic title. Diacritics are ignored, so \"viet\" finds \"Viet\"."},{"name":"author","in":"query","schema":{"type":"string"},"description":"Filter by author or contributor; matches part of a name, diacritics ignored. Recorded for about 39% of the corpus."},{"name":"year_from","in":"query","schema":{"type":"integer"},"description":"Earliest year of composition or printing (corpus runs 1433-1989). Matches only the texts the libraries dated, about 49%."},{"name":"year_to","in":"query","schema":{"type":"integer"},"description":"Latest year; see year_from."},{"name":"subject","in":"query","schema":{"type":"string"},"description":"Filter by subject heading, e.g. History, Philosophy, Literary collections."},{"name":"lang","in":"query","schema":{"type":"string"},"description":"Filter by language, e.g. Chinese, Vietnamese."},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"offset","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"A page of texts"}}}},"/api/v1/texts/{textId}":{"get":{"operationId":"getText","summary":"A text's metadata and page list","parameters":[{"name":"textId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Text detail"},"404":{"description":"Not found"}}}},"/api/v1/texts/{textId}/pages/{pageNumber}":{"get":{"operationId":"getPage","summary":"A page's OCR text and image URL","parameters":[{"name":"textId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"pageNumber","in":"path","required":true,"schema":{"type":"integer"}},{"name":"context","in":"query","schema":{"type":"integer","maximum":3},"description":"Also return this many pages either side. A classical sentence runs across the page break, so a quotation taken from one page alone can end mid-clause."}],"responses":{"200":{"description":"Page OCR"},"404":{"description":"Not found"}}}},"/api/v1/texts/{textId}/full.txt":{"get":{"operationId":"getFullText","summary":"A whole work as one plain-text document, pages marked","parameters":[{"name":"textId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"from","in":"query","schema":{"type":"integer"},"description":"First page to include"},{"name":"to","in":"query","schema":{"type":"integer"},"description":"Last page to include"}],"responses":{"200":{"description":"text/plain, \"--- page N ---\" between pages"},"404":{"description":"Not found"}}}},"/api/v1/concordance":{"get":{"operationId":"getConcordance","summary":"Every occurrence of a term, with context either side","description":"One line per occurrence (left / match / right), not one snippet per page as search gives \u2014 the way to see how a term is actually used across the corpus.\n\n\u570b\u5bb6              the characters together, in order\n\"\u898b\u805e \u5c0f\u9304\"        a quoted phrase\n\u570b AND \u5bb6         both somewhere on the same page\n\u570b\u5bb6 OR \u5929\u4e0b       either one\n\u570b NOT \u5bb6         the first, without the second\n\u570b NEAR/10 \u5bb6     within 10 characters of each other\n\u570b?\u5bb6             ? is any single character\n\u898b\u805e*\u9304            * is a short gap (up to 8 characters)\n\nA character also matches its other glyph forms by default (\u70ba finds \u7232, \u771f finds\n\u771e). Pass variants=0 (API) or variants=false (MCP) to turn that off. Simplified\n\u21c4 traditional conversion is separate and always applies, so \u7232 finds \u4e3a either\nway.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"width","in":"query","schema":{"type":"integer","default":30,"maximum":120},"description":"Characters of context on each side"},{"name":"limit","in":"query","schema":{"type":"integer","default":100,"maximum":500},"description":"Maximum lines returned"},{"name":"per_text","in":"query","schema":{"type":"integer"},"description":"At most this many lines from any one text, so a single heavy work cannot fill the whole result"},{"name":"variants","in":"query","schema":{"type":"string"},"description":"Set to 0 to stop a character matching its other glyph forms. Simplified/traditional conversion is separate and still applies."}],"responses":{"200":{"description":"Concordance lines"},"400":{"description":"Malformed query"}}}},"/api/v1/distribution":{"get":{"operationId":"getDistribution","summary":"Which texts carry a term, heaviest first","description":"Matching pages grouped by text. Call this before reading pages, to decide which works are worth the calls.\n\n\u570b\u5bb6              the characters together, in order\n\"\u898b\u805e \u5c0f\u9304\"        a quoted phrase\n\u570b AND \u5bb6         both somewhere on the same page\n\u570b\u5bb6 OR \u5929\u4e0b       either one\n\u570b NOT \u5bb6         the first, without the second\n\u570b NEAR/10 \u5bb6     within 10 characters of each other\n\u570b?\u5bb6             ? is any single character\n\u898b\u805e*\u9304            * is a short gap (up to 8 characters)\n\nA character also matches its other glyph forms by default (\u70ba finds \u7232, \u771f finds\n\u771e). Pass variants=0 (API) or variants=false (MCP) to turn that off. Simplified\n\u21c4 traditional conversion is separate and always applies, so \u7232 finds \u4e3a either\nway.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"cap","in":"query","schema":{"type":"integer","default":200,"maximum":1000},"description":"Most pages to count before reporting \"truncated\": true"},{"name":"variants","in":"query","schema":{"type":"string"},"description":"Set to 0 to stop a character matching its other glyph forms. Simplified/traditional conversion is separate and still applies."}],"responses":{"200":{"description":"Texts with per-text page counts"},"400":{"description":"Malformed query"}}}},"/api/v1/variants":{"get":{"operationId":"getVariants","summary":"A character's other forms, as search matches them","description":"Woodblock carvers used whichever glyph they liked, so search treats several forms as one character. This reports which, so a match can be explained.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Per-character forms"}}}},"/api/v1/search":{"get":{"operationId":"searchOcr","summary":"Full-text search over the OCR (simplified\u21c4traditional aware)","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"A phrase, or: \"quoted phrase\", A AND B, A OR B, A NOT B, A NEAR/10 B, wildcards ? (one character) and * (short gap)."},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"variants","in":"query","schema":{"type":"string"},"description":"By default a character also matches its other glyph forms (\u70ba finds \u7232, \u771f finds \u771e). Set to 0 to turn that off; simplified/traditional conversion is separate and still applies."}],"responses":{"200":{"description":"Matching pages with snippets"}}}}}}
