---
title: "Search clinical trials"
method: POST
path: "/search/trials"
tags: ["Search"]
---

# Search clinical trials

`POST /search/trials`

Search for clinical trials. Trial records come from ClinicalTrials.gov.

Pass `trialFilters` to narrow by phase, recruitment status, or whether the trial has posted results. Set `searchMode` to `"keyword"` to send the query as a Lucene-style boolean expression directly to the underlying advanced-filter API.

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

To search academic papers instead, use [`POST /api/v2/search/papers`](#tag/Search/paths/~1search~1papers/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/trials \
  -H "Authorization: Bearer elk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query": "semaglutide obesity", "trialFilters": {"phase": ["PHASE3"]}}'
```

## Request body

- TrialSearchRequest
  - `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)
  - `trialFilters` TrialFilters
    - `phase` string[] — Clinical trial phases to include
    - `recruitmentStatus` string[] — Trial recruitment statuses to include
    - `hasResults` boolean — Only include trials that have posted results

## Response `200`

Trial search results returned successfully.

- TrialSearchResponse
  - `trials` Trial[], required — Clinical trials matching the query
    - `nctId` string, required — NCT identifier for the trial
    - `title` string, required — Trial title
    - `summary` string, nullable, required — Plain-text trial description / brief summary
    - `url` string, required — Link to the trial's public record
    - `overallStatus` string, nullable, required — Overall recruitment status (RECRUITING, COMPLETED, TERMINATED, etc.). Null when the trial has no status posted.
    - `phase` string[], required — Trial phases (may list multiple, e.g. PHASE2 + PHASE3). Empty for N/A.
    - `studyType` string, nullable, required — Study type (INTERVENTIONAL, OBSERVATIONAL, EXPANDED_ACCESS).
    - `enrollmentCount` integer, nullable, required — Actual or anticipated enrollment count.
    - `conditions` string[], required — Conditions / diseases being studied.
    - `interventions` string[], required — Intervention names.
    - `leadSponsor` string, nullable, required — Lead sponsor name.
    - `startDate` string, nullable, required — Trial start date (ISO `YYYY-MM-DD` or partial).
    - `primaryCompletionDate` string, nullable, required — Primary completion date (ISO `YYYY-MM-DD` or partial).
    - `completionDate` string, nullable, required — Completion date (ISO `YYYY-MM-DD` or partial).
    - `hasResults` boolean, nullable, required — Whether the trial has posted results.
    - `lastUpdatedYear` integer, nullable, required — Year the trial record was last updated.
  - `warnings` SearchWarning[] — Non-fatal warnings emitted while executing the search.
    - `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.
- `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)
