Search Zotero. From the comfort of your keyboard.

NOTE: I am currently looking for some help in expanding ZotQuery's features by building an accompanying Zotero Plugin in JavaScript. As I do not know JS and do not have the time currently to learn it thoroughly enough to achieve my goals, I am hoping that a satisfied user or curious coder would be interested in joining me in development. I have a number of ideas, but not the technical expertise to execute them. Please contact me, either here or on GitHub if you are interested.

I know that I have been M.I.A. lately, but the end of the semester is always an insane time, and even more so in graduate school. But I haven’t been slacking. I’ve actually spent a lot of my free time for the past few weeks working on a new little “application" that utilizes the power of version 2 of Alfred. Although Alfred is free, there is a paid upgrade for the “PowerPack", which opens up the Workflows feature. In short, Workflows allow users to use Alfred as a platform to build interactive “apps" on top of Alfred’s framework. With a vibrant community of developers, this feature has really taken off. I use various Alfred workflows all of the time. There has also grown up a fair number of modules for various languages that make interfacing with Alfred all the more easy. I myself leaned heavily upon alp, a Python module for Alfred.

Anyways, without further adieu, I offer to you ZotQuery-my very first Alfred workflow which provides deep access to your Zotero library. This page will be my README for the application, explaining all of its functionality and options.

If you want to download the workflow (requires Alfred’s powerpack upgrade), you should get it from my Packal page, since this will more easily allow you to upgrade the workflow over time. If you are interested in my code, you can find it all on my GitHub repo.

New Version - 6.2

In this newest version, I’ve added new, shorter keywords for all of the types of queries that ZotQuery allows:

z = zot
zt = zot:t
za = zot:a
znc = zot:c
znt = zot:tag
zn = zot:n
zat = z:att
ztg = z:tag
zc = z:col

Note: All previous, long keywords still work. Workflow is backwards compatible.

Also, version 6.2 adds the debugging keyword z:bug.


  • v. 6.2: Added new, shorter query keywords
  • v. 6.1: Temporarily removed PDF attachments
  • v. 6.0: Moved to new Python-Alfred backbone
  • v. 5.0: Add PDF attachments to items in Zotero library
  • v. 4.2-8: Various bug fixes. Bundled feed parser and pytz modules with pyzotero package.
  • v. 4.1: Search attachments only.
  • v. 4.0: Export Rich Text. Choose CSL Style.
  • v. 3.2: Fixed caching bug.
  • v. 3.1: Bug fixes.
  • v. 3.0: New configuration ability, few new icons, stability
  • v. 2.6: New icons for items with attachments and bug fixes.
  • v. 2.5: Various bug fixes and maintenance.
  • v. 2.4: Fixed bug that kept initial z:cache from creating cache file.
  • v. 2.3: Fixed alp bug.
  • v. 2.2: New Fallback Search. Bug fixes and more error logging.
  • v. 2.0: Add ability to open attachments.
  • v. 1.2: Various bug fixes. New Notifications.
  • v. 1.1: Added feature to export bibliography of Collections or Tags.
  • v. 1.0: Added features to export formatted citations and references of items.
  • v. 0.9: Added new script filters.
  • v. 0.8: First public release of ZotQuery.


To date, it has only been tested on a Mac with both Zotero Firefox and Standalone installed. ZotQuery should work with only Zotero Firefox or Standalone installed, but that is currently untested. If you are using the workflow successfully with either one only installed, please let me know. It has also only been tested on Alfred 2.1+. Finally, it was tested on the standard Python distribution for Mac OS X Mavericks (10.9), which is 2.7.6, and not on Python 3. Once again, if anyone is using the workflow successfully on another distribution of Python, please let me know.


When you first download the workflow, you will need to run z:config first to configure the necessary settings before you attempt any queries. In fact, ZotQuery will kick you to the z:config command if you try any of the queries without having first configured your settings.

On first run, the configurator will begin by searching for, and creating if necessary, ZotQuery’s workflow data folder, which can always be found at /Users/$USER/Library/Application Support/Alfred 2/Workflow Data/com.hackademic.zotquery/.

Now, in version 5.5 and on, ZotQuery no longer needs to install any Python dependencies. The workflow ships with all necessary components baked in. This has already removed a vast majority of the support issues.

