ClinicalTrials.gov Database
Overview
ClinicalTrials.gov is a comprehensive registry of clinical studies conducted worldwide, maintained by the U.S. National Library of Medicine. Access API v2 to search for trials, retrieve detailed study information, filter by various criteria, and export data for analysis. The API is public (no authentication required) with rate limits of ~50 requests per minute, supporting JSON and CSV formats.
When to Use This Skill
This skill should be used when working with clinical trial data in scenarios such as:
- Patient matching - Finding recruiting trials for specific conditions or patient populations
- Research analysis - Analyzing clinical trial trends, outcomes, or study designs
- Drug/intervention research - Identifying trials testing specific drugs or interventions
- Geographic searches - Locating trials in specific locations or regions
- Sponsor/organization tracking - Finding trials conducted by specific institutions
- Data export - Extracting clinical trial data for further analysis or reporting
- Trial monitoring - Tracking status updates or results for specific trials
- Eligibility screening - Reviewing inclusion/exclusion criteria for trials
Quick Start
Basic Search Query
Search for clinical trials using the helper script:
bash
1cd scientific-databases/clinicaltrials-database/scripts
2python3 query_clinicaltrials.py
Or use Python directly with the requests library:
python
1import requests
2
3url = "https://clinicaltrials.gov/api/v2/studies"
4params = {
5 "query.cond": "breast cancer",
6 "filter.overallStatus": "RECRUITING",
7 "pageSize": 10
8}
9
10response = requests.get(url, params=params)
11data = response.json()
12
13print(f"Found {data['totalCount']} trials")
Retrieve Specific Trial
Get detailed information about a trial using its NCT ID:
python
1import requests
2
3nct_id = "NCT04852770"
4url = f"https://clinicaltrials.gov/api/v2/studies/{nct_id}"
5
6response = requests.get(url)
7study = response.json()
8
9# Access specific modules
10title = study['protocolSection']['identificationModule']['briefTitle']
11status = study['protocolSection']['statusModule']['overallStatus']
Core Capabilities
1. Search by Condition/Disease
Find trials studying specific medical conditions or diseases using the query.cond parameter.
Example: Find recruiting diabetes trials
python
1from scripts.query_clinicaltrials import search_studies
2
3results = search_studies(
4 condition="type 2 diabetes",
5 status="RECRUITING",
6 page_size=20,
7 sort="LastUpdatePostDate:desc"
8)
9
10print(f"Found {results['totalCount']} recruiting diabetes trials")
11for study in results['studies']:
12 protocol = study['protocolSection']
13 nct_id = protocol['identificationModule']['nctId']
14 title = protocol['identificationModule']['briefTitle']
15 print(f"{nct_id}: {title}")
Common use cases:
- Finding trials for rare diseases
- Identifying trials for comorbid conditions
- Tracking trial availability for specific diagnoses
2. Search by Intervention/Drug
Search for trials testing specific interventions, drugs, devices, or procedures using the query.intr parameter.
Example: Find Phase 3 trials testing Pembrolizumab
python
1from scripts.query_clinicaltrials import search_studies
2
3results = search_studies(
4 intervention="Pembrolizumab",
5 status=["RECRUITING", "ACTIVE_NOT_RECRUITING"],
6 page_size=50
7)
8
9# Filter by phase in results
10phase3_trials = [
11 study for study in results['studies']
12 if 'PHASE3' in study['protocolSection'].get('designModule', {}).get('phases', [])
13]
Common use cases:
- Drug development tracking
- Competitive intelligence for pharmaceutical companies
- Treatment option research for clinicians
3. Geographic Search
Find trials in specific locations using the query.locn parameter.
Example: Find cancer trials in New York
python
1from scripts.query_clinicaltrials import search_studies
2
3results = search_studies(
4 condition="cancer",
5 location="New York",
6 status="RECRUITING",
7 page_size=100
8)
9
10# Extract location details
11for study in results['studies']:
12 locations_module = study['protocolSection'].get('contactsLocationsModule', {})
13 locations = locations_module.get('locations', [])
14 for loc in locations:
15 if 'New York' in loc.get('city', ''):
16 print(f"{loc['facility']}: {loc['city']}, {loc.get('state', '')}")
Common use cases:
- Patient referrals to local trials
- Geographic trial distribution analysis
- Site selection for new trials
Find trials conducted by specific organizations using the query.spons parameter.
Example: Find trials sponsored by NCI
python
1from scripts.query_clinicaltrials import search_studies
2
3results = search_studies(
4 sponsor="National Cancer Institute",
5 page_size=100
6)
7
8# Extract sponsor information
9for study in results['studies']:
10 sponsor_module = study['protocolSection']['sponsorCollaboratorsModule']
11 lead_sponsor = sponsor_module['leadSponsor']['name']
12 collaborators = sponsor_module.get('collaborators', [])
13 print(f"Lead: {lead_sponsor}")
14 if collaborators:
15 print(f" Collaborators: {', '.join([c['name'] for c in collaborators])}")
Common use cases:
- Tracking institutional research portfolios
- Analyzing funding organization priorities
- Identifying collaboration opportunities
5. Filter by Study Status
Filter trials by recruitment or completion status using the filter.overallStatus parameter.
Valid status values:
RECRUITING - Currently recruiting participants
NOT_YET_RECRUITING - Not yet open for recruitment
ENROLLING_BY_INVITATION - Only enrolling by invitation
ACTIVE_NOT_RECRUITING - Active but no longer recruiting
SUSPENDED - Temporarily halted
TERMINATED - Stopped prematurely
COMPLETED - Study has concluded
WITHDRAWN - Withdrawn prior to enrollment
Example: Find recently completed trials with results
python
1from scripts.query_clinicaltrials import search_studies
2
3results = search_studies(
4 condition="alzheimer disease",
5 status="COMPLETED",
6 sort="LastUpdatePostDate:desc",
7 page_size=50
8)
9
10# Filter for trials with results
11trials_with_results = [
12 study for study in results['studies']
13 if study.get('hasResults', False)
14]
15
16print(f"Found {len(trials_with_results)} completed trials with results")
Get comprehensive information about specific trials including eligibility criteria, outcomes, contacts, and locations.
Example: Extract eligibility criteria
python
1from scripts.query_clinicaltrials import get_study_details
2
3study = get_study_details("NCT04852770")
4eligibility = study['protocolSection']['eligibilityModule']
5
6print(f"Eligible Ages: {eligibility.get('minimumAge')} - {eligibility.get('maximumAge')}")
7print(f"Eligible Sex: {eligibility.get('sex')}")
8print(f"\nInclusion Criteria:")
9print(eligibility.get('eligibilityCriteria'))
Example: Extract contact information
python
1from scripts.query_clinicaltrials import get_study_details
2
3study = get_study_details("NCT04852770")
4contacts_module = study['protocolSection']['contactsLocationsModule']
5
6# Overall contacts
7if 'centralContacts' in contacts_module:
8 for contact in contacts_module['centralContacts']:
9 print(f"Contact: {contact.get('name')}")
10 print(f"Phone: {contact.get('phone')}")
11 print(f"Email: {contact.get('email')}")
12
13# Study locations
14if 'locations' in contacts_module:
15 for location in contacts_module['locations']:
16 print(f"\nFacility: {location.get('facility')}")
17 print(f"City: {location.get('city')}, {location.get('state')}")
18 if location.get('status'):
19 print(f"Status: {location['status']}")
7. Pagination and Bulk Data Retrieval
Handle large result sets efficiently using pagination.
Example: Retrieve all matching trials
python
1from scripts.query_clinicaltrials import search_with_all_results
2
3# Get all trials (automatically handles pagination)
4all_trials = search_with_all_results(
5 condition="rare disease",
6 status="RECRUITING"
7)
8
9print(f"Retrieved {len(all_trials)} total trials")
Example: Manual pagination with control
python
1from scripts.query_clinicaltrials import search_studies
2
3all_studies = []
4page_token = None
5max_pages = 10 # Limit to avoid excessive requests
6
7for page in range(max_pages):
8 results = search_studies(
9 condition="cancer",
10 page_size=1000, # Max page size
11 page_token=page_token
12 )
13
14 all_studies.extend(results['studies'])
15
16 # Check for next page
17 page_token = results.get('pageToken')
18 if not page_token:
19 break
20
21print(f"Retrieved {len(all_studies)} studies across {page + 1} pages")
8. Data Export to CSV
Export trial data to CSV format for analysis in spreadsheet software or data analysis tools.
Example: Export to CSV file
python
1from scripts.query_clinicaltrials import search_studies
2
3# Request CSV format
4results = search_studies(
5 condition="heart disease",
6 status="RECRUITING",
7 format="csv",
8 page_size=1000
9)
10
11# Save to file
12with open("heart_disease_trials.csv", "w") as f:
13 f.write(results)
14
15print("Data exported to heart_disease_trials.csv")
Note: CSV format returns a string instead of JSON dictionary.
Extract key information for quick overview or reporting.
Example: Create trial summary
python
1from scripts.query_clinicaltrials import get_study_details, extract_study_summary
2
3# Get details and extract summary
4study = get_study_details("NCT04852770")
5summary = extract_study_summary(study)
6
7print(f"NCT ID: {summary['nct_id']}")
8print(f"Title: {summary['title']}")
9print(f"Status: {summary['status']}")
10print(f"Phase: {', '.join(summary['phase'])}")
11print(f"Enrollment: {summary['enrollment']}")
12print(f"Last Update: {summary['last_update']}")
13print(f"\nBrief Summary:\n{summary['brief_summary']}")
10. Combined Query Strategies
Combine multiple filters for targeted searches.
Example: Multi-criteria search
python
1from scripts.query_clinicaltrials import search_studies
2
3# Find Phase 2/3 immunotherapy trials for lung cancer in California
4results = search_studies(
5 condition="lung cancer",
6 intervention="immunotherapy",
7 location="California",
8 status=["RECRUITING", "NOT_YET_RECRUITING"],
9 page_size=100
10)
11
12# Further filter by phase
13phase2_3_trials = [
14 study for study in results['studies']
15 if any(phase in ['PHASE2', 'PHASE3']
16 for phase in study['protocolSection'].get('designModule', {}).get('phases', []))
17]
18
19print(f"Found {len(phase2_3_trials)} Phase 2/3 immunotherapy trials")
Resources
scripts/query_clinicaltrials.py
Comprehensive Python script providing helper functions for common query patterns:
search_studies() - Search for trials with various filters
get_study_details() - Retrieve full information for a specific trial
search_with_all_results() - Automatically paginate through all results
extract_study_summary() - Extract key information for quick overview
Run the script directly for example usage:
bash
1python3 scripts/query_clinicaltrials.py
references/api_reference.md
Detailed API documentation including:
- Complete endpoint specifications
- All query parameters and valid values
- Response data structure and modules
- Common use cases with code examples
- Error handling and best practices
- Data standards (ISO 8601 dates, CommonMark markdown)
Load this reference when working with unfamiliar API features or troubleshooting issues.
Best Practices
Rate Limit Management
The API has a rate limit of approximately 50 requests per minute. For bulk data retrieval:
- Use maximum page size (1000) to minimize requests
- Implement exponential backoff on rate limit errors (429 status)
- Add delays between requests for large-scale data collection
python
1import time
2import requests
3
4def search_with_rate_limit(params):
5 try:
6 response = requests.get("https://clinicaltrials.gov/api/v2/studies", params=params)
7 response.raise_for_status()
8 return response.json()
9 except requests.exceptions.HTTPError as e:
10 if e.response.status_code == 429:
11 print("Rate limited. Waiting 60 seconds...")
12 time.sleep(60)
13 return search_with_rate_limit(params) # Retry
14 raise
Data Structure Navigation
The API response has a nested structure. Key paths to common information:
- NCT ID:
study['protocolSection']['identificationModule']['nctId']
- Title:
study['protocolSection']['identificationModule']['briefTitle']
- Status:
study['protocolSection']['statusModule']['overallStatus']
- Phase:
study['protocolSection']['designModule']['phases']
- Eligibility:
study['protocolSection']['eligibilityModule']
- Locations:
study['protocolSection']['contactsLocationsModule']['locations']
- Interventions:
study['protocolSection']['armsInterventionsModule']['interventions']
Error Handling
Always implement proper error handling for network requests:
python
1import requests
2
3try:
4 response = requests.get(url, params=params, timeout=30)
5 response.raise_for_status()
6 data = response.json()
7except requests.exceptions.HTTPError as e:
8 print(f"HTTP error: {e.response.status_code}")
9except requests.exceptions.RequestException as e:
10 print(f"Request failed: {e}")
11except ValueError as e:
12 print(f"JSON decode error: {e}")
Handling Missing Data
Not all trials have complete information. Always check for field existence:
python
1# Safe navigation with .get()
2phases = study['protocolSection'].get('designModule', {}).get('phases', [])
3enrollment = study['protocolSection'].get('designModule', {}).get('enrollmentInfo', {}).get('count', 'N/A')
4
5# Check before accessing
6if 'resultsSection' in study:
7 # Process results
8 pass
Technical Specifications
- Base URL:
https://clinicaltrials.gov/api/v2
- Authentication: Not required (public API)
- Rate Limit: ~50 requests/minute per IP
- Response Formats: JSON (default), CSV
- Max Page Size: 1000 studies per request
- Date Format: ISO 8601
- Text Format: CommonMark Markdown for rich text fields
- API Version: 2.0 (released March 2024)
- API Specification: OpenAPI 3.0
For complete technical details, see references/api_reference.md.