---
title: "Search for academic papers"
method: POST
path: "/search/papers"
tags: ["Search"]
---

# Search for academic papers

`POST /search/papers`

Search Elicit's database of over 138 million academic papers using natural language queries.

Semantic search uses natural language understanding to find relevant papers even when the exact terms don't match.

Set `corpus` to `pubmed` to restrict results to PubMed, or leave it as the default `elicit` for the full paper index. Set `searchMode` to `"keyword"` to interpret the query as a Lucene-style boolean expression instead of natural language.

Filters and `searchMode: "keyword"` are mutually exclusive — put any filter expressions directly into the query string when using keyword search. Mixing them returns a 400.

To search clinical trials instead, use [`POST /api/v2/search/trials`](#tag/Search/paths/~1search~1trials/post).

### Limits

Each plan caps how many results a single search request may return:

| Plan | Results per request |
|------|--------------------|
| Basic | No access |
| Plus | No access |
| Pro | 300 |
| Scale | 500 |
| Enterprise | 10,000 |

Search is rate-limited only by the global limit of 100 requests per minute per IP address, applied across all endpoints and all plans. Exceeding it returns a `429` and blocks the IP for 5 minutes.

Upgrade your plan in [account settings](https://elicit.com/settings) for higher per-request result caps.

### Example

```bash
curl -X POST https://elicit.com/api/v2/search/papers \
  -H "Authorization: Bearer elk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query": "effects of sleep deprivation on cognitive performance"}'
```

## Request body

- PaperSearchRequest
  - `query` string, required — The search query string
  - `searchMode` 'semantic' | 'keyword' — How to interpret `query`. `semantic` (default) runs Elicit's semantic search. `keyword` sends the query as a Lucene-style boolean expression directly to the corpus search API. Mutually exclusive with `filters` / `trialFilters` — put filter expressions into the query string in keyword mode.
  - `maxResults` integer — Maximum number of results to return (1-10000)
  - `corpus` 'elicit' | 'pubmed' — Paper corpus to search. `elicit` (default) searches Elicit's full paper index; `pubmed` restricts to PubMed.
  - `filters` PaperFilters
    - `minYear` integer — Minimum publication year
    - `maxYear` integer — Maximum publication year
    - `minEpochS` integer — Minimum publication date as Unix epoch seconds
    - `maxEpochS` integer — Maximum publication date as Unix epoch seconds
    - `maxQuartile` integer — Maximum journal quartile (1 = top 25%)
    - `includeKeywords` string[] — Keywords that must appear in the paper
    - `excludeKeywords` string[] — Keywords to exclude from results
    - `typeTags` string[] — Filter by study type
    - `hasPdf` boolean — Only include papers with available PDFs
    - `pubmedOnly` boolean — Only include papers from PubMed
    - `retracted` 'exclude_retracted' | 'include_retracted' | 'only_retracted' — How to handle retracted papers. Defaults to exclude_retracted.

## Response `200`

Search results returned successfully.

- PaperSearchResponse
  - `papers` Paper[], required — Papers matching the query
    - `elicitId` string, nullable, required — Elicit internal paper identifier
    - `title` string, required — Paper title
    - `authors` string[], required — List of author names
    - `year` integer, nullable, required — Publication year
    - `abstract` string, nullable, required — Paper abstract
    - `doi` string, nullable, required — Digital Object Identifier
    - `pmid` string, nullable, required — PubMed identifier
    - `venue` string, nullable, required — Publication venue
    - `citedByCount` integer, nullable, required — Number of citations this paper has received
    - `urls` string[], required — URLs for the paper
    - `studyTypeTags` string[], required — Study design tags (e.g. RCT, Meta-Analysis, Systematic Review, Review, Longitudinal). Populated for the `elicit` corpus; empty for the `pubmed` corpus.
    - `journalQuartile` integer, nullable, required — SJR journal quartile (1 = top 25%). Null when the journal is unranked/unknown or for the `pubmed` corpus.
    - `fullTextUrl` string, nullable, required — Best available full-text / PDF link, or null when none is known.
  - `warnings` SearchWarning[] — Non-fatal warnings emitted while executing the search (e.g. phrases ignored by the PubMed parser).
    - `corpus` 'elicit' | 'pubmed' | 'clinical_trials', required — Corpus that emitted the warning
    - `searchMode` 'semantic' | 'keyword', required — Search mode in effect when the warning was emitted
    - `message` string, required — Human-readable warning message
    - `warningDetails` SearchWarningDetails, required
      - `type` string, required — Warning category
      - `messages` string[], required — Underlying warning messages

## Other responses

- `400` — Invalid request. The request body failed validation — check that `query` is present and `maxResults` is between 1 and 10000.
- `401` — Authentication failed. The API key is missing, invalid, revoked, or expired.
- `402` — Insufficient quota.
- `403` — API access is not available on your current plan. Upgrade to Pro or above to use the API.
- `429` — Rate limit exceeded. More than 100 requests per minute were received from your IP address; further requests are blocked for 5 minutes.
- `500` — An unexpected error occurred. Retry after a short delay.

---

[API](https://skmtc.dev/elicit/apis/elicit-api.md) · [All operations](https://skmtc.dev/elicit/apis/elicit-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/elicit/elicit-api/revisions/2b42624536e5/schema)