The configurator next moves on to find all the necessary Zotero paths. ZotQuery requires the full path to 3 things:

  • your Zotero sqlite database
  • your Zotero storage folder
  • the folder that holds your linked attachments

The configurator attempts to find all necessary paths automatically, but if it fails, it will ask you to select one manually. The title of the dialog box will alert you to what path the configurator requires:

Once all paths are stored, the configurator moves on to set up your Zotero API information. This workflow utilizes the Zotero API to export citations of chosen items. In order for the user to utilize these functions, they must have and set up a Zotero private key. Step one requires your Zotero User ID:

If you do not have or do not know your Zotero User ID, click the Where do I find my User ID? button. This will open Zotero’s "Feeds/API" tab, where you may need to login. Once logged in, you will see a page similar to this:

This shows a user who has two API keys set up, one for personal use and one for the iOS app PaperShip. If you do not have a Personal API key, you can easily set one up by clicking the "Create new private key" link. Your User ID will be a number, probably less than 8 digits. Insert it into the text field and click Set User ID (Note: Applescript text input dialog boxes do not respond, typically, to the keyboard shortcut for paste, so you will likely need to right-click and manually paste in the ID).

Second, you will need to input your API Key:

Since ZotQuery reads this settings.json file whenever it attempts to connect to the Zotero API, if you don’t insert the proper data here, the "Export Citation" and "Export Reference" (see below) functions will not work.

Finally, ZotQuery (now in version 4.0) will also allow you to set your export style and format. Once you have entered your API information, the configurator will move to setting your export preferences:

First, you will select the CSL Style that you wish to use. Currently ZotQuery can export data in 5 different styles: Chicago (author-date), APA, MLA, Zotero’s own RTF-Scan format, and BibTeX. Now, in version 6.2, ZotQuery will also allow users to export in the ODT-RTF Scannable Cites format (option not shown in image below). This will determine the format of exported citations and references.

Next, you will select the text formatting for exported data. ZotQuery (in version 4.0) can export in either Markdown or Rich Text.

All exported text is put in your clipboard, so you can use it anywhere in any text editor. You can also alter your export preferences at any point, using the z:settings command.

Once all settings and preferences are set, the configurator will finally build the JSON cache of your Zotero data. ZotQuery will clone your Zotero database and also generate a JSON file with all pertinent information. Once cached, ZotQuery is configured. If you open the workflow data folder, you will see these files:

These are the essential files for ZotQuery to function, so do not accidentally delete them. With the configuration finished and these files created, you can now use ZotQuery.


ZotQuery (now) has 5 main functions:

  1. Search
  2. Cite
  3. Open
  4. Cache
  5. and Add

In general, the order of operations would be: cache, search, open/cite. This means, in order to search, you need to have an up-to-date cache, and in order to cite or open an item, you will first need to search and select it.

Under Search there are 6 options:

  1. General search
  2. Title-specific search
  3. Author-specific search
  4. Tag-specific search
  5. Collection-specific search
  6. Attachment-specific search

Note that all searches coerce both the query and the data into lowercase, so you can search using lowercase queries and still get matches.

The General search is launched by the keyword zot.

This will search your entire Zotero database for any use of the query provided. The search script is “loose," that is, it searches for matches of the query “in" the data not matches that “equal" the data. This means you can search half words, words in the middle of titles, etc.

ZotQuery will not begin searching until you have entered at least 3 characters. This ensures faster, smarter results. Until you have typed at least 3 characters, you will see this result:

Once you complete your query, and the script catches up with you, you will see a list of all of your Zotero items that match the query. If your query doesn’t have any matches, ZotQuery returns an error:

If, however, you have results, ZotQuery presents them in a ranked order:

For ease of use, the workflow provides unique icons for the various item types:

  • article

  • book

  • chapter

  • conference paper

  • other

If your item has an attachment, the icon changes to signal the addition as will the subtitle field. The subtitle field will include Attachments: n, where n is the number of attachments:

The altered icons each have a small plus sign in the top-right corner:

  • article + attachment

  • book + attachment

  • chapter + attachment

  • conference paper + attachment

  • other + attachment

The Author search is launched by zot:a.

This search only queries the last names of the authors of your Zotero data. For example: zot:a thomas will return all the items that have an author (or editor, translator, etc.) with the last name “Thomas".

