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

# Search clinical trials

`POST /search/trials`

## Request

- Base URL: `https://elicit.com/api/v2`
- URL: `https://elicit.com/api/v2/search/trials`
- Auth: HTTP bearer

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 use ClinicalTrials.gov advanced-search syntax, such as `AREA[Condition]"obesity"`, rather than a natural-language query.

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

`maxResults` defaults to 10. Search returns up to that many results in one response; it does not provide a pagination cursor. Each plan caps how many results a single request may return. A value above your plan's cap returns `400 invalid_request` rather than being silently reduced:

| 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` uses the corpus's native syntax: Lucene-style expressions for the Elicit index, PubMed query syntax for PubMed, or ClinicalTrials.gov advanced-search syntax for trials. Mutually exclusive with `filters` / `trialFilters` — put filter expressions into the query string in keyword mode.
  - `maxResults` integer: Maximum number of results to return (default 10; schema range 1–10000). Your plan may impose a lower per-request cap; exceeding it returns 400 invalid_request. Search returns up to this many results without pagination.
  - `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. For credits-based accounts, and for organization members with a weekly workflow-run limit, `error.details.reason` says why (`credits_exhausted` or `spend_limit_reached`) and `error.details.resetsAt` when the block lifts.
- `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.

## Changes

- **2026-10-16** `22847bf7e65d`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/changes/search/trials/post.md)

---

[API](https://skmtc.dev/elicitlabs/apis/elicit-labs-api.md) - [All operations](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/llms.txt) - [OpenAPI document](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/revisions/cbbe29509d04?raw)
