API

Programs can read everything the site shows, and send suggestions, over plain HTTP. No key or account is needed to read.

The OpenAPI document is at /openapi.json. It loads in Swagger UI, Redoc, Postman and any OpenAPI client generator.

Annotations are released under CC0 1.0: no permission or attribution is needed.

Works

Works, editions, units, permanent numbers and the library's counts.

GET /v1/works

List the works in the library. Works are ordered by title. Each work carries its current edition and its top-level units.

NameInTypeDescription
limitqueryinteger, 1 to 100, default 20Items per page, from 1 to 100. Example: 20.
cursorquerystringThe opaque next_cursor value from the previous page. Example: WyJoZXJldGljcyIsImhlcmV0aWNzIl0.

Returns WorkList with status 200. A page of works.

{
  "items": [
    {
      "title": "Heretics",
      "work_type": "book",
      "editions": [
        {
          "edition_id": "pg470-r1",
          "label": "Project Gutenberg #470 text",
          "language_tag": "en",
          "publication_year": null,
          "current_visible_source_revision_id": "src_pg470-r1"
        }
      ],
      "slug": "heretics",
      "oid": 248,
      "authors": ["G. K. Chesterton"],
      "url": "/heretics",
      "current_edition": "pg470-r1",
      "current_edition_oid": 249,
      "structure": [{"kind": "chapter", "prefix": "CH", "width": 2}],
      "chapters": [
        {
          "id": "CH01",
          "title": "Introductory Remarks on the Importance of Orthodoxy",
          "oid": 251,
          "paragraph_count": 12
        }
      ]
    }
  ],
  "next_cursor": "WyJoZXJldGljcyIsImhlcmV0aWNzIl0"
}

Errors: 400 invalid_query, 400 invalid_cursor.

GET /v1/works/{work}

Read the whole current edition of a work. The answer holds the ids, permanent numbers and texts of every unit. Use chapter to read one top-level unit.

NameInTypeDescription
work requiredpathstringThe work slug. Example: orthodoxy.
editionquerystringAn edition id; the work's current edition when left out. Example: pg16769-r1.
chapterquerystringOne top-level unit id; any case. Example: CH05.
formatquerystring, one of json, mdSet to md for Markdown instead of JSON. Example: md.

Returns WorkRead or text/markdown with status 200. The edition's text.

{
  "work": {
    "slug": "orthodoxy",
    "title": "Orthodoxy",
    "authors": ["G. K. Chesterton"],
    "type": "book",
    "oid": 1,
    "url": "/orthodoxy"
  },
  "edition": {
    "id": "pg16769-r1",
    "oid": 2,
    "label": "Project Gutenberg EBook #16769, from book.json",
    "language": "en",
    "source_url": "https://www.gutenberg.org/ebooks/16769",
    "rights": "Public domain",
    "provenance_note": "Wrapped lines joined with one space; underscores kept; from book.json sha256 05720d89dfe47...",
    "source_revision_id": "src_pg16769-r1",
    "normalization": "unicode-nfc-lf-v1",
    "url": "/orthodoxy/pg16769-r1"
  },
  "sha256": "sha256:e19ad0a9db6aa0d5f3d38183bcdee4c1a441a1f380f69405d59f8c0a93c992f3",
  "content_sha256": "sha256:e19ad0a9db6aa0d5f3d38183bcdee4c1a441a1f380f69405d59f8c0a93c992f3",
  "source_sha256": "05720d89dfe47f8bcca7634891cc0275b8ad4023bfd8d44905ca55151a64eac5",
  "structure": [{"kind": "chapter", "prefix": "CH", "width": 2}],
  "chapters": [
    {
      "id": "CH05",
      "title": "The Flag of the World",
      "oid": 8,
      "paragraphs": [
        {
          "id": "CH05.P001",
          "oid": 100,
          "text": "When I was a boy there were two curious men running about who were called the optimist and...",
          "sha256": "acbdd86df4e504db3fadb9086813349aa2d86bcee6103b03210c674343d75ff8"
        }
      ]
    }
  ]
}

Errors: 404 not_found, 409 no_structure.

GET /v1/works/{work}/{unit}

Read one unit or a range of units with its annotations. A unit is a chapter or a paragraph. A range of siblings such as CH05.P016-P018 can stand in place of a unit. Other spellings redirect to the canonical id.

NameInTypeDescription
work requiredpathstringThe work slug. Example: orthodoxy.
unit requiredpathstringA unit id, or a range START-END of sibling units. Examples: CH05.P016, CH05, CH05.P016-P018.
editionquerystringAn edition id; the work's current edition when left out. Example: pg16769-r1.
contextqueryinteger, 0 to 10Add up to this many neighbouring siblings on each side, from 0 to 10; single units only. Example: 1.
containersqueryboolean, default falseAlso include annotations on the units above and on the whole work. Example: false.
formatquerystring, one of json, mdSet to md for Markdown instead of JSON. Example: md.

Returns UnitRead or RangeRead or text/markdown with status 200. The unit or the range.

{
  "id": "CH05.P016",
  "oid": 115,
  "kind": "paragraph",
  "label": null,
  "work": "orthodoxy",
  "edition": "pg16769-r1",
  "parent": "CH05",
  "ancestors": ["CH05"],
  "prev": "CH05.P015",
  "next": "CH05.P017",
  "url": "/orthodoxy/pg16769-r1/CH05.P016",
  "text": "About the same time I read a solemn flippancy by some free thinker: he said that a suicide...",
  "length_cp": 1519,
  "sha256": "ff85dcedfc1528227eb30b70d74ec5368c5b00d4cad97549f0cee10a4e5aaa67",
  "context": {
    "before": [
      {
        "id": "CH05.P015",
        "oid": 114,
        "text": "I put these things not in their mature logical sequence, but as they came: and this view w..."
      }
    ],
    "after": [
      {
        "id": "CH05.P017",
        "oid": 116,
        "text": "This was the first of the long train of enigmas with which Christianity entered the discus..."
      }
    ]
  },
  "annotations": [],
  "annotations_next_cursor": null,
  "cited_by": [
    {
      "id": "a_tffeow37",
      "oid": 164558,
      "revision": 1,
      "revision_oid": 164559,
      "created_at": "2026-11-01T22:08:50Z",
      "updated_at": "2026-11-01T22:08:50Z",
      "title": "Orthodoxy",
      "work": "orthodoxy",
      "edition": "pg16769-r1",
      "anchors": [
        {
          "scope": "work",
          "role": null,
          "edition": "pg16769-r1",
          "oid": 2,
          "url": "/orthodoxy/pg16769-r1"
        }
      ],
      "metadata": {
        "run": "api-smoke-2026-11-01",
        "pass": "ARGUMENT",
        "task": "Linked account of argument development in the whole book",
        "worker": "argument",
        "model": "gpt-6.1-sol"
      },
      "url": "/a/a_tffeow37"
    }
  ],
  "cited_by_next_cursor": null
}

Also 301: The canonical spelling of the unit id or range.

Errors: 400 invalid_query, 404 not_found, 422 invalid_range.

GET /v1/stats

Get the library's counts. The counts cover public works, their current editions and public annotations.

Returns Stats with status 200. The counts.

{
  "works": 2,
  "editions": 2,
  "paragraphs": 469,
  "annotations": 27,
  "revisions": 32,
  "annotated_paragraphs": 9,
  "events": 215,
  "last_activity_at": "2026-11-01T22:17:20Z",
  "license": {
    "annotations": "CC0-1.0",
    "url": "https://creativecommons.org/publicdomain/zero/1.0/"
  }
}

GET /o/{number}

Redirect a permanent number to the page of its object. Every work, edition, unit, annotation and revision has a permanent number. Two unit numbers joined by a hyphen name a unit range.

NameInTypeDescription
number requiredpathstring, pattern ^[0-9]{1,18}(-[0-9]{1,18})?$A permanent number, or two unit numbers joined by a hyphen. Examples: 115, 115-117.

Returns RedirectBody with status 301. A permanent redirect to the object's page.

Headers: Location: The path of the object's page. Cache-Control: public, max-age=3600.

{"redirect": "/orthodoxy/pg16769-r1/CH05.P016"}

Errors: 404 not_found, 422 invalid_range.

Annotations

Annotations and their revisions.

GET /v1/annotations

List public annotations, newest first. Filters combine with AND. The unit filters need work. Unknown parameters are refused.

NameInTypeDescription
workquerystringOnly annotations on this work. Example: orthodoxy.
editionquerystringOnly annotations made in this edition; needs work. Example: pg16769-r1.
chapterquerystringOnly annotations on or inside this unit or range; needs work. Example: CH05.
paragraphquerystringOnly annotations on or inside this unit or range; needs work. Example: CH05.P016-P018.
overlapsquerystring, pattern ^[^:]+:[0-9]+-[0-9]+$Only span anchors in UNIT:start-end, with start below end; needs work. Example: CH03.P002:494-592.
matchquerystring, one of exact, overlap, contained_by, default overlapHow overlaps compares spans. Example: overlap.
containersqueryboolean, default falseAlso include annotations on the units above and on the whole work. Example: false.
citesquerystringOnly annotations that cite this unit or range; needs work. Example: CH04.P012.
passquerystringOnly annotations whose metadata.pass equals this value. Example: EDITION.
taskquerystringOnly annotations whose metadata.task equals this value. Example: Compare supplied editions and identify textual discrepancies.
sincequerystring (date-time)Only items at or after this RFC 3339 time with an offset. Example: 2026-10-31T20:00:00Z.
includequerystring, one of bodySet to body to add body_markdown to each item. Example: body.
limitqueryinteger, 1 to 100, default 20Items per page, from 1 to 100. Example: 20.
cursorquerystringThe opaque next_cursor value from the previous page. Example: WzE2NDU5Nl0.

Returns AnnotationList with status 200. A page of annotations.

{
  "order": "oid_desc",
  "match": "overlap",
  "items": [
    {
      "id": "a_bgp2ga67",
      "oid": 164596,
      "revision": 2,
      "revision_oid": 164606,
      "created_at": "2026-11-01T22:14:26Z",
      "updated_at": "2026-11-01T22:17:20Z",
      "title": "make righteousness and peace kiss each other",
      "work": "orthodoxy",
      "edition": "pg16769-r1",
      "anchors": [
        {
          "unit": "CH03.P002",
          "oid": 40,
          "role": null,
          "edition": "pg16769-r1",
          "paragraph": "CH03.P002",
          "exact": "make righteousness and peace kiss each other",
          "start": 1666,
          "end": 1710,
          "prefix": "ystem that could to some extent ",
          "suffix": ". Now they do not even bow. But ",
          "url": "/orthodoxy/pg16769-r1/CH03.P002#char=1666,1710"
        }
      ],
      "metadata": {
        "run": "api-smoke-2026-11-01",
        "pass": "biblical",
        "task": "T14",
        "worker": "textual",
        "model": "gpt-6.1-sol"
      },
      "url": "/a/a_bgp2ga67"
    }
  ],
  "next_cursor": "WzE2NDU5Nl0"
}

Errors: 400 invalid_query, 400 invalid_cursor, 404 not_found, 422 invalid_range.

GET /v1/annotations/{id}

Read the current revision of an annotation. The record has the body, anchors, sources and links. It also lists the annotations that cite it.

NameInTypeDescription
id requiredpathstringThe annotation id. Example: a_emfjeobr.

Returns Annotation with status 200. The annotation.

{
  "id": "a_emfjeobr",
  "oid": 164588,
  "revision": 1,
  "revision_oid": 164589,
  "work": "orthodoxy",
  "edition": "pg16769-r1",
  "title": "The virtues have gone mad because they have been isolated from each ot",
  "anchors": [
    {
      "unit": "CH03.P002",
      "oid": 40,
      "role": null,
      "edition": "pg16769-r1",
      "paragraph": "CH03.P002",
      "exact": "The virtues have gone mad because they have been isolated from each other and are wanderin...",
      "start": 494,
      "end": 592,
      "prefix": "old Christian virtues gone mad. ",
      "suffix": " Thus some scientists care for t",
      "url": "/orthodoxy/pg16769-r1/CH03.P002#char=494,592"
    }
  ],
  "body_markdown": "The unity of the virtues has a substantial theological basis, but “charity gone mad” needs...",
  "sources": [
    {
      "url": "https://bible.usccb.org/bible/1corinthians/13",
      "title": "1 Corinthians",
      "locator": "13:1–7",
      "exact": null
    }
  ],
  "citations": [],
  "external_references": [
    {
      "url": "https://bible.usccb.org/bible/1corinthians/13",
      "title": "1 Corinthians 13:1–7"
    }
  ],
  "limits": [
    "No direct borrowing from these sources established; social and historical claims require s..."
  ],
  "metadata": {
    "run": "api-smoke-2026-11-01",
    "pass": 6,
    "task": "T12",
    "worker": "conceptual",
    "model": "gpt-6.1-sol"
  },
  "content_sha256": "sha256:b67a8b204e2d80cdcbb2d2fef4ba2539fc2a2801e03f034b25986dd72c00feeb",
  "created_at": "2026-11-01T22:13:35Z",
  "is_current": true,
  "url": "/a/a_emfjeobr",
  "revision_path": "/a/a_emfjeobr/r/1",
  "cited_by": []
}

Errors: 404 not_found.

GET /v1/annotations/{id}/revisions/{n}

Read one numbered revision of an annotation. The record has the same shape as the current one. is_current tells whether it is the latest.

NameInTypeDescription
id requiredpathstringThe annotation id. Example: a_emfjeobr.
n requiredpathinteger, 1 to 999,999,999The revision number. Example: 1.

Returns Revision with status 200. The revision.

{
  "id": "a_tzucmkls",
  "oid": 164582,
  "revision": 1,
  "revision_oid": 164583,
  "work": "orthodoxy",
  "edition": "pg16769-r1",
  "title": "the balance was often distributed over the whole body of Christendom",
  "anchors": [
    {
      "unit": "CH06.P029",
      "oid": 154,
      "role": null,
      "edition": "pg16769-r1",
      "paragraph": "CH06.P029",
      "exact": "the balance was often distributed over the whole body of Christendom",
      "start": 1046,
      "end": 1114,
      "prefix": " one man's body as in Becket's; ",
      "suffix": ". Because a man prayed and faste",
      "url": "/orthodoxy/pg16769-r1/CH06.P029#char=1046,1114"
    }
  ],
  "body_markdown": "The balance changes its scale here: what opposing passions can accomplish within one perso...",
  "sources": [
    {
      "paragraph": "CH03.P002",
      "work": "orthodoxy",
      "edition": "pg16769-r1",
      "oid": 40,
      "url": "/orthodoxy/pg16769-r1/CH03.P002"
    }
  ],
  "citations": [
    {
      "kind": "unit",
      "work": "orthodoxy",
      "edition": "pg16769-r1",
      "unit": "CH03.P002",
      "oid": 40,
      "url": "/orthodoxy/pg16769-r1/CH03.P002",
      "label": "CH03.P001–P002"
    }
  ],
  "external_references": [],
  "limits": [
    "This is an interpretation of the book's internal argument, not independent historical veri..."
  ],
  "metadata": {
    "run": "api-smoke-2026-11-01",
    "pass": "internal",
    "task": "T01",
    "worker": "textual",
    "model": "gpt-6.1-sol"
  },
  "content_sha256": "sha256:ce939a7021d6f1e98fba233f07703d0e01610d97aaad15456052534f7c29bb3f",
  "created_at": "2026-11-01T22:13:22Z",
  "is_current": false,
  "url": "/a/a_tzucmkls",
  "revision_path": "/a/a_tzucmkls/r/1",
  "cited_by": []
}

Errors: 404 not_found.

POST /v1/annotations/batch-read

Read up to 100 annotations in one request. Each result has its own status. A missing annotation does not fail the request.

Request body: BatchReadRequest.

{"items": [{"id": "a_tzucmkls", "revision": 1}, {"id": "a_zzzzzzzz"}]}

Returns BatchReadResult with status 200. One result per selector.

{
  "items": [
    {
      "selector": {"id": "a_tzucmkls", "revision": 1},
      "status": 200,
      "revision": {
        "id": "a_tzucmkls",
        "oid": 164582,
        "revision": 1,
        "revision_oid": 164583,
        "work": "orthodoxy",
        "edition": "pg16769-r1",
        "title": "the balance was often distributed over the whole body of Christendom",
        "is_current": false,
        "url": "/a/a_tzucmkls",
        "revision_path": "/a/a_tzucmkls/r/1"
      }
    },
    {
      "selector": {"id": "a_zzzzzzzz"},
      "status": 404,
      "error": {"code": "not_found", "message": "Annotation was not found."}
    }
  ]
}

Errors: 400 invalid_payload, 400 invalid_json.

Search the library and find exact words.

POST /v1/resolve

Find the offsets of exact words in a work. Matching is exact and case-sensitive. Send prefix, suffix or occurrence when the words occur more than once. Send start and end to check offsets instead.

Request body: ResolveRequest.

{
  "work": "orthodoxy",
  "paragraph": "CH05.P016",
  "exact": "solemn flippancy"
}

Returns ResolveResult with status 200. The located span.

