HTTP Citing Protocol#

The Google Docs plugin uses a simple HTTP protocol to communicate with Zotero. The below documentation applies to Zotero 6.0 and newer.

Basics#

Zotero operates a server on port 23119 for Zotero Connector integration. It includes endpoints for integrating with Zotero citing functionality. The integrating plugin or application only needs to be able to send HTTP JSON requests to fully implement the citing protocol.

A single citing integration command is implemented as a series of requests and responses to the HTTP endpoints, constituting a transaction. The integration client begins a transaction by sending a request to http://127.0.0.1:23119/connector/document/execCommand which responds a command to be executed by the client, then subsequent requests with executed command results are made to http://127.0.0.1:23119/connector/document/respond until a transaction is complete.

An example#

In order to add a citation to a document, the implementing client sends the following to http://127.0.0.1:23119/connector/document/execCommand:

{
  "command":"addEditCitation",
  "docId":"1ro9AmDxrwbys-xjazJqQG7UlSbBC76CU5xRJ71I8UjE"
}

Zotero then responds by asking for the active document:

{
  "command":"Application.getActiveDocument",
  "arguments":[]
}

The client then sends a response to http://127.0.0.1:23119/connector/document/respond consisting of the the document ID and config options for the implementing client:

{
  "documentID":"1ro9AmDxrwbys-xjazJqQG7UlSbBC76CU5xRJ71I8UjE",
  "outputFormat":"html",
  "supportedNotes":["footnotes"]
}

You can observe the communication between Zotero and Google Docs in the Zotero Connector background page, which is accessed at about:extensions on Chrome by enabling Developer mode and clicking “background page” for Zotero Connector, or at about:debugging on Firefox by clicking “Debug” for Zotero connector. The requests are listed under the Network tab in the developer tools window.

Integration Commands#

These commands are sent from the word processor to Zotero, and do not receive a response. The command payload always follows this format.

{
  "command":"<Command>",
  "docId":"<Document ID>" // an unique document identifying string
}
Command Description
“addEditCitation” Add a new or edit an existing citation
“addEditBibliography” Add a new or edit an existing bibliography
“addNote” Insert a Zotero note into the document
“refresh” Refresh all fields in the document, verifying that they match expectations
“removeCodes” Remove field codes from the document
“setDocPrefs” Change the citation style or other document parameters
“exportDocument” Export the citations in the document to a format importable in other word processors

An up-to-date command list is always available by looking at the methods of Zotero.Integration.Interface.

If Zotero responds with a 503 HTTP response, it means that another integration transaction is already in progress. If your integration client initiates an integration transaction and fails to complete it by either returning an error or responding to requests until #Document.complete is issued the Zotero integration layer will continuously respond with 503 until it is restarted.

Word Processor Commands#

These commands are sent from Zotero to the word processor. They must always receive a response. The command payload is always a JSON-encoded string in the form

{
  "command":"<Command Name>",
  "arguments":[]
}

If the request is successful, the client must send a response with a JSON-encoded payload. This response is often null if the command returns no output, but may also be an array, an integer, a string, or a boolean value depending on the command.

If the request is unsuccessful, the client must send a response with the payload:

{
  "error": "<Error Name>",
  "message": "<Error Message>",
  "stack": "<Optional error stack Object or String>"
}

Zotero will cancel the current operation, log this error, and present it to the user using the Document.displayAlert command if possible. If the subsequent Document.displayAlert command fails, Zotero will present the error using its own dialog box.

A full and up-to-date API of commands is available as part of Zotero Integration tests and |LibreOffice plugin code.

Application.getActiveDocument#

Gets information about the client and the currently active document.

Parameters#

N/A

Returns#

documentIDIntegerStringAn ID corresponding to the document that is currently active
outputFormatStringEither "html" or "rdt". Defaults to "html"
supportedNotesArraySupported options are an empty array if no Note support, "footnotes" and/or "endnotes". Note styles will not be available if this option is an empty array. Default to ["footnotes"]

Document.displayAlert#

Shows an alert.

Parameters#

dialogTextStringThe text to display inside the dialog.
iconIntegerOne of: DIALOG_ICON_STOP = 0 DIALOG_ICON_NOTICE = 1 DIALOG_ICON_CAUTION = 2
buttonsIntegerOne of: DIALOG_BUTTONS_OK = 0 DIALOG_BUTTONS_OK_CANCEL = 1 DIALOG_BUTTONS_YES_NO = 2 DIALOG_BUTTONS_YES_NO_CANCEL = 3

Returns#

(Integer) The index of the button pressed, according to the value of buttons sent as a parameter.

DIALOG_BUTTONS_OKOK = 1
DIALOG_BUTTONS_OK_CANCELCANCEL = 0 OK = 1
DIALOG_BUTTONS_YES_NONO = 0 YES = 1
DIALOG_BUTTONS_YES_NO_CANCELCANCEL = 0 NO = 1 YES = 2

Document.activate#

Brings the document to the foreground.

Parameters#

N/A

Returns#

null

Document.canInsertField#

Indicates whether a field can be inserted at the current cursor position.

Parameters#

N/A

Returns#

(Boolean) Whether a field can be inserted.

Document.setDocumentData#

Stores a document-specific persistent data string. This data contains the style ID and other user preferences.

Parameters#

dataStringStringThe data string

Returns#

null

Document.getDocumentData#

Retrieves data string set by setDocumentData.

Parameters#

N/A

Returns#

