">
 

How to Build a Clinical Trial Search App in 5 Minutes - Clinical Trials API Tutorial

Iniciado por joomlamz, 24 de Maio de 2026, 18:00

Respostas: 0   |   Visualizações: 18

Tópico anterior - Tópico seguinte

0 Membros e 1 Visitante estão a ver este tópico.

How to Build a Clinical Trial Search App in 5 Minutes - Clinical Trials API Tutorial



Tópico: How to Build a Clinical Trial Search App in 5 Minutes - Clinical Trials API Tutorial
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------


What We're Building


In the next 5 minutes, you'll build a simple web app that lets users search for clinical trials by condition and phase, display results in cards, and paginate through results. Clinical Trials API is a REST API that wraps ClinicalTrials.gov into a developer-friendly interface. It gives you structured eligibility criteria (parsed into categories like Age, Gender, Condition, Lab Values -- no regex needed), geographic radius search by lat/lon, HTTP webhook alerts for new trials, cursor-based pagination, and aggregate statistics. Free tier available with no credit card. 480,000+ trials across 220+ countries, updated daily from the FDA. All powered by one API. You'll need basic HTML/JavaScript knowledge and a free RapidAPI account.



Step 1: Get Your API Key (30 Seconds)


• Go to https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api

• Click "Subscribe" on the Free plan (no credit card required)

• Copy your X-RapidAPI-Key from the dashboard

That's it. You're ready to make API calls.



Step 2: Make Your First API Call


Open your terminal and run this curl command (replace YOUR_API_KEY):

curl --request GET \
--url 'https://clinical-trials-api.p.rapidapi.com/v1/trials/search?query=breast+cancer&phase=Phase+2&status=Recruiting&limit=3' \
--header 'X-RapidAPI-Key: YOUR_API_KEY'

You should see something like this:

{
"success": true,
"data": [
{
"nct_id": "NCT04589845",
"title": "Atezolizumab and Chemotherapy for Triple-Negative Breast Cancer",
"brief_summary": "This phase II trial studies how well atezolizumab works with chemotherapy...",
"condition": "Breast Cancer",
"phase": "Phase 2",
"status": "Recruiting",
"enrollment_count": 280,
"last_updated": "2026-05-15",
"locations": [
{
"facility": "Dana-Farber Cancer Institute",
"city": "Boston",
"state": "MA",
"country": "United States"
}
]
}
],
"pagination": {
"total": 847,
"limit": 3,
"next_cursor": "eyJvZmZzZXQiOjN9",
"has_more": true
}
}

That's 847 matching trials, returned in clean JSON with built-in pagination. No scraping, no parsing, no pipeline maintenance.



Step 3: Build the Trial Search App