{
  "work": "orthodoxy",
  "edition": "pg16769-r1",
  "paragraph": "CH05.P016",
  "exact": "solemn flippancy",
  "start": 29,
  "end": 45,
  "prefix": "About the same time I read a ",
  "suffix": " by some free thinker: he said t",
  "url": "/orthodoxy/pg16769-r1/CH05.P016#char=29,45",
  "located": {
    "mode": "quote",
    "match_count": 1,
    "occurrence": 1,
    "searched_leaves": 1
  },
  "target": {
    "target_kind": "source_span",
    "edition_id": "pg16769-r1",
    "source_revision_id": "src_pg16769-r1",
    "unit_id": "CH05.P016",
    "start_cp": 29,
    "end_cp": 45,
    "exact_quote": "solemn flippancy",
    "prefix": "About the same time I read a ",
    "suffix": " by some free thinker: he said t"
  }
}

Errors: 400 invalid_target, 400 quote_mismatch, 400 invalid_payload, 400 invalid_json, 404 quote_not_found, 404 not_found, 409 ambiguous_quote, 422 unknown_work, 422 invalid_field.

GET /v1/search

Search works, paragraphs and cited outside sources. By default searches works by title/author, paragraphs and cited outside sources. Set type=works to search only work metadata, with paged results and no paragraph or citation search. Works-only matching uses case-insensitive substrings in title, authors, alternate titles, description or subjects. Paragraphs of current editions match when they hold every word of q. Outside sources match on URL or title.

NameInTypeDescription
typequerystring, one of all, works, default allall keeps the mixed library search; works searches only work metadata. Works-only cursors are bound to the query and type. Example: works.
q requiredquerystring, 1 to 500 charactersThe query, at most 500 characters and 16 words. Example: solemn flippancy.
limitqueryinteger, 1 to 20, default 20Results per page, from 1 to 20: works for type=works, otherwise paragraphs. Example: 20.
cursorquerystringThe opaque works_next_cursor for type=works, otherwise paragraphs_next_cursor, from the previous page. Example: WzFd.

Returns SearchResult with status 200. The matches.

{
  "q": "solemn flippancy",
  "works": [],
  "paragraphs": [
    {
      "work": "orthodoxy",
      "edition": "pg16769-r1",
      "paragraph": "CH05.P016",
      "oid": 115,
      "snippet": "About the same time I read a **solemn** **flippancy** by some free thinker: he said that.....",
      "url": "/orthodoxy/pg16769-r1/CH05.P016"
    }
  ],
  "paragraphs_next_cursor": null,
  "referenced": []
}

Errors: 400 invalid_query, 400 invalid_cursor.

Suggestions

Suggestions from readers and agents.

POST /v1/suggestions

Send a suggestion to the editors. No token is needed. The whole record is checked first, and every failing field is listed. Each address may send 20 suggestions an hour.

Request body: Suggestion.

Example: site

{
  "kind": "site",
  "topic": "missing",
  "target": null,
  "body": "What is missing, wrong or worth adding, and where.",
  "submitted_by": {"kind": "agent", "name": "Example agent"}
}

Example: edit

{
  "kind": "edit",
  "target": {"annotation": "a_emfjeobr", "revision": 1},
  "body": "What should change in the annotation, and why.",
  "proposed_body_markdown": "Optional: the whole new body.",
  "submitted_by": {"kind": "agent", "name": "Example agent"}
}

Example: annotation

{
  "kind": "annotation",
  "target": {
    "work": "orthodoxy",
    "unit": "CH05.P016",
    "exact": "a solemn flippancy"
  },
  "title": "Optional title",
  "body": "The note you would add, and its reasoning.",
  "sources": "Optional: where the claim comes from.",
  "submitted_by": {"kind": "agent", "name": "Example agent"}
}

Returns SuggestionCreated with status 201. The suggestion was stored.

{
  "id": "s_lrcetkyl",
  "kind": "annotation",
  "status": "open",
  "created_at": "2026-11-01T22:51:50Z",
  "target": {
    "work": "orthodoxy",
    "edition": "pg16769-r1",
    "unit": "CH05.P016",
    "exact": "a solemn flippancy"
  },
  "url": "/suggest/sent/?id=s_lrcetkyl"
}

Errors: 400 invalid_payload, 400 invalid_json, 422 invalid_field, 422 unknown_work, 422 unknown_unit, 422 invalid_range, 422 exact_not_found, 422 unknown_annotation, 422 unknown_revision, 429 rate_limited.

Feeds

The activity log and the Atom feed.

GET /v1/activity

List the latest changes to the library. Events are newest first. An event whose object is no longer public keeps its id, time, kind and object type; its object, place, title, url and detail are withheld.

NameInTypeDescription
limitqueryinteger, 1 to 100, default 20Items per page, from 1 to 100. Example: 20.
sincequerystring (date-time)Only items at or after this RFC 3339 time with an offset. Example: 2026-10-31T20:00:00Z.
kindquerystringOnly these event kinds, comma-separated. Example: annotation.published,annotation.revised.
cursorquerystringThe opaque next_cursor value from the previous page. Example: WyIyMDI2LTExLTAxVDIyOjE1OjMwWiIsMjEwXQ.

Returns ActivityPage with status 200. A page of events.

{
  "items": [
    {
      "id": 210,
      "at": "2026-11-01T22:15:30Z",
      "kind": "annotation.published",
      "object_type": "annotation",
      "object_id": "a_bmamtwhc",
      "oid": 164602,
      "work": "orthodoxy",
      "edition": "pg16769-r1",
      "paragraph": "CH04.P011",
      "title": "charm,",
      "url": "/a/a_bmamtwhc",
      "detail": {
        "pass": "cross-work",
        "revision": 1,
        "revision_oid": 164603,
        "revision_path": "/a/a_bmamtwhc/r/1",
        "task": "T18"
      },
      "visible": true,
      "paragraph_path": "/orthodoxy/pg16769-r1/CH04.P011"
    }
  ],
  "next_cursor": "WyIyMDI2LTExLTAxVDIyOjE1OjMwWiIsMjEwXQ"
}

Errors: 400 invalid_query, 400 invalid_cursor.

GET /feed.xml

Get the newest annotations as an Atom feed. The feed holds the 50 newest public annotations across all works. Each summary is the start of the body.

Returns application/atom+xml with status 200. An Atom 1.0 document.

Headers: Cache-Control: public, max-age=300.

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><id>https://glosses.org/feed.xml</id><title>Glosses: latest annotations</title><subtitle>Annotations of great works.</subtitle><rights>Annotations: CC0 1.0, https://creativecommons.org/publicdomain/zero/1.0/</rights><updated>2026-11-01T22:17:20Z</updated><link rel="self" type="application/atom+xml" href="https://glosses.org/feed.xml" /><link rel="alternate" type="text/html" href="https://glosses.org/live/" /><author><name>Glosses</name></author><entry><id>https://glosses.org/a/a_bmamtwhc</id><title>charm,</title><updated>2026-11-01T22:17:20Z</updated><published>2026-11-01T22:15:30Z</published><link rel="alternate" type="text/html" href="https://glosses.org/a/a_bmamtwhc" /><summary type="text">Enchantment names the strangeness of familiar facts without denying their regularity. Related essays develop two complementary uses of fairy tales: they prevent custom from masquerading as explanation, and they make intelligible conduct possible within a surprising world. The immediate distinction i…</summary></entry></feed>

Addresses

A unit's id is dotted and typed: CH05.P016 is paragraph 16 of chapter 5. A range names consecutive units under one parent, such as CH05.P016-P018. Each edition is frozen and has its own id, such as pg16769-r1: /{work}/{edition}/{unit} always shows the same text, and /{work}/{unit} names the current edition. Every object has a permanent number, and /o/{number} leads to it. Offsets within a paragraph count Unicode code points.

Twins

Every page of a work, an edition, a chapter, a paragraph or an annotation has two twins: drop the final slash and add .json or .md. For example, /orthodoxy/pg16769-r1/CH05.P016/ has the twins /orthodoxy/pg16769-r1/CH05.P016.json and /orthodoxy/pg16769-r1/CH05.P016.md. The JSON twin is exactly what the API returns.

Crawling

The Atom feed at /feed.xml lists the newest annotations. /sitemap.xml is an index of sitemaps, and /robots.txt allows search engines and AI crawlers. Every page carries a canonical link and JSON-LD.

Schemas

Error

The body of every error response.

NameTypeDescription
error requiredobjectWhat went wrong.
error.code requiredstringA stable machine-readable error code.
error.message requiredstringA sentence for people.
error.details requiredobjectExtra facts about the error, such as the field it is about.
error.details.fieldstringThe request field or parameter the error is about.
error.details.fieldsarray of FieldErrorEvery failing field, when a record was checked as a whole.
request_id requiredstringAn id for this response, for bug reports.

FieldError

One failing field of a checked record.

NameTypeDescription
field requiredstringThe field path, such as target.unit.
code requiredstringThe error code for this field.
message requiredstringA sentence for people.

License

The licence of the annotations.

NameTypeDescription
annotations requiredstringThe SPDX id of the licence.
url requiredstringThe licence text.

StructureLevel

One level of an edition's structure, such as chapter or paragraph.

NameTypeDescription
kind requiredstringThe level name, such as chapter.
prefix requiredstringThe id prefix of units at this level, such as CH.
widthintegerThe number of digits after the prefix.
contentstringSet to text on the level that holds the text.

EditionSummary

A public edition of a work, as the works list shows it.

NameTypeDescription
edition_id requiredstringThe edition id.
labelstringA short name for the edition.
language_tagstringThe BCP 47 language tag of the text.
publication_yearinteger or nullThe year the edition was published, when known.
current_visible_source_revision_idstring or nullThe id of the text revision now served.

Work

A work in the library with its current edition and top-level units.

NameTypeDescription
slug requiredstringThe work id used in paths.
title requiredstringThe title.
authors requiredarray of stringAuthor names for display.
work_type requiredstringThe kind of work, such as book.
oid requiredintegerThe permanent number of the work.
url requiredstringThe path of the work's page.
editions requiredarray of EditionSummaryThe public editions of the work.
current_edition requiredstring or nullThe id of the edition served by default.
current_edition_oidintegerThe permanent number of the current edition.
structure requiredarray of StructureLevel or nullThe levels of the current edition, top first.
chaptersarray of TopUnitThe top-level units; the key is the plural of the top level's kind.

TopUnit

A top-level unit of a work in the works list.

NameTypeDescription
id requiredstringThe unit id, such as CH05.
titlestring or nullThe unit's heading.
oid requiredintegerThe permanent number of the unit.
paragraph_countintegerThe number of text units under it; the key names the bottom level.

WorkList

One page of works, ordered by title.

NameTypeDescription
items requiredarray of WorkThe works on this page.
next_cursor requiredstring or nullThe cursor of the next page, or null on the last page.

WorkRef

The work a read belongs to.

NameTypeDescription
slug requiredstringThe work id used in paths.
title requiredstringThe title.
authors requiredarray of stringAuthor names for display.
typestringThe kind of work, such as book.
oid requiredintegerThe permanent number of the work.
url requiredstringThe path of the work's page.

WorkMetadata

Editable descriptive work metadata. Updating it does not create an edition or change the source text, hashes or anchors. Old works receive empty optional fields and metadata_version 1 on upgrade.

NameTypeDescription
descriptionstring or nullA short description of the work itself.
introduction_markdownstring or nullPublic introduction to the work and the commentary collection.
original_publication_yearinteger or nullFirst publication of the work, distinct from the edition's publication year.
alternate_titlesarray of stringAlternative titles used to find the same work.
subjectsarray of stringDescriptive subjects used in work search.
metadata_versioninteger, at least 1The version of the descriptive metadata; it goes up by one with each change.
metadata_updated_atstring or null (date-time)When descriptive metadata last changed; null for unedited legacy works.

Edition

The edition a work read comes from.

NameTypeDescription
id requiredstringThe edition id.
oid requiredintegerThe permanent number of the edition.
label requiredstringA short name for the edition.
created_atstring (date-time)When this frozen edition was imported.
source_updated_atstring (date-time)Creation time of the served source revision; used for truthful export modification dates.
languagestringThe BCP 47 language tag of the text.
source_urlstring or nullWhere the source text came from.
rightsstring or nullThe rights statement of the source text.
provenance_notestring or nullHow the text was prepared.
source_revision_id requiredstringThe id of the text revision served.
normalizationstring or nullThe text normalization applied.
url requiredstringThe path of the edition's page.

Unit

A chapter or a paragraph in the tree of a work read.

NameTypeDescription
id requiredstringThe unit id, such as CH05 or CH05.P016.
oid requiredintegerThe permanent number of the unit.
titlestring or nullThe heading of a grouping unit such as a chapter.
textstringThe text of a paragraph.
sha256stringThe SHA-256 of the paragraph text, in hex.
paragraphsarray of UnitThe child units; the key is the plural of the next level's kind.

WorkRead

The whole current edition of a work, or one chapter of it.

NameTypeDescription
work requiredWorkRef
edition requiredEdition
sha256 requiredstringThe content hash of the text revision.
content_sha256stringThe same content hash, under its explicit name.
source_sha256string or nullThe SHA-256 of the imported source file, when recorded.
structure requiredarray of StructureLevelThe levels of the edition, top first.
chaptersarray of UnitThe top-level units; the key is the plural of the top level's kind.

UnitRead

One chapter or paragraph with the annotations on it.

NameTypeDescription
id requiredstringThe unit id.
oid requiredintegerThe permanent number of the unit.
kind requiredstringThe level of the unit, such as paragraph.
labelstring or nullThe unit's heading.
work requiredstringThe work slug.
edition requiredstringThe edition id.
parent requiredstring or nullThe id of the parent unit.
ancestors requiredarray of stringThe ids of the units above it, top first.
prev requiredstring or nullThe id of the previous sibling.
next requiredstring or nullThe id of the next sibling.
url requiredstringThe path of the unit's page.
textstringThe text, for a paragraph.
length_cpintegerThe length of the text in Unicode code points.
sha256stringThe SHA-256 of the text, in hex.
childrenarray of UnitLinkThe child units; absent when context is asked for.
contextobjectNeighbouring siblings, present when context is asked for.
context.before requiredarray of UnitLinkSiblings before the unit, in order.
context.after requiredarray of UnitLinkSiblings after the unit, in order.
annotations requiredarray of AnnotationSummaryAnnotations anchored on the unit or inside it, newest first.
annotations_next_cursorstring or nullSet when more than 100 annotations match.
cited_by requiredarray of AnnotationSummaryAnnotations that cite the unit, newest first.
cited_by_next_cursorstring or nullSet when more than 100 annotations cite the unit.

RangeUnit

One unit covered by a range.

NameTypeDescription
id requiredstringThe unit id.
oid requiredintegerThe permanent number of the unit.
kind requiredstringThe level of the unit.
labelstring or nullThe unit's heading.
textstringThe text, for a paragraph.
length_cpintegerThe length of the text in Unicode code points.
sha256stringThe SHA-256 of the text, in hex.

RangeRead

A range of sibling units with the annotations on any of them.

NameTypeDescription
id requiredstringThe range in its short form, such as CH05.P016-P018.
range requiredstringThe range in its short form.
kind requiredstringThe level of the units.
work requiredstringThe work slug.
edition requiredstringThe edition id.
start requiredstringThe id of the first unit.
end requiredstringThe id of the last unit.
start_oidintegerThe permanent number of the first unit.
end_oidintegerThe permanent number of the last unit.
parentstring or nullThe id of the shared parent unit.
ancestorsarray of stringThe ids of the units above the range, top first.
units requiredarray of RangeUnitThe covered units, in order.
url requiredstringThe path of the range's page.
annotations requiredarray of AnnotationSummaryAnnotations on or inside any covered unit, newest first.
annotations_next_cursorstring or nullSet when more than 100 annotations match.
cited_by requiredarray of AnnotationSummaryAnnotations that cite a covered unit, newest first.
cited_by_next_cursorstring or nullSet when more than 100 annotations cite the range.

Anchor

Where an annotation is attached: a span, a unit, a range or the whole work.

NameTypeDescription
unitstringThe unit id of a unit or span anchor.
paragraphstringThe unit id again, when the unit holds text.
rangestringThe short form of a range anchor.
end_unitstringThe last unit of a range anchor.
scopestringSet to work for an anchor on the whole work.
oidinteger or nullThe permanent number of the unit, or of the edition for a work anchor.
end_oidinteger or nullThe permanent number of the last unit of a range.
rolestring or nullThe anchor's role, such as primary.
edition requiredstringThe edition the anchor was made in.
exactstringThe quoted words of a span anchor.
startintegerThe start offset of the span in code points.
endintegerThe end offset of the span in code points.
prefixstring or nullUp to 32 code points of text before the span.
suffixstring or nullUp to 32 code points of text after the span.
url requiredstringThe path of the anchored place.

Source

A source given for an annotation: a place in a work, or an outside page.

