API for accessing Paratext Text and Notes

Overview

This API is limited to being able to access data for projects that the requesting user is a member of. The user roles for a project are maintained through Paratext and the official version of projects roles is kept on the Paratext Registry server.

Paratext Registry Server

The project is identified by the Paratext GUID which is available on the Registration tab for the project on the Registry server and also in the JSON data that can be retrieved from the Registry server API.

Registry API

Base URLs

The service will be accessed through one of the following base URLs:


Authentication

JSON Web Token (JWT) authentication is used for calls to this API. The token is acquired from the Paratext registry server when a valid Paratext username and registration code is provided.

Variables used in the code below:

  • userName: Paratext user name
  • registrationCode: Paratext 8 registration code
  • token: JWT to include in the header for calls to the API
// Post data to get JwtToken
var request = new XMLHttpRequest();
request.open("POST", "https://registry-dev.paratext.org/api8/token/", true, 
    userName, registrationCode);
request.setRequestHeader("Content-type", "application/json");
request.onreadystatechange = function () {
    if (request.readyState === 4 && request.status === 200) {
 	    var responseJson = JSON.parse(request.responseText);
 	    token = responseJson["access_token"];
    }
 }
                                    

Variables used in the code below:

  • requestStr: text of an API call to get Scripture or notes
  • token: JWT to include in the header for calls to the API
// Calls to the API must include the JWT in the header for requests. 
var request = new XMLHttpRequest();
var url = "https://data-access-dev.paratext.org" + requestStr;
request.open("GET", url, true);
request.setRequestHeader("Authorization", "Bearer " + token);
request.onreadystatechange = function() {
    if (request.readyState == XMLHttpRequest.DONE) {
		// Use response.responseText to access requested Scripture or notes XML
    }
}
request.send(null);
                                    

Getting projects for current user

URL

/api8/projects

Method: Get

Gets information about all projects in which current user is a member. Information includes:

  • project short name,
  • project id,
  • Mercurial tip revision id,
  • project type, and
  • the id of the base project (if project is derived)

No parameters required

Status code: 200 OK

Content: XML-format information about all projects in which the currently-authenticated user has a role

Status code: 404 NOT FOUND

Reason: User is not a member of any projects on the server

<repos>
	<repo>
		<proj>TPFM</proj>
		<projid>73d667c2e2ddddcd43bdae2f04973e2a51b2d1ce</projid>
		<projecttype>Standard</projecttype>
		<baseprojid/>
		<tipid>08dd403e9126</tipid>
	</repo>
	<repo>
		<proj>F46117</proj>
		<projid>f19d954e657edf2896ee8fe01ab4566962ebffdc</projid>
		<projecttype>Auxiliary</projecttype>
		<baseprojid>45eff14875b6fc356a3cadb5306d40c279deec25</baseprojid>
		<tipid>f9645dc538c5</tipid>
	</repo>
	<repo>
		<proj>TSCNP</proj>
		<projid>395afbeb1009ccc34c8298e47acdbceb189f0e77</projid>
		<projecttype>ConsultantNotes</projecttype>
		<baseprojid/>
		<tipid>71e680838906</tipid>
	</repo>
	<repo>
		<proj>CCP</proj>
		<projid>2508cb12971fd2e48a5303397c33ed882677f826</projid>
		<projecttype>Standard</projecttype>
		<baseprojid/>
		<tipid>3e8bcf7581f2</tipid>
	</repo>
</repos>
                                    

Getting books in a project

URL

/api8/books/{paratextGuid}

Method: Get

Gets the ids of the books which are included in the specified project.

Required:

paratextGuid: unique id that identifies project

Status code: 200 OK

Content: Three-letter book ids for project in XML format

Status code: 403 FORBIDDEN

Reason: User associated with request is not a member of the project


Status code: 404 NOT FOUND

Reason: Requested project, book or chapter does not exist

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server
<ProjectBooks>
    <Book id="GEN" />
    <Book id="EXO" />
    <Book id="JHN" />
    <Book id="1JN" />
</ProjectBooks>
                                        

Getting Mercurial revisions used in a book

URL

/api8/revisions/{paratextGuid}/{bookId}

