openapi: 3.1.0
info:
  title: '酉蓮社（旧増上寺報恩蔵）蔵嘉興版大蔵経目録データベース API'
  version: '1.0.0'
  summary: 'Public Web API for the 酉蓮社（旧増上寺報恩蔵）蔵嘉興版大蔵経目録データベース project: IIIF, DTS, JSON:API metadata, and full-text search.'
  description: |
    本ドキュメントは、**酉蓮社（旧増上寺報恩蔵）蔵嘉興版大蔵経目録データベース** が公開している Web API の一覧と利用方法をまとめたものです。

    ## 提供する API の種別

    - **IIIF Presentation API** — 画像コレクション・マニフェスト・注釈の配信（IIIF 2.0 / 3.0 双方対応）
    - **IIIF Content Search API** — マニフェスト内の本文テキスト検索（IIIF Search 標準）
    - **DTS (Distributed Text Services)** — TEI/XML 形式の本文配信（DTS 1-alpha 準拠）
    - **JSON:API** — Drupal JSON:API 形式によるメタデータ配信（書名目録・詳細目録・函册次）
    - **全文検索 API** — 内部 UI 用のページ単位検索とヒット数集計
    - **内部用エンドポイント** — Search-UI のためのジェネリック ES ブリッジ等

    ## メタデータの一括ダウンロード

    JSON:API 経由で1件ずつ取得するほか、Excel (xlsx) / CSV 形式での一括ダウンロードも提供しています。
    詳細は [データセット ページ](/dataset) をご参照ください。

    ## ライセンス

    本データセットは **CC BY 4.0** のもとで提供されます。
    出典として「酉蓮社（旧増上寺報恩蔵）蔵嘉興版大蔵経目録データベース」を明示してください。
  contact:
    name: '酉蓮社（旧増上寺報恩蔵）蔵嘉興版大蔵経目録データベース'
    url: https://u-renja.toyobunko-lab.jp/
  license:
    name: CC BY 4.0
    url: https://creativecommons.org/licenses/by/4.0/

servers:
  - url: https://u-renja.toyobunko-lab.jp
    description: Production