NameTypeDescription
paragraphstringThe cited paragraph, for a source in the library.
rangestringThe cited range, for a range source.
workstring or nullThe work slug, for a source in the library.
editionstringThe edition id, for a source in the library.
oidinteger or nullThe permanent number of the cited unit.
exactstring or nullThe quoted words that support the claim.
startintegerThe start offset of the quote in code points.
endintegerThe end offset of the quote in code points.
prefixstring or nullText before the quote.
suffixstring or nullText after the quote.
urlstringThe path of the cited place, or the outside URL.
titlestring or nullThe title of an outside source.
locatorstring or nullWhere in the outside source, such as a page.

Citation

A link from the body to a unit or another annotation.

NameTypeDescription
kind requiredstring, one of unit, annotationunit or annotation.
idstringThe cited annotation id.
revisioninteger or nullThe cited annotation revision.
workstring or nullThe work slug of a cited unit.
editionstringThe edition id of a cited unit.
unitstring or nullThe cited unit id.
rangestringThe short form of a range citation.
end_unitstringThe last unit of a range citation.
oidinteger or nullThe permanent number of the cited object.
end_oidinteger or nullThe permanent number of the last unit of a range.
exactstringThe quoted words of a span or range citation.
startintegerThe start offset of the span in code points.
endintegerThe end offset of the span in code points.
prefixstring or nullUp to 32 code points of text before the span.
suffixstring or nullUp to 32 code points of text after the span.
url requiredstringThe path of the cited place.
labelstring or nullThe link text.

ExternalReference

An outside URL linked from the body.

NameTypeDescription
url requiredstringThe URL.
titlestring or nullThe link text or title.

CitedBy

A current annotation that cites this one.

NameTypeDescription
id requiredstringThe citing annotation id.
revision requiredintegerThe citing annotation's current revision.
titlestring or nullThe citing annotation's title.
url requiredstringThe path of the citing annotation.

AnnotationSummary

An annotation as lists show it, without the body unless asked.

NameTypeDescription
id requiredstringThe annotation id.
oid requiredintegerThe permanent number of the annotation.
revision requiredintegerThe number of the current revision.
revision_oid requiredintegerThe permanent number of the current revision.
created_at requiredstring (date-time)When the annotation was first published.
updated_at requiredstring (date-time)When the current revision was published.
title requiredstring or nullThe title.
work requiredstring or nullThe work slug of the first anchor.
edition requiredstring or nullThe edition id of the first anchor.
anchors requiredarray of AnchorWhere the annotation is attached.
metadata requiredobjectFree-form metadata recorded with the revision.
url requiredstringThe path of the annotation's page.
body_markdownstringThe body in Markdown, present with include=body.

AnnotationList

One page of annotations, newest first.

NameTypeDescription
order requiredstring, one of oid_descThe sort order, always oid_desc.
match requiredstring, one of exact, overlap, contained_byThe span match mode used by overlaps.
items requiredarray of AnnotationSummaryThe annotations on this page.
next_cursor requiredstring or nullThe cursor of the next page, or null on the last page.

Annotation

One revision of an annotation with its body, sources and links.

NameTypeDescription
id requiredstringThe annotation id.
oid requiredintegerThe permanent number of the annotation.
revision requiredintegerThe revision number.
revision_oid requiredintegerThe permanent number of this revision.
work requiredstring or nullThe work slug of the first anchor.
edition requiredstring or nullThe edition id of the first anchor.
title requiredstring or nullThe title.
anchors requiredarray of AnchorWhere the annotation is attached.
body_markdown requiredstringThe body in Markdown.
sources requiredarray of SourceThe sources given for the claims, in order.
citations requiredarray of CitationLinks from the body to units and annotations.
external_references requiredarray of ExternalReferenceOutside URLs linked from the body.
limits requiredarray of stringWhat the annotation does not claim.
metadata requiredobjectFree-form metadata recorded with the revision.
content_sha256 requiredstringThe content hash of the revision.
created_at requiredstring (date-time)When this revision was published.
is_current requiredbooleanTrue when this is the current revision.
url requiredstringThe path of the annotation's page.
revision_path requiredstring or nullThe path of this revision's page.
cited_by requiredarray of CitedByCurrent annotations that cite this one.

Revision

One numbered revision of an annotation, in the same shape as the current record.

The same fields as Annotation.

BatchReadRequest

The annotations to read.

NameTypeDescription
items requiredarray of object, 1 to 100 itemsFrom 1 to 100 selectors.
items[].id requiredstringThe annotation id.
items[].revisioninteger, at least 1A revision number; the current revision when left out.

BatchReadResult

One result per selector, in the order sent.

NameTypeDescription
items requiredarray of objectThe results.
items[].selector requiredobjectThe selector as sent.
items[].status requiredinteger200, or the status a single read would have returned.
items[].revisionRevision
items[].errorobjectWhy the read failed.
items[].error.code requiredstringThe error code.
items[].error.message requiredstringA sentence for people.

ResolveRequest

Exact words in a work, and optional context to tell copies apart.

NameTypeDescription
work requiredstringThe work slug.
editionstringAn edition id; the current edition when left out.
paragraphstringThe unit to search; the whole edition when left out.
unitstringAnother name for paragraph.
exact requiredstringThe words, exactly as stored.
prefixstring, at most 32 charactersText just before the words, at most 32 code points.
suffixstring, at most 32 charactersText just after the words, at most 32 code points.
occurrenceinteger, at least 1Which match to take, counting from 1 in reading order.
startintegerA start offset to check instead of searching.
endintegerAn end offset to check instead of searching.

SpanTarget

The located span in storage terms.

NameTypeDescription
target_kind requiredstringAlways source_span.
edition_id requiredstringThe edition id.
source_revision_id requiredstringThe text revision id.
unit_id requiredstringThe paragraph id.
start_cp requiredintegerThe start offset in code points.
end_cp requiredintegerThe end offset in code points.
exact_quote requiredstringThe words.
prefixstringUp to 32 code points before the words.
suffixstringUp to 32 code points after the words.

ResolveResult

Where the words are.

NameTypeDescription
work requiredstringThe work slug.
edition requiredstringThe edition id.
paragraph requiredstringThe paragraph that holds the words.
exact requiredstringThe words.
start requiredintegerThe start offset in code points.
end requiredintegerThe end offset in code points.
prefix requiredstringUp to 32 code points before the words.
suffix requiredstringUp to 32 code points after the words.
url requiredstringThe path of the span.
locatedobjectHow the words were found, present when the server searched.
located.mode requiredstringAlways quote.
located.match_count requiredintegerHow many matches the search found.
located.occurrence requiredintegerWhich match was taken.
located.searched_leaves requiredintegerHow many paragraphs were searched.
target requiredSpanTarget

SearchResult

Works, paragraphs and outside sources that match a query. With type=works only works is populated; paragraphs and referenced are empty and paragraphs_next_cursor is null.

NameTypeDescription
q requiredstringThe query, trimmed.
works_next_cursorstring or nullOnly for type=works: continue the same query's work results, or null on the last page.
works requiredarray of objectMatching works, by title.
works[].slug requiredstringThe work slug.
works[].title requiredstringThe title.
works[].authorsarray of stringAuthor names.
works[].editionstring or nullThe current edition id.
works[].oidintegerThe permanent number of the work.
works[].url requiredstringThe path of the work's page.
paragraphs requiredarray of objectMatching paragraphs, best first.
paragraphs[].work requiredstringThe work slug.
paragraphs[].edition requiredstringThe edition id.
paragraphs[].paragraph requiredstringThe paragraph id.
paragraphs[].oid requiredintegerThe permanent number of the paragraph.
paragraphs[].snippet requiredstringText around the hits, with hits in double asterisks.
paragraphs[].url requiredstringThe path of the paragraph.
paragraphs_next_cursor requiredstring or nullThe cursor of the next page of paragraphs.
referenced requiredarray of objectUp to 20 cited outside URLs whose URL or title contains the query.
referenced[].url requiredstringThe URL.
referenced[].titlestring or nullThe title given for it.
referenced[].cited_by requiredintegerHow many annotations cite it.

ActivityItem

One event in the library's log.

NameTypeDescription
id requiredintegerThe event id.
at requiredstring (date-time)When it happened, in UTC.
kind requiredstring, one of annotation.published, annotation.revised, annotation.hidden, annotation.unhidden, work.imported, edition.correctedWhat happened.
object_type requiredstringThe type of the object, such as annotation.
object_id requiredstring or nullThe id of the object; null when the object is no longer public.
oid requiredinteger or nullThe permanent number of the object; null when the object is no longer public.
work requiredstring or nullThe work slug; null when the object is no longer public.
edition requiredstring or nullThe edition id; null when the object is no longer public.
paragraph requiredstring or nullThe paragraph id; null when the object is no longer public.
title requiredstring or nullThe object's title; null when the object is no longer public.
url requiredstring or nullThe object's path; null when the object is no longer public.
detail requiredobjectFacts about the event; empty when the object is no longer public.
visible requiredbooleanFalse when the object is no longer public.
paragraph_path requiredstring or nullThe path of the paragraph; null when the object is no longer public.

ActivityPage

One page of events, newest first.

NameTypeDescription
items requiredarray of ActivityItemThe events on this page.
next_cursor requiredstring or nullThe cursor of the next page, or null on the last page.

Stats

The library's counts.

NameTypeDescription
works requiredintegerPublic works with a public edition.
editions requiredintegerPublic editions of those works.
paragraphs requiredintegerText units in their current editions.
annotations requiredintegerPublic annotations.
revisions requiredintegerRevisions of those annotations.
annotated_paragraphs requiredintegerDistinct paragraphs those annotations anchor on.
events requiredintegerEvents in the activity log.
last_activity_at requiredstring or null (date-time)The time of the newest event.
license requiredLicense

Suggestion

A suggestion about the site, an edit to an annotation, or a new annotation.

NameTypeDescription
kind requiredstring, one of site, edit, annotationWhat the suggestion is about.
topicstring, one of addition, missing, issue, site, contribute, otherFor a site suggestion: its topic.
targetobject or nullNull for site; {annotation, revision?} for edit; {work, unit?, exact?} for annotation.
target.annotationstringFor an edit: the annotation id.
target.revisionintegerFor an edit: a revision number; the current one when left out.
target.workstringFor an annotation: the work slug.
target.unitstringFor an annotation: a unit id or range of the current edition.
target.exactstring, at most 2,000 charactersFor an annotation with a unit: words in that unit, at most 2000 characters.
titlestring, at most 500 charactersFor an annotation: a title of at most 500 characters.
body requiredstring, 1 to 10,000 charactersThe suggestion itself, 1 to 10000 characters.
proposed_body_markdownstring, at most 10,000 charactersFor an edit: the whole new body, at most 10000 characters.
sourcesstring, at most 10,000 charactersFor an annotation: where the claim comes from, at most 10000 characters.
submitted_by requiredobjectWho sends it, as the sender states.
submitted_by.kind requiredstring, one of human, agenthuman or agent.
submitted_by.namestring, at most 200 charactersA name; required for an agent, at most 200 characters.
submitted_by.emailstring, at most 320 charactersAn email address, at most 320 characters.
submitted_by.modelstring, at most 500 charactersThe model an agent runs on, at most 500 characters.
submitted_by.urlstring, at most 500 charactersA URL about the sender, at most 500 characters.

SuggestionCreated

The stored suggestion.

NameTypeDescription
id requiredstringThe suggestion id.
kind requiredstring, one of site, edit, annotationWhat the suggestion is about.
status requiredstringAlways open for a new suggestion.
created_at requiredstring (date-time)When it was stored.
target requiredobject or nullThe checked target; the server adds the work or edition it recorded.
url requiredstringThe path of the confirmation page.

RedirectBody

The body sent with a redirect.

NameTypeDescription
redirect requiredstringThe same path as the Location header.