Method: Get

Gets the most-recent Mercurial revisions used in each chapter of the specified book.

Required:

paratextGuid: unique id that identifies project

bookId: Three-letter Id that identifies book

Status code: 200 OK

Content: Most recent Mercurial (hg) revisions used in all existing chapters in the requested book.

By comparing the current revisions for a book to the revisions when a book was originally obtained from the Send/Receive server, one can determine if someone else has updated the same book on the Send/Receive server.

Status code: 400 BAD REQUEST

Reason: Incorrectly formatted URL

Error messages:

  • Invalid book: bookId
    • Specified bookId is not a recognized Scripture book

Status code: 403 FORBIDDEN

Reason: User associated with request is not a member of the project


Status code: 404 NOT FOUND

Reason: Requested project or book does not exist

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server
  • Book not included in this project: bookId
    • Specified bookId is not included in the project

This following XML shows the hg revisions for each chapter that is present in the requested book. Things to note about the example XML below:

  • The revision for chapter 0 is the most recent revision for the entire book. Since the chapter 0 and chapter 1 revisions are the same, this indicates that the last change in the book was made in the text of chapter 1. Use another get versions API call immediately before posting changes to the book to confirm that the revision for chapter 0 is unchanged, i.e. that no one else has made a change in the book.
  • The projectTipId shown in the attribute of the root element is not the same as any of the revisions for the chapters. This indicates that the last change to the project was not a change in this book.
  • Chapter 3 is not present in the book so no revision is listed for it.
<RevisionInfo projectTipId="4ca10ded01a3">
  <ChapterInfo chapter="1" revision="63d99e0ca5a8" />
  <ChapterInfo chapter="2" revision="9b88a465bd69" />
  <ChapterInfo chapter="4" revision="f8fdad84d39c" />
  <ChapterInfo chapter="5" revision="74a9dc1991b5" />
  <ChapterInfo chapter="0" revision="63d99e0ca5a8" />
</RevisionInfo>
                                   

Getting Scripture text data

URL

/api8/text/{paratextGuid}/{bookId}/[chapterNumber]

Method: Get

Required:

paratextGuid: unique id that identifies project

bookId: Three-letter Id that identifies book

Optional:

chapterNumber: integer chapter number. if not provided, content of entire book will be returned.

Status code: 200 OK

Content: USX-formatted content of requested book or chapter wrapped with a BookText element. The BookText elment has project, book, chapter and revision attributes. The value of the revision attribute will need to be provided when updated text is posted to this service.

USX Documentation

NOTE: Since the returned USX is for books still in the process of being edited, the results may not pass validation by the schema.

Status code: 400 BAD REQUEST

Reason: Incorrectly formatted URL

Error messages:

  • Invalid book: bookId
    • Specified bookId is not a recognized Scripture book
  • Invalid chapter: chapterNumber
    • Specified chapterNumber is not a valid integer

Status code: 403 FORBIDDEN

Reason: User associated with request is not a member of the project


Status code: 404 NOT FOUND

Reason: Requested project, book or chapter does not exist

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server
  • Book not included in this project: bookId
    • Specified bookId is not included in the project
  • No text found at requested location: bookId (chapterNumber>)
    • No Scripture text found in bookId or, if provided, the chapterNumber within the book
  • No revision found for: bookId (chapterNumber)
    • No revision was found for bookId and, if provided, the chapterNumber. This probably means there is a problem with the history for the project.

Getting notes data

URL

/api8/notes/{paratextGuid}/{bookId}/[chapterNumber]

Method: Get

Required:

paratextGuid: unique id that identifies project

bookId: Three-letter Id that identifies book

Parameters:
  • range: chapter verse range in form of chapterStart[.verseStart[-[chapterEnd.]verseEnd]]. if not provided, all notes for book will be returned (except for conflict notes, biblical term notes and wordlist notes)
  • status: either "unresolved" indicating that only unresolved notes should be returned and "all" indicating that both resolved and unresolved notes in the range should be specified. Default value is "all"
  • after: if specified, include all notes created on and after the date in the format yyyy-mm-dd, e.g. 2017-05-23. If not provided, notes will be returned regardless of their creation date