The Title search is launched by zot:t.

This search only queries the title fields of your Zotero data. For example: zot:t virgil will return all of the items whose title contains the word “Virgil".

The final two searches (Tag and Collection) are two-step searches. In step-one, you search for a particular Tag or Collection; in step-two you search within that particular Tag or Collection for your query.

The Tag search is launched by z:tag.

This allows you to search through all of your Zotero tags.

Once you select a tag, Alfred will automatically initiate the zot:tag search, which will search within that tag for your query. The zot:tag query functions just like the general zot query, except that it is limited to those items with the previously chosen tag.

The Collection search is similar. It is launched by z:col, which begins a search for all of your Zotero collections.

As you type, it will filter any collections that contain the query.

Once you choose a particular collection, Alfred will initiate the zot:c search, which will search within that particular collection.

As above, the zot:c search functions just like the simple zot search.

Finally, you can now (in version 4.1) search only items with attachments using the z:att query. This query allows you to quickly find pdfs or epubs in your Zotero library and open them in your default application. As of now, z:att only allows for you to open the attached files.

Together these 6 search options provide you with various ways to find the exact item you need. Once you find that item, you have a few options with what you can do next.

Once you select an item (in all the searches except z:att), there are 5 options:

  1. Open Zotero to that item.
  2. Export an author-date reference to that item.
  3. Export a citation of that item.
  4. Open the item’s attachment (if it has any).
  5. Append a citation of the item to a temporary bibliography

If you merely hit return on your chosen item, option 1 will occur and Zotero will open to that item.

If you hit option+return when you choose your item, you will export a short reference to that item.

Depending on your style and format settings, your reference will be of various types.

If you hit control+return, you will export a full citation of the item in your chosen format.

Next, if you hit shift+return, you will open the attachment of that item.

Finally, if you hit fn+return, you will append a citation of the item to a temporary bibliography file.

This bibliography file is stored in the workflow’s cache folder. You can add as many citations to it as you wish. This function allows you to dynamically build a Bibliography/Works Cited page. When you have put all the needed citations in the temporary file, you need only run the z:bib command to export them.

This will take all of the citations in the temporary bibliography file, organize them in alphabetical order, and copy the result to the clipboard. A result in Markdown format will resemble this:

The temporary bibliography file is not the only way, however, to automatically generate a full Bibliography/Works Cited page. Since many Zotero users, myself included, use either Tags or Collections to organize their library into writing projects, ZotQuery also allows the user to export a full formatted bibliography (in alphabetical order) for any Tag or Collection.

When you are searching for a Tag or a Collection with z:tag or z:col, you can use control+return to export a bibliography of that Tag or Collection, instead of simply searching within that Tag or Collection by hitting return.

Thus, if you organize the citations for particular project within a certain Collection or under a certain Tag, you can create full, formatted Works Cited pages on the fly from ZotQuery!

Taken together, these export options make ZotQuery an academic’s best friend in the writing process. You can insert in-text references, full citations, or generate entire Works Cited all from ZotQuery. These citations, references, and bibliographies can also now be Rich Text in addition to Markdown. This allows users who write in Microsoft Word, Pages, or Scrivener to utilize ZotQuery. You can also open Zotero directly to an item (for quick meta-data editing) or even open an item’s attachment to double check a quote.

There are, however, a few caveats and possible configurations. First, these final options (export reference, export citations, append citation, and generate works cited) all use Zotero’s web API, and so they require an internet connection. If you are not connected to the internet, all will fail (gracefully). Second, the workflow defaults to Chicago (author-date) style both for short references and full citations (examples above). If you wish to use another of Zotero’s CSL styles, you will need to change the style via the z:settings command. Since ZotQuery now exports BibTeX and RTF-Scan cite keys, even users who prefer to write in MultiMarkdown and convert to LaTeX can utilize ZotQuery.

Note: These features will also require that you have the proper Zotero API data in the settings.json file. For instructions on setting this up, see above.

There is also the Caching function. All of the query scripts are querying a JSON cache of your Zotero database. This file is created and then updated with the keyword z:cache.

This function will find your Zotero sqlite database, read its contents, and create a JSON cache of the pertinent information.