tags:
  - name: IIIF Presentation
    description: |
      IIIF Presentation API 形式の画像コレクション・マニフェスト配信。
      Mirador, Universal Viewer などの IIIF 互換ビューアで閲覧可能です。
  - name: IIIF Search
    description: IIIF Content Search API（マニフェスト内の本文検索）
  - name: DTS
    description: |
      DTS (Distributed Text Services) 1-alpha 準拠のテキスト配信 API。
      [DTS Viewer](https://dts-viewer.vercel.app/ja/?url=https://u-renja.toyobunko-lab.jp/api/dts/collection) で閲覧できます。
  - name: JSON:API
    description: |
      Drupal JSON:API 互換のメタデータ配信。書名目録・詳細目録・函册次の3種を提供します。
      一括ダウンロード（xlsx/csv）は [データセット ページ](/dataset) を参照してください。
  - name: Fulltext Search
    description: 全文検索 API。主に本サイトの検索 UI から利用される内部エンドポイントです。
  - name: Internal
    description: 内部利用エンドポイント（基本認証・Search-UI 連携など）

paths:
  # ============================================================
  # IIIF Presentation API
  # ============================================================
  /api/iiif/{version}/collection/top:
    get:
      tags: [IIIF Presentation]
      summary: トップレベル IIIF コレクション
      description: |
        酉蓮社本のトップレベルの IIIF コレクションを返します。
        分類（經・律・論など）の階層構造を含む `Collection` リソースです。

        **ビューアで開く:**
        - [Image Annotator (kanzaki.com) で開く](https://www.kanzaki.com/works/2016/pub/image-annotator?u=https://u-renja.toyobunko-lab.jp/api/iiif/2/collection/top)
        - Mirador / Universal Viewer などの IIIF 互換ビューアにこの URL を貼り付けてください
      parameters:
        - $ref: '#/components/parameters/IIIFVersion'
      responses:
        '200':
          description: IIIF Collection
          content:
            application/json:
              schema:
                type: object
              examples:
                top:
                  summary: トップレベル
                  externalValue: https://u-renja.toyobunko-lab.jp/api/iiif/2/collection/top

  /api/iiif/{version}/collection/{id}:
    get:
      tags: [IIIF Presentation]
      summary: 分類別 IIIF コレクション
      description: |
        分類 ID（千字文番号など）を指定して、その配下の経典マニフェスト一覧を含む
        IIIF Collection を返します。
      parameters:
        - $ref: '#/components/parameters/IIIFVersion'
        - name: id
          in: path
          required: true
          description: 分類 ID
          schema:
            type: string
          example: '001'
      responses:
        '200':
          description: IIIF Collection
          content:
            application/json:
              schema:
                type: object

  /api/iiif/{version}/collection/bib/{id}:
    get:
      tags: [IIIF Presentation]
      summary: 書誌 ID 別 IIIF コレクション
      description: |
        書誌 ID（経番）を指定して、その経典に属する全冊のマニフェスト一覧を含む
        IIIF Collection を返します。
      parameters:
        - $ref: '#/components/parameters/IIIFVersion'
        - name: id
          in: path
          required: true
          description: 書誌 ID（経番）
          schema:
            type: string
          example: '0001'
      responses:
        '200':
          description: IIIF Collection
          content:
            application/json:
              schema:
                type: object

  /api/iiif/{version}/{id}/manifest:
    get:
      tags: [IIIF Presentation]
      summary: IIIF マニフェスト
      description: |
        指定された ID（函册次、例: `069-05`）に対応する IIIF Presentation マニフェストを返します。
        画像（Canvas）一覧とメタデータを含みます。

        **ビューアで開く:**
        - [Mirador で開く](https://projectmirador.org/embed/?iiif-content=https://u-renja.toyobunko-lab.jp/api/iiif/2/069-05/manifest)
        - [Universal Viewer で開く](https://uv-v4.netlify.app/#?iiifManifestId=https://u-renja.toyobunko-lab.jp/api/iiif/2/069-05/manifest)
      parameters:
        - $ref: '#/components/parameters/IIIFVersion'
        - name: id
          in: path
          required: true
          description: "函册次（例: `069-05`）"
          schema:
            type: string
          example: '069-05'
      responses:
        '200':
          description: IIIF Manifest（v2 または v3）
          content:
            application/json:
              schema:
                type: object

  /api/iiif/{version}/{id}/canvas/{page}/annotation:
    get:
      tags: [IIIF Presentation]
      summary: Canvas の OCR 注釈リスト
      description: |
        指定 Canvas（ページ）の OCR テキストを座標付きで返す IIIF AnnotationList です。
        全文検索のヒット位置や、本文の領域単位アクセスに利用できます。
      parameters:
        - $ref: '#/components/parameters/IIIFVersion'
        - name: id
          in: path
          required: true
          description: 函册次
          schema:
            type: string
          example: '069-05'
        - name: page
          in: path
          required: true
          description: ページ番号（1-based）
          schema:
            type: integer
          example: 1
      responses:
        '200':
          description: IIIF AnnotationList
          content:
            application/json:
              schema:
                type: object

  # ============================================================
  # IIIF Content Search API
  # ============================================================
  /api/iiif-search/{version}/{id}:
    get:
      tags: [IIIF Search]
      summary: IIIF Content Search
      description: |
        IIIF Content Search API 標準に準拠した、マニフェスト内テキスト検索です。
        Mirador などの IIIF 互換ビューアの検索機能から自動的に呼び出されます。

        - パラメータ `q` に検索語を渡します
        - レスポンスはヒット位置を Annotation として含む AnnotationList です
      parameters:
        - $ref: '#/components/parameters/IIIFVersion'
        - name: id
          in: path
          required: true
          description: 函册次（マニフェストID）
          schema:
            type: string
          example: '069-05'
        - name: q
          in: query
          required: false
          description: 検索語
          schema:
            type: string
          example: '佛'
      responses:
        '200':
          description: IIIF AnnotationList（ヒット結果）
          content:
            application/json:
              schema:
                type: object

  # ============================================================
  # DTS
  # ============================================================
  /api/dts:
    get:
      tags: [DTS]
      summary: DTS Entry Point
      description: |
        DTS API のエントリポイントです。`collection`, `navigation`, `document` の各エンドポイントへの
        URI テンプレートを返します。

        **ビューアで開く:**
        - [DTS Viewer で開く](https://dts-viewer.vercel.app/ja/?url=https://u-renja.toyobunko-lab.jp/api/dts/collection)
      responses:
        '200':
          description: DTS Entry Point
          content:
            application/json:
              schema:
                type: object

  /api/dts/collection:
    get:
      tags: [DTS]
      summary: DTS Collection
      description: |
        本文コレクションを返します。階層構造（経典 → 巻 → ページ → 行）を持ち、
        各メンバーは citation を伴います。

        **ビューアで開く:**
        - [DTS Viewer で開く](https://dts-viewer.vercel.app/ja/?url=https://u-renja.toyobunko-lab.jp/api/dts/collection)
      parameters:
        - name: id
          in: query
          required: false
          description: コレクション ID（IIIF `@id`）。省略時はルートコレクション。
          schema:
            type: string
      responses:
        '200':
          description: DTS Collection
          content:
            application/json:
              schema:
                type: object

  /api/dts/navigation:
    get:
      tags: [DTS]
      summary: DTS Navigation
      description: |
        指定リソースの本文構造（citable units）を取得します。
      parameters:
        - name: resource
          in: query
          required: true
          description: 対象リソースの IIIF `@id`
          schema:
            type: string
            example: https://u-renja.toyobunko-lab.jp/api/iiif/2/001-01/manifest
        - name: ref
          in: query
          required: false
          description: citable unit の参照
          schema:
            type: string
        - name: down
          in: query
          required: false
          description: 取得階層の深さ
          schema:
            type: integer
      responses:
        '200':
          description: DTS Navigation
          content:
            application/json:
              schema:
                type: object

  /api/dts/document:
    get:
      tags: [DTS]
      summary: DTS Document
      description: |
        指定リソースの TEI/XML 本文を返します。`ref` を指定するとフラグメント取得になります。
      parameters:
        - name: resource
          in: query
          required: true
          description: 対象リソースの IIIF `@id`
          schema:
            type: string
            example: https://u-renja.toyobunko-lab.jp/api/iiif/2/001-01/manifest
        - name: ref
          in: query
          required: false
          description: citable unit の参照（フラグメント取得）
          schema:
            type: string
      responses:
        '200':
          description: TEI/XML 本文
          content:
            application/xml:
              schema:
                type: string

  # ============================================================
  # JSON:API
  # ============================================================
  /api/jsonapi/node/u_bib:
    get:
      tags: [JSON:API]
      summary: 書名目録（経典単位）
      description: |
        書名目録（経典単位）のメタデータを Drupal JSON:API 形式で返します。
        譯者・刊記・寸法等を含みます。

        **一括ダウンロード:** [Excel/CSV はこちら](/dataset)
      parameters:
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageOffset'
        - name: filter[field_id]
          in: query
          required: false
          description: 経典 ID で絞り込み
          schema:
            type: string
      responses:
        '200':
          description: JSON:API レスポンス
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonApiCollection'

  /api/jsonapi/node/u_detail:
    get:
      tags: [JSON:API]
      summary: 詳細目録（冊次単位）
      description: |
        詳細目録（冊次単位）のメタデータを Drupal JSON:API 形式で返します。
        刊記・千字文・印記等の詳細項目を含みます。

        **一括ダウンロード:** [Excel/CSV はこちら](/dataset)
      parameters:
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageOffset'
        - name: filter[field_u_tsuban]
          in: query
          required: false
          description: 通番で絞り込み
          schema:
            type: string
      responses:
        '200':
          description: JSON:API レスポンス
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonApiCollection'

  /api/jsonapi/node/u_satsu:
    get:
      tags: [JSON:API]
      summary: 函册次メタデータ
      description: |
        函册次単位の物理構成（連・箱・段・冊）と表紙情報を含むメタデータを返します。

        **一括ダウンロード:** [Excel/CSV はこちら](/dataset)
      parameters:
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageOffset'
        - name: filter[field_u_parent_str]
          in: query
          required: false
          description: 親（函）で絞り込み
          schema:
            type: string
      responses:
        '200':
          description: JSON:API レスポンス
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonApiCollection'

  /api/jsonapi/node/u_image_detail_field:
    get:
      tags: [JSON:API]
      summary: 画像詳細フィールド
      description: |
        画像単位の詳細フィールド（領域・補足情報など）を返します。
        主に item ページの画像詳細表示で利用されています。
      parameters:
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageOffset'
        - name: filter[field_u_parent]
          in: query
          required: false
          description: 親 ID で絞り込み
          schema:
            type: integer
      responses:
        '200':
          description: JSON:API レスポンス
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonApiCollection'

  # ============================================================
  # Fulltext Search
  # ============================================================
  /api/fulltext-search:
    post:
      tags: [Fulltext Search]
      summary: 全文検索（ページ単位）
      description: |
        本サイトの全文検索 UI から呼び出される内部 POST エンドポイントです。
        Elasticsearch 上の `u_pages_v3` インデックスをクエリし、ファセット付きの結果を返します。

        外部から直接利用する場合は、以下のような body を送信してください。

        > **注**: このエンドポイントは内部 UI の都合に合わせた形になっており、API として安定したインタフェースを保証するものではありません。
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FulltextSearchRequest'
            example:
              state:
                searchTerm: 佛
                current: 1
                resultsPerPage: 20
                filters: []
      responses:
        '200':
          description: 検索結果
          content:
            application/json:
              schema:
                type: object

  /api/fulltext-search/word-count:
    post:
      tags: [Fulltext Search]
      summary: 全文検索ヒット語数の集計
      description: |
        全文検索の検索語が、結果セット内で何回出現するかを集計して返します。
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FulltextSearchRequest'
      responses:
        '200':
          description: 集計結果
          content:
            application/json:
              schema:
                type: object
                properties:
                  wordCount:
                    type: integer

  # ============================================================
  # Internal
  # ============================================================
  /api/{index}/search:
    get:
      tags: [Internal]
      summary: ジェネリック ES 検索ブリッジ
      description: |
        Search-UI 用のジェネリック Elasticsearch ブリッジです。
        本サイトの React 検索 UI から内部的に利用されます。
      parameters:
        - name: index
          in: path
          required: true
          description: Elasticsearch インデックス名
          schema:
            type: string
      responses:
        '200':
          description: ES 結果
          content:
            application/json:
              schema:
                type: object
    post:
      tags: [Internal]
      summary: ジェネリック ES 検索ブリッジ（Search-UI 形式）
      description: |
        Search-UI の `state` と `queryConfig` を受け取り、ES クエリに変換して結果を返します。
      parameters:
        - name: index
          in: path
          required: true
          description: Elasticsearch インデックス名
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                state:
                  type: object
                queryConfig:
                  type: object
      responses:
        '200':
          description: ES 結果（Search-UI 形式）
          content:
            application/json:
              schema:
                type: object

  /api/{index}/item/{id}:
    get:
      tags: [Internal]
      summary: ES ドキュメント単一取得
      description: |
        指定 ES インデックスから `field_id` でドキュメント1件を取得します。
      parameters:
        - name: index
          in: path
          required: true
          schema:
            type: string
        - name: id
          in: path
          required: true
          description: field_id の値
          schema:
            type: string
      responses:
        '200':
          description: ES ドキュメント
          content:
            application/json:
              schema:
                type: object

  /api/jsonapi/node/u_hako:
    get:
      tags: [Internal]
      summary: 函（hako）一覧（集計）
      description: |
        函（親 ID = `field_u_parent_str`）ごとの冊数を集計して返します。
        現状フロントエンドからは利用されていない補助的なエンドポイントです。
      responses:
        '200':
          description: JSON:API レスポンス
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonApiCollection'

  /api/openapi/{locale}:
    get:
      tags: [Internal]
      summary: OpenAPI 仕様書配信
      description: |
        本ドキュメント自身（OpenAPI 3.1 YAML）をロケール別に配信するメタエンドポイントです。
        テンプレート中の `酉蓮社（旧増上寺報恩蔵）蔵嘉興版大蔵経目録データベース` 等のプレースホルダはサーバ側で差し替えられます。
      parameters:
        - name: locale
          in: path
          required: true
          description: ロケール (`ja` または `en`)
          schema:
            type: string
            enum: ['ja', 'en']
          example: ja
      responses:
        '200':
          description: OpenAPI YAML
          content:
            application/yaml:
              schema:
                type: string

  /api/auth:
    get:
      tags: [Internal]
      summary: Basic 認証用エンドポイント
      description: |
        ステージング環境等で Basic 認証を要求するための内部エンドポイントです。
        通常の利用者が直接呼ぶことはありません。
      responses:
        '401':
          description: "401 Unauthorized（`WWW-Authenticate: Basic` を返す）"

components:
  parameters:
    IIIFVersion:
      name: version
      in: path
      required: true
      description: IIIF Presentation API のバージョン（`2` または `3`）
      schema:
        type: string
        enum: ['2', '3']
      example: '2'
    PageLimit:
      name: page[limit]
      in: query
      required: false
      description: >-
        1ページあたりの取得件数（既定 50、最大 3000）。
        Cloudflare Worker の資源上限を超えないよう、サーバ側で 3000 にクランプされる。
      schema:
        type: integer
        default: 50
        maximum: 3000
        # example は疎通テスト(scripts/test-openapi-endpoints.js)が使う値。
        example: 50
    PageOffset:
      name: page[offset]
      in: query
      required: false
      description: 取得開始位置
      schema:
        type: integer
        default: 0

  schemas:
    JsonApiCollection:
      type: object
      description: Drupal JSON:API 互換のコレクション形式レスポンス
      properties:
        jsonapi:
          type: object
          properties:
            version:
              type: string
              example: '1.0'
        meta:
          type: object
          properties:
            total:
              type: integer
              description: 全件数
              example: 2390
        data:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                example: node--u_satsu
              id:
                type: string
                example: '069-05'
              attributes:
                type: object
                additionalProperties: true

    FulltextSearchRequest:
      type: object
      required: [state]
      properties:
        state:
          type: object
          properties:
            searchTerm:
              type: string
              example: '佛'
            current:
              type: integer
              default: 1
            resultsPerPage:
              type: integer
              default: 20
            filters:
              type: array
              items:
                type: object
            sortField:
              type: string
            sortDirection:
              type: string
              enum: [asc, desc]
            facets:
              type: object
