[Cotlet](https://cotlet.dev/index.md) · [Integrations](https://cotlet.dev/integrations.md) · [How it works](https://cotlet.dev/how-it-works.md) · [Use cases](https://cotlet.dev/use-cases.md) · [Security](https://cotlet.dev/security.md) · [For developers](https://cotlet.dev/for-developers.md) · [For automation agencies](https://cotlet.dev/for-agencies.md) · [Blog](https://cotlet.dev/blog.md) · [API docs](https://cotlet.dev/docs.md) · [Help center](https://cotlet.dev/help.md) · [Changelog](https://cotlet.dev/changelog.md) · [Contact](https://cotlet.dev/contact.md) · [Pricing](https://cotlet.dev/pricing.md) · [Sign up](https://cotlet.dev/signup)

# Add papers to Zotero by DOI

> Paste a list of DOIs and let your agent add the papers to Zotero, file them in a collection and report which ones were not found. Hosted.

Source: https://cotlet.dev/integrations/zotero-api-mcp-server/add-papers-by-doi

You finish a reading session with twenty DOIs in a notes file, and every one still has to be pasted into Zotero and dragged into the right collection.

Cotlet does it in your own Zotero account with search\_items, add\_item\_by\_identifier and add\_items\_to\_collection, called by your AI agent, an n8n workflow or a script.

[Sign up free](https://cotlet.dev/app/signup?app=zotero) [All Zotero tools](https://cotlet.dev/integrations/zotero-api-mcp-server.md)

Hosted · nothing to install or maintain

## Can Zotero do this on its own?

Zotero offers Add Item by Identifier in the desktop app and nothing hosted for it (checked 16 Oct 2026). The Web API creates an item from JSON you fill in, with itemType required, and its docs describe no lookup by DOI or ISBN. A script that calls the API alone has to fetch the metadata somewhere else first.

## How you do it in Zotero today

1. Select the collection you want first in the left pane: Zotero saves new items into the collection selected at that moment.
2. Click the Add Item by Identifier button in the toolbar, paste the identifier and press Enter. Several identifiers can go in at once, separated by spaces, commas or line breaks.
3. Zotero fetches the metadata, for DOIs from CrossRef and other registries, and adds one item per identifier.
4. An identifier the registries do not know adds nothing, so you compare the new items against your list to find the gaps.
5. Papers that belong in a second collection are dragged over by hand, one selection at a time.

## How to add papers to Zotero by DOI

Prompt

```
Add these DOIs to my Zotero library and put them in the collection "Thesis: related work". Tell me which ones Zotero could not find.
```

1. 01  
### Clean the list  
Your agent trims each DOI to its bare form, drops repeats inside the list and keeps the original order, so the report matches what you pasted.
2. 02  
### Look for what you already have  
For each DOI it runs search\_items on the likely title once the paper is resolved, and flags a probable duplicate in the report. It does not skip silently, because quick search covers titles and creators, not DOIs.
3. 03  
### Add the papers  
add\_item\_by\_identifier takes the whole batch in one call and files the new items straight into the collection you named. Identifiers that Zotero cannot resolve come back in not\_found.
4. 04  
### Second collections  
If a paper belongs in more than one collection, add\_items\_to\_collection adds the same item keys to the others. The item stays in the first one.
5. 05  
### Report the gaps  
The agent lists created items with titles, the DOIs that were not found and the probable duplicates, so you fix the three odd ones by hand instead of checking all twenty.

### What you get back

Example data

```
3 DOIs received, 2 added to "Thesis: related work"
Added: Sparse attention for long documents (2025), A survey of retrieval for question answering (2024)
Not found: 10.9999/broken.2026.7
Possible duplicate: Sparse attention for long documents already in "Reading queue"
```

### Other ways to ask

- Every Monday, read the DOIs from my notes file and add the new ones to "Reading queue".
- Add these ISBNs to my library and put them in the collection "Course books".
- Add these arXiv IDs, tag each one "to read" and tell me which have no DOI.

## What Zotero allows, and what to know first

- Zotero accepts ISBN, DOI, PubMed ID, arXiv ID and ADS Bibcode as identifiers, so the same call works for books and preprints.
- DOI metadata comes from CrossRef and other registries; the item is only as complete as the registry record.
- New items go into the collection that is selected when you add them, so the collection key matters for where a paper lands.
- Zotero accepts up to 50 items, collections or saved searches in one write request, so long lists are sent in batches.
- Added papers sync to zotero.org with the rest of your data, which is free and unlimited; PDF files count against the 300 MB free storage.

add\_item\_by\_identifier and add\_items\_to\_collection change only your own Zotero data and reach no one else, so they run without asking first.

Sources: [Zotero: adding items to Zotero](https://www.zotero.org/support/adding%5Fitems%5Fto%5Fzotero) · [Zotero: collections and tags](https://www.zotero.org/support/collections%5Fand%5Ftags) · [Zotero Web API v3: write requests](https://www.zotero.org/support/dev/web%5Fapi/v3/write%5Frequests) · [Zotero: syncing](https://www.zotero.org/support/sync)

## Call add\_item\_by\_identifier from a script

curl

```
curl -X POST https://cotlet.dev/api/v1/zotero/item-by-identifiers \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"identifiers":["10.1234/example.2026.001","10.1234/example.2026.002","10.9999/broken.2026.7"],"collection_key":"C4T8WZ2N"}'
```

Example response

```
{
"requested": 3,
"created": [
{
"item_key": "H6R2VB5D",
"title": "Sparse attention for long documents",
"identifier": "10.1234/example.2026.001"
},
{
"item_key": "N9Q4XA7E",
"title": "A survey of retrieval for question answering",
"identifier": "10.1234/example.2026.002"
}
],
"not_found": [
"10.9999/broken.2026.7"
],
"collection_key": "C4T8WZ2N"
}
```

MCP: add https://cotlet.dev/mcp/v1 with the same key; the call is zotero\_write → add\_item\_by\_identifier. Example data.

[Schedule it in n8n, Make, Zapier or cron](https://cotlet.dev/integrations/zotero-api-mcp-server.md#automations)

## Zotero tools this automation uses

__Cotlet Zotero tools used to add papers to Zotero by DOI__
| Tool | Parameters |
| -------------------------- | -------------------------------------------------------------------------------------------------- |
| search\_items | library, query, full\_text, tag, item\_type, collection\_key, unfiled, added\_since, limit, cursor |
| add\_item\_by\_identifier | identifiers, collection\_key |
| add\_items\_to\_collection | collection\_key, item\_keys |

[All 11 Zotero tools with descriptions](https://cotlet.dev/integrations/zotero-api-mcp-server.md#tools)

## Frequently asked questions

### Does it download the PDF too?

The tool adds the item with its metadata. Attaching files uses Zotero Storage, which has 300 MB free, and is a separate step in Zotero.

### Is it safe to connect Zotero to Cotlet?

Yes. You sign in to Zotero yourself, in your own Cloud Browser in the EU, and we never save your password. Your agents only get Zotero once you enable it, every background request is listed, and the browser profile is stored encrypted with AES-256-GCM, the cipher 1Password uses for its vaults. The AI model never sees a login, posts and messages wait for your OK, and Disable for agents cuts access in one click. Independent scanners grade cotlet.dev A+ on Qualys SSL Labs, securityheaders.com and Mozilla Observatory; live results are on https://cotlet.dev/security.

## More Zotero automations

- [Export a Zotero collection as BibTeX](https://cotlet.dev/integrations/zotero-api-mcp-server/export-collection-bibtex.md)
- [Turn Zotero PDF highlights into a literature note](https://cotlet.dev/integrations/zotero-api-mcp-server/pdf-annotations-to-note.md)
- [Zotero API and MCP server: every tool](https://cotlet.dev/integrations/zotero-api-mcp-server.md)
- [All use cases](https://cotlet.dev/use-cases.md)

## Give your agent access to Zotero.

Free 7-day trial with 2,000 credits, no card needed. Cotlet is independent and not affiliated with Zotero.

[Sign up free](https://cotlet.dev/app/signup?app=zotero)

---

Give your AI agents your signed-in browser.

**Product:** [Integrations](https://cotlet.dev/integrations.md) · [Use cases](https://cotlet.dev/use-cases.md) · [How it works](https://cotlet.dev/how-it-works.md) · [Pricing](https://cotlet.dev/pricing.md) · [Security](https://cotlet.dev/security.md)

**Resources:** [Blog](https://cotlet.dev/blog.md) · [API docs](https://cotlet.dev/docs.md) · [Help center](https://cotlet.dev/help.md) · [Changelog](https://cotlet.dev/changelog.md) · [GitHub](https://github.com/cotletdev/cotlet)

**Solutions:** [For developers](https://cotlet.dev/for-developers.md) · [For automation agencies](https://cotlet.dev/for-agencies.md)

**Company:** [About](https://cotlet.dev/about.md) · [AI info: company facts](https://cotlet.dev/ai-info.md) · [Contact](https://cotlet.dev/contact.md)

**Legal:** [Terms of service](https://cotlet.dev/terms) · [Privacy policy](https://cotlet.dev/privacy) · [Refund policy](https://cotlet.dev/refunds) · [Acceptable use](https://cotlet.dev/acceptable-use) · [Cookie policy](https://cotlet.dev/cookies) · [DPA](https://cotlet.dev/dpa) · [Subprocessors](https://cotlet.dev/subprocessors)

**Elsewhere:** [Status page](https://status.cotlet.dev) · [Cotlet on GitHub](https://github.com/cotletdev) · [Cotlet on X](https://x.com/cotletdev) · [Cotlet on LinkedIn](https://www.linkedin.com/company/cotletdev) · [Cotlet on Product Hunt](https://www.producthunt.com/products/cotlet) · [Cotlet on Crunchbase](https://www.crunchbase.com/organization/cotlet) · [Cotlet on SaaSHub](https://www.saashub.com/cotlet)

Cotlet is an independent service. It is not affiliated with, endorsed by or sponsored by any of the products listed on this site. Product names are trademarks of their respective owners.

## For AI agents: sign your user up

Is your user asking you to sign them up for Cotlet? You can do it for them, no account or key needed.

1. Read the fields and their allowed values: GET https://cotlet.dev/api/v1/access-requests
2. Ask the user for each value: email, apps, what you will do with them. If they leave the password to you, generate a strong one and show it to them.
3. Show the user what you will send, then POST it as JSON to https://cotlet.dev/api/v1/access-requests.

One call creates the account and sends the access request; we email the user when access is granted.