When you first download the workflow, the configurator will run this command in order to create the cache that all of the query scripts will read. You will always be able to update the cache with this command as well, although the workflow is configured to auto-update the cache after every query execution; that is, after you do any action on an item (open, reference, citation, append). This means that after you perform an action on an item, the workflow will check if the cache needs updating and if so, the workflow will update it in the background.

Note, however, that if you have altered your Zotero data and are about to use ZotQuery, you will need to force an update using z:cache before any of the queries have access to the new information. As a general rule of thumb, I will force update the cache each time I sit down to a lot of work with ZotQuery, but will let it auto-update most of the time.

NOTE: This feature has temporarily been removed. It will be added back soon, but the move away from alp has made it a bit buggy.

Last, but not least, is the newest feature for ZotQuery: adding attachments. I found myself often receiving PDFs for class and wanting to store them as attachments to items in my Zotero library, but the process was tedious in Zotero. You would need to open the app, scroll to find the item you wanted to add an attachment to, click the “Attach" button, and then find your file in the drop-down menu. To much clicking, too much time. No more!

You can now add attachments to items in your Zotero library directly through ZotQuery. I have provided 2 means to attaching your PDF. First, you can use a new File Action to add a PDF you find directly within Alfred. File Action’s can be found in Alfred’s internal file manager. If you search for files (tap the space bar as soon as you launch Alfred), you can use the right-arrow key to enter Alfred’s file manager:

If you have selected a PDF, you will find ZotQuery’s file action: “Attach to Zotero Item" near the bottom of the possible actions (tip: use the up-arrow key to jump to the bottom immediately). Once selected, simply press Return to jump to the next step.

If you’re not interested in searching for your PDF, but you already have it open in your PDF reader of choice, you can set up a Hotkey instead. You can find the hotkey near the bottom of ZotQuery’s workflow pane within Alfred. As you can see, I use cmd+shift+A as my hotkey, but you can set it up however you like.

This hotkey will function in one of two ways. If you only have 1 open PDF, ZotQuery will immediately jump to the next step (more on that in just a bit). If, however, you have more than 1 open PDF (even if in different PDF apps), ZotQuery will prompt you to choose which PDF you wish to attach. Once you’ve chosen, the script will move on.

However you chose the PDF you want to attach, File Action or Hotkey, you will need to select which item you wish to attach it to. Once you’ve chosen your PDF, ZotQuery will automatically launch the z:add search. This query functions exactly like the general zot search in terms of its parameters, but only has one possible action: Attach. Once you’ve found the item that you want to attach the PDF to, you merely press Return to initiate the final step.

In order to attach your PDF, ZotQuery uses Zotero’s online API. This means that you will need to be connected to the Internet when you attempt to attach a PDF to an item. If the script can successfully attach the PDF to the item, you will see this notification:

The sub-title is important. Since ZotQuery adds the attachment to your online Zotero library, you will need to open your local Zotero app and refresh in order to see the attachment locally. Then you should manually update your ZotQuery cache (use the z:cache keyword) so that ZotQuery will “see" the new Zotero attachment. Once your Zotero app and ZotQuery are up-to-date with the new attachment, you’re in the clear.

While this may seem like a number of steps, it is almost entirely keyboard-centric and, in my experience, is still about twice as fast as interacting directly with the Zotero app. Hopefully it will help you as well.


Aside from the core features, ZotQuery comes with some additional features. First, ZotQuery comes with the ability to set up a keyboard shortcut to launch the title-specific search. I use command+shift+Z as my hotkey. If you setup the hotkey, you can launch immediately into the title search (with a snazzy interface):

You can also change this hotkey to launch whichever query you like.

ZotQuery also has the ability to be an option in your Alfred fallback searches. In order to setup ZotQuery as a fallback search option, open Alfred’s preferences and go to the Features tab. Near the bottom of the page you will see a button to Setup fallback results:

When you click that button a panel will slide out of top:

Click the + button and select ZotQuery from the Workflow Trigger list. You can even re-order the fallback searches, and put ZotQuery near the top. When setup, this will allow you to search in Alfred like this:

And have it immediately become a ZotQuery search:

So that’s how you use ZotQuery. It’s a powerful tool. I hope you like it.

The Hackademic,
Stephen Margheim