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.
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer, 1 to 100, default 20 | Items per page, from 1 to 100. Example: 20. |
cursor | query | string | The 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"
}
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.
| Name | In | Type | Description |
|---|---|---|---|
work required | path | string | The work slug. Example: orthodoxy. |
edition | query | string | An edition id; the work's current edition when left out. Example: pg16769-r1. |
chapter | query | string | One top-level unit id; any case. Example: CH05. |
format | query | string, one of json, md | Set 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"
}
]
}
]
}
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.
| Name | In | Type | Description |
|---|---|---|---|
work required | path | string | The work slug. Example: orthodoxy. |
unit required | path | string | A unit id, or a range START-END of sibling units. Examples: CH05.P016, CH05, CH05.P016-P018. |
edition | query | string | An edition id; the work's current edition when left out. Example: pg16769-r1. |
context | query | integer, 0 to 10 | Add up to this many neighbouring siblings on each side, from 0 to 10; single units only. Example: 1. |
containers | query | boolean, default false | Also include annotations on the units above and on the whole work. Example: false. |
format | query | string, one of json, md | Set 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
}
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.
| Name | In | Type | Description |
|---|---|---|---|
number required | path | string, 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.
{"redirect": "/orthodoxy/pg16769-r1/CH05.P016"}
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.
| Name | In | Type | Description |
|---|---|---|---|
work | query | string | Only annotations on this work. Example: orthodoxy. |
edition | query | string | Only annotations made in this edition; needs work. Example: pg16769-r1. |
chapter | query | string | Only annotations on or inside this unit or range; needs work. Example: CH05. |
paragraph | query | string | Only annotations on or inside this unit or range; needs work. Example: CH05.P016-P018. |
overlaps | query | string, pattern ^[^:]+:[0-9]+-[0-9]+$ | Only span anchors in UNIT:start-end, with start below end; needs work. Example: CH03.P002:494-592. |
match | query | string, one of exact, overlap, contained_by, default overlap | How overlaps compares spans. Example: overlap. |
containers | query | boolean, default false | Also include annotations on the units above and on the whole work. Example: false. |
cites | query | string | Only annotations that cite this unit or range; needs work. Example: CH04.P012. |
pass | query | string | Only annotations whose metadata.pass equals this value. Example: EDITION. |
task | query | string | Only annotations whose metadata.task equals this value. Example: Compare supplied editions and identify textual discrepancies. |
since | query | string (date-time) | Only items at or after this RFC 3339 time with an offset. Example: 2026-10-31T20:00:00Z. |
include | query | string, one of body | Set to body to add body_markdown to each item. Example: body. |
limit | query | integer, 1 to 100, default 20 | Items per page, from 1 to 100. Example: 20. |
cursor | query | string | The 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"
}
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.
| Name | In | Type | Description |
|---|---|---|---|
id required | path | string | The 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": []
}
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.
| Name | In | Type | Description |
|---|---|---|---|
id required | path | string | The annotation id. Example: a_emfjeobr. |
n required | path | integer, 1 to 999,999,999 | The 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": []
}
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."}
}
]
}
Search
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"
}
}
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.
| Name | In | Type | Description |
|---|---|---|---|
type | query | string, one of all, works, default all | all keeps the mixed library search; works searches only work metadata. Works-only cursors are bound to the query and type. Example: works. |
q required | query | string, 1 to 500 characters | The query, at most 500 characters and 16 words. Example: solemn flippancy. |
limit | query | integer, 1 to 20, default 20 | Results per page, from 1 to 20: works for type=works, otherwise paragraphs. Example: 20. |
cursor | query | string | The 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": []
}
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.
{
"kind": "site",
"topic": "missing",
"target": null,
"body": "What is missing, wrong or worth adding, and where.",
"submitted_by": {"kind": "agent", "name": "Example agent"}
}
{
"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"}
}
{
"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"
}
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.
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer, 1 to 100, default 20 | Items per page, from 1 to 100. Example: 20. |
since | query | string (date-time) | Only items at or after this RFC 3339 time with an offset. Example: 2026-10-31T20:00:00Z. |
kind | query | string | Only these event kinds, comma-separated. Example: annotation.published,annotation.revised. |
cursor | query | string | The 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"
}
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.
<?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.
| Name | Type | Description |
|---|---|---|
error required | object | What went wrong. |
error.code required | string | A stable machine-readable error code. |
error.message required | string | A sentence for people. |
error.details required | object | Extra facts about the error, such as the field it is about. |
error.details.field | string | The request field or parameter the error is about. |
error.details.fields | array of FieldError | Every failing field, when a record was checked as a whole. |
request_id required | string | An id for this response, for bug reports. |
FieldError
One failing field of a checked record.
| Name | Type | Description |
|---|---|---|
field required | string | The field path, such as target.unit. |
code required | string | The error code for this field. |
message required | string | A sentence for people. |
License
The licence of the annotations.
| Name | Type | Description |
|---|---|---|
annotations required | string | The SPDX id of the licence. |
url required | string | The licence text. |
StructureLevel
One level of an edition's structure, such as chapter or paragraph.
| Name | Type | Description |
|---|---|---|
kind required | string | The level name, such as chapter. |
prefix required | string | The id prefix of units at this level, such as CH. |
width | integer | The number of digits after the prefix. |
content | string | Set to text on the level that holds the text. |
EditionSummary
A public edition of a work, as the works list shows it.
| Name | Type | Description |
|---|---|---|
edition_id required | string | The edition id. |
label | string | A short name for the edition. |
language_tag | string | The BCP 47 language tag of the text. |
publication_year | integer or null | The year the edition was published, when known. |
current_visible_source_revision_id | string or null | The id of the text revision now served. |
Work
A work in the library with its current edition and top-level units.
| Name | Type | Description |
|---|---|---|
slug required | string | The work id used in paths. |
title required | string | The title. |
authors required | array of string | Author names for display. |
work_type required | string | The kind of work, such as book. |
oid required | integer | The permanent number of the work. |
url required | string | The path of the work's page. |
editions required | array of EditionSummary | The public editions of the work. |
current_edition required | string or null | The id of the edition served by default. |
current_edition_oid | integer | The permanent number of the current edition. |
structure required | array of StructureLevel or null | The levels of the current edition, top first. |
chapters | array of TopUnit | The 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.
| Name | Type | Description |
|---|---|---|
id required | string | The unit id, such as CH05. |
title | string or null | The unit's heading. |
oid required | integer | The permanent number of the unit. |
paragraph_count | integer | The number of text units under it; the key names the bottom level. |
WorkList
One page of works, ordered by title.
| Name | Type | Description |
|---|---|---|
items required | array of Work | The works on this page. |
next_cursor required | string or null | The cursor of the next page, or null on the last page. |
WorkRef
The work a read belongs to.
| Name | Type | Description |
|---|---|---|
slug required | string | The work id used in paths. |
title required | string | The title. |
authors required | array of string | Author names for display. |
type | string | The kind of work, such as book. |
oid required | integer | The permanent number of the work. |
url required | string | The 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.
| Name | Type | Description |
|---|---|---|
description | string or null | A short description of the work itself. |
introduction_markdown | string or null | Public introduction to the work and the commentary collection. |
original_publication_year | integer or null | First publication of the work, distinct from the edition's publication year. |
alternate_titles | array of string | Alternative titles used to find the same work. |
subjects | array of string | Descriptive subjects used in work search. |
metadata_version | integer, at least 1 | The version of the descriptive metadata; it goes up by one with each change. |
metadata_updated_at | string or null (date-time) | When descriptive metadata last changed; null for unedited legacy works. |
Edition
The edition a work read comes from.
| Name | Type | Description |
|---|---|---|
id required | string | The edition id. |
oid required | integer | The permanent number of the edition. |
label required | string | A short name for the edition. |
created_at | string (date-time) | When this frozen edition was imported. |
source_updated_at | string (date-time) | Creation time of the served source revision; used for truthful export modification dates. |
language | string | The BCP 47 language tag of the text. |
source_url | string or null | Where the source text came from. |
rights | string or null | The rights statement of the source text. |
provenance_note | string or null | How the text was prepared. |
source_revision_id required | string | The id of the text revision served. |
normalization | string or null | The text normalization applied. |
url required | string | The path of the edition's page. |
Unit
A chapter or a paragraph in the tree of a work read.
| Name | Type | Description |
|---|---|---|
id required | string | The unit id, such as CH05 or CH05.P016. |
oid required | integer | The permanent number of the unit. |
title | string or null | The heading of a grouping unit such as a chapter. |
text | string | The text of a paragraph. |
sha256 | string | The SHA-256 of the paragraph text, in hex. |
paragraphs | array of Unit | The 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.
| Name | Type | Description |
|---|---|---|
work required | WorkRef | |
edition required | Edition | |
sha256 required | string | The content hash of the text revision. |
content_sha256 | string | The same content hash, under its explicit name. |
source_sha256 | string or null | The SHA-256 of the imported source file, when recorded. |
structure required | array of StructureLevel | The levels of the edition, top first. |
chapters | array of Unit | The top-level units; the key is the plural of the top level's kind. |
UnitLink
A unit named by id and number.
| Name | Type | Description |
|---|---|---|
id required | string | The unit id. |
oid required | integer | The permanent number of the unit. |
label | string or null | The unit's heading, for a grouping unit. |
text | string | The unit's text, for a neighbouring paragraph in context. |
UnitRead
One chapter or paragraph with the annotations on it.
| Name | Type | Description |
|---|---|---|
id required | string | The unit id. |
oid required | integer | The permanent number of the unit. |
kind required | string | The level of the unit, such as paragraph. |
label | string or null | The unit's heading. |
work required | string | The work slug. |
edition required | string | The edition id. |
parent required | string or null | The id of the parent unit. |
ancestors required | array of string | The ids of the units above it, top first. |
prev required | string or null | The id of the previous sibling. |
next required | string or null | The id of the next sibling. |
url required | string | The path of the unit's page. |
text | string | The text, for a paragraph. |
length_cp | integer | The length of the text in Unicode code points. |
sha256 | string | The SHA-256 of the text, in hex. |
children | array of UnitLink | The child units; absent when context is asked for. |
context | object | Neighbouring siblings, present when context is asked for. |
context.before required | array of UnitLink | Siblings before the unit, in order. |
context.after required | array of UnitLink | Siblings after the unit, in order. |
annotations required | array of AnnotationSummary | Annotations anchored on the unit or inside it, newest first. |
annotations_next_cursor | string or null | Set when more than 100 annotations match. |
cited_by required | array of AnnotationSummary | Annotations that cite the unit, newest first. |
cited_by_next_cursor | string or null | Set when more than 100 annotations cite the unit. |
RangeUnit
One unit covered by a range.
| Name | Type | Description |
|---|---|---|
id required | string | The unit id. |
oid required | integer | The permanent number of the unit. |
kind required | string | The level of the unit. |
label | string or null | The unit's heading. |
text | string | The text, for a paragraph. |
length_cp | integer | The length of the text in Unicode code points. |
sha256 | string | The SHA-256 of the text, in hex. |
RangeRead
A range of sibling units with the annotations on any of them.
| Name | Type | Description |
|---|---|---|
id required | string | The range in its short form, such as CH05.P016-P018. |
range required | string | The range in its short form. |
kind required | string | The level of the units. |
work required | string | The work slug. |
edition required | string | The edition id. |
start required | string | The id of the first unit. |
end required | string | The id of the last unit. |
start_oid | integer | The permanent number of the first unit. |
end_oid | integer | The permanent number of the last unit. |
parent | string or null | The id of the shared parent unit. |
ancestors | array of string | The ids of the units above the range, top first. |
units required | array of RangeUnit | The covered units, in order. |
url required | string | The path of the range's page. |
annotations required | array of AnnotationSummary | Annotations on or inside any covered unit, newest first. |
annotations_next_cursor | string or null | Set when more than 100 annotations match. |
cited_by required | array of AnnotationSummary | Annotations that cite a covered unit, newest first. |
cited_by_next_cursor | string or null | Set when more than 100 annotations cite the range. |
Anchor
Where an annotation is attached: a span, a unit, a range or the whole work.
| Name | Type | Description |
|---|---|---|
unit | string | The unit id of a unit or span anchor. |
paragraph | string | The unit id again, when the unit holds text. |
range | string | The short form of a range anchor. |
end_unit | string | The last unit of a range anchor. |
scope | string | Set to work for an anchor on the whole work. |
oid | integer or null | The permanent number of the unit, or of the edition for a work anchor. |
end_oid | integer or null | The permanent number of the last unit of a range. |
role | string or null | The anchor's role, such as primary. |
edition required | string | The edition the anchor was made in. |
exact | string | The quoted words of a span anchor. |
start | integer | The start offset of the span in code points. |
end | integer | The end offset of the span in code points. |
prefix | string or null | Up to 32 code points of text before the span. |
suffix | string or null | Up to 32 code points of text after the span. |
url required | string | The path of the anchored place. |
Source
A source given for an annotation: a place in a work, or an outside page.
| Name | Type | Description |
|---|---|---|
paragraph | string | The cited paragraph, for a source in the library. |
range | string | The cited range, for a range source. |
work | string or null | The work slug, for a source in the library. |
edition | string | The edition id, for a source in the library. |
oid | integer or null | The permanent number of the cited unit. |
exact | string or null | The quoted words that support the claim. |
start | integer | The start offset of the quote in code points. |
end | integer | The end offset of the quote in code points. |
prefix | string or null | Text before the quote. |
suffix | string or null | Text after the quote. |
url | string | The path of the cited place, or the outside URL. |
title | string or null | The title of an outside source. |
locator | string or null | Where in the outside source, such as a page. |
Citation
A link from the body to a unit or another annotation.
| Name | Type | Description |
|---|---|---|
kind required | string, one of unit, annotation | unit or annotation. |
id | string | The cited annotation id. |
revision | integer or null | The cited annotation revision. |
work | string or null | The work slug of a cited unit. |
edition | string | The edition id of a cited unit. |
unit | string or null | The cited unit id. |
range | string | The short form of a range citation. |
end_unit | string | The last unit of a range citation. |
oid | integer or null | The permanent number of the cited object. |
end_oid | integer or null | The permanent number of the last unit of a range. |
exact | string | The quoted words of a span or range citation. |
start | integer | The start offset of the span in code points. |
end | integer | The end offset of the span in code points. |
prefix | string or null | Up to 32 code points of text before the span. |
suffix | string or null | Up to 32 code points of text after the span. |
url required | string | The path of the cited place. |
label | string or null | The link text. |
ExternalReference
An outside URL linked from the body.
| Name | Type | Description |
|---|---|---|
url required | string | The URL. |
title | string or null | The link text or title. |
CitedBy
A current annotation that cites this one.
| Name | Type | Description |
|---|---|---|
id required | string | The citing annotation id. |
revision required | integer | The citing annotation's current revision. |
title | string or null | The citing annotation's title. |
url required | string | The path of the citing annotation. |
AnnotationSummary
An annotation as lists show it, without the body unless asked.
| Name | Type | Description |
|---|---|---|
id required | string | The annotation id. |
oid required | integer | The permanent number of the annotation. |
revision required | integer | The number of the current revision. |
revision_oid required | integer | The permanent number of the current revision. |
created_at required | string (date-time) | When the annotation was first published. |
updated_at required | string (date-time) | When the current revision was published. |
title required | string or null | The title. |
work required | string or null | The work slug of the first anchor. |
edition required | string or null | The edition id of the first anchor. |
anchors required | array of Anchor | Where the annotation is attached. |
metadata required | object | Free-form metadata recorded with the revision. |
url required | string | The path of the annotation's page. |
body_markdown | string | The body in Markdown, present with include=body. |
AnnotationList
One page of annotations, newest first.
| Name | Type | Description |
|---|---|---|
order required | string, one of oid_desc | The sort order, always oid_desc. |
match required | string, one of exact, overlap, contained_by | The span match mode used by overlaps. |
items required | array of AnnotationSummary | The annotations on this page. |
next_cursor required | string or null | The cursor of the next page, or null on the last page. |
Annotation
One revision of an annotation with its body, sources and links.
| Name | Type | Description |
|---|---|---|
id required | string | The annotation id. |
oid required | integer | The permanent number of the annotation. |
revision required | integer | The revision number. |
revision_oid required | integer | The permanent number of this revision. |
work required | string or null | The work slug of the first anchor. |
edition required | string or null | The edition id of the first anchor. |
title required | string or null | The title. |
anchors required | array of Anchor | Where the annotation is attached. |
body_markdown required | string | The body in Markdown. |
sources required | array of Source | The sources given for the claims, in order. |
citations required | array of Citation | Links from the body to units and annotations. |
external_references required | array of ExternalReference | Outside URLs linked from the body. |
limits required | array of string | What the annotation does not claim. |
metadata required | object | Free-form metadata recorded with the revision. |
content_sha256 required | string | The content hash of the revision. |
created_at required | string (date-time) | When this revision was published. |
is_current required | boolean | True when this is the current revision. |
url required | string | The path of the annotation's page. |
revision_path required | string or null | The path of this revision's page. |
cited_by required | array of CitedBy | Current 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.
| Name | Type | Description |
|---|---|---|
items required | array of object, 1 to 100 items | From 1 to 100 selectors. |
items[].id required | string | The annotation id. |
items[].revision | integer, at least 1 | A revision number; the current revision when left out. |
BatchReadResult
One result per selector, in the order sent.
| Name | Type | Description |
|---|---|---|
items required | array of object | The results. |
items[].selector required | object | The selector as sent. |
items[].status required | integer | 200, or the status a single read would have returned. |
items[].revision | Revision | |
items[].error | object | Why the read failed. |
items[].error.code required | string | The error code. |
items[].error.message required | string | A sentence for people. |
ResolveRequest
Exact words in a work, and optional context to tell copies apart.
| Name | Type | Description |
|---|---|---|
work required | string | The work slug. |
edition | string | An edition id; the current edition when left out. |
paragraph | string | The unit to search; the whole edition when left out. |
unit | string | Another name for paragraph. |
exact required | string | The words, exactly as stored. |
prefix | string, at most 32 characters | Text just before the words, at most 32 code points. |
suffix | string, at most 32 characters | Text just after the words, at most 32 code points. |
occurrence | integer, at least 1 | Which match to take, counting from 1 in reading order. |
start | integer | A start offset to check instead of searching. |
end | integer | An end offset to check instead of searching. |
SpanTarget
The located span in storage terms.
| Name | Type | Description |
|---|---|---|
target_kind required | string | Always source_span. |
edition_id required | string | The edition id. |
source_revision_id required | string | The text revision id. |
unit_id required | string | The paragraph id. |
start_cp required | integer | The start offset in code points. |
end_cp required | integer | The end offset in code points. |
exact_quote required | string | The words. |
prefix | string | Up to 32 code points before the words. |
suffix | string | Up to 32 code points after the words. |
ResolveResult
Where the words are.
| Name | Type | Description |
|---|---|---|
work required | string | The work slug. |
edition required | string | The edition id. |
paragraph required | string | The paragraph that holds the words. |
exact required | string | The words. |
start required | integer | The start offset in code points. |
end required | integer | The end offset in code points. |
prefix required | string | Up to 32 code points before the words. |
suffix required | string | Up to 32 code points after the words. |
url required | string | The path of the span. |
located | object | How the words were found, present when the server searched. |
located.mode required | string | Always quote. |
located.match_count required | integer | How many matches the search found. |
located.occurrence required | integer | Which match was taken. |
located.searched_leaves required | integer | How many paragraphs were searched. |
target required | SpanTarget |
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.
| Name | Type | Description |
|---|---|---|
q required | string | The query, trimmed. |
works_next_cursor | string or null | Only for type=works: continue the same query's work results, or null on the last page. |
works required | array of object | Matching works, by title. |
works[].slug required | string | The work slug. |
works[].title required | string | The title. |
works[].authors | array of string | Author names. |
works[].edition | string or null | The current edition id. |
works[].oid | integer | The permanent number of the work. |
works[].url required | string | The path of the work's page. |
paragraphs required | array of object | Matching paragraphs, best first. |
paragraphs[].work required | string | The work slug. |
paragraphs[].edition required | string | The edition id. |
paragraphs[].paragraph required | string | The paragraph id. |
paragraphs[].oid required | integer | The permanent number of the paragraph. |
paragraphs[].snippet required | string | Text around the hits, with hits in double asterisks. |
paragraphs[].url required | string | The path of the paragraph. |
paragraphs_next_cursor required | string or null | The cursor of the next page of paragraphs. |
referenced required | array of object | Up to 20 cited outside URLs whose URL or title contains the query. |
referenced[].url required | string | The URL. |
referenced[].title | string or null | The title given for it. |
referenced[].cited_by required | integer | How many annotations cite it. |
ActivityItem
One event in the library's log.
| Name | Type | Description |
|---|---|---|
id required | integer | The event id. |
at required | string (date-time) | When it happened, in UTC. |
kind required | string, one of annotation.published, annotation.revised, annotation.hidden, annotation.unhidden, work.imported, edition.corrected | What happened. |
object_type required | string | The type of the object, such as annotation. |
object_id required | string or null | The id of the object; null when the object is no longer public. |
oid required | integer or null | The permanent number of the object; null when the object is no longer public. |
work required | string or null | The work slug; null when the object is no longer public. |
edition required | string or null | The edition id; null when the object is no longer public. |
paragraph required | string or null | The paragraph id; null when the object is no longer public. |
title required | string or null | The object's title; null when the object is no longer public. |
url required | string or null | The object's path; null when the object is no longer public. |
detail required | object | Facts about the event; empty when the object is no longer public. |
visible required | boolean | False when the object is no longer public. |
paragraph_path required | string or null | The path of the paragraph; null when the object is no longer public. |
ActivityPage
One page of events, newest first.
| Name | Type | Description |
|---|---|---|
items required | array of ActivityItem | The events on this page. |
next_cursor required | string or null | The cursor of the next page, or null on the last page. |
Stats
The library's counts.
| Name | Type | Description |
|---|---|---|
works required | integer | Public works with a public edition. |
editions required | integer | Public editions of those works. |
paragraphs required | integer | Text units in their current editions. |
annotations required | integer | Public annotations. |
revisions required | integer | Revisions of those annotations. |
annotated_paragraphs required | integer | Distinct paragraphs those annotations anchor on. |
events required | integer | Events in the activity log. |
last_activity_at required | string or null (date-time) | The time of the newest event. |
license required | License |
Suggestion
A suggestion about the site, an edit to an annotation, or a new annotation.
| Name | Type | Description |
|---|---|---|
kind required | string, one of site, edit, annotation | What the suggestion is about. |
topic | string, one of addition, missing, issue, site, contribute, other | For a site suggestion: its topic. |
target | object or null | Null for site; {annotation, revision?} for edit; {work, unit?, exact?} for annotation. |
target.annotation | string | For an edit: the annotation id. |
target.revision | integer | For an edit: a revision number; the current one when left out. |
target.work | string | For an annotation: the work slug. |
target.unit | string | For an annotation: a unit id or range of the current edition. |
target.exact | string, at most 2,000 characters | For an annotation with a unit: words in that unit, at most 2000 characters. |
title | string, at most 500 characters | For an annotation: a title of at most 500 characters. |
body required | string, 1 to 10,000 characters | The suggestion itself, 1 to 10000 characters. |
proposed_body_markdown | string, at most 10,000 characters | For an edit: the whole new body, at most 10000 characters. |
sources | string, at most 10,000 characters | For an annotation: where the claim comes from, at most 10000 characters. |
submitted_by required | object | Who sends it, as the sender states. |
submitted_by.kind required | string, one of human, agent | human or agent. |
submitted_by.name | string, at most 200 characters | A name; required for an agent, at most 200 characters. |
submitted_by.email | string, at most 320 characters | An email address, at most 320 characters. |
submitted_by.model | string, at most 500 characters | The model an agent runs on, at most 500 characters. |
submitted_by.url | string, at most 500 characters | A URL about the sender, at most 500 characters. |
SuggestionCreated
The stored suggestion.
| Name | Type | Description |
|---|---|---|
id required | string | The suggestion id. |
kind required | string, one of site, edit, annotation | What the suggestion is about. |
status required | string | Always open for a new suggestion. |
created_at required | string (date-time) | When it was stored. |
target required | object or null | The checked target; the server adds the work or edition it recorded. |
url required | string | The path of the confirmation page. |
RedirectBody
The body sent with a redirect.
| Name | Type | Description |
|---|---|---|
redirect required | string | The same path as the Location header. |