<?xml version="1.0" encoding="UTF-8"?>
<!--
  notes.rng
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  A compact syntax Relax NG Schema for Paratext Notes version 1.1
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
-->
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <ref name="Notes"/>
    </start>
    <define name="Notes">
        <element name="notes">
            <attribute name="version">
                <data type="string">
                    <param name="minLength">3</param>
                    <param name="pattern">\d+\.\d+(\.\d+)?</param>
                </data>
            </attribute>
            <zeroOrMore>
                <ref name="Thread"/>
            </zeroOrMore>
        </element>
    </define>
    <define name="Thread">
        <element name="thread">
            <attribute name="id">
                <data type="string"/>
            </attribute>
            <optional>
                <attribute name="type">
                    <data type="string"/>
                </attribute>
            </optional>
            <ref name="Selection"/>
            <oneOrMore>
                <ref name="Comment"/>
            </oneOrMore>
        </element>
    </define>
    <define name="Comment">
        <element name="comment">
            <attribute name="user">
                <data type="string"/>
            </attribute>
            <attribute name="date">
                <data type="string">
                    <param name="pattern">\d{4}-\d\d\-\d\dT\d\d:\d\d:\d\d\.\d{5,}[\-\+]\d\d:\d\d</param>
                </data>
            </attribute>
            <optional>
                <attribute name="extUser">
                    <data type="string"/>
                </attribute>
            </optional>
            <optional>
                <attribute name="deleted">
                    <choice>
                      <value>true</value>
                      <value>false</value>
                    </choice>
                </attribute>
            </optional>
            <optional>
                <attribute name="versionNbr">
                    <data type="string">
                        <param name="pattern">\d+</param>
                    </data>
                </attribute>
            </optional>
            <ref name="Content"/>
        </element>
    </define>
    <define name="Selection">
        <element name="selection">
            <interleave>
                <attribute name="verseRef">
                    <data type="string"/>
                </attribute>
                <attribute name="startPos">
                    <data type="integer"/>
                </attribute>
                <attribute name="selectedText">
                    <data type="string"/>
                </attribute>
                <optional>
                    <attribute name="beforeContext">
                        <data type="string"/>
                    </attribute>
                </optional>
                <optional>
                    <attribute name="afterContext">
                        <data type="string"/>
                    </attribute>
                </optional>
            </interleave>
            <empty />
        </element>
    </define>
    <define name="Content">
        <element name="content">
            <optional>
                <text />
            </optional>
            <zeroOrMore>
                <ref name="Paragraph"/>
            </zeroOrMore>
        </element>
    </define>
    <define name="Paragraph">
        <element name="p">
            <oneOrMore>
                <choice>
                    <ref name="Span"/>
                    <ref name="Language"/>
                    <text />
                </choice>
            </oneOrMore>
        </element>
    </define>
    <define name="Span">
        <element name="span">
            <attribute name="style">
                <data type="string" />
            </attribute>
            <text />
        </element>
    </define>
    <define name="Language">
        <element name="lang">
            <attribute name="name">
                <data type="string" />
            </attribute>
            <text />
        </element>
    </define>
</grammar>
                                        

Status code: 200 OK

Content: Notes within selected range formatted according to schema.

Status code: 204 NO CONTENT

Content: Valid request, but no notes found

Status code: 400 BAD REQUEST

Reason: Incorrectly formatted URL

Error messages:

  • Invalid book: bookId
    • Specified bookId is not a recognized Scripture book
  • Invalid chapter/verse range: chapterVerseRange
    • Unable to parse the chapterVerseRange
  • Invalid status: statusType
    • Status is not recognized, i.e. either "all" or "unresolved"
  • Invalid date: afterDate
    • Date was not specified in the format yyyy-mm-dd

Status code: 403 FORBIDDEN

Reason: User associated with request is not a member of the project


Status code: 404 NOT FOUND

Reason: Requested book not found

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server
  • Book not included in this project: bookId
    • Specified bookId is not included in the project

Posting Scripture text data

URL

/api8/text/{paratextGuid}/{revision}/{bookId}/[chapterNumber]

