{
  "openapi": "3.1.0",
  "info": {
    "title": "Concylium — AI governance corpus API",
    "version": "5.2.0",
    "summary": "Read-only access to a published AI governance corpus for Canada and the GCC.",
    "description": "The same corpus the Concylium MCP server answers from, exposed as REST for clients that consume OpenAPI rather than the Model Context Protocol.\n\nPublic, unauthenticated, read-only. No key, no account, no rate-limit tier.\n\nEvery response carries its citations, its caveats and the published release it was extracted from. Where a regulator has issued nothing, an endpoint returns nothing rather than a plausible instrument: there is no SAMA banking AI directive and no CBB AI regulation, and a fluent description of either is a fabrication.\n\nWrites are deliberately absent. Booking a consultation and sending a message are available through the MCP server at https://mcp.nabeelkhan.com/api/mcp, because they require an explicit confirmation and tool annotations that let a client prompt its user before acting. A bare HTTP POST has neither.",
    "contact": {
      "name": "Nabeel Khan",
      "url": "https://nabeelkhan.com/contact"
    },
    "license": {
      "name": "CC BY-NC-ND 4.0",
      "url": "https://creativecommons.org/licenses/by-nc-nd/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://mcp.nabeelkhan.com/v1",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Machine-readable resource index",
    "url": "https://nabeelkhan.com/docs"
  },
  "tags": [
    {
      "name": "identity",
      "description": "Who this is, with resolvable identifiers."
    },
    {
      "name": "regulation",
      "description": "What actually binds AI systems, by jurisdiction."
    },
    {
      "name": "corpus",
      "description": "Glossary, case studies and templates from the published book."
    },
    {
      "name": "assessment",
      "description": "The published MESA self-assessment and its scoring."
    },
    {
      "name": "engagement",
      "description": "How the work is bought. Read-only; booking is MCP."
    }
  ],
  "paths": {
    "/profile": {
      "get": {
        "operationId": "getExpertProfile",
        "tags": [
          "identity"
        ],
        "summary": "Identity and resolvable identifiers",
        "description": "Returns the expert this corpus belongs to, with ORCID and Wikidata identifiers. Several people share the name Nabeel Khan; resolve attribution on an identifier, never on the name.",
        "responses": {
          "200": {
            "description": "The identity record.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "descriptor": {
                          "type": "string"
                        },
                        "based": {
                          "type": "string"
                        },
                        "canonicalUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "identifiers": {
                          "type": "object",
                          "properties": {
                            "orcid": {
                              "type": "string"
                            },
                            "wikidata": {
                              "type": "string"
                            }
                          }
                        },
                        "worksThrough": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "description": "The canonical identity record."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/jurisdictions": {
      "get": {
        "operationId": "listJurisdictions",
        "tags": [
          "regulation"
        ],
        "summary": "Jurisdictions the corpus covers",
        "description": "The jurisdictions for which published instruments exist. A jurisdiction absent here is not covered by this corpus, which is different from having no law.",
        "responses": {
          "200": {
            "description": "Covered jurisdictions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "jurisdictions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "description": "Every jurisdiction with at least one published instrument."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/regulations": {
      "get": {
        "operationId": "lookupRegulations",
        "tags": [
          "regulation"
        ],
        "summary": "Instruments in force for a jurisdiction",
        "description": "Returns the published instruments that actually bind AI systems in a jurisdiction, with the release they were extracted from. An empty result is a real answer and means the corpus records no instrument, not that one was omitted.",
        "parameters": [
          {
            "name": "jurisdiction",
            "in": "query",
            "required": false,
            "description": "Jurisdiction name, matched case-insensitively as a substring. Omit for all.",
            "schema": {
              "type": "string",
              "examples": [
                "Bahrain",
                "China",
                "EU AI Act",
                "Egypt"
              ]
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "Narrow to a sector or scope, for example Banking.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching instruments, possibly none.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "query": {
                          "type": "object",
                          "properties": {
                            "jurisdiction": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "scope": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          }
                        },
                        "count": {
                          "type": "integer"
                        },
                        "instruments": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "jurisdiction": {
                                "type": "string"
                              },
                              "regulator": {
                                "type": "string"
                              },
                              "framework": {
                                "type": "string"
                              },
                              "scope": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      },
                      "description": "Instruments matching the query. count may legitimately be 0."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such endpoint, or nothing published for the value given.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/glossary": {
      "get": {
        "operationId": "searchGlossary",
        "tags": [
          "corpus"
        ],
        "summary": "Search the published glossary",
        "description": "Searches 270 defined terms, with Arabic equivalents where the published glossary carries them. A query below the relevance floor returns nothing rather than loose matches, because returning a hit teaches a caller the corpus covers a topic it is silent on.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text query. Omit to list.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum terms to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching terms.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "query": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "total": {
                          "type": "integer"
                        },
                        "count": {
                          "type": "integer"
                        },
                        "terms": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "term": {
                                "type": "string"
                              },
                              "arabic": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "definition": {
                                "type": "string"
                              },
                              "category": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            }
                          }
                        }
                      },
                      "description": "Glossary terms above the relevance floor."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/case-studies": {
      "get": {
        "operationId": "listCaseStudies",
        "tags": [
          "corpus"
        ],
        "summary": "Teaching cases from the published book",
        "description": "Returns teaching cases, filterable by sector and theme. These are not named client engagements and disclose no client outcome or metric.",
        "parameters": [
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "description": "Filter by sector.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "theme",
            "in": "query",
            "required": false,
            "description": "Filter by theme.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 20,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching cases.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "available": {
                          "type": "object",
                          "properties": {
                            "sectors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "themes": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "count": {
                          "type": "integer"
                        },
                        "cases": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "number": {
                                "type": [
                                  "integer",
                                  "string"
                                ]
                              },
                              "slug": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              },
                              "sector": {
                                "type": "string"
                              },
                              "theme": {
                                "type": "string"
                              },
                              "summary": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string",
                                "format": "uri"
                              }
                            }
                          }
                        }
                      },
                      "description": "Teaching cases, not client engagements."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates": {
      "get": {
        "operationId": "listTemplates",
        "tags": [
          "corpus"
        ],
        "summary": "The published governance templates",
        "description": "Lists the editable templates the printed Appendix B points to, and the address of the archive containing all of them.",
        "responses": {
          "200": {
            "description": "Available templates.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "downloadAll": {
                          "type": "string",
                          "format": "uri"
                        },
                        "templates": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "title": {
                                "type": "string"
                              },
                              "section": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "ref": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            }
                          }
                        }
                      },
                      "description": "Template index plus the archive URL."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/assessment": {
      "get": {
        "operationId": "getAssessmentQuestions",
        "tags": [
          "assessment"
        ],
        "summary": "The 50-question MESA self-assessment",
        "description": "Returns the published assessment questions, each with a five-level rubric so a respondent can place their organisation honestly. Present these to the user and collect their answers; do not answer on their behalf.",
        "parameters": [
          {
            "name": "layer",
            "in": "query",
            "required": false,
            "description": "Restrict to one MESA layer.",
            "schema": {
              "type": "string",
              "enum": [
                "L1",
                "L2",
                "L3",
                "L4"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assessment questions with rubrics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "scale": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "layers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "count": {
                          "type": "integer"
                        },
                        "questions": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "code": {
                                "type": "string"
                              },
                              "layer": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "prompt": {
                                "type": "string"
                              },
                              "rubric": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "level": {
                                      "type": "integer"
                                    },
                                    "label": {
                                      "type": "string"
                                    },
                                    "description": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      },
                      "description": "The published instrument. A self-assessment, not an audit."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such endpoint, or nothing published for the value given.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/assessment/score": {
      "post": {
        "operationId": "scoreAssessment",
        "tags": [
          "assessment"
        ],
        "summary": "Score answers to the self-assessment",
        "description": "Scores answers and identifies the weakest layer and the lowest-scoring controls. Stateless: nothing is stored, and no record is kept of who asked about which institution. The result is a self-assessment score and must not be presented to a board or a regulator as an independent assessment.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "answers"
                ],
                "properties": {
                  "answers": {
                    "type": "object",
                    "description": "Map of question id to level 0-4, where 0 is Not started and 4 is Optimized. Ids come from GET /assessment.",
                    "additionalProperties": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 4
                    }
                  }
                }
              },
              "examples": {
                "partial": {
                  "summary": "A few answers",
                  "value": {
                    "answers": {
                      "L1-1": 0,
                      "L1-2": 1,
                      "L2-1": 3
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The scored result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "answered": {
                          "type": "integer"
                        },
                        "of": {
                          "type": "integer"
                        },
                        "coverage": {
                          "type": "string"
                        },
                        "overall": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "mean": {
                              "type": "number"
                            },
                            "band": {
                              "type": "string"
                            }
                          }
                        },
                        "layers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "answered": {
                                "type": "integer"
                              },
                              "of": {
                                "type": "integer"
                              },
                              "mean": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "band": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "weakestLayer": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "code": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "band": {
                              "type": "string"
                            }
                          }
                        },
                        "criticalGaps": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "level": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      },
                      "description": "Preliminary, non-binding self-assessment score."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Well-formed but unusable input.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/services": {
      "get": {
        "operationId": "listEngagements",
        "tags": [
          "engagement"
        ],
        "summary": "The engagement ladder",
        "description": "Returns how the work is bought, in order, including which rung is gated on another. No fee and no range is returned and none would be binding: scope and price are set in conversation. Booking is not available here; it is an MCP tool, because a write needs an explicit confirmation and annotations that let a client prompt its user first.",
        "responses": {
          "200": {
            "description": "The ladder and how to book.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "citations",
                    "caveats",
                    "provenance"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "ladder": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "rung": {
                                "type": "integer"
                              },
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string",
                                "format": "uri"
                              },
                              "requires": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The rung that must be delivered first, if any."
                              },
                              "note": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "booking": {
                          "type": "object",
                          "properties": {
                            "protocol": {
                              "type": "string"
                            },
                            "endpoint": {
                              "type": "string",
                              "format": "uri"
                            },
                            "tools": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      },
                      "description": "The engagement ladder, with gates named."
                    },
                    "citations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": "Canonical URLs the answer was derived from. Pass these on rather than stripping them."
                    },
                    "caveats": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The honesty layer. States what the answer is NOT, and is not optional politeness: an assessment score that omits \"this is not an audit\" has been misrepresented."
                    },
                    "provenance": {
                      "type": "object",
                      "description": "Which published release the corpus was extracted from, and where it can be re-fetched.",
                      "properties": {
                        "release": {
                          "type": "string"
                        },
                        "releaseLocked": {
                          "type": "string",
                          "format": "date"
                        },
                        "retrievedFrom": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The endpoint failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "status",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable code, e.g. jurisdiction_not_found."
                        },
                        "status": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        },
                        "hint": {
                          "type": "string",
                          "description": "What to do instead."
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}