Using the ESV Bible as a Web Service - API
This version of the API is deprecated. Please use the latest version.
Show me a general introduction...
What's New
- July 10, 2007 - Added start-date parameter to the various reading-plan queries.
- July 9, 2007 - Added a <is-complete-chapter> element to the response of getQueryInfo.
- April 24, 2007 - Added documentation of include-word-ids for HTML and XML output.
- March 14, 2007 - Added link to WCF sample code.
- November 30, 2006 - Added getReadingPlanInfo.
- November 29, 2006 - Added bcp (Book of Common Prayer) as a reading plan for doReadingPlanQuery.
- June 26, 2006 - Added a <unit> element to the response of getQueryInfo.
- June 22, 2006 - Added audio-version parameter and made more options available for audio-format.
- October 20, 2005 - Changed examples to use the new IP key for IP-based access.
- October 12, 2005 - Added WordPress Plugins section.
- August 15, 2005 - Added audio-format parameters to the HTML options.
- June 21, 2005 - Added Python sample code.
- May 2, 2005 - Added include-audio-link and link-url parameters to the HTML options.
- April 27, 2005 - Added Ruby sample code.
- March 2, 2005 - Added a Demonstrations section.
- November 30, 2004 - Added Java sample code.
- November 22, 2004 - WSDL link and sample code added. doQuery is now available via SOAP.
- November 18, 2003, January 30, 2004 - ASP sample code added.
- November 17, 2003 - Added doQuery.
- October 23, 2003 - Added ColdFusion sample code.
- July 29, 2003 - getVerse and getDailyVerse are now available.
- May 12, 2003 - doReadingPlanQuery can now query The One-Year Tract Bible reading plan.
- Feb 24, 2003 - getQueryInfo - parse a query and identify whether it is a passage reference or a word search.
Because this service is still in beta, this API is subject to change without notice. In the examples below, the testing key is used, which scrambles the text. When you have an access key, the text appears normally.
HTTP-GET Interface
The base url for all GET requests is: http://www.gnpcb.org/esv/share/get/
Certain variables are required to receive the desired response, depending on your desired action:
For doPassageQuery:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| passage | The passage you want to display. It accepts a wide variety of input formats (e.g., Isaiah 1, Isa 1, and Is 1 all go to Isaiah 1). |
| action | Set to doPassageQuery (look up a passage). |
For doQuery:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| q | The passage you want to display or string you want to search for. It is weighted toward finding passages, so a search for is shows you Isaiah 1. To override this behavior, see below. |
| action | Set to doQuery (look up a passage or show word-search results, depending on the query). |
For doReadingPlanQuery:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| action | Set to doReadingPlanQuery (retrieve passages from our Devotions section. More...). |
For getQueryInfo:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| q | The string you want to parse. |
| action | Set to getQueryInfo (parse and display information about your query, including identify whether it is a passage reference or a word search. More...). |
For getReadingPlanInfo:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| action | Set to getReadingPlanInfo (parse and display information about the reading plan for a given date. More...). |
For getVerse:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| action | Set to getVerse (display a random verse from a preselected list, or specify verse(s). More...). |
For getDailyVerse:
| Variable | Description |
|---|---|
| key | Your access key. For testing purposes, you can use the key TEST. For general-purpose queries, you can use the key IP. |
| action | Set to getDailyVerse (display a verse that changes every day. More...). |
Additionally, for doPassageQuery and doReadingPlanQuery, you can set a number of optional variables, depending on your desired output format. (See below.)
Sample Queries using the testing key (scrambled output)
SOAP Interface
The SOAP interface should be considered experimental. We've tested it with Perl's SOAP::Lite module and PHP's NuSOAP. It does not always return SOAP faults correctly (for example, if you execute doQuery without an options argument).
The base url for all SOAP requests is http://www.gnpcb.org/esv/share/soap/
We suggest a namespace of http://www.crosswaybibles.org/soap
Currently, the available functions are:
- doPassageQuery, which takes the following inputs:
- Parameter 1: $key. Your access key.
- Parameter 2: $passage. The passage(s) you want to look up.
- Parameter 3: $options. Optional. An associative array containing any of the options listed below. The available options depend on your desired output format.
- doQuery, which returns search results or a passage depending on the query. It takes the following inputs:
- Parameter 1: $key. Your access key.
- Parameter 2: $options. An associative array containing any of the options listed below. It must contain at least one of the following keys: q, passage, words, phrase. More about doQuery...
- doReadingPlanQuery, which shows passages corresoponding to a reading
plan. It takes the following inputs:
- Parameter 1: $key. Your access key.
- Parameter 2: $options. Optional. An associative array containing any of the options listed below. As with doPassageQuery, the available options depend on your desired output format. More about doReadingPlanQuery...
- getQueryInfo, which parses your query and gives you information
about it. It takes the following inputs:
- Parameter 1: $key. Your access key.
- Parameter 2: $q. A string containing the query. More about getQueryInfo...
- getVerse, which resembles doPassageQuery except it corrects
beginning punctuation and matches quotes. It takes the following inputs:
- Parameter 1: $key. Your access key.
- Parameter 2: $options. Optional. An associative array containing any of the options described in getVerse below, including a passage reference. It can also contain any output formatting options.
- getDailyVerse, which is identical to getVerse except
that it shows the same verse for a span of one day, making it suitable for
verse-of-the-day applications. It takes the following inputs:
- Parameter 1: $key. Your access key.
- Parameter 2: $options. Optional. An associative array containing any of the options described in getDailyVerse below. It can also contain any output formatting options.
WSDL
Technical documentation and a WSDL file are also available.
Sample Queries (the exact format depends on the language you're using. These are in Perl)
- my $content = doPassageQuery("IP", "rev 1:7, 3:2", {"output-format" => "plain-text"});
- my $content = doReadingPlanQuery("IP");
HTML Output
HTML is the default output and will appear unless output-format is specified. To make full use of the text, you will probably want to link a CSS stylesheet to your page, either one you've created or ours (http://www.gnpcb.org/esv/assets/style/text.css). This stylesheet contains close to the minimum markup needed to render the text accurately.
The following options all take a Boolean value of true or false (or 1 or 0).
| Option | Default | Description |
|---|---|---|
| include-passage-references | true | Include <h2>s that indicate which passage is being displayed. For example: Isaiah 53:1-5. |
| include-first-verse-numbers | true | Show the verse number (e.g., 53:1) at the beginnings of chapters. |
| include-verse-numbers | true | Show verse numbers in the text. |
| include-footnotes | true | Include footnotes and references to them in the text. |
| include-footnote-links | true | If you have set include-footnotes to true, set this option to false to turn off the links to the footnotes within the text. The footnotes will still appear at the bottom of the passage. If include-footnotes is false, this parameter does not do anything. |
| include-headings | true | Include section headings. For example, the section heading of Matthew 5 is The Sermon on the Mount. |
| include-subheadings | true | Include subheadings. Subheadings are the titles of psalms (e.g., Psalm 73's A Maskil of Asaph), the acrostic divisions in Psalm 119, the speakers in Song of Solomon, and the textual notes that appear in John 7 and Mark 16. |
| include-surrounding-chapters | false | Show links under the reference to the previous, current (if not showing the whole chapter) and next chapters in the Bible. The link points to the ESV website, but you can modify it by changing the link-url parameter. |
| include-word-ids | false | Include a <span> tags surrounding each word with a unique id. The id has several parts; the id "w40001002.01-1" consists of: the letter w (needed for XHTML ids), an eight-digit verse identifier (40001002 indicates Matthew 1:2), a period (.), a two-digit word identifier (01), and a hyphen followed by a number (this number is incremented with each passage; it starts with 1). Footnotes do not have word ids. |
| link-url | http:// www.gnpcb.org/ esv/search/ | Where embedded links to other passages should point. It currently applies only when include-surrounding-chapters is set to true. |
| include-audio-link | true | Include a link to the audio version of the requested passage. The link appears in a <small> tag in the passage's identifying <h2>. |
| audio-format | real | Takes a value of flash, mp3, real, or wma to indicate the format of the audio. It defaults to real for historical reasons, but the default could change (to flash); if you have a strong preference for one of these formats, we recommend that you specify it explicitly. We recommend flash as the most flexible; an embedded Flash player is included in the text. The mp3 option includes a link to an M3U file. However, this link expires after about 24 hours, making it unsuitable for extended caching. The other two options, real and wma, only have New Testament recordings by Marquis Laughlin available. (The real option refers to RealAudio, and wma refers to Windows Media.) |
| audio-version | mm | Which recording to use. The options are: mm (Max McLean, complete Bible), ml (Marquis Laughlin, New Testament only), and ml-mm (Max McLean for Old Testament, Marquis Laughlin for New Testament. Only affects the output if audio-format is flash or mp3. (Max McLean's version is only available in these two formats.) |
| include-short-copyright | true | Each passage from the ESV needs to include the letters "ESV" at the end of the passage. To turn off this behavior, set this option to false. |
| include-copyright | false | Show a copyright notice at the bottom of the text. Any page that shows the ESV text from this service needs to include a copyright notice, but you do not need to include it with each passage. Best practice is probably to include the copyright manually on your page, rather than download it every time. This option is mutually exclusive with include-short-copyright, which overrides include-copyright. |
Sample Output (line breaks added for clarity)
<div class="esv">
<h2>Matthew 22:43 - 23:1</h2>
<div class="esv-text">
<p class="virtual"><span class="verse-num">43 </span>He said to them,
<span class="woc">“How is it then that David, in the Spirit,
calls him Lord, saying,</span></p>
<div class="block-indent">
<p class="line-group"><span class="verse-num woc">44 </span>
<span class="woc">“‘The Lord said to my Lord,<br />
Sit at my right hand,<br />
<span class="indent"></span>until I put your enemies under
your feet’?</span></p>
</div>
<p class="same-paragraph"><span class="verse-num-woc">45 </span>
<span class="woc">If then David calls him Lord, how is he his son?”</span>
<span class="verse-num">46 </span>And no one was able to answer him a word,
nor from that day did anyone dare to ask him any more questions.</p>
<h3>Seven Woes to the Scribes and Pharisees</h3>
<p><span class="chapter-num">23:1</span>Then Jesus said
to the crowds and to his disciples,</p>
</div>
<p class="copyright">The Holy Bible, English Standard Version
copyright © 2001 by <a href="http://www.crosswaybibles.org">Crossway
Bibles</a>, a publishing ministry of Good News Publishers. Used by permission. All rights
reserved. <a
href="http://www.gnpcb.org/page/esv.copyright">Quotation information</a>.</p>
</div>
Crossway XML Output
This format shows you how we store the text in our database. It has fewer options because we assume that you will have to transform the output anyway, so you will be able to remove the elements you don't need. You can find a description of the schema here. We designed it to be easily transformed into HTML and other paragraph-based markup. See the PHP code we use to transform the XML into HTML. Note that this script only formats the data in the <content> tags, and it doesn't handle footnotes.
Set the option output-format to crossway-xml-1.0 if you want to display this format.
The following options all take a Boolean value of true or false (or 1 or 0).
| Option | Default | Description |
|---|---|---|
| include-xml-declaration | false | Include a <?xml version="1.0" ?> at the top of the document. |
| include-doctype | true | Include a DOCTYPE declaration. Note that it links to a DTD that only explains the character entities, not the elements. |
| include-quote-entities | true | The original XML files contain an elaborate system of marking where quotations begin and end. This information is unnecessary for most purposes. Leaving this option set to true transforms the quotations from <q> elements to the entities referenced in the DTD (e.g., &ldblquot; for an opening double quotation mark). Setting this option to false leaves in the <q> tags, as described in the XML Schema. |
| include-simple-entities | false | Translates character entities to native XML entities (e.g., &ldblquot; becomes ") for non-DTD-aware parsers. You can see the specific transformations we do in our PHP function translate_entities_to_simple_xml(). If you also disable the option include-quote-entities, the quote entities are translated to <q> tags before applying this transformation. |
| include-cross-references | false | Currently, the cross-references don't point to anything, so there's little reason to include them. |
| include-line-breaks | true | Include line breaks in the XML output. It doesn't make any functional difference; it's just easier to read. |
| include-word-ids | false | Include word ids (<w> tags) around each word in the text. The wid attribute consists of an eight-digit verse identifier, followed by a period (.) and a two-digit word identifier. The wids are unique for each word in the Bible; however, if you call the same passage more than once, the wids will repeat. In other words, two instances of Matthew 1:2 will have <w> tags with identical wid values. |
| include-virtual-attributes | false | All begin- and end- tags must match--for example, a <begin-paragraph/> tag always has a corresponding <end-paragraph/> tag. If a tag had to be added programmatically (for example, if the requested passage ends in the middle of a paragraph), a virtual="virtual" attribute is added to the tag (for example, <end-paragraph virtual="virtual"/>). If you want to know whether a given tag was added programmatically and doesn't really exist in the text, set this option to true. |
| base-element | verse-unit | Set to paragraph to transform the output from verse-unit-based markup (<verse-unit> <begin-block-indent/> <begin-paragraph/> <begin-line/>...<end-line/> <end-paragraph/> <end-block-indent/> </verse-unit>) to paragraph-based markup (<begin-verse-unit/> <block-indent> <paragraph><line>...</line></paragraph> </block-indent> <end-verse-unit/>). In doing so, you lose a little bit of information--you can no longer tell whether the end of a passage indicates the true end of a paragraph or block indent in the text, or whether it was put there to allow the proper closing of tags. That is to say, there is no longer <end-(paragraph|block-indent) class="virtual"/>. |
Sample Output (formatting added for clarity)
<?xml version="1.0" ?>
<!DOCTYPE crossway-bible SYSTEM
"http://www.gnpcb.org/esv/share/schemas/crossway.base.entities.dtd">
<crossway-bible class="passage-query">
<passage>
<reference>Matthew 22:43 - 23:1</reference>
<surrounding-chapters>
<previous>Matthew 21</previous>
<current>Matthew 22 - 23</current>
<next>Matthew 24</next>
</surrounding-chapters>
<content>
<verse-unit unit-id="40022043">
<begin-paragraph class="virtual"/>
<verse-num>43</verse-num>He said to them,
<woc>&ldblquot;How is it then that David, in the Spirit, calls
him Lord, saying,
</woc>
<end-paragraph/>
</verse-unit>
<verse-unit unit-id="40022044">
<begin-block-indent/>
<begin-paragraph class="line-group"/>
<begin-line/>
<verse-num class="woc">44</verse-num>
<woc>&ldblquot;&lquot;The Lord said to my Lord,
<end-line class="br"/>
<begin-line/>Sit at my right hand,<end-line class="br"/>
<begin-line class="indent"/>until I put your enemies
under your feet&rquot;?
</woc>
<end-line/>
<end-paragraph/>
<end-block-indent/>
</verse-unit>
<verse-unit unit-id="40022045">
<begin-paragraph class="same-paragraph"/>
<verse-num class="woc">45</verse-num>
<woc>If then David calls him Lord, how is he his
son?&rdblquot;
</woc>
</verse-unit>
<verse-unit unit-id="40022046">
<verse-num>46</verse-num>And no one was able to answer him
a word, nor from that day did anyone dare to ask him any
more questions.
<end-paragraph/>
<end-chapter/>
</verse-unit>
<verse-unit unit-id="40023001">
<begin-chapter num="23"/>
<heading>Seven Woes to the Scribes and Pharisees</heading>
<begin-paragraph/>
<verse-num begin-chapter="23">1</verse-num>Then Jesus
said to the crowds and to his disciples,
<end-paragraph class="virtual"/>
</verse-unit>
</content>
</passage>
<copyright>The Holy Bible, English Standard Version copyright (c)2001
by Crossway Bibles, a publishing ministry of Good News Publishers. Used by permission.
All rights reserved. http://www.crosswaybibles.org
</copyright>
</crossway-bible>
Plain Text Output
This format is suitable for use in plain-text environments such as email.
Set the option output-format to plain-text to display this format.
The following options all take a Boolean value of true or false (or 1 or 0) except for line-length, which takes an integer.
| Option | Default | Description |
|---|---|---|
| include-passage-references | true | Include a line saying which passage is being displayed. In the example below, Matthew 22:43 - 23:1. |
| include-first-verse-numbers | true | Show the verse number at the beginnings of chapters. In the example below, [23:1]. |
| include-verse-numbers | true | Show verse numbers in brackets. |
| include-footnotes | true | Show references to footnotes in the text in parentheses, and include the text of the footnotes at the bottom of the text. |
| include-short-copyright | true | Each passage from the ESV needs to include the letters "ESV" at the end of the passage. To turn off this behavior, set this option to false. |
| include-copyright | false | Show a copyright notice at the bottom of the text. Any page that shows the ESV text from this service needs to include a copyright notice, but you do not need to include it with each passage. Best practice is probably to include the copyright manually on your page, rather than download it every time. This option is mutually exclusive with include-short-copyright, which overrides include-copyright. |
| include-passage-horizontal-lines | true | Include a line of equals signs (===) above the beginning of each passage. |
| include-heading-horizontal-lines | true | Include a line of underscores (___) above each section heading. |
| include-headings | true | Include section headings. In the below example, Seven Woes to the Scribes and Pharisees. |
| include-subheadings | true | Include subheadings. Subheadings are the titles of psalms (e.g., Psalm 73's A Maskil of Asaph), the acrostic divisions in Psalm 119, the speakers in Song of Solomon, and the textual notes that appear in John 7 and Mark 16. |
| include-selahs | true | Include Selahs, which are found mostly in the Psalms (e.g., Psalm 46:3). |
| include-content-type | true | Adds a Content-Type: text/plain HTTP header. Set to false if you want the default content type. (For example, in an RSS feed you want the content type to remain text/xml). |
| line-length | 74 | How long to make each line. Can be any integer 36 and over. Set to 0 for unlimited length--each paragraph or line of poetry will be on a separate line. |
Sample Output
=====================================
Matthew 22:43 - 23:1
[43]He said to them, "How is it then that
David, in the Spirit, calls him Lord, saying,
[44]"'The Lord said to my Lord,
Sit at my right hand,
until I put your enemies under your feet'?
[45]If then David calls him Lord, how is he his
son?" [46]And no one was able to answer him a
word, nor from that day did anyone dare to ask
him any more questions.
_____________________________________
Seven Woes to the Scribes and Pharisees
[23:1]Then Jesus said to the crowds and to his
disciples,
The Holy Bible, English Standard Version
copyright (c)2001 by Crossway Bibles, a division
of Good News Publishers. Used by permission. All
rights reserved. http://www.crosswaybibles.org
Function doQuery
This function takes any of the above arguments except output-format, which is always HTML. (For passage pages, you can use the HTML formatting functions above.) It can also take a number of optional arguments:
| Option | Default | Description |
|---|---|---|
| q | The string to search for. | |
| passage | Put a string in here to force a passage search. This behavior is otherwise identical to doPassageQuery. | |
| words | Put a string in here to force a word search. | |
| phrase | Search for an exact phrase. In general, you can also surround words in q with quotation marks to mimic this functionality. | |
| not-words | Exclude verses containing certain words. Can only be used in conjunction with the words and phrase options. | |
| scope | [Complete Bible] | Limit your search to certain sections of the Bible. Accepts the predefined inputs listed in the dropdown menu on the Advanced Search page. |
| matches | [Empty] matches anywhere in words (the finds father). beginning matches beginnings of words (the finds there). exact matches exact words only (the only finds the). The latter two options are slower. | |
| search-text | all | all searches the complete text of the Bible, including headings and footnotes. Set to text to exclude headings and footnotes. |
| page | 1 | If the results span more than one page (e.g., 27 results were found, but only 25 are shown per page), set the page number (starting at 1) to show a different page of results. |
| link-url | /esv/search/ | Specifies what link to use when linking from the search results page to another page. If the page that handles your requests is named bible.search.php, for example, set this option to bible.search.php. |
| results-per-page | 25 | How many search results to show per page. Must be between 2 and 100 (inclusive). |
On your server, you will probably have to catch at least the page variable that's submitted. In PHP, you might do the following:
<?php
$options = '';
foreach ($_GET as $key => $value)
{
$options .= "&$key=" . urlencode($value);
}
#continue as below, but use $options .= ... instead of $options =
?>
Function doReadingPlanQuery
This function takes any of the above arguments, depending on your desired output format. It can also take two optional arguments:
| Option | Default | Description |
|---|---|---|
| date | Today's date | Get the reading plan for a certain date. Should be in YYYY-MM-DD format (e.g., 2009-11-07 for today). The date changes at midnight US Eastern Time (GMT -0500). |
| reading-plan | one-year-tract | Specifies which reading plan to use. Possibilities are one-year-tract, through-the-bible, every-day-in-the-word, and bcp. For more information about these reading plans, please see our Devotions area. |
| start-date | Specify a start date for the reading plan if you want to begin your readings at the beginning of the plan on dates besides January 1. Should be in YYYY-MM-DD format. |
You can, of course, create your own Bible reading plan and query our server for the appropriate passages each day.
Function getQueryInfo
This function takes two arguments, a key and a query, and returns information about the query. One of the most difficult parts of implementing a Bible search engine comes from having to parse the user's query and decide whether the query is a passage reference or a word search. You can use our search engine to decide for you.
See a demonstration of a possible use with the Bible Gateway.
| Option | Default | Description |
|---|---|---|
| q | The words or passage you want to parse. |
It returns an XML document with a structure similar to the following. The query was for ha. (Indentation added for clarity.)
<crossway-bible class="query-type">
<query>ha</query>
<query-type>passage</query-type>
<readable>Habakkuk 1</readable>
<unit>35001001-35001017</unit>
<is-complete-chapter>1</is-complete-chapter>
<alternate-query-type>word-search</alternate-query-type>
<alternate-result-count>18803</alternate-result-count>
<warnings>
<warning>
<code>ambiguous-book</code>
<readable>It
looks like the book abbreviation used in this search can stand for for more than
one book. We're showing you <strong>Habakkuk
1</strong>. You may also want to see:<br
/>• <a href="http://www.gnpcb.org/esv/search/?q=Haggai+1">Haggai
1</a></readable>
</warning>
</warnings>
</crossway-bible>
| Element | Description |
|---|---|
| crossway-bible | Always has a class query-type for this function. |
| error | (Not shown.) Some sort of fatal error, usually indicating an invalid key or no query. The content of this tag is a human-readable error message. |
| query | The text of your original query. |
| query-type | Either passage or word-search. Tells you how we understood your query. |
| readable | Appears if the query-type is passage. Gives a normalized passage reference (full book names and chapter references) that any Bible search engine should be able to understand. |
| unit | Appears if the query-type is passage. Numerically identifies the verses returned. Each unit component is 8 characters long: the first two characters identify the book (01-66), the next three characters identify the chapter (001-150), and the final three characters identify the verse (001-176). Hyphens (-) indicate a range of verses; commas (,) indicate separate passages. |
| result-count | Appears if the query-type is word-count. Tells how many times the word appears in the ESV text (up to 1,000). |
| is-complete-chapter | Appears if the query-type is passage. Has a value of 1 if the passage references refer only to complete chapters. Has a value of 0 if any of the passage references refer to a partial chapter. |
| alternate-query-type, alternate-result-count | If a passage reference could also be a word (as above, or, e.g., when someone searches for mark), these two tags appear set to word-search and the number of times the word appears in the ESV, respectively. |
| warnings | Container tag. Doesn't appear in most queries. Can contain multiple <warning> tags. You can safely ignore these. |
| warning | Contains a <code> and a <readable> tag. |
| warning > code | The error code that pertains to the error. A complete list is forthcoming. |
| warning > readable | An HTML human-readable description of the error. Any links in the code point to our site, but you can manipulate them to point wherever you wish. |
Function getReadingPlanInfo
This function provides information about the readings for a given day. It doesn't return any Bible text. It has two optional arguments:
| Option | Default | Description |
|---|---|---|
| date | Today's date | Get the reading plan for a certain date. Should be in YYYY-MM-DD format (e.g., 2009-11-07 for today). The date changes at midnight US Eastern Time (GMT -0500). |
| reading-plan | one-year-tract | Specifies which reading plan to use. Possibilities are one-year-tract, through-the-bible, every-day-in-the-word, and bcp. For more information about these reading plans, please see our Devotions area. |
| start-date | Specify a start date for the reading plan if you want to begin your readings at the beginning of the plan on dates besides January 1. Should be in YYYY-MM-DD format. |
It returns an XML document with a structure similar to the following. (Indentation added for clarity.)
Response:
<crossway-bible class="reading-plan-info">
<date>20061225</date>
<plan>bcp</plan>
<id>1.28</id>
<url>http://www.gnpcb.org/esv/devotions/bcp/?date=2006-12-25</url>
<info>
<psalm-1>Ps. 2,85</psalm-1>
<psalm-2>Ps. 110:1-5,6-7,Ps. 132</psalm-2>
<ot>Zech. 2:10-13</ot>
<nt>1 John 4:7-16</nt>
<gospel>John 3:31-36</gospel>
<liturgical>
<season>Christmas</season>
<week>Christmas</week>
<day>Christmas Day</day>
</liturgical>
<raw>Ps. 2, 85; Ps. 110:1-5(6-7), Ps. 132; Zech. 2:10-13; 1 John 4:7-16; John 3:31-36</raw>
</info>
</crossway-bible>
| Element | Description |
|---|---|
| crossway-bible | Always has a class reading-plan-info for this function. |
| error | (Not shown.) Some sort of fatal error, usually indicating an invalid key or no query. The content of this tag is a human-readable error message. An <error> will be the only element returned. |
| date | The date (in YYYYMMDD format) used in the query. |
| start-date | If the start-date parameter was sent, shows the date used as January 1. |
| plan | The reading plan id. |
| url | The URL to access the day's reading on the ESV site. |
| id | A unique identifier for the day within each reading plan. An <id> always occurs only once in a given calendar year. |
| info | Contains an XML structure that varies depending on the reading plan. This structure contains exactly what we store in our database. For the bcp plan, the <liturgical> element will always contain exactly one <season>, 0 or 1 <week>s, and 0 or 1 <day>s. |
Function getVerse
This function resembles doPassageQuery, except the additional formatting options described in getDailyVerse are available. It is designed for short passages (1-5 verses), but the requested passages can be up to 500 verses in length. If you don't include a passage, it picks a verse at random from a preselected list of verses. (See the RSS Feed page for a list.) This function takes any of the arguments related to its output format, depending on your desired output format. It can also take two optional arguments:
| Option | Default | Description |
|---|---|---|
| passage | A random passage | Get a specific passage or group of passages (e.g., Matthew 5:1,3,5). |
| seed | A random number | You can send your own seed to the random number generator if you want to get a specific result consistently. (For example, getDailyVerse simply calls this function using the current date as the seed.) |
For example, the following url:
Retrieves the following (the ” (a closing double quotation mark) at the end is added by the script; it doesn't exist in the text):
<h2>John 5:25</h2>
<div class="esv-text"><p><span class="woc">“Truly,
truly, I say to you, an hour is coming, and is now here, when the dead will
hear the voice of the Son of God, and those who hear will live.”</span> (<a
href="http://www.esv.org" class="copyright">ESV</a>)</p>
</div>
Function getDailyVerse
This argument retrieves a verse at random from the verses we've collected. The verse rolls over at midnight U.S. Eastern Time (GMT -5 or -4). This function takes any of the arguments related to its output format, depending on your desired output format. You probably want to set include-footnotes to false. For a list of verses, please see the RSS Feed page. Additionally, you can set the following parameters:
| Option | Default | Description |
|---|---|---|
| include-headings | false | Whether to include the section headings (e.g., Jesus Feeds the Five Thousand in John 6). |
| begin-character | An empty string | If the first letter of the verse is lower-case, indicating that the verse begins in the middle of a sentence, you can prepend a string to the verse. For example, you might set this option to &ellipsis; or ... to begin such verses with an ellipsis. |
| correct-capitalization | true | If the first letter of the verse is lower-case, setting this option to true will upper-case it. |
| correct-end-punctuation | true | If the verse ends with anything besides a period, question mark, or exclamation mark (for example, a comma, semicolon, or dash), it replaces the ending punctuation with whatever you set in end-character. |
| end-character | &ellipsis4; | If the verse ends with anything besides a period, question mark, or exclamation mark (for example, a comma, semicolon, or dash), the ending punctuation will be replaced with this string. |
| correct-quotes | true | Balances quotes. If a quotation beginning in a previous verse ends in the current verse, an opening quotation mark is added to the beginning of the verse. Similarly, an ending quotation mark is added to the end of the verse if the quotation begins in the verse but extends beyond the end of the verse. So, all quotations have both beginning and ending marks. |
Sample Code
The following code is offered "as-is." It may or may not work on your system.
Perl
GET
use LWP::Simple;
my $key = "IP";
my $passage = "Matthew 5";
my $options = "action=doPassageQuery&include-verse-numbers=false";
my $output = get("http://www.gnpcb.org/esv/share/get/?key=$key&passage=$passage&$options");
print $output;
SOAP
use SOAP::Lite;
my $key = "IP";
my $passage = "Matthew 5";
my $options = {
"include-quote-entities" => 1,
"output-format" => "plain-text",
};
print SOAP::Lite
-> uri('http://www.crosswaybibles.org/soap')
-> proxy('http://www.gnpcb.org/esv/share/soap/')
-> doPassageQuery($key, $passage, $options)
-> result;
SOAP (using WSDL file)
use SOAP::Lite;
my $key = "IP";
my $options = {
"q" => "Elijah",
};
print SOAP::Lite
-> service('http://www.gnpcb.org/esv/share/soap/?wsdl')
-> doQuery($key, $options)
-> result;
PHP
GET
If you have Curl installed with PHP, you can use the following:
<?php
$key = "IP";
$passage = urlencode("john 3:16");
$options = "action=doPassageQuery&include-passage-references=false";
$url = "http://www.gnpcb.org/esv/share/get/?key=$key&passage=$passage&$options";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
print $response;
?>
If your server allows remote fopen (allow_url_fopen), you can use the following (thanks to David Sanders for this code):
<?php
$key = "IP";
$passage = urlencode("john 3:16");
$options = "action=doPassageQuery&include-passage-references=false&audio-format=flash";
$url = "http://www.gnpcb.org/esv/share/get/?key=$key&passage=$passage&$options";
$data = fopen($url, "r") ;
if ($data)
{
while (!feof($data))
{
$buffer = fgets($data, 4096);
echo $buffer;
}
fclose($data);
}
else
{
die("fopen failed for url to webservice");
}
?>
SOAP (using NuSOAP)
Thanks to Ben Edgington for this code.
<?php
require_once('nusoap.php');
$server = 'http://www.gnpcb.org/esv/share/soap/';
$soapclient = new soapclient($server);
$options = array(
'output-format'=>'html',
'include-footnotes' => false,
);
$parameters = array(
'key' => 'IP',
'passage' => 'Rom 8',
'options' => $options);
$result = $soapclient->call('doPassageQuery', $parameters);
print $result;
?>
SOAP (using NuSOAP and WSDL file)
<?php
//require_once('nusoap.php'); // Second declaration.
$soapclient = new soapclient('http://www.gnpcb.org/esv/share/soap/?wsdl', true);
$parameters = array(
'key' => 'IP',
'options' => array(
'output-format' => 'plain-text',
'include-short-copyright' => false,
'include-passage-horizontal-lines' => false,
'include-section-horizontal-lines' => false,
'include-verse-numbers' => false,
),
);
print $soapclient->call('getDailyVerse', $parameters);
?>
VB.NET
GET
Thanks to Charles Cherry for this and the C# code.
Dim strURL as New StringBuilder()
With strURL
.Append("http://www.gnpcb.org/esv/share/get/")
.Append("?key=IP")
.Append("&passage=" & Server.URLEncode("Matthew 5"))
.Append("&action=doPassageQuery")
.Append("&include-headings=true")
End With
Dim objWebClient as New WebClient()
Dim objUTF8 as New UTF8Encoding()
Response.Write(objUTF8.GetString(objWebClient.DownloadData(strURL.ToString())))
C#
GET
StringBuilder sUrl = new StringBuilder();
sUrl.Append("http://www.gnpcb.org/esv/share/get/");
sUrl.Append("?key=IP");
sUrl.Append("&passage=" + Server.UrlEncode("Matthew 5").ToString());
sUrl.Append("&action=doPassageQuery");
sUrl.Append("&include-headings=true");
WebRequest oReq = WebRequest.Create(sUrl.ToString());
StreamReader sStream = new StreamReader(oReq.GetResponse().GetResponseStream());
StringBuilder sOut = new StringBuilder();
sOut.Append(sStream.ReadToEnd());
sStream.Close();
Response.Write(sOut.ToString());
WCF (.NET 3.0)
David Betz has written a WCF proxy for the web service.
ASP
GET
Thanks to Simon Job for this code.
<%
'Reference Search
key = "IP"
strSearch = "John 1"
passage = Server.URLEncode(strSearch)
options = "action=doPassageQuery&include-passage-references=true"
set objHTTP = Server.CreateObject("Microsoft.XMLHTTP")
objHTTP.open "GET", "http://www.gnpcb.org/esv/share/get/?key=" & _
key & "&passage=" & passage & "&" & options, false
objHTTP.send
Response.Write(objHTTP.responseText)
%>
Additionally, Jeff Owens has made available extensive ASP sample code for both normal searches and reading plans. More...
ColdFusion
GET
Thanks to David Scarbrough for this code.
<cfset key = "IP"> <cfset passage = "2 Tim 3:16"> <cfset options = "action=doPassageQuery&include-verse-numbers=false"> <cfhttp url = "http://www.gnpcb.org/esv/share/get/?key=#key#&passage=#passage#&#options#" method = "get"> </cfhttp> <cfoutput>#cfhttp.fileContent#</cfoutput>
Java
Thanks to Brian Wohlin for this code.
JDK Version 5.0
package org.esv.bible.service;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
public class ESVService {
public String getPassage(String book, String chapter) throws Exception {
StringBuilder urlStringBuilder = new StringBuilder();
urlStringBuilder.append("http://www.gnpcb.org/esv/share/get/");
urlStringBuilder.append("?key=IP");
urlStringBuilder.append("&passage="
+ URLEncoder.encode(book + " " + chapter, "ISO-8859-1"));
urlStringBuilder.append("&action=doPassageQuery");
urlStringBuilder.append("&include-headings=true");
URL esvURL = new URL(urlStringBuilder.toString());
InputStream esvStream = esvURL.openStream();
StringBuilder outStringBuilder = new StringBuilder();
int nextChar;
while ((nextChar = esvStream.read()) != -1) {
outStringBuilder.append((char) nextChar);
}
esvStream.close();
return outStringBuilder.toString();
}
}
As a Servlet (Using JDK 1.3.1)
package org.esv.bible.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ESVServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String book = req.getParameter("book");
String chapter = req.getParameter("chapter");
StringBuffer urlStringBuffer = new StringBuffer();
urlStringBuffer.append("http://www.gnpcb.org/esv/share/get/");
urlStringBuffer.append("?key=IP");
urlStringBuffer.append(
"&passage=" + URLEncoder.encode(book + " " + chapter));
urlStringBuffer.append("&action=doPassageQuery");
urlStringBuffer.append("&include-headings=true");
URL esvURL = new URL(urlStringBuffer.toString());
InputStream esvStream = esvURL.openStream();
StringBuffer outStringBuffer = new StringBuffer();
int nextChar;
while ((nextChar = esvStream.read()) != -1) {
outStringBuffer.append((char) nextChar);
}
esvStream.close();
PrintWriter out = resp.getWriter();
out.print(outStringBuffer.toString());
}
}
Ruby
Thanks to Richard Kilmer for this code.
#!/usr/local/bin/ruby
puts "Welcome to ESV bible passage lookup."
puts "Enter the passage (i.e. Rom 3:15-20) or 'exit' to end."
require 'net/http'
class ESV
def initialize(key)
@options = ["include-short-copyright=0",
"output-format=plain-text",
"include-passage-horizontal-lines=0",
"include-heading-horizontal-lines=0"].join("&")
@base_url = "http://www.gnpcb.org/esv/share/get/?key=#{key}"
end
def doPassageQuery(passage)
passage = passage.gsub(/\s/, "+")
passage = passage.gsub(/\:/, "%3A")
passage = passage.gsub(/\,/, "%2C")
get_url @base_url +
"&passage=#{passage}&action=doPassageQuery{@options}"
end
private
def get_url(url)
Net::HTTP.get(::URI.parse(url))
end
end
bible = ESV.new(ARGV[0] || 'IP')
while(true)
print 'Passage> '
passage = gets.strip
unless passage==""
exit if passage=="exit" || passage=="quit"
puts bible.doPassageQuery(passage)
end
end
Python
Thanks to Christian Wyglendowski for this code.
#!/usr/bin/env python
import urllib
import sys
print "Welcome to the ESV Bible passage lookup tool."
print "Enter a passage to view (ex. John 3:16) or 'quit'."
class ESVSession:
def __init__(self, key):
options = ['include-short-copyright=0',
'output-format=plain-text',
'include-passage-horizontal-lines=0',
'include-heading-horizontal-lines=0']
self.options = '&'.join(options)
self.baseUrl = 'http://www.gnpcb.org/esv/share/get/?key=%s' % (key)
def doPassageQuery(self, passage):
passage = passage.split()
passage = '+'.join(passage)
url = self.baseUrl + '&passage=%s&action=doPassageQuery&%s' % (passage, self.options)
page = urllib.urlopen(url)
return page.read()
try:
key = sys.argv[1]
except IndexError:
key = 'IP'
bible = ESVSession(key)
passage = raw_input('Enter Passage: ')
while passage != 'quit':
print bible.doPassageQuery(passage)
passage = raw_input('Enter Passage: ')
Also see an OpenOffice plugin written in Python.
XSLT
Ben Edgington has created an XSLT file to convert Crossway's XML to XHTML. You may also want to see his tutorial below.
Blog Plugins
- Joe Paravisini - TextPattern. Shows the Bible text.
- Musterion.net - Wordpress. Displays the text of Scripture in your blog.
- LaurenceO.com - Wordpress. A "remixed" version of Musterion.net's plugin that features more administration options and an automatic linking feature.
- GetXML plugin - Movable Type. Uses the ESV web service as an example.
Other Languages
If you would like to contribute simple code for your favorite programming language, we would be happy to post it here.
Tutorials
- ESV Bible Search Script, by Sean Buscay, provides a ready-made PHP script that you can adapt as needed.
- ESV Bible Text via AJAX, by Simon Job, integrates the web service with AJAX to update a page dynamically with Bible text.
- Making Use of the ESV Web Service, by Ben Edginton, discusses using SOAP, PHP, and XSLT together to produce XHTML output.
- Bible Web Services 101, by Sean Boisen, is an introduction to the ESV web service.
- Retreiving ESV Passages From References, by Sean Boisen, talks about reformatting the XHTML provided by the web service to make it easier to include in blog entries.
Demonstrations
- West Side Christian Church - Hover over the links to Scripture passages to see the ESV text.
- ScriptureMenu.com - Uses the web service to display passages relating to a topic.
