{
  "openapi": "3.1.0",
  "info": {
    "title": "LXKeys Public API",
    "version": "1.0.0",
    "description": "Public and controlled interoperability interfaces for LXKeys. Read interfaces are public. Chronoscript submission is a non-canonical preparation boundary and is disabled by default unless explicitly enabled and authenticated. Canonical issuance remains exclusively controlled by LXKeys.",
    "x-lxkeys-title-fr": "API publique LXKeys",
    "x-lxkeys-description-fr": "Interfaces publiques orientées lecture pour l’interopérabilité, la consultation et la vérification de LXKeys. L’émission canonique et les opérations d’écriture privilégiées ne font pas partie de cette API publique.",
    "x-lxkeys-chronoscript-submission-schema": "/schemas/chronoscript-submission.schema.json"
  },
  "servers": [
    {
      "url": "https://lxkeys.org"
    }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "summary": "Platform status",
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "x-lxkeys-summary-fr": "État public de la plateforme"
      }
    },
    "/api/v1/dypclt/current": {
      "get": {
        "summary": "Current UTC date and DYPCLT address",
        "responses": {
          "200": {
            "description": "Current address"
          }
        },
        "x-lxkeys-summary-fr": "Date UTC courante et adresse DYPCLT correspondante"
      }
    },
    "/api/v1/dypclt": {
      "get": {
        "summary": "Calculate DYPCLT from a UTC civil date",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calculated address"
          },
          "400": {
            "description": "Invalid date"
          }
        },
        "x-lxkeys-summary-fr": "Calculer DYPCLT à partir d’une date civile UTC"
      }
    },
    "/api/v1/lx/{number}": {
      "get": {
        "summary": "Canonical LX data",
        "parameters": [
          {
            "name": "number",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 72
            }
          }
        ],
        "responses": {
          "200": {
            "description": "LX data"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-lxkeys-summary-fr": "Données canoniques d’un LX"
      }
    },
    "/api/v1/ecosystem": {
      "get": {
        "summary": "Public LXKeys platform directory",
        "responses": {
          "200": {
            "description": "Platforms"
          }
        },
        "x-lxkeys-summary-fr": "Répertoire public des plateformes LXKeys"
      }
    },
    "/api/v1/docs": {
      "get": {
        "summary": "Published public documents",
        "responses": {
          "200": {
            "description": "Document index"
          }
        },
        "x-lxkeys-summary-fr": "Documents publics publiés"
      }
    },
    "/api/v1/docs/export": {
      "get": {
        "summary": "Download bilingual public documentation set",
        "responses": {
          "200": {
            "description": "ZIP package",
            "content": {
              "application/zip": {}
            }
          }
        },
        "x-lxkeys-summary-fr": "Télécharger l’ensemble bilingue de documentation publique"
      }
    },
    "/api/v1/docs/{documentId}": {
      "get": {
        "summary": "Get a published public document",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "fr"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Document"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-lxkeys-summary-fr": "Obtenir un document public publié"
      }
    },
    "/api/v1/registry/records": {
      "get": {
        "summary": "Finalized Chronoscript registry positions",
        "responses": {
          "200": {
            "description": "Registry records"
          }
        },
        "x-lxkeys-summary-fr": "Positions finalisées du registre Chronoscript",
        "description": "Returns the canonical finalized registry sequence. Public records expose public content; restricted or private positions expose only the minimum metadata needed to preserve sequence continuity.",
        "x-lxkeys-description-fr": "Retourne la séquence canonique finalisée du registre. Les enregistrements publics exposent leur contenu public ; les positions restreintes ou privées n’exposent que les métadonnées minimales nécessaires à la continuité de la séquence."
      }
    },
    "/api/v1/registry/records/{record}": {
      "get": {
        "summary": "Read or verify one finalized registry position",
        "parameters": [
          {
            "name": "record",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Registry record"
          },
          "404": {
            "description": "Not found"
          }
        },
        "x-lxkeys-summary-fr": "Lire ou vérifier une position finalisée du registre",
        "description": "Accepts a Registry Sequence or Record ID. Disclosure follows the record visibility policy.",
        "x-lxkeys-description-fr": "Accepte une Registry Sequence ou un Record ID. La divulgation respecte la politique de visibilité de l’enregistrement."
      }
    },
    "/api/v1/registry/editions": {
      "get": {
        "summary": "Published cumulative Registry Editions",
        "responses": {
          "200": {
            "description": "Registry editions"
          }
        },
        "x-lxkeys-summary-fr": "Éditions cumulatives publiées du registre"
      }
    },
    "/api/v1/search": {
      "get": {
        "summary": "Search public LXKeys content",
        "x-lxkeys-summary-fr": "Rechercher dans le contenu public LXKeys",
        "description": "Lexical search by complete terms and quoted phrases. Very short or overly general standalone terms may be rejected. Prefix matching is explicit with a trailing * and results are paginated and relevance-ranked.",
        "x-lxkeys-description-fr": "Recherche lexicale par termes complets et expressions entre guillemets. Les termes isolés trop courts ou trop généraux peuvent être refusés. La recherche par préfixe est explicite avec un * final ; les résultats sont paginés et classés par pertinence.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 120
            }
          },
          {
            "name": "lang",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "fr"
              ],
              "default": "en"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 30,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search result page"
          }
        }
      }
    },
    "/api/v1/registry/relations": {
      "get": {
        "summary": "Current Registry Relational Index",
        "x-lxkeys-summary-fr": "Index relationnel courant du registre",
        "description": "Returns a deterministic derived projection of record-to-record relations from the canonical finalized registry. It is not a second source of truth.",
        "x-lxkeys-description-fr": "Retourne une projection dérivée déterministe des relations entre enregistrements à partir du registre canonique finalisé. Il ne s’agit pas d’une seconde source de vérité.",
        "responses": {
          "200": {
            "description": "Derived relational index"
          }
        }
      }
    },
    "/api/v1/registry/records/{record}/relations": {
      "get": {
        "summary": "Relations and current context for one registry record",
        "x-lxkeys-summary-fr": "Relations et contexte courant d’un enregistrement du registre",
        "parameters": [
          {
            "name": "record",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Returns canonical outgoing record relations and derived incoming relations for the requested finalized record.",
        "x-lxkeys-description-fr": "Retourne les relations canoniques sortantes et les relations entrantes dérivées pour l’enregistrement finalisé demandé.",
        "responses": {
          "200": {
            "description": "Record relation context"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/registry/records/{record}/graph": {
      "get": {
        "summary": "Immediate relation graph for one registry record",
        "x-lxkeys-summary-fr": "Graphe relationnel immédiat d’un enregistrement du registre",
        "parameters": [
          {
            "name": "record",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Returns a depth-1 nodes-and-edges graph derived from canonical registry relations.",
        "x-lxkeys-description-fr": "Retourne un graphe nœuds-arêtes de profondeur 1 dérivé des relations canoniques du registre.",
        "responses": {
          "200": {
            "description": "Derived record graph"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/registry/editions/{edition}": {
      "get": {
        "summary": "Read one published Registry Edition",
        "x-lxkeys-summary-fr": "Lire une édition publiée du registre",
        "parameters": [
          {
            "name": "edition",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Registry edition"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/registry/editions/{edition}/relations": {
      "get": {
        "summary": "Relational Index frozen to one Registry Edition",
        "x-lxkeys-summary-fr": "Index relationnel figé pour une édition du registre",
        "parameters": [
          {
            "name": "edition",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Rebuilds the deterministic relation projection only from canonical records included through the edition closing sequence.",
        "x-lxkeys-description-fr": "Reconstruit la projection relationnelle déterministe uniquement à partir des enregistrements canoniques inclus jusqu’à la séquence de clôture de l’édition.",
        "responses": {
          "200": {
            "description": "Edition relational index"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/registry/editions/{edition}/download": {
      "get": {
        "summary": "Download one published Registry Edition package",
        "x-lxkeys-summary-fr": "Télécharger le paquet d’une édition publiée du registre",
        "parameters": [
          {
            "name": "edition",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ZIP package containing canonical registry and relational index"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/registry/records/{record}/evidence-manifest": {
      "get": {
        "summary": "Get canonical Evidence Manifest summary for a finalized Registry Record",
        "parameters": [
          {
            "name": "record",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Evidence Manifest summary"
          },
          "404": {
            "description": "Record not found"
          }
        }
      }
    },
    "/api/v1/registry/evidence/{id}/view": {
      "get": {
        "summary": "Preview a public evidence object",
        "x-lxkeys-summary-fr": "Prévisualiser un objet de preuve public",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public evidence bytes for inline preview"
          },
          "404": {
            "description": "Public evidence not found"
          },
          "415": {
            "description": "Evidence media type not previewable inline"
          }
        }
      }
    },
    "/api/v1/registry/evidence/{id}/download": {
      "get": {
        "summary": "Download a public evidence object",
        "x-lxkeys-summary-fr": "Télécharger un objet de preuve public",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public evidence bytes"
          },
          "404": {
            "description": "Public evidence not found"
          }
        }
      }
    },
    "/api/v1/registry/editions/{edition}/pdf": {
      "get": {
        "summary": "Download the human-readable Registry Edition PDF",
        "x-lxkeys-summary-fr": "Télécharger le PDF lisible de la Registry Edition",
        "parameters": [
          {
            "name": "edition",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Human-readable Registry Edition PDF"
          },
          "404": {
            "description": "Edition not found"
          }
        }
      }
    },
    "/api/v1/releases": {
      "get": {
        "summary": "List activated LXKeys Platform releases",
        "responses": {
          "200": {
            "description": "Public release history"
          }
        }
      }
    },
    "/api/v1/chronoscript/profiles": {
      "get": {
        "summary": "List registered Chronoscript semantic profiles",
        "responses": {
          "200": {
            "description": "Versioned semantic profile registry"
          }
        }
      }
    },
    "/api/v1/chronoscript/submissions": {
      "post": {
        "summary": "Submit a non-canonical Chronoscript preparation",
        "description": "Authenticated opt-in endpoint. A successful request creates a pending submission only. It cannot assign Registry Sequence, Record ID, finality, registration time or canonical hashes. LXKeys review remains required.",
        "parameters": [
          {
            "name": "X-API-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "/schemas/chronoscript-submission.schema.json"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Submission accepted for review"
          },
          "400": {
            "description": "Invalid submission"
          },
          "401": {
            "description": "Unauthorized"
          },
          "503": {
            "description": "Submission API disabled"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/v1/chronoscript/relations": {
      "get": {
        "summary": "List the versioned Chronoscript relation vocabulary",
        "x-lxkeys-summary-fr": "Lister le vocabulaire relationnel Chronoscript versionné",
        "description": "Returns stable relation identifiers, versions, labels and inverse relation names. Relation labels describe declared record relationships and do not themselves determine legal effect.",
        "x-lxkeys-description-fr": "Retourne les identifiants, versions, libellés et relations inverses stables. Les libellés décrivent des relations déclarées entre enregistrements et ne déterminent pas à eux seuls un effet juridique.",
        "responses": {
          "200": {
            "description": "Versioned relation registry"
          }
        }
      }
    }
  }
}