Method: Post

Required:

paratextGuid: unique id that identifies project

revision: revision that was given when the text was retrieved from this service.

bookId: Three-letter Id that identifies book

Optional:

chapterNumber: integer chapter number. if not provided, content of entire book will be replaced.

Body:

USX for whole book or specified chapter

Status code: 200 OK

Content: The updated book text in the same format as describe for Getting Scripture text data

Result: If the revision supplied in the post command doesn't match the current revision of the book or chapter, the update will be applied to the given revision and a merge will be done. The result of this request will reflect the merge and conflict notes may have been created. The changed text will be immediately committed and available to other users on the project via send/receive.

Status code: 400 BAD REQUEST

Reason: Incorrectly formatted URL or body content

Error messages:

  • Invalid book: bookId
    • Specified bookId is not a recognized Scripture book
  • Invalid chapter: chapterNumber
    • Specified chapterNumber is not a valid integer
  • No text found in body of request
    • No Scripture text was found in the body of the request
  • Root element of XML is not USX: foundName
    • A full validation of the USX cannot be done since text in progress can be invalid. However, a check is made to ensure the XML has the expected root element. Instead of <usx>, <foundName> was the root element.
  • No text found in body of request
    • An empty body (i.e. no Scripture text) will not be accepted
  • Invalid revision: revision
    • The revision must be the 12 character short form or the 40 character long form and it must exist in the repository of the project.

Status code: 403 FORBIDDEN

Reason: User does not have permission to change Scripture specified in post request

  • Not a member of the request project
    • User is not associated with the requested project
  • Do not have edit permission for: bookId [chapterNumber]
    • User does not have edit permission for whole book of bookId (if no chapter is specified), or for requested chapterNumber
  • Could not lock project for updating
    • Another user has locked the project. Request should be tried again after a short delay

Status code: 404 NOT FOUND

Reason: Requested project does not exist

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server

Status code: 500 Internal Server Error

Reason: Unexpected error when updating text. This should be reported to Paratext developers.

Error messages:

  • Updating of Scripture text failed: detailedMessage
    • Server returned the error detailedMessage during post attempt

Posting notes data

URL

/api8/notes/{paratextGuid}

Method: Post

Required:

paratextGuid: unique id that identifies project

Body:

XML that conforms to notes schema

If the user submitting the request is an administrator on the project, the notes can be for any user on the project. Use the extUser attribute if you need to track the external user who created the note.

If the thread, user and date of a comment match an existing comment, that comment will be updated rather than a new comment added. Only the extUser, deleted or content of a comment can be changed.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  notes.rng
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  A compact syntax Relax NG Schema for Paratext Notes version 1.1
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
-->
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <ref name="Notes"/>
    </start>
    <define name="Notes">
        <element name="notes">
            <attribute name="version">
                <data type="string">
                    <param name="minLength">3</param>
                    <param name="pattern">\d+\.\d+(\.\d+)?</param>
                </data>
            </attribute>
            <zeroOrMore>
                <ref name="Thread"/>
            </zeroOrMore>
        </element>
    </define>
    <define name="Thread">
        <element name="thread">
            <attribute name="id">
                <data type="string"/>
            </attribute>
            <optional>
                <attribute name="type">
                    <data type="string"/>
                </attribute>
            </optional>
            <ref name="Selection"/>
            <oneOrMore>
                <ref name="Comment"/>
            </oneOrMore>
        </element>
    </define>
    <define name="Comment">
        <element name="comment">
            <attribute name="user">
                <data type="string"/>
            </attribute>
            <attribute name="date">
                <data type="string">
                    <param name="pattern">\d{4}-\d\d\-\d\dT\d\d:\d\d:\d\d\.\d{5,}[\-\+]\d\d:\d\d</param>
                </data>
            </attribute>
            <optional>
                <attribute name="extUser">
                    <data type="string"/>
                </attribute>
            </optional>
            <optional>
                <attribute name="deleted">
                    <choice>
                      <value>true</value>
                      <value>false</value>
                    </choice>
                </attribute>
            </optional>
            <optional>
                <attribute name="versionNbr">
                    <data type="string">
                        <param name="pattern">\d+</param>
                    </data>
                </attribute>
            </optional>
            <ref name="Content"/>
        </element>
    </define>
    <define name="Selection">
        <element name="selection">
            <interleave>
                <attribute name="verseRef">
                    <data type="string"/>
                </attribute>
                <attribute name="startPos">
                    <data type="integer"/>
                </attribute>
                <attribute name="selectedText">
                    <data type="string"/>
                </attribute>
                <optional>
                    <attribute name="beforeContext">
                        <data type="string"/>
                    </attribute>
                </optional>
                <optional>
                    <attribute name="afterContext">
                        <data type="string"/>
                    </attribute>
                </optional>
            </interleave>
            <empty />
        </element>
    </define>
    <define name="Content">
        <element name="content">
            <optional>
                <text />
            </optional>
            <zeroOrMore>
                <ref name="Paragraph"/>
            </zeroOrMore>
        </element>
    </define>
    <define name="Paragraph">
        <element name="p">
            <oneOrMore>
                <choice>
                    <ref name="Span"/>
                    <ref name="Language"/>
                    <text />
                </choice>
            </oneOrMore>
        </element>
    </define>
    <define name="Span">
        <element name="span">
            <attribute name="style">
                <data type="string" />
            </attribute>
            <text />
        </element>
    </define>
    <define name="Language">
        <element name="lang">
            <attribute name="name">
                <data type="string" />
            </attribute>
            <text />
        </element>
    </define>