Create a single HTML file (index.html) and paste this code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clinical Trial Search</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; background: #f5f5f5; }
h1 { color: #1a1a2e; }
.search-box { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
input, select, button { padding: 10px 15px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; }
input { flex: 1; min-width: 200px; }
button { background: #1a56db; color: white; border: none; cursor: pointer; font-weight: 600; }
button:hover { background: #1647b8; }
.trial-card { background: white; border-radius: 8px; padding: 20px; margin-bottom: 15px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.trial-card h3 { margin: 0 0 8px 0; color: #1a1a2e; font-size: 16px; }
.trial-meta { display: flex; gap: 15px; font-size: 13px; color: #666; margin-bottom: 8px; flex-wrap: wrap; }
.badge { padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 600; }
.badge-recruiting { background: #d4edda; color: #155724; }
.badge-phase { background: #cce5ff; color: #004085; }
.summary { font-size: 14px; color: #444; line-height: 1.5; }
.pagination { display: flex; gap: 10px; align-items: center; margin-top: 20px; justify-content: center; }
.loading { text-align: center; padding: 40px; color: #666; }
.error { text-align: center; padding: 20px; color: #dc3545; background: #f8d7da; border-radius: 8px; }
.nct { color: #1a56db; font-family: monospace; font-size: 14px; }
.location { font-size: 12px; color: #888; margin-top: 6px; }
</style>
</head>
<body>
<h1>Clinical Trial Search</h1>
<p style="color: #666; margin-bottom: 20px;">Powered by <a href="https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api">Clinical Trials API</a> -- 480K+ FDA trials, free tier, no credit card.</p>

<div class="search-box">
<input type="text" id="query" placeholder="Search condition or keyword (e.g., breast cancer)" value="breast cancer">
<select id="phase">
<option value="">All Phases</option>
<option value="Phase 1">Phase 1</option>
<option value="Phase 2" selected>Phase 2</option>
<option value="Phase 3">Phase 3</option>
<option value="Phase 4">Phase 4</option>
</select>
<select id="status">
<option value="">All Statuses</option>
<option value="Recruiting" selected>Recruiting</option>
<option value="Not yet recruiting">Not Yet Recruiting</option>
<option value="Active not recruiting">Active, Not Recruiting</option>
<option value="Completed">Completed</option>
</select>
<button onclick="searchTrials()">Search</button>
</div>

<div id="results"></div>

<script>
const API_KEY = 'YOUR_RAPIDAPI_KEY'; // Replace with your key
const BASE_URL = 'https://clinical-trials-api.p.rapidapi.com';

let currentCursor = null;
let currentQuery = null;

async function searchTrials(cursor = null) {
const query = document.getElementById('query').value;
const phase = document.getElementById('phase').value;
const status = document.getElementById('status').value;

const params = new URLSearchParams({ query, limit: '5' });
if (phase) params.append('phase', phase);
if (status) params.append('status', status);
if (cursor) params.append('cursor', cursor);

const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = '<div class="loading">Searching 480K+ clinical trials...</div>';

try {
const r = await fetch(`${BASE_URL}/v1/trials/search?${params}`, {
headers: { 'X-RapidAPI-Key': API_KEY }
});

if (r.status === 401) {
resultsDiv.innerHTML = '<div class="error">Invalid API key. Get your free key at <a href="https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api">rapidapi.com/clinical-trials-api</a></div>';
return;
}

if (!r.ok) {
resultsDiv.innerHTML = `<div class="error">API error: HTTP ${r.status}</div>`;
return;
}

const body = await r.json();
if (!body.success) {
resultsDiv.innerHTML = `<div class="error">${body.error?.message || 'Unknown error'}</div>`;
return;
}

currentCursor = cursor;
currentQuery = { query, phase, status };
renderResults(body);

} catch (e) {
resultsDiv.innerHTML = `<div class="error">Network error: ${e.message}</div>`;
}
}

function renderResults(body) {
const resultsDiv = document.getElementById('results');
const pagination = body.pagination;

let html = `<p style="color: #666; margin-bottom: 15px;">Found ${pagination.total.toLocaleString()} trials. Showing ${(currentCursor ? 'next page' : 'first')} ${body.data.length} results.</p>`;

body.data.forEach(trial => {
const loc = trial.locations && trial.locations[0] ? `${trial.locations[0].facility}, ${trial.locations[0].city}, ${trial.locations[0].state}` : '';
html += `
<div class="trial-card">
<h3>${trial.title}</h3>
<div class="trial-meta">
<span class="nct">${trial.nct_id}</span>
<span class="badge badge-phase">${trial.phase}</span>
<span class="badge badge-recruiting">${trial.status}</span>
${trial.enrollment_count ? `<span>${trial.enrollment_count} participants</span>` : ''}
</div>
<p class="summary">${(trial.brief_summary || '').substring(0, 200)}${(trial.brief_summary || '').length > 200 ? '...' : ''}</p>
${loc ? `<p class="location">${loc}</p>` : ''}
</div>
`;
});

html += '<div class="pagination">';

if (currentCursor) {
html += `<button onclick="searchTrials(null)">First Page</button>`;
}

if (pagination.has_more) {
html += `<button onclick="loadNextPage('${pagination.next_cursor}')">Next Page (${pagination.total - (currentCursor ? parseInt(currentCursor.match(/\d+/)?.[0] || 0) : body.data.length)} remaining)</button>`;
} else if (body.data.length > 0) {
html += '<span style="color: #666;">All results loaded.</span>';
}

html += '</div>';
resultsDiv.innerHTML = html;
}

function loadNextPage(cursor) {
document.getElementById('query').value = currentQuery.query;
document.getElementById('phase').value = currentQuery.phase;
document.getElementById('status').value = currentQuery.status;
searchTrials(cursor);
}

// Search on load
searchTrials();
</script>
</body>
</html>



Step 4: Run It


• Replace YOUR_RAPIDAPI_KEY on line ~70 with your actual API key

• Open index.html in your browser (just double-click the file)

• You have a working clinical trial search app

Try searching for "Alzheimer", "diabetes", or leave the default "breast cancer" -- you'll see real FDA trial data appear in under a second.



What's Next?


• Add the geographic radius search endpoint (/v1/trials/nearby) to build a "trials near me" feature with HTML5 geolocation

• Add structured eligibility display by calling /v1/trials/{nct_id}/eligibility when a user clicks a trial card (Pro tier: $19/mo)

• Set up a webhook alert via POST /v1/alerts to get notified when new trials match your users' saved search criteria

• Deploy to Vercel, Netlify, or GitHub Pages for a live demo

• Style it with Tailwind CSS for a professional look



The API



Free tier: 100 requests/day, basic search, nearby search, stats, conditions browser, 3 saved alerts


Pro: $19/mo -- 10,000 requests, structured eligibility parsing, 25 webhook alerts, email support

• Ultra: $49/mo -- 50,000 requests, unlimited alerts, priority support

• Docs: https://rapidapi.com/capifactory-capifactory-default/api/clinical-trials-api/docs

Subscribe on RapidAPI - free tier, no credit card required.

If you build something with this API, tag me - I'd love to see what you create. Drop questions in the comments and I'll answer them.


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: