# Bookmarks API v1: endpoint and schema reference

This reference is generated from the checked-in [OpenAPI contract](https://bookmarks.getbible.net/v1/openapi.json). Return to the [integration guide](/api/bookmarks/v1/) for workflows and ready-to-run examples.

Resolved request server: `https://bookmarks.getbible.net/v1`.

## GET /index.json

Discover the catalogue and resource paths

Resource paths are relative to this directory. counts.verses counts topic-to-verse associations, not distinct verses. checksum is the SHA-256 of the exact all.json bytes. catalog_version increments when that content checksum changes; documentation-only changes do not increment it. schema_version describes the payload format.

Operation ID: `getIndex`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Index |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getIndex",
  "tags": [
    "Discovery"
  ],
  "summary": "Discover the catalogue and resource paths",
  "description": "Resource paths are relative to this directory. counts.verses counts topic-to-verse associations, not distinct verses. checksum is the SHA-256 of the exact all.json bytes. catalog_version increments when that content checksum changes; documentation-only changes do not increment it. schema_version describes the payload format.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Index"
          },
          "examples": {
            "published": {
              "summary": "Complete published response",
              "externalValue": "./index.json"
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## GET /all.json

Download the complete catalogue and all translations

Contains all topic metadata and verse coordinates, plus every locale's names. This is the content document hashed by index.json. No Scripture text is included.

Operation ID: `getAll`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/All |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getAll",
  "tags": [
    "Topics"
  ],
  "summary": "Download the complete catalogue and all translations",
  "description": "Contains all topic metadata and verse coordinates, plus every locale's names. This is the content document hashed by index.json. No Scripture text is included.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/All"
          },
          "examples": {
            "published": {
              "summary": "Complete published response",
              "externalValue": "./all.json"
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## GET /catalog.json

Download every topic with its verse coordinates

The same topics array as all.json, without locale documents. Verse coordinates are translation-independent [book, chapter, verse] triples in the 66-book Protestant canon, sorted without duplicates within a topic. No Scripture text is included.

Operation ID: `getCatalog`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Catalog |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getCatalog",
  "tags": [
    "Topics"
  ],
  "summary": "Download every topic with its verse coordinates",
  "description": "The same topics array as all.json, without locale documents. Verse coordinates are translation-independent [book, chapter, verse] triples in the 66-book Protestant canon, sorted without duplicates within a topic. No Scripture text is included.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Catalog"
          },
          "examples": {
            "published": {
              "summary": "Complete published response",
              "externalValue": "./catalog.json"
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## GET /topics.json

List topics with verse counts

Topic summaries use an integer verses count instead of the coordinate arrays returned by catalog.json and individual topic files. Use the stable id to request a topic. Names and aliases are English display text, not alternative URL identifiers.

Operation ID: `getTopics`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Topics |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getTopics",
  "tags": [
    "Topics"
  ],
  "summary": "List topics with verse counts",
  "description": "Topic summaries use an integer verses count instead of the coordinate arrays returned by catalog.json and individual topic files. Use the stable id to request a topic. Names and aliases are English display text, not alternative URL identifiers.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Topics"
          },
          "examples": {
            "published": {
              "summary": "Complete published response",
              "externalValue": "./topics.json"
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## GET /topics/{id}.json

Read one topic and its translated names

Returns metadata, all verse coordinates, and names keyed by the locales that translate this topic. English (en) is always included. For a missing translation the client should display the English name. Deleted or unknown topic ids have no file.

Operation ID: `getTopic`.

| Parameter | In | Required | Type | Example / default | Description |
| --- | --- | --- | --- | --- | --- |
| `id` | path | Yes | string | adultery | Exact topic id from topics.json. Aliases and display names are not URL ids. |

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Topic |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getTopic",
  "tags": [
    "Topics"
  ],
  "summary": "Read one topic and its translated names",
  "description": "Returns metadata, all verse coordinates, and names keyed by the locales that translate this topic. English (en) is always included. For a missing translation the client should display the English name. Deleted or unknown topic ids have no file.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Topic"
          },
          "examples": {
            "published": {
              "summary": "Complete response from topics/adultery.json",
              "value": {
                "schema_version": 1,
                "id": "adultery",
                "name": "Adultery",
                "color": "#f9a8b8",
                "aliases": [],
                "default": true,
                "names": {
                  "af": "Owerspel",
                  "ar": "الزنا",
                  "br": "Avoultrie",
                  "ch": "Adulterio",
                  "cs": "Cizoložství",
                  "da": "Utroskab",
                  "de": "Ehebruch",
                  "el": "Μοιχεία",
                  "en": "Adultery",
                  "eo": "Adulterio",
                  "es": "Adulterio",
                  "et": "Abielurikkumine",
                  "eu": "Adulterioa",
                  "fi": "Aviorikos",
                  "fr": "Adultère",
                  "gd": "Adhaltranas",
                  "gv": "Brishey-poosey",
                  "hbo": "ניאוף",
                  "hr": "Preljub",
                  "hu": "Házasságtörés",
                  "hy": "Շնություն",
                  "id": "Perzinahan",
                  "it": "Adulterio",
                  "ja": "姦淫",
                  "ko": "간음",
                  "la": "Adulterium",
                  "lt": "Svetimavimas",
                  "lv": "Laulības pārkāpšana",
                  "mg": "fanitsakitsaham-bady",
                  "mi": "puremu",
                  "mn": "Садар самуун",
                  "my": "အိမ်ထောင်ရေးဖောက်ပြန်မှု",
                  "nb": "Utroskap",
                  "nd": "Ukuphinga",
                  "nl": "Overspel",
                  "nn": "Utruskap",
                  "pl": "Cudzołóstwo",
                  "prs": "زنا",
                  "pt": "Adultério",
                  "ro": "Adulter",
                  "ru": "Прелюбодеяние",
                  "sn": "Upombwe",
                  "sq": "Tradhtia bashkëshortore",
                  "sr": "Прељуба",
                  "sv": "Äktenskapsbrott",
                  "sw": "Uzinzi",
                  "th": "การล่วงประเวณี",
                  "tl": "pangangalunya",
                  "tpi": "Pasin pamuk",
                  "tr": "Zina",
                  "uk": "Подружня зрада",
                  "vi": "Ngoại tình",
                  "zh": "奸淫",
                  "zh-hant": "姦淫"
                },
                "verses": [
                  [
                    2,
                    20,
                    14
                  ],
                  [
                    3,
                    18,
                    20
                  ],
                  [
                    3,
                    20,
                    10
                  ],
                  [
                    5,
                    22,
                    22
                  ],
                  [
                    18,
                    24,
                    15
                  ],
                  [
                    20,
                    2,
                    16
                  ],
                  [
                    20,
                    2,
                    17
                  ],
                  [
                    20,
                    5,
                    18
                  ],
                  [
                    20,
                    5,
                    19
                  ],
                  [
                    20,
                    5,
                    20
                  ],
                  [
                    20,
                    6,
                    24
                  ],
                  [
                    20,
                    6,
                    25
                  ],
                  [
                    20,
                    6,
                    26
                  ],
                  [
                    20,
                    6,
                    27
                  ],
                  [
                    20,
                    6,
                    28
                  ],
                  [
                    20,
                    6,
                    29
                  ],
                  [
                    20,
                    6,
                    30
                  ],
                  [
                    20,
                    6,
                    31
                  ],
                  [
                    20,
                    6,
                    32
                  ],
                  [
                    20,
                    7,
                    10
                  ],
                  [
                    20,
                    7,
                    11
                  ],
                  [
                    20,
                    7,
                    12
                  ],
                  [
                    20,
                    7,
                    25
                  ],
                  [
                    20,
                    7,
                    26
                  ],
                  [
                    20,
                    7,
                    27
                  ],
                  [
                    21,
                    5,
                    4
                  ],
                  [
                    21,
                    5,
                    5
                  ],
                  [
                    21,
                    5,
                    6
                  ],
                  [
                    39,
                    2,
                    14
                  ],
                  [
                    39,
                    2,
                    15
                  ],
                  [
                    39,
                    2,
                    16
                  ],
                  [
                    40,
                    5,
                    27
                  ],
                  [
                    40,
                    5,
                    28
                  ],
                  [
                    40,
                    5,
                    31
                  ],
                  [
                    40,
                    5,
                    32
                  ],
                  [
                    40,
                    15,
                    19
                  ],
                  [
                    40,
                    19,
                    3
                  ],
                  [
                    40,
                    19,
                    4
                  ],
                  [
                    40,
                    19,
                    5
                  ],
                  [
                    40,
                    19,
                    6
                  ],
                  [
                    40,
                    19,
                    7
                  ],
                  [
                    40,
                    19,
                    8
                  ],
                  [
                    40,
                    19,
                    9
                  ],
                  [
                    40,
                    19,
                    10
                  ],
                  [
                    41,
                    6,
                    17
                  ],
                  [
                    41,
                    6,
                    18
                  ],
                  [
                    41,
                    6,
                    19
                  ],
                  [
                    41,
                    7,
                    21
                  ],
                  [
                    41,
                    10,
                    2
                  ],
                  [
                    41,
                    10,
                    3
                  ],
                  [
                    41,
                    10,
                    4
                  ],
                  [
                    41,
                    10,
                    5
                  ],
                  [
                    41,
                    10,
                    6
                  ],
                  [
                    41,
                    10,
                    7
                  ],
                  [
                    41,
                    10,
                    8
                  ],
                  [
                    41,
                    10,
                    9
                  ],
                  [
                    41,
                    10,
                    10
                  ],
                  [
                    41,
                    10,
                    11
                  ],
                  [
                    41,
                    10,
                    12
                  ],
                  [
                    42,
                    16,
                    18
                  ],
                  [
                    45,
                    7,
                    1
                  ],
                  [
                    45,
                    7,
                    2
                  ],
                  [
                    45,
                    7,
                    3
                  ],
                  [
                    46,
                    6,
                    9
                  ],
                  [
                    46,
                    7,
                    10
                  ],
                  [
                    46,
                    7,
                    11
                  ],
                  [
                    46,
                    7,
                    12
                  ],
                  [
                    46,
                    7,
                    13
                  ],
                  [
                    46,
                    7,
                    14
                  ],
                  [
                    46,
                    7,
                    15
                  ],
                  [
                    46,
                    7,
                    16
                  ],
                  [
                    46,
                    7,
                    39
                  ],
                  [
                    48,
                    5,
                    19
                  ],
                  [
                    48,
                    5,
                    20
                  ],
                  [
                    48,
                    5,
                    21
                  ],
                  [
                    58,
                    13,
                    4
                  ],
                  [
                    59,
                    4,
                    4
                  ],
                  [
                    61,
                    2,
                    14
                  ]
                ]
              }
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
        "maxLength": 80
      },
      "description": "Exact topic id from topics.json. Aliases and display names are not URL ids.",
      "example": "adultery"
    }
  ]
}
```

</details>

## GET /verses/{book}.json

Find topics associated with verses in a book

A file exists for each of the 66 books. chapters maps chapter-number strings to verse-number strings to sorted topic-id arrays. Only linked chapters and verses appear in the maps. An empty chapters object means no associations in the book.

Operation ID: `getBook`.

| Parameter | In | Required | Type | Example / default | Description |
| --- | --- | --- | --- | --- | --- |
| `book` | path | Yes | integer | 2 | Book number in the 66-book Protestant canon, without leading zeros.  \| Book \| Name \| Chapters \| \|---\|---\|---\| \| 1 \| Genesis \| 50 \| \| 2 \| Exodus \| 40 \| \| 3 \| Leviticus \| 27 \| \| 4 \| Numbers \| 36 \| \| 5 \| Deuteronomy \| 34 \| \| 6 \| Joshua \| 24 \| \| 7 \| Judges \| 21 \| \| 8 \| Ruth \| 4 \| \| 9 \| 1 Samuel \| 31 \| \| 10 \| 2 Samuel \| 24 \| \| 11 \| 1 Kings \| 22 \| \| 12 \| 2 Kings \| 25 \| \| 13 \| 1 Chronicles \| 29 \| \| 14 \| 2 Chronicles \| 36 \| \| 15 \| Ezra \| 10 \| \| 16 \| Nehemiah \| 13 \| \| 17 \| Esther \| 10 \| \| 18 \| Job \| 42 \| \| 19 \| Psalms \| 150 \| \| 20 \| Proverbs \| 31 \| \| 21 \| Ecclesiastes \| 12 \| \| 22 \| Song of Solomon \| 8 \| \| 23 \| Isaiah \| 66 \| \| 24 \| Jeremiah \| 52 \| \| 25 \| Lamentations \| 5 \| \| 26 \| Ezekiel \| 48 \| \| 27 \| Daniel \| 12 \| \| 28 \| Hosea \| 14 \| \| 29 \| Joel \| 3 \| \| 30 \| Amos \| 9 \| \| 31 \| Obadiah \| 1 \| \| 32 \| Jonah \| 4 \| \| 33 \| Micah \| 7 \| \| 34 \| Nahum \| 3 \| \| 35 \| Habakkuk \| 3 \| \| 36 \| Zephaniah \| 3 \| \| 37 \| Haggai \| 2 \| \| 38 \| Zechariah \| 14 \| \| 39 \| Malachi \| 4 \| \| 40 \| Matthew \| 28 \| \| 41 \| Mark \| 16 \| \| 42 \| Luke \| 24 \| \| 43 \| John \| 21 \| \| 44 \| Acts \| 28 \| \| 45 \| Romans \| 16 \| \| 46 \| 1 Corinthians \| 16 \| \| 47 \| 2 Corinthians \| 13 \| \| 48 \| Galatians \| 6 \| \| 49 \| Ephesians \| 6 \| \| 50 \| Philippians \| 4 \| \| 51 \| Colossians \| 4 \| \| 52 \| 1 Thessalonians \| 5 \| \| 53 \| 2 Thessalonians \| 3 \| \| 54 \| 1 Timothy \| 6 \| \| 55 \| 2 Timothy \| 4 \| \| 56 \| Titus \| 3 \| \| 57 \| Philemon \| 1 \| \| 58 \| Hebrews \| 13 \| \| 59 \| James \| 5 \| \| 60 \| 1 Peter \| 5 \| \| 61 \| 2 Peter \| 3 \| \| 62 \| 1 John \| 5 \| \| 63 \| 2 John \| 1 \| \| 64 \| 3 John \| 1 \| \| 65 \| Jude \| 1 \| \| 66 \| Revelation \| 22 \| |

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Book |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getBook",
  "tags": [
    "Verse lookup"
  ],
  "summary": "Find topics associated with verses in a book",
  "description": "A file exists for each of the 66 books. chapters maps chapter-number strings to verse-number strings to sorted topic-id arrays. Only linked chapters and verses appear in the maps. An empty chapters object means no associations in the book.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Book"
          },
          "examples": {
            "published": {
              "summary": "Complete response from verses/2.json",
              "value": {
                "schema_version": 1,
                "book": 2,
                "chapters": {
                  "6": {
                    "6": [
                      "gods-judgment"
                    ]
                  },
                  "12": {
                    "12": [
                      "gods-judgment"
                    ]
                  },
                  "20": {
                    "6": [
                      "obey-gods-commandments"
                    ],
                    "12": [
                      "longevity"
                    ],
                    "14": [
                      "adultery"
                    ]
                  },
                  "22": {
                    "28": [
                      "obey-government-laws"
                    ]
                  },
                  "23": {
                    "2": [
                      "no-fellowship"
                    ],
                    "4": [
                      "non-resistance"
                    ]
                  },
                  "28": {
                    "3": [
                      "wisdom-origin"
                    ],
                    "42": [
                      "christian-clothing"
                    ]
                  },
                  "31": {
                    "3": [
                      "wisdom-origin"
                    ]
                  },
                  "33": {
                    "20": [
                      "effective-prayer"
                    ]
                  },
                  "34": {
                    "7": [
                      "gods-judgment"
                    ],
                    "12": [
                      "no-fellowship"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": [
    {
      "name": "book",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 66
      },
      "description": "Book number in the 66-book Protestant canon, without leading zeros.\n\n| Book | Name | Chapters |\n|---|---|---|\n| 1 | Genesis | 50 |\n| 2 | Exodus | 40 |\n| 3 | Leviticus | 27 |\n| 4 | Numbers | 36 |\n| 5 | Deuteronomy | 34 |\n| 6 | Joshua | 24 |\n| 7 | Judges | 21 |\n| 8 | Ruth | 4 |\n| 9 | 1 Samuel | 31 |\n| 10 | 2 Samuel | 24 |\n| 11 | 1 Kings | 22 |\n| 12 | 2 Kings | 25 |\n| 13 | 1 Chronicles | 29 |\n| 14 | 2 Chronicles | 36 |\n| 15 | Ezra | 10 |\n| 16 | Nehemiah | 13 |\n| 17 | Esther | 10 |\n| 18 | Job | 42 |\n| 19 | Psalms | 150 |\n| 20 | Proverbs | 31 |\n| 21 | Ecclesiastes | 12 |\n| 22 | Song of Solomon | 8 |\n| 23 | Isaiah | 66 |\n| 24 | Jeremiah | 52 |\n| 25 | Lamentations | 5 |\n| 26 | Ezekiel | 48 |\n| 27 | Daniel | 12 |\n| 28 | Hosea | 14 |\n| 29 | Joel | 3 |\n| 30 | Amos | 9 |\n| 31 | Obadiah | 1 |\n| 32 | Jonah | 4 |\n| 33 | Micah | 7 |\n| 34 | Nahum | 3 |\n| 35 | Habakkuk | 3 |\n| 36 | Zephaniah | 3 |\n| 37 | Haggai | 2 |\n| 38 | Zechariah | 14 |\n| 39 | Malachi | 4 |\n| 40 | Matthew | 28 |\n| 41 | Mark | 16 |\n| 42 | Luke | 24 |\n| 43 | John | 21 |\n| 44 | Acts | 28 |\n| 45 | Romans | 16 |\n| 46 | 1 Corinthians | 16 |\n| 47 | 2 Corinthians | 13 |\n| 48 | Galatians | 6 |\n| 49 | Ephesians | 6 |\n| 50 | Philippians | 4 |\n| 51 | Colossians | 4 |\n| 52 | 1 Thessalonians | 5 |\n| 53 | 2 Thessalonians | 3 |\n| 54 | 1 Timothy | 6 |\n| 55 | 2 Timothy | 4 |\n| 56 | Titus | 3 |\n| 57 | Philemon | 1 |\n| 58 | Hebrews | 13 |\n| 59 | James | 5 |\n| 60 | 1 Peter | 5 |\n| 61 | 2 Peter | 3 |\n| 62 | 1 John | 5 |\n| 63 | 2 John | 1 |\n| 64 | 3 John | 1 |\n| 65 | Jude | 1 |\n| 66 | Revelation | 22 |",
      "example": 2
    }
  ]
}
```

</details>

## GET /verses/{book}/{chapter}.json

Find topics associated with verses in a chapter

Every valid canonical chapter has a file, even when verses is empty. Keys are verse numbers as strings; values are sorted topic-id arrays. A missing verse key means no associations. A chapter beyond the selected book's chapter count has no file.

Operation ID: `getChapter`.

| Parameter | In | Required | Type | Example / default | Description |
| --- | --- | --- | --- | --- | --- |
| `book` | path | Yes | integer | 2 | Book number in the 66-book Protestant canon, without leading zeros.  \| Book \| Name \| Chapters \| \|---\|---\|---\| \| 1 \| Genesis \| 50 \| \| 2 \| Exodus \| 40 \| \| 3 \| Leviticus \| 27 \| \| 4 \| Numbers \| 36 \| \| 5 \| Deuteronomy \| 34 \| \| 6 \| Joshua \| 24 \| \| 7 \| Judges \| 21 \| \| 8 \| Ruth \| 4 \| \| 9 \| 1 Samuel \| 31 \| \| 10 \| 2 Samuel \| 24 \| \| 11 \| 1 Kings \| 22 \| \| 12 \| 2 Kings \| 25 \| \| 13 \| 1 Chronicles \| 29 \| \| 14 \| 2 Chronicles \| 36 \| \| 15 \| Ezra \| 10 \| \| 16 \| Nehemiah \| 13 \| \| 17 \| Esther \| 10 \| \| 18 \| Job \| 42 \| \| 19 \| Psalms \| 150 \| \| 20 \| Proverbs \| 31 \| \| 21 \| Ecclesiastes \| 12 \| \| 22 \| Song of Solomon \| 8 \| \| 23 \| Isaiah \| 66 \| \| 24 \| Jeremiah \| 52 \| \| 25 \| Lamentations \| 5 \| \| 26 \| Ezekiel \| 48 \| \| 27 \| Daniel \| 12 \| \| 28 \| Hosea \| 14 \| \| 29 \| Joel \| 3 \| \| 30 \| Amos \| 9 \| \| 31 \| Obadiah \| 1 \| \| 32 \| Jonah \| 4 \| \| 33 \| Micah \| 7 \| \| 34 \| Nahum \| 3 \| \| 35 \| Habakkuk \| 3 \| \| 36 \| Zephaniah \| 3 \| \| 37 \| Haggai \| 2 \| \| 38 \| Zechariah \| 14 \| \| 39 \| Malachi \| 4 \| \| 40 \| Matthew \| 28 \| \| 41 \| Mark \| 16 \| \| 42 \| Luke \| 24 \| \| 43 \| John \| 21 \| \| 44 \| Acts \| 28 \| \| 45 \| Romans \| 16 \| \| 46 \| 1 Corinthians \| 16 \| \| 47 \| 2 Corinthians \| 13 \| \| 48 \| Galatians \| 6 \| \| 49 \| Ephesians \| 6 \| \| 50 \| Philippians \| 4 \| \| 51 \| Colossians \| 4 \| \| 52 \| 1 Thessalonians \| 5 \| \| 53 \| 2 Thessalonians \| 3 \| \| 54 \| 1 Timothy \| 6 \| \| 55 \| 2 Timothy \| 4 \| \| 56 \| Titus \| 3 \| \| 57 \| Philemon \| 1 \| \| 58 \| Hebrews \| 13 \| \| 59 \| James \| 5 \| \| 60 \| 1 Peter \| 5 \| \| 61 \| 2 Peter \| 3 \| \| 62 \| 1 John \| 5 \| \| 63 \| 2 John \| 1 \| \| 64 \| 3 John \| 1 \| \| 65 \| Jude \| 1 \| \| 66 \| Revelation \| 22 \| |
| `chapter` | path | Yes | integer | 20 | Chapter number without leading zeros. Must not exceed the selected book's chapter count (see the book parameter table); 150 is only the maximum across all books. |

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Chapter |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getChapter",
  "tags": [
    "Verse lookup"
  ],
  "summary": "Find topics associated with verses in a chapter",
  "description": "Every valid canonical chapter has a file, even when verses is empty. Keys are verse numbers as strings; values are sorted topic-id arrays. A missing verse key means no associations. A chapter beyond the selected book's chapter count has no file.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Chapter"
          },
          "examples": {
            "published": {
              "summary": "Complete response from verses/2/20.json",
              "value": {
                "schema_version": 1,
                "book": 2,
                "chapter": 20,
                "verses": {
                  "6": [
                    "obey-gods-commandments"
                  ],
                  "12": [
                    "longevity"
                  ],
                  "14": [
                    "adultery"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": [
    {
      "name": "book",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 66
      },
      "description": "Book number in the 66-book Protestant canon, without leading zeros.\n\n| Book | Name | Chapters |\n|---|---|---|\n| 1 | Genesis | 50 |\n| 2 | Exodus | 40 |\n| 3 | Leviticus | 27 |\n| 4 | Numbers | 36 |\n| 5 | Deuteronomy | 34 |\n| 6 | Joshua | 24 |\n| 7 | Judges | 21 |\n| 8 | Ruth | 4 |\n| 9 | 1 Samuel | 31 |\n| 10 | 2 Samuel | 24 |\n| 11 | 1 Kings | 22 |\n| 12 | 2 Kings | 25 |\n| 13 | 1 Chronicles | 29 |\n| 14 | 2 Chronicles | 36 |\n| 15 | Ezra | 10 |\n| 16 | Nehemiah | 13 |\n| 17 | Esther | 10 |\n| 18 | Job | 42 |\n| 19 | Psalms | 150 |\n| 20 | Proverbs | 31 |\n| 21 | Ecclesiastes | 12 |\n| 22 | Song of Solomon | 8 |\n| 23 | Isaiah | 66 |\n| 24 | Jeremiah | 52 |\n| 25 | Lamentations | 5 |\n| 26 | Ezekiel | 48 |\n| 27 | Daniel | 12 |\n| 28 | Hosea | 14 |\n| 29 | Joel | 3 |\n| 30 | Amos | 9 |\n| 31 | Obadiah | 1 |\n| 32 | Jonah | 4 |\n| 33 | Micah | 7 |\n| 34 | Nahum | 3 |\n| 35 | Habakkuk | 3 |\n| 36 | Zephaniah | 3 |\n| 37 | Haggai | 2 |\n| 38 | Zechariah | 14 |\n| 39 | Malachi | 4 |\n| 40 | Matthew | 28 |\n| 41 | Mark | 16 |\n| 42 | Luke | 24 |\n| 43 | John | 21 |\n| 44 | Acts | 28 |\n| 45 | Romans | 16 |\n| 46 | 1 Corinthians | 16 |\n| 47 | 2 Corinthians | 13 |\n| 48 | Galatians | 6 |\n| 49 | Ephesians | 6 |\n| 50 | Philippians | 4 |\n| 51 | Colossians | 4 |\n| 52 | 1 Thessalonians | 5 |\n| 53 | 2 Thessalonians | 3 |\n| 54 | 1 Timothy | 6 |\n| 55 | 2 Timothy | 4 |\n| 56 | Titus | 3 |\n| 57 | Philemon | 1 |\n| 58 | Hebrews | 13 |\n| 59 | James | 5 |\n| 60 | 1 Peter | 5 |\n| 61 | 2 Peter | 3 |\n| 62 | 1 John | 5 |\n| 63 | 2 John | 1 |\n| 64 | 3 John | 1 |\n| 65 | Jude | 1 |\n| 66 | Revelation | 22 |",
      "example": 2
    },
    {
      "name": "chapter",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1,
        "maximum": 150
      },
      "description": "Chapter number without leading zeros. Must not exceed the selected book's chapter count (see the book parameter table); 150 is only the maximum across all books.",
      "example": 20
    }
  ]
}
```

</details>

## GET /locales.json

List available locales and translation coverage

Each entry gives the locale code, its English language name (null if unrecorded), and the number of topic names translated. English (en) is always complete; other locales may translate only part of the catalogue.

Operation ID: `getLocales`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Locales |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getLocales",
  "tags": [
    "Translations"
  ],
  "summary": "List available locales and translation coverage",
  "description": "Each entry gives the locale code, its English language name (null if unrecorded), and the number of topic names translated. English (en) is always complete; other locales may translate only part of the catalogue.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Locales"
          },
          "examples": {
            "published": {
              "summary": "Complete published response",
              "externalValue": "./locales.json"
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## GET /locales/{locale}.json

Read topic names for one locale

topics maps stable topic ids to translated names. name is omitted when no language name is recorded. en is derived from the English topic names and is always present. Other locales may be partial. Clients must implement English fallback; requesting an unavailable locale does not automatically return English.

Operation ID: `getLocale`.

| Parameter | In | Required | Type | Example / default | Description |
| --- | --- | --- | --- | --- | --- |
| `locale` | path | Yes | string | en | Exact lowercase locale code from locales.json, such as en or zh-hant. Unsupported locales do not fall back automatically. |

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Locale |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getLocale",
  "tags": [
    "Translations"
  ],
  "summary": "Read topic names for one locale",
  "description": "topics maps stable topic ids to translated names. name is omitted when no language name is recorded. en is derived from the English topic names and is always present. Other locales may be partial. Clients must implement English fallback; requesting an unavailable locale does not automatically return English.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Locale"
          },
          "examples": {
            "published": {
              "summary": "Complete response from locales/en.json",
              "value": {
                "schema_version": 1,
                "locale": "en",
                "name": "English",
                "topics": {
                  "adultery": "Adultery",
                  "authority-of-the-bible": "Authority of the Bible",
                  "baptism": "Baptism",
                  "biblical-love": "Biblical Love",
                  "blessings-and-curses": "Blessings and Curses",
                  "christian-clothing": "Christian Clothing",
                  "christian-offices": "Christian Offices",
                  "communion": "Communion",
                  "conditional-security": "Conditional Security",
                  "dating": "Dating",
                  "dietary-guidance": "Dietary Guidance",
                  "discipline": "Discipline",
                  "education": "Education",
                  "effective-prayer": "Effective Prayer",
                  "family-planning": "Family Planning",
                  "fear-not": "Fear Not",
                  "first-day": "First Day",
                  "flattery": "Flattery",
                  "free-will": "Free Will",
                  "gods-judgment": "God's Judgment",
                  "grace": "Grace",
                  "home-church": "Home Church",
                  "immutability": "Immutability",
                  "jesus-christs-deity": "Jesus Christ's Deity",
                  "jesus-christs-humanity": "Jesus Christ's Humanity",
                  "leadership": "Leadership",
                  "longevity": "Longevity",
                  "mans-role": "Man's Role",
                  "marriage": "Marriage",
                  "musics-influence": "Music's Influence",
                  "no-fellowship": "No Fellowship",
                  "no-one-is-good": "No One is Good",
                  "non-resistance": "Non-Resistance",
                  "not-under-the-law": "Not Under the Law",
                  "obey-gods-commandments": "Obey God's Commandments",
                  "obey-government-laws": "Obey Government Laws",
                  "omnipotent": "Omnipotent",
                  "omnipresent": "Omnipresent",
                  "omniscient": "Omniscient",
                  "orderly-home": "Orderly Home",
                  "ordinances": "Ordinances",
                  "prince-of-this-world": "Prince of this World",
                  "providence": "Providence",
                  "renewing-of-the-mind": "Renewing of the Mind",
                  "repentance": "Repentance",
                  "saved-by-faith": "Saved by Faith",
                  "sodomy": "Sodomy",
                  "spirit-of-prophecy": "Spirit of Prophecy",
                  "spiritual-gifts": "Spiritual Gifts",
                  "spiritual-judgment": "Spiritual Judgment",
                  "spiritual-rebirth": "Spiritual Rebirth",
                  "temptation": "Temptation",
                  "what-is-life": "What is Life",
                  "wine": "Wine",
                  "wisdom-cause": "Wisdom Cause",
                  "wisdom-fruit": "Wisdom Fruit",
                  "wisdom-origin": "Wisdom Origin",
                  "wisdom-value": "Wisdom Value",
                  "womans-role": "Woman's Role",
                  "word-of-god": "Word of God",
                  "worldly-wisdom": "Worldly Wisdom"
                }
              }
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": [
    {
      "name": "locale",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string",
        "pattern": "^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$",
        "maxLength": 16
      },
      "description": "Exact lowercase locale code from locales.json, such as en or zh-hant. Unsupported locales do not fall back automatically.",
      "example": "en"
    }
  ]
}
```

</details>

## GET /checksums.json

Read SHA-256 hashes for the generated files

files maps relative paths to SHA-256 hashes of the exact published bytes. Includes index.json and openapi.json; excludes checksums.json itself to avoid self-reference. Use this manifest to verify downloads from the same build.

Operation ID: `getChecksums`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | #/components/schemas/Checksums |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getChecksums",
  "tags": [
    "Discovery"
  ],
  "summary": "Read SHA-256 hashes for the generated files",
  "description": "files maps relative paths to SHA-256 hashes of the exact published bytes. Includes index.json and openapi.json; excludes checksums.json itself to avoid self-reference. Use this manifest to verify downloads from the same build.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Checksums"
          },
          "examples": {
            "published": {
              "summary": "Complete published response",
              "externalValue": "./checksums.json"
            }
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## GET /openapi.json

Read this OpenAPI description

Generated with the API on every build. Describes the available GET routes, path parameters, response schemas and examples. Response schemas are embedded with local references so schema resolution does not require another download.

Operation ID: `getOpenapi`.

### Responses

| Status | Description | Media type | Schema |
| --- | --- | --- | --- |
| 200 | The published JSON document. | application/json | object |
| 404 | The requested static file is unavailable (for example an unknown topic or locale, or an invalid book/chapter). The hosting server determines the response body and content type; no JSON error envelope is defined by this builder. | — | See contract |

<details><summary>Complete operation contract</summary>

```json
{
  "operationId": "getOpenapi",
  "tags": [
    "Discovery"
  ],
  "summary": "Read this OpenAPI description",
  "description": "Generated with the API on every build. Describes the available GET routes, path parameters, response schemas and examples. Response schemas are embedded with local references so schema resolution does not require another download.",
  "responses": {
    "200": {
      "description": "The published JSON document.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "description": "An OpenAPI 3.1 description."
          }
        }
      }
    },
    "404": {
      "$ref": "#/components/responses/NotFound"
    }
  },
  "parameters": []
}
```

</details>

## Component schemas

Types, required properties, nested objects, constraints and examples below are copied directly from the contract. A property omitted from a schema’s `required` array is optional, even when examples include it.

### Index

Discovery document. checksum is the SHA-256 of all.json; catalog_version increments whenever that checksum changes between published builds.

<details><summary>View full Index schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/index.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "catalog_version",
    "checksum",
    "counts",
    "resources",
    "locales"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "catalog_version": {
      "type": "integer",
      "minimum": 1
    },
    "checksum": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "counts": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "topics",
        "verses",
        "locales"
      ],
      "properties": {
        "topics": {
          "type": "integer",
          "minimum": 0
        },
        "verses": {
          "type": "integer",
          "minimum": 0
        },
        "locales": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "resources": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    },
    "locales": {
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$",
        "maxLength": 16
      }
    }
  },
  "description": "Discovery document. checksum is the SHA-256 of all.json; catalog_version increments whenever that checksum changes between published builds."
}
```

</details>

### All



<details><summary>View full All schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/all.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "topics",
    "locales"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "topics": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "color",
          "aliases",
          "default",
          "verses"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
            "maxLength": 80
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-f]{6}$"
          },
          "aliases": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
              "maxLength": 80
            }
          },
          "default": {
            "type": "boolean"
          },
          "verses": {
            "type": "array",
            "maxItems": 100000,
            "items": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "prefixItems": [
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 66
                },
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 150
                },
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2000
                }
              ],
              "items": false,
              "description": "Translation-independent [book, chapter, verse] in the 66-book Protestant canon."
            }
          }
        }
      }
    },
    "locales": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$",
        "maxLength": 16
      },
      "additionalProperties": {
        "$ref": "#/components/schemas/Locale"
      }
    }
  }
}
```

</details>

### Catalog



<details><summary>View full Catalog schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/catalog.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "topics"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "topics": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "color",
          "aliases",
          "default",
          "verses"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
            "maxLength": 80
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-f]{6}$"
          },
          "aliases": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
              "maxLength": 80
            }
          },
          "default": {
            "type": "boolean"
          },
          "verses": {
            "type": "array",
            "maxItems": 100000,
            "items": {
              "type": "array",
              "minItems": 3,
              "maxItems": 3,
              "prefixItems": [
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 66
                },
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 150
                },
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2000
                }
              ],
              "items": false,
              "description": "Translation-independent [book, chapter, verse] in the 66-book Protestant canon."
            }
          }
        }
      }
    }
  }
}
```

</details>

### Topics



<details><summary>View full Topics schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/topics.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "topics"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "topics": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "color",
          "aliases",
          "default",
          "verses"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
            "maxLength": 80
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-f]{6}$"
          },
          "aliases": {
            "type": "array",
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
              "maxLength": 80
            }
          },
          "default": {
            "type": "boolean"
          },
          "verses": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    }
  }
}
```

</details>

### Topic



<details><summary>View full Topic schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/topics/<id>.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "id",
    "name",
    "color",
    "aliases",
    "default",
    "names",
    "verses"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "id": {
      "type": "string",
      "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
      "maxLength": 80
    },
    "name": {
      "type": "string",
      "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
      "maxLength": 80
    },
    "color": {
      "type": "string",
      "pattern": "^#[0-9a-f]{6}$"
    },
    "aliases": {
      "type": "array",
      "maxItems": 20,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z0-9][A-Za-z0-9 &'():?-]*[A-Za-z0-9)]$",
        "maxLength": 80
      }
    },
    "default": {
      "type": "boolean"
    },
    "names": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$",
        "maxLength": 16
      },
      "additionalProperties": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120
      }
    },
    "verses": {
      "type": "array",
      "maxItems": 100000,
      "items": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "prefixItems": [
          {
            "type": "integer",
            "minimum": 1,
            "maximum": 66
          },
          {
            "type": "integer",
            "minimum": 1,
            "maximum": 150
          },
          {
            "type": "integer",
            "minimum": 1,
            "maximum": 2000
          }
        ],
        "items": false,
        "description": "Translation-independent [book, chapter, verse] in the 66-book Protestant canon."
      }
    }
  }
}
```

</details>

### Book



<details><summary>View full Book schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/verses/<book>.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "book",
    "chapters"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "book": {
      "type": "integer",
      "minimum": 1,
      "maximum": 66
    },
    "chapters": {
      "type": "object",
      "propertyNames": {
        "pattern": "^[1-9][0-9]{0,2}$"
      },
      "additionalProperties": {
        "type": "object",
        "propertyNames": {
          "pattern": "^[1-9][0-9]{0,3}$"
        },
        "additionalProperties": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "maxLength": 80
          }
        }
      }
    }
  }
}
```

</details>

### Chapter



<details><summary>View full Chapter schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/verses/<book>/<chapter>.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "book",
    "chapter",
    "verses"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "book": {
      "type": "integer",
      "minimum": 1,
      "maximum": 66
    },
    "chapter": {
      "type": "integer",
      "minimum": 1,
      "maximum": 150
    },
    "verses": {
      "type": "object",
      "propertyNames": {
        "pattern": "^[1-9][0-9]{0,3}$"
      },
      "additionalProperties": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "string",
          "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
          "maxLength": 80
        }
      }
    }
  }
}
```

</details>

### Locales



<details><summary>View full Locales schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/locales.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "locales"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "locales": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "name",
          "topics"
        ],
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$",
            "maxLength": 16
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 80
          },
          "topics": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    }
  }
}
```

</details>

### Locale



<details><summary>View full Locale schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Translated topic names for one locale (data/locales/<locale>.json and v1/locales/<locale>.json)",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "locale",
    "topics"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "locale": {
      "type": "string",
      "pattern": "^[a-z]{2,3}(?:-[a-z0-9]{2,8})*$",
      "maxLength": 16
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "topics": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
        "maxLength": 80
      },
      "additionalProperties": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120
      }
    }
  }
}
```

</details>

### Checksums



<details><summary>View full Checksums schema</summary>

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "v1/checksums.json",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "files"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "files": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "pattern": "^[0-9a-f]{64}$"
      }
    }
  }
}
```

</details>

## Authentication contract

```json
{
  "security": [],
  "securitySchemes": {}
}
```

See [access and tokens](/tokens/) for public usage and token requests.