</grammar>
                                

Status code: 200 OK

Content: New tip version as plain text.

Result:The new and updated notes will be immediately committed and available to other users on the project via send/receive.

Status code: 400 BAD REQUEST

Reason: Incorrectly formatted body content

Error messages:

  • Could not parse body of request: detailMessage
    • Error that occurs if the XML for the posted notes cannot be parsed as a valid document
  • Request does not conform to notes schema. First error: message
    • The validation check of the XML in the body failed. The message for the first error will be returned to help diagnose the problem.
  • No notes found in submitted XML
    • The submitted XML was empty.
  • Notes can only be added for users on the project. First unknown user: user
    • One or more of the notes in the submitted XML contained a user that is not a member of the project.

Status code: 403 FORBIDDEN

Reason: User does not have permission to complete post request

Error messages:

  • Not a member of the requested project
    • User is not associated with the requested project
  • Role on project does not allow adding notes
    • User posting notes to the requested project must have be an Administrator, Consultant or Translator.
  • Only project administrators can add notes for other users
    • User posting notes is not a project administrator, so the user attribute on the comments must match their user name
  • Could not lock project for updating
    • Another user has locked the project. Request should be tried again after a short delay.

Status code: 404 NOT FOUND

Reason: Requested project does not exist

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server

Status code: 500 Internal Server Error

Reason: Unexpected error when attempting to post notes. This should be reported to Paratext developers.

Error messages:

  • Adding notes failed: detailedMessage
    • Server returned the error detailedMessage during post attempt

Getting plugin data

URL

/api8/notes/{paratextGuid}/{pluginfolder}/{pluginname}/[filename]

Method: Get

Required:

paratextGuid: unique id that identifies project

pluginfolder: string that identifies the base folder where a plugin stores its data (Note: This is identical to the subfolder in Paratext’s plugins folder where the plugin DLL is installed.)

pluginname: string that identifies the name of a plugin. This is a subfolder inside pluginFolder. (Note: This is the name of the DLL, without the extension, containing the plugin.)

Optional:

filename: Name file desired file. If not provided, the result will just indicate whether or not the combination of pluginfolder and pluginname exist for the project.

Status code: 200 OK

Content: If filename is specified, the content of the file is returned. If filename is not specified, true or false will be returned depending on whether or not the specified plugin exists in the project.

Status code: 403 FORBIDDEN

Reason: User associated with request is not a member of the project


Status code: 404 NOT FOUND

Reason: Requested book not found

Error messages:

  • Unable to locate specified project
    • Project with paratextGuid does not exist on the server
  • Requested file does not exist: pluginfolder/pluginname/filename
    • No file exists in the project with the specified relative path.