(String) The document data string.

Document.cursorInField#

Indicates whether the cursor is in a given field. If it is, returns information about that field.

Parameters#

fieldTypeStringThe type of field used by the document, always "Http" for HTTP integration and can be ignored

Returns#

Either null, indicating that the cursor isn’t in a field, or (Array)

0fieldIDIntegerStringA unique identifier corresponding to this field
1fieldCodeIntegerStringThe code stored within this field
2noteIndexIntegerThe number of the footnote in which this field resides, or 0 if the field is not in a footnote.

Document.insertField#

Inserts a new field at the current cursor position.

Parameters#

fieldTypeStringThe type of field used by the document, either ReferenceMark or Bookmark
noteTypeIntegerThe type of note specified by the style: NOTE_IN_TEXT = 0 NOTE_FOOTNOTE = 1 NOTE_ENDNOTE = 2If noteType is not NOTE_IN_TEXT, the implementation should create a new note before inserting the field

Returns#

(Array)

0fieldIDIntegerStringA unique identifier corresponding to this field
1fieldCodeIntegerStringThe code stored within this field. Since no data has been set, this should be empty.
2noteIndexIntegerThe number of the footnote in which this field resides, or 0 if the field is not in a footnote.

Document.insertText#

Inserts rich text (HTML) at cursor position. The rich text may contain citation placeholder hyperlinks (to https://www.zotero.org/?[placeholderID]) which are later converted to citations via Document.convertPlaceholdersToFields.

Parameters#

textStringThe text

Returns#

null

Document.getFields#

Get all fields present in the document, in document order.

Parameters#

fieldTypeStringThe type of field used by the document, always "Http" for HTTP integration and can be ignored

Returns#

(Array)

0fieldIDArray(IntegerString)Unique identifiers for each field
1fieldCodeArray(IntegerString)The code stored in each field
2noteIndexArray(Integer)The number of the footnote in which each field resides, or 0 if the field is not in a footnote

Document.convert#

Converts all fields in a document to a different fieldType or noteType. Called upon style change from a an in-text to note type or vice-versa

Parameters#

fieldsArray(String)Array of field IDs to be converted
toFieldTypeArray(String)Should be ignored
toNoteTypeArray(Number)Array of note types to be converted to. Each array entry corresponds to a field in the fields parameter and is one of NOTE_IN_TEXT = 0 NOTE_FOOTNOTE = 1 NOTE_ENDNOTE = 2
countNumberSize of the above arrays

Returns#

null

Document.convertPlaceholdersToFields#

Converts placeholders (which are text with links to https://www.zotero.org/?[placeholderID]) to fields and sets their field codes to strings in `codes` in the reverse order of their appearance

Parameters#

0placeholderIDsArray(String)An array of placeholderID strings which are to be converted to citation fields in the document.
1noteTypeNumberNote type to convert citation placeholders to. Is one of NOTE_IN_TEXT = 0 NOTE_FOOTNOTE = 1 NOTE_ENDNOTE = 2
2fieldTypeNumberTo be ignored

Returns#

Array of fields after conversion

(Array)

0fieldIDArray(IntegerString)Unique identifiers for each field
1fieldCodeArray(IntegerString)The code stored in each field
2noteIndexArray(Integer)The number of the footnote in which each field resides, or 0 if the field is not in a footnote

Document.setBibliographyStyle#

Sets parameters to be used to style the bibliography. Numbers are in twips

Parameters#

firstLineIndentNumberFirst line indent of each bibliography paragraph
indentNumberThe indent of each bibliography paragraph
lineSpacingNumberParagraph line spacing
entrySpacingNumberLine spacing between paragraphs
tabStopsArray(Number)An array of tab stops
tabStopsCountNumberSize of the tabStops array

Returns#

null

Document.complete#

Indicates that the given documentID will no longer be used and associated resources may be freed. NOTE: No further requests to http://127.0.0.1:23119/connector/document/respond should be made after this point

Parameters#

N/A

Returns#

null

Field.delete#

Deletes a field from the document (both its code and its contents).

Parameters#

fieldIDIntegerStringThe fieldID, as originally returned by Document.cursorInField, Document.insertField, or Document.getFields

Returns#

null

Field.select#

Moves the current cursor position to encompass a field.

Parameters#

fieldIDIntegerStringThe fieldID, as originally returned by Document.cursorInField, Document.insertField, or Document.getFields

Returns#

null

Field.removeCode#

Removes the field code from a field, leaving it as plain text.

Parameters#

fieldIDIntegerStringThe fieldID, as originally returned by Document.cursorInField, Document.insertField, or Document.getFields

Returns#

null

Field.setText#

Sets the (visible) text of a field.

Parameters#

fieldIDIntegerStringThe fieldID, as originally returned by Document.cursorInField, Document.insertField, or Document.getFields
textStringThe text
isRichBooleanWhether the text should be interpreted as RTF if Document.outputFormat is RTF, otherwise always true

Returns#

null

Field.getText#

Gets the (visible) text of a field.

Parameters#

fieldIDIntegerStringThe fieldID, as originally returned by Document.cursorInField, Document.insertField, or Document.getFields

Returns#

(String) The (visible) text

Field.setCode#

Sets the (hidden, persistent) code of a field.

Parameters#

fieldIDIntegerStringThe fieldID, as originally returned by Document.cursorInField, Document.insertField, or Document.getFields
codeStringThe field code

Returns#

null

Other resources#

See: