{
  "openapi": "3.1.0",
  "info": {
    "title": "Mondonomo public API",
    "version": "2026-09-05",
    "summary": "The data behind the name and country pages.",
    "description": "A hand-written description of the endpoints that are public and stable. It is deliberately not the framework's generated document: that one also describes the model-lab routes and the server-render-only page endpoints, which are neither public nor stable, and publishing it would advertise them. Rate-limited for casual use; bulk access is licensed (see /business).",
    "license": { "name": "Licensed; see https://mondonomo.ai/business" }
  },
  "servers": [
    { "url": "https://api.mondonomo.ai/api/v1", "description": "Current host" },
    { "url": "https://nelma-api.mondonomo.ai/api/v1", "description": "Alias; the host this service answered on before 2026-09-07" }
  ],
  "paths": {
    "/name-graph/{form}": {
      "get": {
        "summary": "Everything a name page is built from",
        "description": "Spellings and scripts, the country and language distribution, the cluster of related spellings, notable bearers, the etymology where a source makes the claim, and the related-name graph.",
        "parameters": [
          { "name": "form", "in": "path", "required": true, "schema": { "type": "string" },
            "description": "The spelling, case-folded. Percent-encode it: most of the corpus is not ASCII.",
            "example": "ivan" }
        ],
        "responses": {
          "200": { "description": "The name graph.", "content": { "application/json": { "schema": { "type": "object" } } } },
          "404": { "description": "No node for this spelling. An ordinary answer for the long tail, not an error." }
        }
      }
    },
    "/name/{form}/evidence": {
      "get": {
        "summary": "The registers that attest a spelling",
        "description": "Official registers with their counts, reference works listed without figures, and one register's per-year series where it exists. Licensed works are named as attesting the name and never carry a count: their figures are not ours to publish. The timeline is one register's own series and never a sum, because two registers counting the same people would double them.",
        "parameters": [
          { "name": "form", "in": "path", "required": true, "schema": { "type": "string" }, "example": "ivan" }
        ],
        "responses": {
          "200": { "description": "The receipts." },
          "404": { "description": "No register in the corpus attests this spelling. Ordinary for most of the long tail: 91.6% of the top 100k personal-name forms have receipts, 78% of the top million." },
          "503": { "description": "The attestation artifact is unavailable. Not a fact about the name." }
        }
      }
    },
    "/names": {
      "get": {
        "summary": "The country atlas index",
        "description": "All 250 countries with what each page is built from: its tier, how many official registers it has, whether any publishes a per-year series.",
        "responses": { "200": { "description": "The index." } }
      }
    },
    "/names/{cc}": {
      "get": {
        "summary": "One country",
        "description": "The registers that country publishes and their rankings, the same ranking over our record corpus, the characteristic names, the scripts, the diaspora and the naming system.",
        "parameters": [
          { "name": "cc", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[A-Za-z]{2}$" }, "example": "HR" }
        ],
        "responses": {
          "200": { "description": "The country." },
          "404": { "description": "Not one of the 250 countries the atlas covers." }
        }
      }
    },
    "/parse": {
      "post": {
        "summary": "Split a full name into labelled parts",
        "description": "Returns ranked alternative parses, each with per-token labels, the language and entity-type scores behind it, and the country and language statistics for every token.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": {
            "type": "object",
            "required": ["name"],
            "properties": {
              "name": { "type": "string", "example": "Nguyễn Thị Hương" },
              "lang": { "type": "string", "description": "ISO language hint." },
              "cc": { "type": "string", "description": "ISO country hint." },
              "top_k": { "type": "integer", "default": 3, "maximum": 20 },
              "lang_hints": { "type": "array", "items": { "type": "string" } }
            }
          } } }
        },
        "responses": { "200": { "description": "Ranked parses." } }
      }
    },
    "/transliterate": {
      "post": {
        "summary": "Romanize a name, or produce its pronunciation",
        "description": "Ranked variants with a renormalized confidence, an absolute probability and the models that produced each. Set task to g2p for a phonetic transcription instead of a romanization.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": {
            "type": "object",
            "required": ["text"],
            "properties": {
              "text": { "type": "string", "example": "สมชาย" },
              "top_k": { "type": "integer", "default": 5 },
              "task": { "type": "string", "enum": ["translit", "g2p"], "default": "translit" },
              "src_lang": { "type": "string" }
            }
          } } }
        },
        "responses": { "200": { "description": "Ranked variants." } }
      }
    },
    "/classify": {
      "post": {
        "summary": "Is this string a name, and what kind",
        "responses": { "200": { "description": "Entity-type scores." },
          "400": { "description": "Malformed request." } }
      }
    },
    "/health": {
      "get": {
        "summary": "Service health",
        "responses": { "200": { "description": "Status of each loaded component." } }
      }
    }
  }
}
